UNPKG

@empathyco/x-components

Version:
82 lines (79 loc) 3.33 kB
import { defineComponent, inject, computed, provide, h } from 'vue'; import { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts.js'; import ItemsList from '../../../components/items-list.vue.js'; import { use$x } from '../../../composables/use-_x.js'; import { useState } from '../../../composables/use-state.js'; import { AnimationProp } from '../../../types/animation-prop.js'; import { searchXModule } from '../x-module.js'; /** * It renders a {@link ItemsList} of promoteds from {@link SearchState.promoteds}. * * The component provides a default slot which wraps the whole component with the `promoteds` * plus the `injectedListItems` which also contains the injected list items from * the ancestor. * * It also provides the parent slots to customize the items. * * @public */ var _sfc_main = defineComponent({ name: 'PromotedsList', xModule: searchXModule.name, props: { /** Animation component that will be used to animate the promoteds. */ animation: { type: AnimationProp, default: 'ul', }, }, setup(props, { slots }) { const $x = use$x(); /** The promoteds to render from the state. */ const stateItems = useState('search').promoteds; /** It injects {@link ListItem} provided by an ancestor as injectedListItems. */ const injectedListItems = inject(LIST_ITEMS_KEY); /** * The `stateItems` concatenated with the `injectedListItems` if there are. * * @remarks This computed defines the merging strategy of the `stateItems` and the * `injectedListItems`. * * @returns List of {@link ListItem}. */ const items = computed(() => { if (!injectedListItems?.value.length) { return stateItems.value; } const items = [...injectedListItems.value]; for (const item of stateItems.value) { const position = item.position ?? 1; let index = position - 1; while (items.at(index)?.modelName === 'Promoted') { index++; } const isIndexInLoadedPages = index <= items.length; const areAllPagesLoaded = $x.results.length === $x.totalResults; if (!isIndexInLoadedPages && !areAllPagesLoaded) { break; } items.splice(index, 0, item); } return items; }); /** * The computed list items of the entity that uses the mixin. * * @remarks It should be overridden in the component that uses the mixin and it's intended to be * filled with items from the state. Vue doesn't allow mixins as abstract classes. * @returns An empty array as fallback in case it is not overridden. */ provide(LIST_ITEMS_KEY, items); return () => { const innerProps = { items: items.value, animation: props.animation }; // https://vue-land.github.io/faq/forwarding-slots#passing-all-slots return slots.default?.(innerProps)[0] ?? h(ItemsList, innerProps, slots); }; }, }); export { _sfc_main as default }; //# sourceMappingURL=promoteds-list.vue.js.map