{"version":3,"file":"useParentProvider-26MPTCZ6.mjs","sources":["../../src/composables/useParentProvider.ts"],"sourcesContent":["import {\n    getCurrentInstance,\n    inject,\n    onUnmounted,\n    provide,\n    ref,\n    watch,\n    type Component,\n    type ComputedRef,\n    type MaybeRefOrGetter,\n    type Ref,\n} from \"vue\";\nimport { unrefElement } from \"./unrefElement\";\nimport { useDebounce } from \"./useDebounce\";\nimport { useSequentialId } from \"./useSequentialId\";\n\nexport type ProviderItem<T = unknown> = {\n    index: number;\n    data?: T;\n    identifier: string;\n};\n\ntype PovidedData<P, I = unknown> = {\n    registerItem: (data?: I) => ProviderItem<I>;\n    unregisterItem: (item: ProviderItem) => void;\n    data?: ComputedRef<P>;\n};\n\ntype ProviderParentOptions<T = unknown> = {\n    /**\n     * Root element of the provider component\n     */\n    rootRef?: MaybeRefOrGetter<HTMLElement | Component | null | undefined>;\n    /**\n     * Override the provide/inject key.\n     * Default is the component configField attribute\n     */\n    key?: string;\n    /**\n     * Additional data provided for the child to the item\n     */\n    data?: ComputedRef<T>;\n};\n\n/**\n * Provide functionalities and data to child components\n * @param options parent provider options\n */\nexport function useProviderParent<ItemData = unknown, ParentData = unknown>(\n    options?: ProviderParentOptions<ParentData>,\n): {\n    childItems: Readonly<Ref<ProviderItem<ItemData>[]>>;\n} {\n    // getting a hold of the internal instance in setup()\n    const vm = getCurrentInstance();\n    if (!vm)\n        throw new Error(\n            \"useProviderChild must be called within a component setup function.\",\n        );\n\n    const configField = vm.proxy?.$options.configField;\n    const key = options?.key || configField;\n\n    const childItems = ref<ProviderItem<ItemData>[]>([]);\n\n    if (options?.rootRef) {\n        // debounced sort function\n        const sortHandler = useDebounce((items: typeof childItems.value) => {\n            const parent = unrefElement(options.rootRef);\n            if (!parent) return;\n\n            // create a list of child item ids\n            const ids = items\n                .map((item) => `[data-id=\"${key}-${item.identifier}\"]`)\n                .join(\",\");\n\n            // query all child items in the order of the DOM appearance\n            const children = parent.querySelectorAll(ids);\n\n            // create a list of ids ordered after the elements in DOM\n            const sortedIds = Array.from(children).map((el) =>\n                el.getAttribute(\"data-id\")?.replace(`${key}-`, \"\"),\n            );\n\n            // update the index attribute of the child items\n            items.forEach(\n                (item) =>\n                    (item.index = sortedIds.indexOf(`${item.identifier}`)),\n            );\n\n            // sort items according to their index position\n            items.sort((a, b) => a.index - b.index);\n        }, 500);\n\n        // when child items are added/removed (no deep change - only list update)\n        // sort them according to their DOM position\n        watch(childItems, sortHandler);\n    }\n\n    const { nextSequence } = useSequentialId(1);\n\n    function registerItem(data?: ItemData): ProviderItem<ItemData> {\n        const index = childItems.value.length;\n        const identifier = nextSequence();\n        const item = { index, data, identifier };\n        // add new item to the child list\n        childItems.value = [\n            ...childItems.value,\n            item,\n        ] as ProviderItem<ItemData>[];\n        return item;\n    }\n\n    function unregisterItem(item: ProviderItem): void {\n        childItems.value = childItems.value.filter((i) => i !== item);\n    }\n\n    /** Provide functionality for child components via dependency injection. */\n    provide<PovidedData<ParentData, ItemData>>(\"$o-\" + key, {\n        registerItem,\n        unregisterItem,\n        data: options?.data,\n    });\n\n    return {\n        childItems: childItems as Ref<ProviderItem<ItemData>[]>,\n    };\n}\n\ntype ProviderChildOptions<T = unknown> = {\n    /**\n     * Override the provide/inject key.\n     * Default is the component configField attribute\n     */\n    key?: string;\n    /**\n     * Does the child need the be below the parent?\n     * @default true\n     */\n    needParent?: boolean;\n    /**\n     * Additional data appended to the item\n     */\n    data?: ComputedRef<T>;\n    /**\n     * Register child on parent\n     * @default true\n     */\n    register?: boolean;\n};\n\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options: Omit<ProviderChildOptions<ItemData>, \"needParent\"> & {\n        needParent: true;\n    },\n): {\n    parent: Readonly<Ref<ParentData>>;\n    item: Readonly<Ref<ProviderItem<ItemData> | undefined>>;\n};\n\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options: Omit<ProviderChildOptions<ItemData>, \"needParent\"> & {\n        needParent: false;\n    },\n): {\n    parent: Readonly<Ref<ParentData | undefined>>;\n    item: Readonly<Ref<ProviderItem<ItemData> | undefined>>;\n};\n\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options: Omit<ProviderChildOptions<ItemData>, \"needParent\"> & {\n        register: false;\n    },\n): {\n    parent: Readonly<Ref<ParentData>>;\n    item: Readonly<Ref<undefined>>;\n};\n\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options: Omit<ProviderChildOptions<ItemData>, \"needParent\" | \"register\"> & {\n        needParent: true;\n        register: true;\n    },\n): {\n    parent: Readonly<Ref<ParentData>>;\n    item: Readonly<Ref<ProviderItem<ItemData>>>;\n};\n\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options?: Omit<ProviderChildOptions<ItemData>, \"needParent\" | \"register\">,\n): {\n    parent: Readonly<Ref<ParentData>>;\n    item: Readonly<Ref<ProviderItem<ItemData>>>;\n};\n\n/**\n * Inject functionalities and data from parent components\n * @param options additional options\n */\nexport function useProviderChild<ParentData, ItemData = unknown>(\n    options?: ProviderChildOptions<ItemData>,\n): {\n    parent: Readonly<Ref<ParentData | undefined>>;\n    item: Readonly<Ref<ProviderItem<ItemData> | undefined>>;\n} {\n    options = Object.assign({ needParent: true, register: true }, options);\n\n    // getting a hold of the internal instance in setup()\n    const vm = getCurrentInstance();\n    if (!vm)\n        throw new Error(\n            \"useProviderChild must be called within a component setup function.\",\n        );\n\n    const configField = vm.proxy?.$options.configField;\n    const key = options?.key || configField;\n\n    /** Inject parent component functionality if used inside one **/\n    const parent = inject<\n        PovidedData<ParentData, ComputedRef<ItemData>> | undefined\n    >(\"$o-\" + key, undefined);\n\n    if (options.needParent && !parent)\n        throw new Error(\n            `You should wrap ${vm.proxy?.$options.name} in a ${key} component`,\n        );\n\n    const item = ref<ProviderItem<ItemData>>();\n\n    if (parent && options.register)\n        item.value = parent.registerItem(\n            options?.data,\n        ) as ProviderItem<ItemData>;\n\n    onUnmounted(() => {\n        if (parent && item.value) parent.unregisterItem(item.value);\n    });\n\n    const data = parent?.data || ref();\n\n    return { parent: data, item: item };\n}\n"],"names":["_a"],"mappings":";;;;;AAgDO,SAAS,kBACZ,SAGF;;AAEE,QAAM,KAAK,mBAAmB;AAC9B,MAAI,CAAC;AACD,UAAM,IAAI;AAAA,MACN;AAAA,IACJ;AAEE,QAAA,eAAc,QAAG,UAAH,mBAAU,SAAS;AACjC,QAAA,OAAM,mCAAS,QAAO;AAEtB,QAAA,aAAa,IAA8B,EAAE;AAEnD,MAAI,mCAAS,SAAS;AAEZ,UAAA,cAAc,YAAY,CAAC,UAAmC;AAC1D,YAAA,SAAS,aAAa,QAAQ,OAAO;AAC3C,UAAI,CAAC,OAAQ;AAGb,YAAM,MAAM,MACP,IAAI,CAAC,SAAS,aAAa,GAAG,IAAI,KAAK,UAAU,IAAI,EACrD,KAAK,GAAG;AAGP,YAAA,WAAW,OAAO,iBAAiB,GAAG;AAG5C,YAAM,YAAY,MAAM,KAAK,QAAQ,EAAE;AAAA,QAAI,CAAC,OACxC;;AAAA,kBAAAA,MAAA,GAAG,aAAa,SAAS,MAAzB,gBAAAA,IAA4B,QAAQ,GAAG,GAAG,KAAK;AAAA;AAAA,MACnD;AAGM,YAAA;AAAA,QACF,CAAC,SACI,KAAK,QAAQ,UAAU,QAAQ,GAAG,KAAK,UAAU,EAAE;AAAA,MAC5D;AAGA,YAAM,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA,OACvC,GAAG;AAIN,UAAM,YAAY,WAAW;AAAA,EAAA;AAGjC,QAAM,EAAE,aAAA,IAAiB,gBAAgB,CAAC;AAE1C,WAAS,aAAa,MAAyC;AACrD,UAAA,QAAQ,WAAW,MAAM;AAC/B,UAAM,aAAa,aAAa;AAChC,UAAM,OAAO,EAAE,OAAO,MAAM,WAAW;AAEvC,eAAW,QAAQ;AAAA,MACf,GAAG,WAAW;AAAA,MACd;AAAA,IACJ;AACO,WAAA;AAAA,EAAA;AAGX,WAAS,eAAe,MAA0B;AAC9C,eAAW,QAAQ,WAAW,MAAM,OAAO,CAAC,MAAM,MAAM,IAAI;AAAA,EAAA;AAIhE,UAA2C,QAAQ,KAAK;AAAA,IACpD;AAAA,IACA;AAAA,IACA,MAAM,mCAAS;AAAA,EAAA,CAClB;AAEM,SAAA;AAAA,IACH;AAAA,EACJ;AACJ;AAwEO,SAAS,iBACZ,SAIF;;AACY,YAAA,OAAO,OAAO,EAAE,YAAY,MAAM,UAAU,QAAQ,OAAO;AAGrE,QAAM,KAAK,mBAAmB;AAC9B,MAAI,CAAC;AACD,UAAM,IAAI;AAAA,MACN;AAAA,IACJ;AAEE,QAAA,eAAc,QAAG,UAAH,mBAAU,SAAS;AACjC,QAAA,OAAM,mCAAS,QAAO;AAG5B,QAAM,SAAS,OAEb,QAAQ,KAAK,MAAS;AAEpB,MAAA,QAAQ,cAAc,CAAC;AACvB,UAAM,IAAI;AAAA,MACN,oBAAmB,QAAG,UAAH,mBAAU,SAAS,IAAI,SAAS,GAAG;AAAA,IAC1D;AAEJ,QAAM,OAAO,IAA4B;AAEzC,MAAI,UAAU,QAAQ;AAClB,SAAK,QAAQ,OAAO;AAAA,MAChB,mCAAS;AAAA,IACb;AAEJ,cAAY,MAAM;AACd,QAAI,UAAU,KAAK,MAAc,QAAA,eAAe,KAAK,KAAK;AAAA,EAAA,CAC7D;AAEK,QAAA,QAAO,iCAAQ,SAAQ,IAAI;AAE1B,SAAA,EAAE,QAAQ,MAAM,KAAW;AACtC;"}