UNPKG

@empathyco/x-components

Version:
93 lines (90 loc) 3.65 kB
import { defineComponent, inject, computed } from 'vue'; import { SELECT_RESULT_VARIANT_KEY, RESULT_WITH_VARIANTS_KEY, SELECTED_VARIANTS_KEY } from '../decorators/injection.consts.js'; /** * Component to show and select the available variants of a product for a given nest level. * TODO: Log warning on mount when result is not injected. * * @public */ var _sfc_main = defineComponent({ name: 'ResultVariantSelector', props: { /** The nest level of the variants to be rendered. */ level: { type: Number, default: 0, }, }, setup(props, { slots }) { /** * Callback to be called when a variant is selected. * * @public * @returns The 'selectResultVariant' injection key. */ const selectResultVariant = inject(SELECT_RESULT_VARIANT_KEY); /** The original result, used to retrieve the available variants for the level. */ const result = inject(RESULT_WITH_VARIANTS_KEY); /** Array containing the selected variants. */ const selectedVariants = inject(SELECTED_VARIANTS_KEY); /** * It retrieves the available variants from the result. * * @returns - The variants of the result for the current level. */ const variants = computed(() => { if (props.level === 0) { return result.value?.variants; } return selectedVariants.value[props.level - 1]?.variants; }); /** * Gets the selected variant of the current level. * * @returns - The selected variant. */ const selectedVariant = computed(() => variants.value?.find(variant => variant === selectedVariants.value[props.level])); /** * Calls the provided method to select a variant. * * @param variant - Variant to select. */ const selectVariant = (variant) => { selectResultVariant(variant, props.level); }; /** * Checks if a variant is selected. * * @param variant - Variant to check. * @returns True if the variant is selected, false if not. */ const variantIsSelected = (variant) => { return selectedVariant.value === variant; }; /** * Render function to execute the `default` slot, binding `slotsProps` and getting only the * first `vNode` to avoid Fragments and Text root nodes. * If there are no result or variants, nothing is rendered. * * @remarks `slotProps` must be values without Vue reactivity and located inside the * render-function to update the binding data properly. * * @returns The root `vNode` of the `default` slot or empty string if there are * no result or variants. */ function renderDefaultSlot() { const slotProps = { variants: variants.value, selectedVariant: selectedVariant.value, selectVariant, }; return result && variants.value ? slots.default?.(slotProps)[0] : ''; } /* Hack to render through a render-function, the `default` slot or, in its absence, the component itself. It is the alternative for the NoElement antipattern. */ const componentProps = { result, variants, variantIsSelected, selectVariant }; return (slots.default ? renderDefaultSlot : componentProps); }, }); export { _sfc_main as default }; //# sourceMappingURL=result-variant-selector.vue2.js.map