UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

187 lines (186 loc) 6.93 kB
const require_keys = require("./keys-durSVUrO.js"); const require_floatingUi = require("./floatingUi-Cs4rDXmO.js"); //#region src/directives/utils.ts /** * Gets the component instance UID from a directive binding * @throws Error if binding.instance is not available */ function getDirectiveUid(binding) { if (!binding.instance) throw new Error("[Bootstrap-Vue-Next] Directive binding.instance is not available"); return binding.instance.$.uid; } /** * Initializes UID-namespaced storage on an element for a directive * @param el - The HTML element * @param propertyName - The property name (e.g., '$__tooltip', '$__popover') * @param uid - The component instance UID * @param binding - The directive binding value to cache * @returns The initialized instance state */ function initDirectiveInstance(el, propertyName, uid, binding) { const elWithProps = el; elWithProps[propertyName] = elWithProps[propertyName] ?? Object.create(null); const state = { binding: JSON.stringify([binding.modifiers, binding.value]), destroying: false }; elWithProps[propertyName][uid] = state; return state; } /** * Gets the instance state for a directive, if it exists * @param el - The HTML element * @param propertyName - The property name (e.g., '$__tooltip', '$__popover') * @param uid - The component instance UID * @returns The instance state or undefined if not found */ function getDirectiveInstance(el, propertyName, uid) { return el[propertyName]?.[uid]; } /** * Checks if the directive binding has changed for this instance * @param instance - The directive instance state * @param binding - The current directive binding * @returns true if the binding has changed, false otherwise */ function hasBindingChanged(instance, binding) { const newBinding = JSON.stringify([binding.modifiers, binding.value]); return instance.binding !== newBinding; } /** * Updates the cached binding value for a directive instance * @param instance - The directive instance state * @param binding - The new directive binding */ function updateBindingCache(instance, binding) { instance.binding = JSON.stringify([binding.modifiers, binding.value]); } /** * Cleans up a directive instance * @param el - The HTML element * @param propertyName - The property name (e.g., '$__tooltip', '$__popover') * @param uid - The component instance UID */ function cleanupDirectiveInstance(el, propertyName, uid) { const elWithProps = el; const instance = elWithProps[propertyName]?.[uid]; if (instance) { instance.destroying = true; delete elWithProps[propertyName][uid]; } } function findProvides(binding, vnode) { return (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides; } function findComponentParent(vnode, root) { const stack = /* @__PURE__ */ new Set(); const walk = (children) => { for (const child of children) { if (!child) continue; if (child === vnode || child.el && vnode.el && child.el === vnode.el) return true; stack.add(child); let result; if (child.suspense) result = walk([child.ssContent]); else if (Array.isArray(child.children)) result = walk(child.children); else if (child.component?.vnode) result = walk([child.component?.subTree]); if (result) return result; stack.delete(child); } return false; }; if (!walk([root.subTree])) { console.error("Could not find original vnode, will not inherit provides"); return root; } const result = Array.from(stack).reverse(); for (const child of result) if (child.component) return child.component; return root; } /** * Creates a floating UI directive (tooltip or popover) with UID-namespaced state management * @param propertyName - The property name for storing state (e.g., '$__tooltip', '$__popover') * @param componentDefaultsKey - The key for accessing component defaults (e.g., 'BTooltip', 'BPopover') * @param buildProps - Optional function to customize the props passed to bind() * @returns A Vue directive object */ function createFloatingDirective(propertyName, componentDefaultsKey, buildProps) { return { mounted(el, binding, vnode) { const uid = getDirectiveUid(binding); const defaultsMap = findProvides(binding, vnode)[require_keys.defaultsKey]?.value; if (!require_floatingUi.resolveActiveStatus(binding.value)) return; const text = require_floatingUi.resolveContent(binding.value, el); if (!text.body && !text.title) return; initDirectiveInstance(el, propertyName, uid, binding); require_floatingUi.bind(el, binding, buildProps ? buildProps(text, defaultsMap?.[componentDefaultsKey], binding, el) : { ...defaultsMap?.[componentDefaultsKey] || void 0, ...require_floatingUi.resolveDirectiveProps(binding, el), ...text }); }, updated(el, binding, vnode) { const uid = getDirectiveUid(binding); let instance = getDirectiveInstance(el, propertyName, uid); const defaultsMap = findProvides(binding, vnode)[require_keys.defaultsKey]?.value; if (!require_floatingUi.resolveActiveStatus(binding.value)) { if (instance && el.$__element) { require_floatingUi.unbind(el); cleanupDirectiveInstance(el, propertyName, uid); } return; } const text = require_floatingUi.resolveContent(binding.value, el); if (!text.body && !text.title) { if (instance && el.$__element) { require_floatingUi.unbind(el); cleanupDirectiveInstance(el, propertyName, uid); } return; } if (!instance) { instance = initDirectiveInstance(el, propertyName, uid, binding); require_floatingUi.bind(el, binding, buildProps ? buildProps(text, defaultsMap?.[componentDefaultsKey], binding, el) : { ...defaultsMap?.[componentDefaultsKey] || void 0, ...require_floatingUi.resolveDirectiveProps(binding, el), ...text }); return; } if (!hasBindingChanged(instance, binding)) return; if (instance.destroying) return; require_floatingUi.unbind(el); require_floatingUi.bind(el, binding, buildProps ? buildProps(text, defaultsMap?.[componentDefaultsKey], binding, el) : { ...defaultsMap?.[componentDefaultsKey] || void 0, ...require_floatingUi.resolveDirectiveProps(binding, el), ...text }); updateBindingCache(instance, binding); }, beforeUnmount(el, binding) { const uid = getDirectiveUid(binding); if (!getDirectiveInstance(el, propertyName, uid)) return; require_floatingUi.unbind(el); cleanupDirectiveInstance(el, propertyName, uid); } }; } //#endregion Object.defineProperty(exports, "createFloatingDirective", { enumerable: true, get: function() { return createFloatingDirective; } }); Object.defineProperty(exports, "findProvides", { enumerable: true, get: function() { return findProvides; } }); Object.defineProperty(exports, "getDirectiveUid", { enumerable: true, get: function() { return getDirectiveUid; } }); //# sourceMappingURL=utils-CaC78Zdk.js.map