UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

1 lines 9.55 kB
{"version":3,"file":"useParentProvider-D71VAfNa.cjs","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 if (!ids) return;\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":["getCurrentInstance","ref","useDebounce","unrefElement","watch","useSequentialId","provide","inject","onUnmounted"],"mappings":";;;;;;AAgDO,SAAS,kBACZ,SAGF;AAEE,QAAM,KAAKA,IAAAA,mBAAA;AACX,MAAI,CAAC;AACD,UAAM,IAAI;AAAA,MACN;AAAA,IAAA;AAGR,QAAM,cAAc,GAAG,OAAO,SAAS;AACvC,QAAM,MAAM,SAAS,OAAO;AAE5B,QAAM,aAAaC,IAAAA,IAA8B,EAAE;AAEnD,MAAI,SAAS,SAAS;AAElB,UAAM,cAAcC,wBAAY,CAAC,UAAmC;AAChE,YAAM,SAASC,aAAAA,aAAa,QAAQ,OAAO;AAC3C,UAAI,CAAC,OAAQ;AAGb,YAAM,MAAM,MACP,IAAI,CAAC,SAAS,aAAa,GAAG,IAAI,KAAK,UAAU,IAAI,EACrD,KAAK,GAAG;AAEb,UAAI,CAAC,IAAK;AAGV,YAAM,WAAW,OAAO,iBAAiB,GAAG;AAG5C,YAAM,YAAY,MAAM,KAAK,QAAQ,EAAE;AAAA,QAAI,CAAC,OACxC,GAAG,aAAa,SAAS,GAAG,QAAQ,GAAG,GAAG,KAAK,EAAE;AAAA,MAAA;AAIrD,YAAM;AAAA,QACF,CAAC,SACI,KAAK,QAAQ,UAAU,QAAQ,GAAG,KAAK,UAAU,EAAE;AAAA,MAAA;AAI5D,YAAM,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA,IAC1C,GAAG,GAAG;AAINC,QAAAA,MAAM,YAAY,WAAW;AAAA,EACjC;AAEA,QAAM,EAAE,aAAA,IAAiBC,gBAAAA,gBAAgB,CAAC;AAE1C,WAAS,aAAa,MAAyC;AAC3D,UAAM,QAAQ,WAAW,MAAM;AAC/B,UAAM,aAAa,aAAA;AACnB,UAAM,OAAO,EAAE,OAAO,MAAM,WAAA;AAE5B,eAAW,QAAQ;AAAA,MACf,GAAG,WAAW;AAAA,MACd;AAAA,IAAA;AAEJ,WAAO;AAAA,EACX;AAEA,WAAS,eAAe,MAA0B;AAC9C,eAAW,QAAQ,WAAW,MAAM,OAAO,CAAC,MAAM,MAAM,IAAI;AAAA,EAChE;AAGAC,MAAAA,QAA2C,QAAQ,KAAK;AAAA,IACpD;AAAA,IACA;AAAA,IACA,MAAM,SAAS;AAAA,EAAA,CAClB;AAED,SAAO;AAAA,IACH;AAAA,EAAA;AAER;AAwEO,SAAS,iBACZ,SAIF;AACE,YAAU,OAAO,OAAO,EAAE,YAAY,MAAM,UAAU,KAAA,GAAQ,OAAO;AAGrE,QAAM,KAAKN,IAAAA,mBAAA;AACX,MAAI,CAAC;AACD,UAAM,IAAI;AAAA,MACN;AAAA,IAAA;AAGR,QAAM,cAAc,GAAG,OAAO,SAAS;AACvC,QAAM,MAAM,SAAS,OAAO;AAG5B,QAAM,SAASO,IAAAA,OAEb,QAAQ,KAAK,MAAS;AAExB,MAAI,QAAQ,cAAc,CAAC;AACvB,UAAM,IAAI;AAAA,MACN,mBAAmB,GAAG,OAAO,SAAS,IAAI,SAAS,GAAG;AAAA,IAAA;AAG9D,QAAM,OAAON,IAAAA,IAAA;AAEb,MAAI,UAAU,QAAQ;AAClB,SAAK,QAAQ,OAAO;AAAA,MAChB,SAAS;AAAA,IAAA;AAGjBO,MAAAA,YAAY,MAAM;AACd,QAAI,UAAU,KAAK,MAAO,QAAO,eAAe,KAAK,KAAK;AAAA,EAC9D,CAAC;AAED,QAAM,OAAO,QAAQ,QAAQP,QAAA;AAE7B,SAAO,EAAE,QAAQ,MAAM,KAAA;AAC3B;;;"}