UNPKG

@empathyco/x-components

Version:
126 lines (123 loc) 5.17 kB
import { defineComponent, computed, ref, inject, provide, watch } from 'vue'; import { useXBus } from '../../composables/use-x-bus.js'; import { RESULT_WITH_VARIANTS_KEY, SELECTED_VARIANTS_KEY, SELECT_RESULT_VARIANT_KEY } from '../decorators/injection.consts.js'; /** * Component that exposes the result merged with its selected variant in the default slot. * * It receives the original result and keeps track of the selected variant. * * It provides the original result, the array containing the selected variants and a callback to * set the selected variant to be used from a child. * * @public */ var _sfc_main = defineComponent({ name: 'ResultVariantsProvider', props: { /** The original result containing the variants. */ result: { type: Object, required: true, }, /** * The provider by default will auto select the first variants of all levels. * This prop allows to limit the number of variants auto selected when the provider is created. * Take into account that the depth will be the variants level + 1, so, setting autoSelectDepth * to 0 will not select any variant, setting it to 1 will select only the first variant of the * first level, and so on. */ autoSelectDepth: { type: Number, default: Number.POSITIVE_INFINITY, }, }, setup(props, { slots }) { const xBus = useXBus(); /** * The original result containing the variants as a computed ref object to enable watching * prop changes. */ const result = computed(() => props.result); /** * Array to keep track of the selected variants of the result. * Each position of the array is a nest level in the variants' hierarchy, so, * the second position will contain a variant that is present inside the variant of the first * position, and so on. */ const selectedVariants = ref([]); /** * It injects the queryPreviewHash provided by a query-preview. * * @internal */ const queryPreviewHash = inject('queryPreviewHash', null); /** * Selects a variant of the result. * When called, it slices the array of selected variants to remove the selected child variants. * Emits the {@link XEventsTypes.UserSelectedAResultVariant} when called. * * @param variant - The variant to set. * @param level - The nest level where the variant is placed inside the result. */ function selectResultVariant(variant, level = 0) { if (selectedVariants.value[level] === variant) { return; } selectedVariants.value.splice(level, Number.POSITIVE_INFINITY, variant); xBus.emit('UserSelectedAResultVariant', { variant, level, result: result.value, queryPreviewHash, }); } /** * Merges the original result with the selected variant. * The merge is done with all the selected variants of the array. * * @returns - The result with the selected variant merged. */ const resultToProvide = computed(() => { if (!selectedVariants.value.length) { return result.value; } const mergedResult = selectedVariants.value.reduce((result, variant) => { return { ...result, ...variant, }; }, result.value); mergedResult.variants = result.value.variants; return mergedResult; }); /** * Adds to the selectedVariants array the variants up to the autoSelectDepth level. * * @param variant - Variant to add to the array. */ function selectFirstVariants(variant) { if (!!variant && selectedVariants.value.length <= props.autoSelectDepth - 1) { selectedVariants.value.push(variant); selectFirstVariants(variant.variants?.[0]); } } /** Provides the original result passed as a prop. */ provide(RESULT_WITH_VARIANTS_KEY, result); /** The selected variants of the result. */ provide(SELECTED_VARIANTS_KEY, selectedVariants); /** The result variant key that will be selected. */ provide(SELECT_RESULT_VARIANT_KEY, selectResultVariant); /** * Resets the selected variants when the result changes. * That includes doing the auto selection of the variants when the component is created * and when the result is changed. */ watch(result, () => { selectedVariants.value = []; selectFirstVariants(result.value?.variants?.[0]); }, { immediate: true }); return () => slots.default?.({ result: resultToProvide.value })[0] ?? ''; }, }); export { _sfc_main as default }; //# sourceMappingURL=result-variants-provider.vue.js.map