UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

1 lines 9.36 kB
{"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;"}