import { loadBaseStyle } from 'primevue/base'; import { ObjectUtils } from 'primevue/utils'; import { mergeProps } from 'vue'; const BaseDirective = { _getMeta: (...args) => [ObjectUtils.isObject(args[0]) ? undefined : args[0], ObjectUtils.getItemValue(ObjectUtils.isObject(args[0]) ? args[0] : args[1])], _getOptionValue: (options, key = '', params = {}) => { const fKeys = ObjectUtils.toFlatCase(key).split('.'); const fKey = fKeys.shift(); return fKey ? ObjectUtils.isObject(options) ? BaseDirective._getOptionValue(ObjectUtils.getItemValue(options[Object.keys(options).find((k) => ObjectUtils.toFlatCase(k) === fKey) || ''], params), fKeys.join('.'), params) : undefined : ObjectUtils.getItemValue(options, params); }, _getPTValue: (instance = {}, obj = {}, key = '', params = {}, searchInDefaultPT = true) => { const getValue = (...args) => { const value = BaseDirective._getOptionValue(...args); return ObjectUtils.isString(value) || ObjectUtils.isArray(value) ? { class: value } : value; }; const datasetPrefix = 'data-pc-'; const self = getValue(obj, key, params); const globalPT = searchInDefaultPT ? getValue(instance.defaultPT, key, params) : undefined; const merged = mergeProps(self, globalPT, { ...(key === 'root' && { [`${datasetPrefix}name`]: ObjectUtils.toFlatCase(instance.$name) }), [`${datasetPrefix}section`]: ObjectUtils.toFlatCase(key) }); return merged; }, _hook: (directiveName, hookName, el, binding, vnode, prevVnode) => { const name = `on${ObjectUtils.toCapitalCase(hookName)}`; const config = binding?.instance?.$primevue?.config; const selfHook = binding?.value?.pt?.hooks?.[name]; const globalHook = config?.pt?.directives?.[directiveName]?.hooks?.[name]; const options = { el, binding, vnode, prevVnode }; selfHook?.(el?.$instance, options); globalHook?.(el?.$instance, options); }, _extend: (name, options = {}) => { const handleHook = (hook, el, binding, vnode, prevVnode) => { el._$instances = el._$instances || {}; const config = binding?.instance?.$primevue?.config; const $prevInstance = el._$instances[name] || {}; const $options = ObjectUtils.isEmpty($prevInstance) ? { ...options, ...options?.methods } : {}; el._$instances[name] = { ...$prevInstance, /* new instance variables to pass in directive methods */ $name: name, $host: el, $binding: binding, $el: $prevInstance['$el'] || undefined, $css: { classes: undefined, inlineStyles: undefined, loadStyle: () => {}, ...options?.css }, /* computed instance variables */ defaultPT: config?.pt?.directives?.[name], isUnstyled: el.unstyled !== undefined ? el.unstyled : config?.unstyled, /* instance's methods */ ptm: (key = '', params = {}) => BaseDirective._getPTValue(el.$instance, el.$instance?.$binding?.value?.pt, key, { ...params }), ptmo: (obj = {}, key = '', params = {}) => BaseDirective._getPTValue(el.$instance, obj, key, params, false), cx: (key = '', params = {}) => (!el.$instance?.isUnstyled ? BaseDirective._getOptionValue(el.$instance?.$css?.classes, key, { ...params }) : undefined), sx: (key = '', when = true, params = {}) => (when ? BaseDirective._getOptionValue(el.$instance?.$css?.inlineStyles, key, { ...params }) : undefined), ...$options }; el.$instance = el._$instances[name]; // pass instance data to hooks el.$instance[hook]?.(el, binding, vnode, prevVnode); // handle hook in directive implementation BaseDirective._hook(name, hook, el, binding, vnode, prevVnode); // handle hooks during directive uses (global and self-definition) }; return { created: (el, binding, vnode, prevVnode) => { handleHook('created', el, binding, vnode, prevVnode); }, beforeMount: (el, binding, vnode, prevVnode) => { loadBaseStyle(); !el.$instance?.isUnstyled && el.$instance?.$css?.loadStyle(); handleHook('beforeMount', el, binding, vnode, prevVnode); }, mounted: (el, binding, vnode, prevVnode) => { handleHook('mounted', el, binding, vnode, prevVnode); }, beforeUpdate: (el, binding, vnode, prevVnode) => { handleHook('beforeUpdate', el, binding, vnode, prevVnode); }, updated: (el, binding, vnode, prevVnode) => { handleHook('updated', el, binding, vnode, prevVnode); }, beforeUnmount: (el, binding, vnode, prevVnode) => { handleHook('beforeUnmount', el, binding, vnode, prevVnode); }, unmounted: (el, binding, vnode, prevVnode) => { handleHook('unmounted', el, binding, vnode, prevVnode); } }; }, extend: (...args) => { const [name, options] = BaseDirective._getMeta(...args); return { extend: (..._args) => { const [_name, _options] = BaseDirective._getMeta(..._args); return BaseDirective.extend(_name, { ...options, ...options?.methods, ..._options }); }, ...BaseDirective._extend(name, options) }; } }; export default BaseDirective;