@empathyco/x-components 6.0.0-alpha.237 → 6.0.0-alpha.239
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/core/index.d.ts +0 -1
- package/docs/API-reference/api/x-components.aioverview.md +0 -21
- package/docs/API-reference/api/x-components.allfilter.md +1 -1
- package/docs/API-reference/api/x-components.highlight_2.md +1 -1
- package/docs/API-reference/api/x-components.md +0 -11
- package/docs/API-reference/api/x-components.slidingpanel.md +2 -2
- package/docs/API-reference/components/ai/x-components.ai-overview.md +0 -3
- package/docs/API-reference/components/common/column-picker/x-components.base-column-picker-list.md +1 -1
- package/docs/API-reference/components/common/x-components.base-slider.md +2 -2
- package/js/components/animations/change-height.vue.js.map +1 -1
- package/js/components/animations/change-height.vue2.js.map +1 -1
- package/js/components/auto-progress-bar.vue.js +2 -2
- package/js/components/auto-progress-bar.vue.js.map +1 -1
- package/js/components/auto-progress-bar.vue2.js.map +1 -1
- package/js/components/base-slider.vue.js.map +1 -1
- package/js/components/base-slider.vue2.js.map +1 -1
- package/js/components/base-slider.vue3.js +1 -1
- package/js/components/base-switch.vue.js.map +1 -1
- package/js/components/base-switch.vue2.js +1 -1
- package/js/components/base-switch.vue2.js.map +1 -1
- package/js/components/column-picker/base-column-picker-list.vue.js +2 -2
- package/js/components/column-picker/base-column-picker-list.vue.js.map +1 -1
- package/js/components/column-picker/base-column-picker-list.vue2.js +1 -1
- package/js/components/column-picker/base-column-picker-list.vue2.js.map +1 -1
- package/js/components/highlight.vue.js +1 -1
- package/js/components/highlight.vue.js.map +1 -1
- package/js/components/highlight.vue2.js +1 -1
- package/js/components/highlight.vue2.js.map +1 -1
- package/js/components/icons/ai-star.vue.js +1 -0
- package/js/components/icons/ai-star.vue.js.map +1 -1
- package/js/components/icons/arrow-down.vue.js +1 -1
- package/js/components/icons/arrow-down.vue.js.map +1 -1
- package/js/components/icons/arrow-left.vue.js +1 -1
- package/js/components/icons/arrow-left.vue.js.map +1 -1
- package/js/components/icons/arrow-right.vue.js +1 -1
- package/js/components/icons/arrow-right.vue.js.map +1 -1
- package/js/components/icons/arrow-up.vue.js +1 -1
- package/js/components/icons/arrow-up.vue.js.map +1 -1
- package/js/components/icons/bag.vue.js +1 -1
- package/js/components/icons/bag.vue.js.map +1 -1
- package/js/components/icons/bar-code.vue.js +1 -1
- package/js/components/icons/bar-code.vue.js.map +1 -1
- package/js/components/icons/barcode-tiny.vue.js +1 -1
- package/js/components/icons/barcode-tiny.vue.js.map +1 -1
- package/js/components/icons/cart-filled.vue.js +1 -1
- package/js/components/icons/cart-filled.vue.js.map +1 -1
- package/js/components/icons/cart.vue.js +1 -1
- package/js/components/icons/cart.vue.js.map +1 -1
- package/js/components/icons/check-tiny.vue.js +1 -1
- package/js/components/icons/check-tiny.vue.js.map +1 -1
- package/js/components/icons/check.vue.js +1 -1
- package/js/components/icons/check.vue.js.map +1 -1
- package/js/components/icons/checkbox-selected-filled.vue.js +1 -1
- package/js/components/icons/checkbox-selected-filled.vue.js.map +1 -1
- package/js/components/icons/checkbox-selected.vue.js +1 -1
- package/js/components/icons/checkbox-selected.vue.js.map +1 -1
- package/js/components/icons/checkbox-unselected-filled.vue.js +1 -1
- package/js/components/icons/checkbox-unselected-filled.vue.js.map +1 -1
- package/js/components/icons/checkbox-unselected.vue.js +1 -1
- package/js/components/icons/checkbox-unselected.vue.js.map +1 -1
- package/js/components/icons/chevron-down.vue.js +1 -1
- package/js/components/icons/chevron-down.vue.js.map +1 -1
- package/js/components/icons/chevron-left.vue.js +1 -1
- package/js/components/icons/chevron-left.vue.js.map +1 -1
- package/js/components/icons/chevron-right.vue.js +1 -1
- package/js/components/icons/chevron-right.vue.js.map +1 -1
- package/js/components/icons/chevron-tiny-down.vue.js +1 -1
- package/js/components/icons/chevron-tiny-down.vue.js.map +1 -1
- package/js/components/icons/chevron-tiny-left.vue.js +1 -1
- package/js/components/icons/chevron-tiny-left.vue.js.map +1 -1
- package/js/components/icons/chevron-tiny-right.vue.js +1 -1
- package/js/components/icons/chevron-tiny-right.vue.js.map +1 -1
- package/js/components/icons/chevron-tiny-up.vue.js +1 -1
- package/js/components/icons/chevron-tiny-up.vue.js.map +1 -1
- package/js/components/icons/chevron-up.vue.js +1 -1
- package/js/components/icons/chevron-up.vue.js.map +1 -1
- package/js/components/icons/corner-arrow-left.vue.js +1 -1
- package/js/components/icons/corner-arrow-left.vue.js.map +1 -1
- package/js/components/icons/corner-arrow-right.vue.js +1 -1
- package/js/components/icons/corner-arrow-right.vue.js.map +1 -1
- package/js/components/icons/cross-tiny.vue.js +1 -1
- package/js/components/icons/cross-tiny.vue.js.map +1 -1
- package/js/components/icons/cross.vue.js +1 -1
- package/js/components/icons/cross.vue.js.map +1 -1
- package/js/components/icons/curated-check-filled.vue.js +1 -1
- package/js/components/icons/curated-check-filled.vue.js.map +1 -1
- package/js/components/icons/curated-check-tiny-filled.vue.js +1 -1
- package/js/components/icons/curated-check-tiny-filled.vue.js.map +1 -1
- package/js/components/icons/curated-check-tiny.vue.js +1 -1
- package/js/components/icons/curated-check-tiny.vue.js.map +1 -1
- package/js/components/icons/curated-check.vue.js +1 -1
- package/js/components/icons/curated-check.vue.js.map +1 -1
- package/js/components/icons/diagonal-arrow-left-down.vue.js +1 -1
- package/js/components/icons/diagonal-arrow-left-down.vue.js.map +1 -1
- package/js/components/icons/diagonal-arrow-left-top.vue.js +1 -1
- package/js/components/icons/diagonal-arrow-left-top.vue.js.map +1 -1
- package/js/components/icons/diagonal-arrow-right-down.vue.js +1 -1
- package/js/components/icons/diagonal-arrow-right-down.vue.js.map +1 -1
- package/js/components/icons/diagonal-arrow-right-top.vue.js +1 -1
- package/js/components/icons/diagonal-arrow-right-top.vue.js.map +1 -1
- package/js/components/icons/filters.vue.js +1 -1
- package/js/components/icons/filters.vue.js.map +1 -1
- package/js/components/icons/grid-1-col.vue.js +1 -1
- package/js/components/icons/grid-1-col.vue.js.map +1 -1
- package/js/components/icons/grid-2-col.vue.js +1 -1
- package/js/components/icons/grid-2-col.vue.js.map +1 -1
- package/js/components/icons/grid-2-rows.vue.js +1 -1
- package/js/components/icons/grid-2-rows.vue.js.map +1 -1
- package/js/components/icons/grid-4-col.vue.js +1 -1
- package/js/components/icons/grid-4-col.vue.js.map +1 -1
- package/js/components/icons/heart-filled.vue.js +1 -1
- package/js/components/icons/heart-filled.vue.js.map +1 -1
- package/js/components/icons/heart.vue.js +1 -1
- package/js/components/icons/heart.vue.js.map +1 -1
- package/js/components/icons/hide.vue.js +1 -1
- package/js/components/icons/hide.vue.js.map +1 -1
- package/js/components/icons/history-tiny.vue.js +1 -1
- package/js/components/icons/history-tiny.vue.js.map +1 -1
- package/js/components/icons/history.vue.js +1 -1
- package/js/components/icons/history.vue.js.map +1 -1
- package/js/components/icons/light-bulb-off.vue.js +1 -1
- package/js/components/icons/light-bulb-off.vue.js.map +1 -1
- package/js/components/icons/light-bulb-on.vue.js +1 -1
- package/js/components/icons/light-bulb-on.vue.js.map +1 -1
- package/js/components/icons/menu.vue.js +1 -1
- package/js/components/icons/menu.vue.js.map +1 -1
- package/js/components/icons/minus-tiny.vue.js +1 -1
- package/js/components/icons/minus-tiny.vue.js.map +1 -1
- package/js/components/icons/minus.vue.js +1 -1
- package/js/components/icons/minus.vue.js.map +1 -1
- package/js/components/icons/plus-tiny.vue.js +1 -1
- package/js/components/icons/plus-tiny.vue.js.map +1 -1
- package/js/components/icons/plus.vue.js +1 -1
- package/js/components/icons/plus.vue.js.map +1 -1
- package/js/components/icons/radiobutton-selected.vue.js +1 -1
- package/js/components/icons/radiobutton-selected.vue.js.map +1 -1
- package/js/components/icons/radiobutton-unselected.vue.js +1 -1
- package/js/components/icons/radiobutton-unselected.vue.js.map +1 -1
- package/js/components/icons/search-tiny.vue.js +1 -1
- package/js/components/icons/search-tiny.vue.js.map +1 -1
- package/js/components/icons/search.vue.js +1 -1
- package/js/components/icons/search.vue.js.map +1 -1
- package/js/components/icons/settings.vue.js +1 -1
- package/js/components/icons/settings.vue.js.map +1 -1
- package/js/components/icons/show.vue.js +1 -1
- package/js/components/icons/show.vue.js.map +1 -1
- package/js/components/icons/sort-az.vue.js +1 -1
- package/js/components/icons/sort-az.vue.js.map +1 -1
- package/js/components/icons/sort-price-down.vue.js +1 -1
- package/js/components/icons/sort-price-down.vue.js.map +1 -1
- package/js/components/icons/sort-price-up.vue.js +1 -1
- package/js/components/icons/sort-price-up.vue.js.map +1 -1
- package/js/components/icons/sort-relevancy.vue.js +1 -1
- package/js/components/icons/sort-relevancy.vue.js.map +1 -1
- package/js/components/icons/sort-za.vue.js +1 -1
- package/js/components/icons/sort-za.vue.js.map +1 -1
- package/js/components/icons/spinner.vue.js +1 -1
- package/js/components/icons/spinner.vue.js.map +1 -1
- package/js/components/icons/star-filled.vue.js +1 -1
- package/js/components/icons/star-filled.vue.js.map +1 -1
- package/js/components/icons/star.vue.js +1 -1
- package/js/components/icons/star.vue.js.map +1 -1
- package/js/components/icons/tag-filled.vue.js +1 -1
- package/js/components/icons/tag-filled.vue.js.map +1 -1
- package/js/components/icons/tag.vue.js +1 -1
- package/js/components/icons/tag.vue.js.map +1 -1
- package/js/components/icons/trash-open.vue.js +1 -1
- package/js/components/icons/trash-open.vue.js.map +1 -1
- package/js/components/icons/trash.vue.js +1 -1
- package/js/components/icons/trash.vue.js.map +1 -1
- package/js/components/icons/trending-tiny.vue.js +1 -1
- package/js/components/icons/trending-tiny.vue.js.map +1 -1
- package/js/components/icons/trending.vue.js +1 -1
- package/js/components/icons/trending.vue.js.map +1 -1
- package/js/components/icons/user-filled.vue.js +1 -1
- package/js/components/icons/user-filled.vue.js.map +1 -1
- package/js/components/icons/user.vue.js +1 -1
- package/js/components/icons/user.vue.js.map +1 -1
- package/js/components/layouts/multi-column-max-width-layout.vue4.js +1 -1
- package/js/components/layouts/single-column-layout.vue3.js +1 -1
- package/js/components/modals/base-events-modal-close.vue.js +1 -1
- package/js/components/modals/base-events-modal-close.vue.js.map +1 -1
- package/js/components/modals/base-events-modal-close.vue2.js.map +1 -1
- package/js/components/modals/base-events-modal-open.vue.js +1 -1
- package/js/components/modals/base-events-modal-open.vue.js.map +1 -1
- package/js/components/modals/base-events-modal-open.vue2.js.map +1 -1
- package/js/components/modals/base-id-modal-close.vue.js +1 -1
- package/js/components/modals/base-id-modal-close.vue.js.map +1 -1
- package/js/components/modals/base-id-modal-close.vue2.js.map +1 -1
- package/js/components/modals/base-id-modal-open.vue.js +1 -1
- package/js/components/modals/base-id-modal-open.vue.js.map +1 -1
- package/js/components/modals/base-id-modal-open.vue2.js.map +1 -1
- package/js/components/page-loader-button.vue.js +1 -1
- package/js/components/page-loader-button.vue.js.map +1 -1
- package/js/components/page-loader-button.vue2.js.map +1 -1
- package/js/components/page-selector.vue.js +3 -3
- package/js/components/page-selector.vue.js.map +1 -1
- package/js/components/page-selector.vue2.js.map +1 -1
- package/js/components/panels/base-id-toggle-panel-button.vue.js +1 -1
- package/js/components/panels/base-id-toggle-panel-button.vue.js.map +1 -1
- package/js/components/panels/base-id-toggle-panel-button.vue2.js.map +1 -1
- package/js/components/result/base-result-add-to-cart.vue.js +1 -1
- package/js/components/result/base-result-add-to-cart.vue.js.map +1 -1
- package/js/components/result/base-result-add-to-cart.vue2.js.map +1 -1
- package/js/components/result/base-result-image.vue.js +3 -3
- package/js/components/result/base-result-image.vue.js.map +1 -1
- package/js/components/result/base-result-image.vue2.js.map +1 -1
- package/js/components/scroll/base-scroll.vue.js +1 -1
- package/js/components/scroll/base-scroll.vue.js.map +1 -1
- package/js/components/scroll/base-scroll.vue2.js.map +1 -1
- package/js/components/sliding-panel.vue.js +4 -4
- package/js/components/sliding-panel.vue.js.map +1 -1
- package/js/components/sliding-panel.vue2.js +2 -2
- package/js/components/sliding-panel.vue2.js.map +1 -1
- package/js/components/sliding-panel.vue3.js +1 -1
- package/js/index.js +1 -1
- package/js/x-bus/x-bus.js +1 -3
- package/js/x-bus/x-bus.js.map +1 -1
- package/js/x-modules/ai/components/ai-carousel.vue.js +1 -1
- package/js/x-modules/ai/components/ai-carousel.vue.js.map +1 -1
- package/js/x-modules/ai/components/ai-carousel.vue2.js.map +1 -1
- package/js/x-modules/ai/components/ai-carousel.vue3.js +1 -1
- package/js/x-modules/ai/components/ai-overview.vue.js +120 -173
- package/js/x-modules/ai/components/ai-overview.vue.js.map +1 -1
- package/js/x-modules/ai/components/ai-overview.vue2.js +2 -38
- package/js/x-modules/ai/components/ai-overview.vue2.js.map +1 -1
- package/js/x-modules/ai/components/ai-overview.vue3.js +1 -1
- package/js/x-modules/ai/wiring.js +2 -6
- package/js/x-modules/ai/wiring.js.map +1 -1
- package/js/x-modules/facets/components/clear-filters.vue.js +1 -1
- package/js/x-modules/facets/components/clear-filters.vue.js.map +1 -1
- package/js/x-modules/facets/components/clear-filters.vue2.js.map +1 -1
- package/js/x-modules/facets/components/filters/all-filter.vue.js +1 -1
- package/js/x-modules/facets/components/filters/all-filter.vue.js.map +1 -1
- package/js/x-modules/facets/components/filters/all-filter.vue2.js +1 -1
- package/js/x-modules/facets/components/filters/all-filter.vue2.js.map +1 -1
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue.js +4 -4
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue.js.map +1 -1
- package/js/x-modules/facets/components/filters/editable-number-range-filter.vue2.js.map +1 -1
- package/js/x-modules/facets/components/filters/renderless-filter.vue.js +2 -2
- package/js/x-modules/facets/components/filters/renderless-filter.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/filters-search.vue.js +1 -1
- package/js/x-modules/facets/components/lists/filters-search.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/filters-search.vue2.js.map +1 -1
- package/js/x-modules/facets/components/lists/selected-filters-list.vue.js +1 -1
- package/js/x-modules/facets/components/lists/selected-filters-list.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/selected-filters-list.vue2.js.map +1 -1
- package/js/x-modules/facets/components/lists/sliced-filters.vue.js +2 -2
- package/js/x-modules/facets/components/lists/sliced-filters.vue.js.map +1 -1
- package/js/x-modules/facets/components/lists/sliced-filters.vue2.js.map +1 -1
- package/js/x-modules/history-queries/components/clear-history-queries.vue.js +1 -1
- package/js/x-modules/history-queries/components/clear-history-queries.vue.js.map +1 -1
- package/js/x-modules/history-queries/components/clear-history-queries.vue2.js.map +1 -1
- package/js/x-modules/history-queries/components/history-queries.vue.js +1 -1
- package/js/x-modules/history-queries/components/history-queries.vue.js.map +1 -1
- package/js/x-modules/history-queries/components/history-queries.vue2.js.map +1 -1
- package/js/x-modules/history-queries/components/history-query.vue.js +2 -2
- package/js/x-modules/history-queries/components/history-query.vue.js.map +1 -1
- package/js/x-modules/history-queries/components/history-query.vue2.js.map +1 -1
- package/js/x-modules/history-queries/components/my-history.vue.js +1 -1
- package/js/x-modules/history-queries/components/my-history.vue.js.map +1 -1
- package/js/x-modules/history-queries/components/my-history.vue2.js.map +1 -1
- package/js/x-modules/next-queries/components/next-queries.vue.js +1 -1
- package/js/x-modules/next-queries/components/next-queries.vue.js.map +1 -1
- package/js/x-modules/next-queries/components/next-queries.vue2.js.map +1 -1
- package/js/x-modules/popular-searches/components/popular-searches.vue.js +1 -1
- package/js/x-modules/popular-searches/components/popular-searches.vue.js.map +1 -1
- package/js/x-modules/popular-searches/components/popular-searches.vue2.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview-button.vue.js +1 -1
- package/js/x-modules/queries-preview/components/query-preview-button.vue.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview-button.vue2.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview-list.vue3.js +1 -1
- package/js/x-modules/queries-preview/components/query-preview.vue.js.map +1 -1
- package/js/x-modules/queries-preview/components/query-preview.vue2.js.map +1 -1
- package/js/x-modules/query-suggestions/components/query-suggestions.vue.js +1 -1
- package/js/x-modules/query-suggestions/components/query-suggestions.vue.js.map +1 -1
- package/js/x-modules/query-suggestions/components/query-suggestions.vue2.js.map +1 -1
- package/js/x-modules/related-prompts/components/related-prompt.vue3.js +1 -1
- package/js/x-modules/related-tags/components/related-tag.vue.js +1 -1
- package/js/x-modules/related-tags/components/related-tag.vue.js.map +1 -1
- package/js/x-modules/related-tags/components/related-tag.vue2.js +1 -1
- package/js/x-modules/related-tags/components/related-tag.vue2.js.map +1 -1
- package/js/x-modules/scroll/components/scroll-to-top.vue.js +1 -1
- package/js/x-modules/scroll/components/scroll-to-top.vue.js.map +1 -1
- package/js/x-modules/scroll/components/scroll-to-top.vue2.js.map +1 -1
- package/js/x-modules/search/components/partial-query-button.vue.js +1 -1
- package/js/x-modules/search/components/partial-query-button.vue.js.map +1 -1
- package/js/x-modules/search/components/partial-query-button.vue2.js.map +1 -1
- package/js/x-modules/search/components/sort-list.vue.js +1 -1
- package/js/x-modules/search/components/sort-list.vue.js.map +1 -1
- package/js/x-modules/search/components/sort-list.vue2.js.map +1 -1
- package/js/x-modules/search/components/sort-picker-list.vue.js.map +1 -1
- package/js/x-modules/search/components/sort-picker-list.vue2.js +1 -1
- package/js/x-modules/search/components/sort-picker-list.vue2.js.map +1 -1
- package/js/x-modules/search-box/components/clear-search-input.vue.js +1 -1
- package/js/x-modules/search-box/components/clear-search-input.vue.js.map +1 -1
- package/js/x-modules/search-box/components/clear-search-input.vue2.js.map +1 -1
- package/js/x-modules/search-box/components/search-button.vue.js +2 -2
- package/js/x-modules/search-box/components/search-button.vue.js.map +1 -1
- package/js/x-modules/search-box/components/search-button.vue2.js.map +1 -1
- package/js/x-modules/search-box/components/search-input-placeholder.vue.js +1 -1
- package/js/x-modules/search-box/components/search-input-placeholder.vue.js.map +1 -1
- package/js/x-modules/search-box/components/search-input-placeholder.vue2.js.map +1 -1
- package/js/x-modules/search-box/components/search-input-placeholder.vue4.js +1 -1
- package/js/x-modules/search-box/components/search-input.vue.js +1 -1
- package/js/x-modules/search-box/components/search-input.vue.js.map +1 -1
- package/js/x-modules/search-box/components/search-input.vue2.js.map +1 -1
- package/js/x-modules/tagging/wiring.js +2 -22
- package/js/x-modules/tagging/wiring.js.map +1 -1
- package/package.json +6 -9
- package/report/x-components.api.json +7 -89
- package/report/x-components.api.md +5 -35
- package/tagging/index.js +1 -1
- package/types/demo/main.d.ts +1 -1
- package/types/demo/main.d.ts.map +1 -1
- package/types/demo/views/base-config.d.ts.map +1 -1
- package/types/demo/views/home/types.d.ts +0 -3
- package/types/demo/views/home/types.d.ts.map +1 -1
- package/types/demo/vite.config.d.ts.map +1 -1
- package/types/src/components/base-grid.types.d.ts.map +1 -1
- package/types/src/components/column-picker/base-column-picker-list.vue.d.ts +8 -1
- package/types/src/components/column-picker/base-column-picker-list.vue.d.ts.map +1 -1
- package/types/src/components/highlight.vue.d.ts +1 -1
- package/types/src/components/sliding-panel.vue.d.ts +2 -2
- package/types/src/index.d.ts +0 -1
- package/types/src/index.d.ts.map +1 -1
- package/types/src/x-bus/x-bus.d.ts.map +1 -1
- package/types/src/x-modules/ai/components/ai-overview.vue.d.ts +0 -21
- package/types/src/x-modules/ai/components/ai-overview.vue.d.ts.map +1 -1
- package/types/src/x-modules/ai/wiring.d.ts +0 -3
- package/types/src/x-modules/ai/wiring.d.ts.map +1 -1
- package/types/src/x-modules/facets/components/filters/all-filter.vue.d.ts +1 -1
- package/types/src/x-modules/tagging/wiring.d.ts +0 -9
- package/types/src/x-modules/tagging/wiring.d.ts.map +1 -1
- package/docs/API-reference/api/x-components.trackaioverviewbuttonclickedwire.md +0 -13
- package/types/demo/views/adapter.d.ts +0 -3
- package/types/demo/views/adapter.d.ts.map +0 -1
- package/types/src/components/column-picker/base-column-picker-list.types.d.ts +0 -9
- package/types/src/components/column-picker/base-column-picker-list.types.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editable-number-range-filter.vue.js","sources":["../../../../../../src/x-modules/facets/components/filters/editable-number-range-filter.vue"],"sourcesContent":["<template>\n <div\n class=\"x-editable-number-range-filter\"\n :class=\"cssClasses\"\n data-test=\"editable-number-range-filter\"\n >\n <!--\n @slot Empty slot used to customize the whole component.\n @binding {min} number - Component min value.\n @binding {max} number - Component max value.\n @binding {setMin} function - Component min setter.\n @binding {setMax} function - Component max setter.\n @binding {emitUserModifiedFilter} function - It emits the\n `UserModifiedEditableNumberRangeFilter` X event.\n @binding {clearValues} function - It sets component min and max values to null.\n @binding {hasError} boolean - Returns true when there is an error with component values.\n -->\n <slot\n v-bind=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <!-- eslint-disable max-len -->\n <input\n name=\"min\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--min x-input\"\n :class=\"inputsClass\"\n :value=\"!isAnyRange ? min : null\"\n data-test=\"range-min\"\n :aria-label=\"rangeFilterMin\"\n @change=\"setMin(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n\n <input\n name=\"max\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--max x-input\"\n :class=\"inputsClass\"\n :value=\"max\"\n data-test=\"range-max\"\n :aria-label=\"rangeFilterMax\"\n @change=\"setMax(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n <!-- eslint-enable max-len -->\n\n <button\n v-if=\"!isInstant\"\n class=\"x-editable-number-range-filter__apply x-button\"\n :class=\"buttonsClass\"\n :disabled=\"hasError\"\n data-test=\"range-apply\"\n @click=\"emitUserModifiedFilter\"\n >\n <!--\n @slot Slot used to customize the apply button content.\n -->\n <slot name=\"apply-content\">✓</slot>\n </button>\n\n <button\n v-if=\"renderClearButton\"\n class=\"x-editable-number-range-filter__clear x-button\"\n :class=\"buttonsClass\"\n data-test=\"range-clear\"\n @click=\"clearValues\"\n >\n <!--\n @slot Slot used to customize the clear button content.\n -->\n <slot name=\"clear-content\">𐄂</slot>\n </button>\n </slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type {\n EditableNumberRangeFilter as EditableNumberRangeFilterModel,\n RangeValue,\n} from '@empathyco/x-types'\nimport type { PropType, Ref } from 'vue'\nimport { computed, defineComponent, ref, watch } from 'vue'\nimport { use$x } from '../../../../composables'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders an editable number range filter. It has two input fields to handle min and max values,\n * emitting the needed events when clicked.\n *\n * It provides a default slot, with some utils bind, to customize the whole component; and two\n * named slots `apply-content` and `clear-content` to override each button content.\n *\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\nexport default defineComponent({\n name: 'EditableNumberRangeFilter',\n xModule: facetsXModule.name,\n props: {\n /**\n * The filter data to render and edit.\n *\n * @public\n */\n filter: {\n type: Object as PropType<EditableNumberRangeFilterModel>,\n required: true,\n },\n /**\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * @public\n */\n isInstant: Boolean,\n /**\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\n hasClearButton: {\n type: Boolean,\n default: true,\n },\n /** Class inherited by content element. */\n inputsClass: String,\n /** Class inherited by content element. */\n buttonsClass: String,\n },\n setup(props) {\n const $x = use$x()\n\n const rangeFilterMin = 'minimum amount'\n const rangeFilterMax = 'maximum amount'\n /**\n * Component min value.\n *\n * @internal\n */\n const min: Ref<RangeValue['min']> = ref(null)\n /**\n * Component max value.\n *\n * @internal\n */\n const max: Ref<RangeValue['max']> = ref(null)\n\n /**\n * Returns {@link @empathyco/x-types#RangeValue} with component min and max\n * values.\n *\n * @returns Range value object with component values.\n *\n * @internal\n */\n const range = computed((): RangeValue => {\n return { min: min.value, max: max.value }\n })\n\n /**\n * It checks if component min and max values are valid.\n *\n * @returns True if there is any error in the component min and max values.\n *\n * @internal\n */\n const hasError = computed(\n () => min.value !== null && max.value !== null && min.value > max.value,\n )\n\n /**\n * It checks if component min and max values are different from the ones within the filter\n * provided as property.\n *\n * @returns True if they are different.\n *\n * @internal\n */\n const areValuesDifferent = computed(\n () => min.value !== props.filter.range.min || max.value !== props.filter.range.max,\n )\n\n /**\n * Dynamic CSS classes.\n *\n * @returns Object which contains dynamic CSS classes.\n *\n * @internal\n */\n const cssClasses = computed(() => {\n return { 'x-editable-number-range-filter--error': hasError.value }\n })\n\n /**\n * Checks if the range of the filter allows any value, which happens when the min is\n * null or 0 and the max is null.\n *\n * @returns True if the range of the filter allows any value.\n *\n * @internal\n */\n const isAnyRange = computed(() => !min.value && max.value === null)\n\n /**\n * It returns true if the property `hasClearButton` is true and there are values to clear.\n *\n * @returns True if the clear button has to be rendered.\n *\n * @internal\n */\n const renderClearButton = computed(() => props.hasClearButton && !isAnyRange.value)\n\n /**\n * It emits {@link FacetsXEvents.UserModifiedEditableNumberRangeFilter} event if there are no\n * errors and component `min` and `max` values are different than `filter.range` ones.\n *\n * @internal\n */\n const emitUserModifiedFilter = () => {\n if (!hasError.value && areValuesDifferent.value) {\n $x.emit('UserModifiedEditableNumberRangeFilter', {\n ...props.filter,\n range: range.value,\n })\n }\n }\n\n /**\n * It returns the number if possible or null otherwise.\n *\n * @param value - Value.\n * @returns The element value as a number if possible or null.\n *\n * @internal\n */\n const parseRangeValue = (value: number) => (Number.isNaN(value) ? null : value)\n\n /**\n * `min` setter.\n *\n * @param value - The component `min` value to be set.\n *\n * @internal\n */\n const setMin = (value: number) => {\n min.value = parseRangeValue(value)\n }\n\n /**\n * `max` setter.\n *\n * @param value - The component `max` value to be set.\n *\n * @internal\n */\n const setMax = (value: number) => {\n max.value = parseRangeValue(value)\n }\n\n /**\n * It sets component `min` and `max` values to null , and it emits the change if component is\n * working in instant mode.\n *\n * @internal\n */\n const clearValues = () => {\n min.value = null\n max.value = null\n }\n\n /**\n * It resets the min/max range values to null if the\n * {@link FacetsXEvents.UserClickedClearAllFilters} event is fired.\n *\n * @public\n */\n $x.on('UserClickedClearAllFilters', false).subscribe(clearValues)\n\n /**\n * It watches the filter range values passed as property and updates component range values if\n * they change.\n *\n * @param newRange - New range value.\n *\n * @internal\n */\n watch(\n () => props.filter.range,\n (newRange: RangeValue) => {\n min.value = newRange.min\n max.value = newRange.max\n },\n { immediate: true, deep: true },\n )\n\n /**\n * It watches range values in order to emit the event with the change if `isInstant`\n * property is true.\n *\n * @internal\n */\n watch(\n range,\n () => {\n if (props.isInstant) {\n emitUserModifiedFilter()\n }\n },\n { deep: true },\n )\n\n return {\n rangeFilterMin,\n rangeFilterMax,\n cssClasses,\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n renderClearButton,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-editable-number-range-filter--error .x-editable-number-range-filter__input {\n border-color: red;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- [`UserModifiedEditableNumberRangeFilter`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n this event is emitted instantly after typing the value or clicking the submit button. The event\n payload in both cases is an object containing the filter and the new value for the range.\n\n## Example\n\nRenders an editable number range filter. It has two input fields to handle min and max values,\nemitting the needed events when clicked.\n\nIt provides a default slot, with some utils bind, to customize the whole component; and two named\nslots `apply-content` and `clear-content` to override each button content.\n\nIf `instant` prop is true, the needed events are emitted immediately; else, apply button is rendered\nto confirm to do it. False by default.\n\nIf `clear` prop is true, clear button, which sets to null component min and max values, is rendered.\nTrue by default.\n\n### Basic usage\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Properties\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" :isInstant=\"true\" :hasClearButton=\"false\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing content slots\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\">\n <template #apply-content>Apply</template>\n <template #clear-content>Clear</template>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing default slot\n\n```vue\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n #default=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <button @click=\"emitUserModifiedFilter\">✅ Apply!</button>\n <button @click=\"clearValues\">🗑 Clear!</button>\n <input :value=\"!isAnyRange ? min : null\" @change=\"setMin($event.target.valueAsNumber)\" />\n <input :value=\"max\" @change=\"setMax($event.target.valueAsNumber)\" />\n <div class=\"has-error\" v-if=\"hasError\">⚠️ Invalid range values</div>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonsClass` and `inputsClass` props can be used to add classes to the inputs and buttons of\nthe component.\n\n```\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n :inputsClass=\"'my-inputs-class'\"\n :buttonsClass=\"'my-buttons-class'\"\n />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_normalizeProps","_guardReactiveProps","_createElementVNode","_createTextVNode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"editable-number-range-filter.vue.js","sources":["../../../../../../src/x-modules/facets/components/filters/editable-number-range-filter.vue"],"sourcesContent":["<template>\n <div\n class=\"x-editable-number-range-filter\"\n :class=\"cssClasses\"\n data-test=\"editable-number-range-filter\"\n >\n <!--\n @slot Empty slot used to customize the whole component.\n @binding {min} number - Component min value.\n @binding {max} number - Component max value.\n @binding {setMin} function - Component min setter.\n @binding {setMax} function - Component max setter.\n @binding {emitUserModifiedFilter} function - It emits the\n `UserModifiedEditableNumberRangeFilter` X event.\n @binding {clearValues} function - It sets component min and max values to null.\n @binding {hasError} boolean - Returns true when there is an error with component values.\n -->\n <slot\n v-bind=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <!-- eslint-disable max-len -->\n <input\n name=\"min\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--min xds:input\"\n :class=\"inputsClass\"\n :value=\"!isAnyRange ? min : null\"\n data-test=\"range-min\"\n :aria-label=\"rangeFilterMin\"\n @change=\"setMin(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n\n <input\n name=\"max\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--max xds:input\"\n :class=\"inputsClass\"\n :value=\"max\"\n data-test=\"range-max\"\n :aria-label=\"rangeFilterMax\"\n @change=\"setMax(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n <!-- eslint-enable max-len -->\n\n <button\n v-if=\"!isInstant\"\n class=\"x-editable-number-range-filter__apply xds:button\"\n :class=\"buttonsClass\"\n :disabled=\"hasError\"\n data-test=\"range-apply\"\n @click=\"emitUserModifiedFilter\"\n >\n <!--\n @slot Slot used to customize the apply button content.\n -->\n <slot name=\"apply-content\">✓</slot>\n </button>\n\n <button\n v-if=\"renderClearButton\"\n class=\"x-editable-number-range-filter__clear xds:button\"\n :class=\"buttonsClass\"\n data-test=\"range-clear\"\n @click=\"clearValues\"\n >\n <!--\n @slot Slot used to customize the clear button content.\n -->\n <slot name=\"clear-content\">𐄂</slot>\n </button>\n </slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type {\n EditableNumberRangeFilter as EditableNumberRangeFilterModel,\n RangeValue,\n} from '@empathyco/x-types'\nimport type { PropType, Ref } from 'vue'\nimport { computed, defineComponent, ref, watch } from 'vue'\nimport { use$x } from '../../../../composables'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders an editable number range filter. It has two input fields to handle min and max values,\n * emitting the needed events when clicked.\n *\n * It provides a default slot, with some utils bind, to customize the whole component; and two\n * named slots `apply-content` and `clear-content` to override each button content.\n *\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\nexport default defineComponent({\n name: 'EditableNumberRangeFilter',\n xModule: facetsXModule.name,\n props: {\n /**\n * The filter data to render and edit.\n *\n * @public\n */\n filter: {\n type: Object as PropType<EditableNumberRangeFilterModel>,\n required: true,\n },\n /**\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * @public\n */\n isInstant: Boolean,\n /**\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\n hasClearButton: {\n type: Boolean,\n default: true,\n },\n /** Class inherited by content element. */\n inputsClass: String,\n /** Class inherited by content element. */\n buttonsClass: String,\n },\n setup(props) {\n const $x = use$x()\n\n const rangeFilterMin = 'minimum amount'\n const rangeFilterMax = 'maximum amount'\n /**\n * Component min value.\n *\n * @internal\n */\n const min: Ref<RangeValue['min']> = ref(null)\n /**\n * Component max value.\n *\n * @internal\n */\n const max: Ref<RangeValue['max']> = ref(null)\n\n /**\n * Returns {@link @empathyco/x-types#RangeValue} with component min and max\n * values.\n *\n * @returns Range value object with component values.\n *\n * @internal\n */\n const range = computed((): RangeValue => {\n return { min: min.value, max: max.value }\n })\n\n /**\n * It checks if component min and max values are valid.\n *\n * @returns True if there is any error in the component min and max values.\n *\n * @internal\n */\n const hasError = computed(\n () => min.value !== null && max.value !== null && min.value > max.value,\n )\n\n /**\n * It checks if component min and max values are different from the ones within the filter\n * provided as property.\n *\n * @returns True if they are different.\n *\n * @internal\n */\n const areValuesDifferent = computed(\n () => min.value !== props.filter.range.min || max.value !== props.filter.range.max,\n )\n\n /**\n * Dynamic CSS classes.\n *\n * @returns Object which contains dynamic CSS classes.\n *\n * @internal\n */\n const cssClasses = computed(() => {\n return { 'x-editable-number-range-filter--error': hasError.value }\n })\n\n /**\n * Checks if the range of the filter allows any value, which happens when the min is\n * null or 0 and the max is null.\n *\n * @returns True if the range of the filter allows any value.\n *\n * @internal\n */\n const isAnyRange = computed(() => !min.value && max.value === null)\n\n /**\n * It returns true if the property `hasClearButton` is true and there are values to clear.\n *\n * @returns True if the clear button has to be rendered.\n *\n * @internal\n */\n const renderClearButton = computed(() => props.hasClearButton && !isAnyRange.value)\n\n /**\n * It emits {@link FacetsXEvents.UserModifiedEditableNumberRangeFilter} event if there are no\n * errors and component `min` and `max` values are different than `filter.range` ones.\n *\n * @internal\n */\n const emitUserModifiedFilter = () => {\n if (!hasError.value && areValuesDifferent.value) {\n $x.emit('UserModifiedEditableNumberRangeFilter', {\n ...props.filter,\n range: range.value,\n })\n }\n }\n\n /**\n * It returns the number if possible or null otherwise.\n *\n * @param value - Value.\n * @returns The element value as a number if possible or null.\n *\n * @internal\n */\n const parseRangeValue = (value: number) => (Number.isNaN(value) ? null : value)\n\n /**\n * `min` setter.\n *\n * @param value - The component `min` value to be set.\n *\n * @internal\n */\n const setMin = (value: number) => {\n min.value = parseRangeValue(value)\n }\n\n /**\n * `max` setter.\n *\n * @param value - The component `max` value to be set.\n *\n * @internal\n */\n const setMax = (value: number) => {\n max.value = parseRangeValue(value)\n }\n\n /**\n * It sets component `min` and `max` values to null , and it emits the change if component is\n * working in instant mode.\n *\n * @internal\n */\n const clearValues = () => {\n min.value = null\n max.value = null\n }\n\n /**\n * It resets the min/max range values to null if the\n * {@link FacetsXEvents.UserClickedClearAllFilters} event is fired.\n *\n * @public\n */\n $x.on('UserClickedClearAllFilters', false).subscribe(clearValues)\n\n /**\n * It watches the filter range values passed as property and updates component range values if\n * they change.\n *\n * @param newRange - New range value.\n *\n * @internal\n */\n watch(\n () => props.filter.range,\n (newRange: RangeValue) => {\n min.value = newRange.min\n max.value = newRange.max\n },\n { immediate: true, deep: true },\n )\n\n /**\n * It watches range values in order to emit the event with the change if `isInstant`\n * property is true.\n *\n * @internal\n */\n watch(\n range,\n () => {\n if (props.isInstant) {\n emitUserModifiedFilter()\n }\n },\n { deep: true },\n )\n\n return {\n rangeFilterMin,\n rangeFilterMax,\n cssClasses,\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n renderClearButton,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-editable-number-range-filter--error .x-editable-number-range-filter__input {\n border-color: red;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- [`UserModifiedEditableNumberRangeFilter`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n this event is emitted instantly after typing the value or clicking the submit button. The event\n payload in both cases is an object containing the filter and the new value for the range.\n\n## Example\n\nRenders an editable number range filter. It has two input fields to handle min and max values,\nemitting the needed events when clicked.\n\nIt provides a default slot, with some utils bind, to customize the whole component; and two named\nslots `apply-content` and `clear-content` to override each button content.\n\nIf `instant` prop is true, the needed events are emitted immediately; else, apply button is rendered\nto confirm to do it. False by default.\n\nIf `clear` prop is true, clear button, which sets to null component min and max values, is rendered.\nTrue by default.\n\n### Basic usage\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Properties\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" :isInstant=\"true\" :hasClearButton=\"false\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing content slots\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\">\n <template #apply-content>Apply</template>\n <template #clear-content>Clear</template>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing default slot\n\n```vue\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n #default=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <button @click=\"emitUserModifiedFilter\">✅ Apply!</button>\n <button @click=\"clearValues\">🗑 Clear!</button>\n <input :value=\"!isAnyRange ? min : null\" @change=\"setMin($event.target.valueAsNumber)\" />\n <input :value=\"max\" @change=\"setMax($event.target.valueAsNumber)\" />\n <div class=\"has-error\" v-if=\"hasError\">⚠️ Invalid range values</div>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonsClass` and `inputsClass` props can be used to add classes to the inputs and buttons of\nthe component.\n\n```\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n :inputsClass=\"'my-inputs-class'\"\n :buttonsClass=\"'my-buttons-class'\"\n />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_normalizeProps","_guardReactiveProps","_createElementVNode","_createTextVNode"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editable-number-range-filter.vue2.js","sources":["../../../../../../src/x-modules/facets/components/filters/editable-number-range-filter.vue"],"sourcesContent":["<template>\n <div\n class=\"x-editable-number-range-filter\"\n :class=\"cssClasses\"\n data-test=\"editable-number-range-filter\"\n >\n <!--\n @slot Empty slot used to customize the whole component.\n @binding {min} number - Component min value.\n @binding {max} number - Component max value.\n @binding {setMin} function - Component min setter.\n @binding {setMax} function - Component max setter.\n @binding {emitUserModifiedFilter} function - It emits the\n `UserModifiedEditableNumberRangeFilter` X event.\n @binding {clearValues} function - It sets component min and max values to null.\n @binding {hasError} boolean - Returns true when there is an error with component values.\n -->\n <slot\n v-bind=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <!-- eslint-disable max-len -->\n <input\n name=\"min\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--min x-input\"\n :class=\"inputsClass\"\n :value=\"!isAnyRange ? min : null\"\n data-test=\"range-min\"\n :aria-label=\"rangeFilterMin\"\n @change=\"setMin(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n\n <input\n name=\"max\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--max x-input\"\n :class=\"inputsClass\"\n :value=\"max\"\n data-test=\"range-max\"\n :aria-label=\"rangeFilterMax\"\n @change=\"setMax(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n <!-- eslint-enable max-len -->\n\n <button\n v-if=\"!isInstant\"\n class=\"x-editable-number-range-filter__apply x-button\"\n :class=\"buttonsClass\"\n :disabled=\"hasError\"\n data-test=\"range-apply\"\n @click=\"emitUserModifiedFilter\"\n >\n <!--\n @slot Slot used to customize the apply button content.\n -->\n <slot name=\"apply-content\">✓</slot>\n </button>\n\n <button\n v-if=\"renderClearButton\"\n class=\"x-editable-number-range-filter__clear x-button\"\n :class=\"buttonsClass\"\n data-test=\"range-clear\"\n @click=\"clearValues\"\n >\n <!--\n @slot Slot used to customize the clear button content.\n -->\n <slot name=\"clear-content\">𐄂</slot>\n </button>\n </slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type {\n EditableNumberRangeFilter as EditableNumberRangeFilterModel,\n RangeValue,\n} from '@empathyco/x-types'\nimport type { PropType, Ref } from 'vue'\nimport { computed, defineComponent, ref, watch } from 'vue'\nimport { use$x } from '../../../../composables'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders an editable number range filter. It has two input fields to handle min and max values,\n * emitting the needed events when clicked.\n *\n * It provides a default slot, with some utils bind, to customize the whole component; and two\n * named slots `apply-content` and `clear-content` to override each button content.\n *\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\nexport default defineComponent({\n name: 'EditableNumberRangeFilter',\n xModule: facetsXModule.name,\n props: {\n /**\n * The filter data to render and edit.\n *\n * @public\n */\n filter: {\n type: Object as PropType<EditableNumberRangeFilterModel>,\n required: true,\n },\n /**\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * @public\n */\n isInstant: Boolean,\n /**\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\n hasClearButton: {\n type: Boolean,\n default: true,\n },\n /** Class inherited by content element. */\n inputsClass: String,\n /** Class inherited by content element. */\n buttonsClass: String,\n },\n setup(props) {\n const $x = use$x()\n\n const rangeFilterMin = 'minimum amount'\n const rangeFilterMax = 'maximum amount'\n /**\n * Component min value.\n *\n * @internal\n */\n const min: Ref<RangeValue['min']> = ref(null)\n /**\n * Component max value.\n *\n * @internal\n */\n const max: Ref<RangeValue['max']> = ref(null)\n\n /**\n * Returns {@link @empathyco/x-types#RangeValue} with component min and max\n * values.\n *\n * @returns Range value object with component values.\n *\n * @internal\n */\n const range = computed((): RangeValue => {\n return { min: min.value, max: max.value }\n })\n\n /**\n * It checks if component min and max values are valid.\n *\n * @returns True if there is any error in the component min and max values.\n *\n * @internal\n */\n const hasError = computed(\n () => min.value !== null && max.value !== null && min.value > max.value,\n )\n\n /**\n * It checks if component min and max values are different from the ones within the filter\n * provided as property.\n *\n * @returns True if they are different.\n *\n * @internal\n */\n const areValuesDifferent = computed(\n () => min.value !== props.filter.range.min || max.value !== props.filter.range.max,\n )\n\n /**\n * Dynamic CSS classes.\n *\n * @returns Object which contains dynamic CSS classes.\n *\n * @internal\n */\n const cssClasses = computed(() => {\n return { 'x-editable-number-range-filter--error': hasError.value }\n })\n\n /**\n * Checks if the range of the filter allows any value, which happens when the min is\n * null or 0 and the max is null.\n *\n * @returns True if the range of the filter allows any value.\n *\n * @internal\n */\n const isAnyRange = computed(() => !min.value && max.value === null)\n\n /**\n * It returns true if the property `hasClearButton` is true and there are values to clear.\n *\n * @returns True if the clear button has to be rendered.\n *\n * @internal\n */\n const renderClearButton = computed(() => props.hasClearButton && !isAnyRange.value)\n\n /**\n * It emits {@link FacetsXEvents.UserModifiedEditableNumberRangeFilter} event if there are no\n * errors and component `min` and `max` values are different than `filter.range` ones.\n *\n * @internal\n */\n const emitUserModifiedFilter = () => {\n if (!hasError.value && areValuesDifferent.value) {\n $x.emit('UserModifiedEditableNumberRangeFilter', {\n ...props.filter,\n range: range.value,\n })\n }\n }\n\n /**\n * It returns the number if possible or null otherwise.\n *\n * @param value - Value.\n * @returns The element value as a number if possible or null.\n *\n * @internal\n */\n const parseRangeValue = (value: number) => (Number.isNaN(value) ? null : value)\n\n /**\n * `min` setter.\n *\n * @param value - The component `min` value to be set.\n *\n * @internal\n */\n const setMin = (value: number) => {\n min.value = parseRangeValue(value)\n }\n\n /**\n * `max` setter.\n *\n * @param value - The component `max` value to be set.\n *\n * @internal\n */\n const setMax = (value: number) => {\n max.value = parseRangeValue(value)\n }\n\n /**\n * It sets component `min` and `max` values to null , and it emits the change if component is\n * working in instant mode.\n *\n * @internal\n */\n const clearValues = () => {\n min.value = null\n max.value = null\n }\n\n /**\n * It resets the min/max range values to null if the\n * {@link FacetsXEvents.UserClickedClearAllFilters} event is fired.\n *\n * @public\n */\n $x.on('UserClickedClearAllFilters', false).subscribe(clearValues)\n\n /**\n * It watches the filter range values passed as property and updates component range values if\n * they change.\n *\n * @param newRange - New range value.\n *\n * @internal\n */\n watch(\n () => props.filter.range,\n (newRange: RangeValue) => {\n min.value = newRange.min\n max.value = newRange.max\n },\n { immediate: true, deep: true },\n )\n\n /**\n * It watches range values in order to emit the event with the change if `isInstant`\n * property is true.\n *\n * @internal\n */\n watch(\n range,\n () => {\n if (props.isInstant) {\n emitUserModifiedFilter()\n }\n },\n { deep: true },\n )\n\n return {\n rangeFilterMin,\n rangeFilterMax,\n cssClasses,\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n renderClearButton,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-editable-number-range-filter--error .x-editable-number-range-filter__input {\n border-color: red;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- [`UserModifiedEditableNumberRangeFilter`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n this event is emitted instantly after typing the value or clicking the submit button. The event\n payload in both cases is an object containing the filter and the new value for the range.\n\n## Example\n\nRenders an editable number range filter. It has two input fields to handle min and max values,\nemitting the needed events when clicked.\n\nIt provides a default slot, with some utils bind, to customize the whole component; and two named\nslots `apply-content` and `clear-content` to override each button content.\n\nIf `instant` prop is true, the needed events are emitted immediately; else, apply button is rendered\nto confirm to do it. False by default.\n\nIf `clear` prop is true, clear button, which sets to null component min and max values, is rendered.\nTrue by default.\n\n### Basic usage\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Properties\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" :isInstant=\"true\" :hasClearButton=\"false\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing content slots\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\">\n <template #apply-content>Apply</template>\n <template #clear-content>Clear</template>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing default slot\n\n```vue\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n #default=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <button @click=\"emitUserModifiedFilter\">✅ Apply!</button>\n <button @click=\"clearValues\">🗑 Clear!</button>\n <input :value=\"!isAnyRange ? min : null\" @change=\"setMin($event.target.valueAsNumber)\" />\n <input :value=\"max\" @change=\"setMax($event.target.valueAsNumber)\" />\n <div class=\"has-error\" v-if=\"hasError\">⚠️ Invalid range values</div>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonsClass` and `inputsClass` props can be used to add classes to the inputs and buttons of\nthe component.\n\n```\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n :inputsClass=\"'my-inputs-class'\"\n :buttonsClass=\"'my-buttons-class'\"\n />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"editable-number-range-filter.vue2.js","sources":["../../../../../../src/x-modules/facets/components/filters/editable-number-range-filter.vue"],"sourcesContent":["<template>\n <div\n class=\"x-editable-number-range-filter\"\n :class=\"cssClasses\"\n data-test=\"editable-number-range-filter\"\n >\n <!--\n @slot Empty slot used to customize the whole component.\n @binding {min} number - Component min value.\n @binding {max} number - Component max value.\n @binding {setMin} function - Component min setter.\n @binding {setMax} function - Component max setter.\n @binding {emitUserModifiedFilter} function - It emits the\n `UserModifiedEditableNumberRangeFilter` X event.\n @binding {clearValues} function - It sets component min and max values to null.\n @binding {hasError} boolean - Returns true when there is an error with component values.\n -->\n <slot\n v-bind=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <!-- eslint-disable max-len -->\n <input\n name=\"min\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--min xds:input\"\n :class=\"inputsClass\"\n :value=\"!isAnyRange ? min : null\"\n data-test=\"range-min\"\n :aria-label=\"rangeFilterMin\"\n @change=\"setMin(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n\n <input\n name=\"max\"\n type=\"number\"\n class=\"x-editable-number-range-filter__input x-editable-number-range-filter__input--max xds:input\"\n :class=\"inputsClass\"\n :value=\"max\"\n data-test=\"range-max\"\n :aria-label=\"rangeFilterMax\"\n @change=\"setMax(($event?.target as HTMLInputElement)?.valueAsNumber)\"\n />\n <!-- eslint-enable max-len -->\n\n <button\n v-if=\"!isInstant\"\n class=\"x-editable-number-range-filter__apply xds:button\"\n :class=\"buttonsClass\"\n :disabled=\"hasError\"\n data-test=\"range-apply\"\n @click=\"emitUserModifiedFilter\"\n >\n <!--\n @slot Slot used to customize the apply button content.\n -->\n <slot name=\"apply-content\">✓</slot>\n </button>\n\n <button\n v-if=\"renderClearButton\"\n class=\"x-editable-number-range-filter__clear xds:button\"\n :class=\"buttonsClass\"\n data-test=\"range-clear\"\n @click=\"clearValues\"\n >\n <!--\n @slot Slot used to customize the clear button content.\n -->\n <slot name=\"clear-content\">𐄂</slot>\n </button>\n </slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type {\n EditableNumberRangeFilter as EditableNumberRangeFilterModel,\n RangeValue,\n} from '@empathyco/x-types'\nimport type { PropType, Ref } from 'vue'\nimport { computed, defineComponent, ref, watch } from 'vue'\nimport { use$x } from '../../../../composables'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders an editable number range filter. It has two input fields to handle min and max values,\n * emitting the needed events when clicked.\n *\n * It provides a default slot, with some utils bind, to customize the whole component; and two\n * named slots `apply-content` and `clear-content` to override each button content.\n *\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\nexport default defineComponent({\n name: 'EditableNumberRangeFilter',\n xModule: facetsXModule.name,\n props: {\n /**\n * The filter data to render and edit.\n *\n * @public\n */\n filter: {\n type: Object as PropType<EditableNumberRangeFilterModel>,\n required: true,\n },\n /**\n * If `instant` prop is true, the needed events are emitted immediately; else, apply button is\n * rendered to confirm to do it. False by default.\n *\n * @public\n */\n isInstant: Boolean,\n /**\n * If `clear` prop is true, clear button, which sets to null component min and max values, is\n * rendered. True by default.\n *\n * @public\n */\n hasClearButton: {\n type: Boolean,\n default: true,\n },\n /** Class inherited by content element. */\n inputsClass: String,\n /** Class inherited by content element. */\n buttonsClass: String,\n },\n setup(props) {\n const $x = use$x()\n\n const rangeFilterMin = 'minimum amount'\n const rangeFilterMax = 'maximum amount'\n /**\n * Component min value.\n *\n * @internal\n */\n const min: Ref<RangeValue['min']> = ref(null)\n /**\n * Component max value.\n *\n * @internal\n */\n const max: Ref<RangeValue['max']> = ref(null)\n\n /**\n * Returns {@link @empathyco/x-types#RangeValue} with component min and max\n * values.\n *\n * @returns Range value object with component values.\n *\n * @internal\n */\n const range = computed((): RangeValue => {\n return { min: min.value, max: max.value }\n })\n\n /**\n * It checks if component min and max values are valid.\n *\n * @returns True if there is any error in the component min and max values.\n *\n * @internal\n */\n const hasError = computed(\n () => min.value !== null && max.value !== null && min.value > max.value,\n )\n\n /**\n * It checks if component min and max values are different from the ones within the filter\n * provided as property.\n *\n * @returns True if they are different.\n *\n * @internal\n */\n const areValuesDifferent = computed(\n () => min.value !== props.filter.range.min || max.value !== props.filter.range.max,\n )\n\n /**\n * Dynamic CSS classes.\n *\n * @returns Object which contains dynamic CSS classes.\n *\n * @internal\n */\n const cssClasses = computed(() => {\n return { 'x-editable-number-range-filter--error': hasError.value }\n })\n\n /**\n * Checks if the range of the filter allows any value, which happens when the min is\n * null or 0 and the max is null.\n *\n * @returns True if the range of the filter allows any value.\n *\n * @internal\n */\n const isAnyRange = computed(() => !min.value && max.value === null)\n\n /**\n * It returns true if the property `hasClearButton` is true and there are values to clear.\n *\n * @returns True if the clear button has to be rendered.\n *\n * @internal\n */\n const renderClearButton = computed(() => props.hasClearButton && !isAnyRange.value)\n\n /**\n * It emits {@link FacetsXEvents.UserModifiedEditableNumberRangeFilter} event if there are no\n * errors and component `min` and `max` values are different than `filter.range` ones.\n *\n * @internal\n */\n const emitUserModifiedFilter = () => {\n if (!hasError.value && areValuesDifferent.value) {\n $x.emit('UserModifiedEditableNumberRangeFilter', {\n ...props.filter,\n range: range.value,\n })\n }\n }\n\n /**\n * It returns the number if possible or null otherwise.\n *\n * @param value - Value.\n * @returns The element value as a number if possible or null.\n *\n * @internal\n */\n const parseRangeValue = (value: number) => (Number.isNaN(value) ? null : value)\n\n /**\n * `min` setter.\n *\n * @param value - The component `min` value to be set.\n *\n * @internal\n */\n const setMin = (value: number) => {\n min.value = parseRangeValue(value)\n }\n\n /**\n * `max` setter.\n *\n * @param value - The component `max` value to be set.\n *\n * @internal\n */\n const setMax = (value: number) => {\n max.value = parseRangeValue(value)\n }\n\n /**\n * It sets component `min` and `max` values to null , and it emits the change if component is\n * working in instant mode.\n *\n * @internal\n */\n const clearValues = () => {\n min.value = null\n max.value = null\n }\n\n /**\n * It resets the min/max range values to null if the\n * {@link FacetsXEvents.UserClickedClearAllFilters} event is fired.\n *\n * @public\n */\n $x.on('UserClickedClearAllFilters', false).subscribe(clearValues)\n\n /**\n * It watches the filter range values passed as property and updates component range values if\n * they change.\n *\n * @param newRange - New range value.\n *\n * @internal\n */\n watch(\n () => props.filter.range,\n (newRange: RangeValue) => {\n min.value = newRange.min\n max.value = newRange.max\n },\n { immediate: true, deep: true },\n )\n\n /**\n * It watches range values in order to emit the event with the change if `isInstant`\n * property is true.\n *\n * @internal\n */\n watch(\n range,\n () => {\n if (props.isInstant) {\n emitUserModifiedFilter()\n }\n },\n { deep: true },\n )\n\n return {\n rangeFilterMin,\n rangeFilterMax,\n cssClasses,\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n renderClearButton,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-editable-number-range-filter--error .x-editable-number-range-filter__input {\n border-color: red;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nA list of events that the component will emit:\n\n- [`UserModifiedEditableNumberRangeFilter`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n this event is emitted instantly after typing the value or clicking the submit button. The event\n payload in both cases is an object containing the filter and the new value for the range.\n\n## Example\n\nRenders an editable number range filter. It has two input fields to handle min and max values,\nemitting the needed events when clicked.\n\nIt provides a default slot, with some utils bind, to customize the whole component; and two named\nslots `apply-content` and `clear-content` to override each button content.\n\nIf `instant` prop is true, the needed events are emitted immediately; else, apply button is rendered\nto confirm to do it. False by default.\n\nIf `clear` prop is true, clear button, which sets to null component min and max values, is rendered.\nTrue by default.\n\n### Basic usage\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Properties\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\" :isInstant=\"true\" :hasClearButton=\"false\" />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing content slots\n\n```vue\n<template>\n <EditableNumberRangeFilter :filter=\"editableFilter\">\n <template #apply-content>Apply</template>\n <template #clear-content>Clear</template>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing default slot\n\n```vue\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n #default=\"{\n min,\n max,\n setMin,\n setMax,\n emitUserModifiedFilter,\n clearValues,\n hasError,\n isAnyRange,\n }\"\n >\n <button @click=\"emitUserModifiedFilter\">✅ Apply!</button>\n <button @click=\"clearValues\">🗑 Clear!</button>\n <input :value=\"!isAnyRange ? min : null\" @change=\"setMin($event.target.valueAsNumber)\" />\n <input :value=\"max\" @change=\"setMax($event.target.valueAsNumber)\" />\n <div class=\"has-error\" v-if=\"hasError\">⚠️ Invalid range values</div>\n </EditableNumberRangeFilter>\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonsClass` and `inputsClass` props can be used to add classes to the inputs and buttons of\nthe component.\n\n```\n<template>\n <EditableNumberRangeFilter\n :filter=\"editableFilter\"\n :inputsClass=\"'my-inputs-class'\"\n :buttonsClass=\"'my-buttons-class'\"\n />\n</template>\n\n<script setup>\nimport { EditableNumberRangeFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst editableFilter = ref({\n facetId: 'age',\n id: 'age:primary',\n label: 'primary',\n modelName: 'EditableNumberRangeFilter',\n range: {\n min: null,\n max: null,\n },\n})\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
|
|
@@ -37,8 +37,8 @@ var _sfc_main = defineComponent({
|
|
|
37
37
|
const isDisabled = computed(() => props.filter.totalResults === 0);
|
|
38
38
|
/** CSS classes to apply to the element. */
|
|
39
39
|
const innerCssClasses = computed(() => [
|
|
40
|
-
'
|
|
41
|
-
{ '
|
|
40
|
+
'xds:filter-facet',
|
|
41
|
+
{ 'xds:selected': props.filter.selected },
|
|
42
42
|
...props.cssClasses,
|
|
43
43
|
]);
|
|
44
44
|
/** The events that will be emitted when the filter is clicked. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderless-filter.vue.js","sources":["../../../../../../src/x-modules/facets/components/filters/renderless-filter.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { BooleanFilter } from '@empathyco/x-types'\nimport type { Dictionary } from '@empathyco/x-utils'\nimport type { PropType } from 'vue'\nimport type { XEvent, XEventsTypes } from '../../../../wiring/events.types'\nimport { computed, defineComponent } from 'vue'\nimport { useXBus } from '../../../../composables/use-x-bus'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders default slot content. It binds to the default slot a\n * {@link @empathyco/x-types#BooleanFilter}, the {@link XEvent}\n * that will be emitted when clicking the content, the CSS classes and if the content should be\n * deactivated.\n *\n * @remarks The default slot expects a root element, if it receives a list of elements, it will\n * render the first element.\n *\n * @public\n */\nexport default defineComponent({\n name: 'RenderlessFilter',\n xModule: facetsXModule.name,\n inheritAttrs: false,\n props: {\n /** The filter data to render. */\n filter: {\n type: Object as PropType<BooleanFilter>,\n required: true,\n },\n /** Additional events with its payload to emit when the filter is clicked. */\n clickEvents: Object as PropType<Partial<XEventsTypes>>,\n /** Inheritance CSS classes. */\n cssClasses: {\n type: Array as PropType<(string | Dictionary<boolean>)[]>,\n default: () => [],\n },\n },\n setup(props, { slots }) {\n const xBus = useXBus()\n\n /** Returns `true` when the filter should be disabled. */\n const isDisabled = computed(() => props.filter.totalResults === 0)\n\n /** CSS classes to apply to the element. */\n const innerCssClasses = computed(() => [\n '
|
|
1
|
+
{"version":3,"file":"renderless-filter.vue.js","sources":["../../../../../../src/x-modules/facets/components/filters/renderless-filter.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { BooleanFilter } from '@empathyco/x-types'\nimport type { Dictionary } from '@empathyco/x-utils'\nimport type { PropType } from 'vue'\nimport type { XEvent, XEventsTypes } from '../../../../wiring/events.types'\nimport { computed, defineComponent } from 'vue'\nimport { useXBus } from '../../../../composables/use-x-bus'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders default slot content. It binds to the default slot a\n * {@link @empathyco/x-types#BooleanFilter}, the {@link XEvent}\n * that will be emitted when clicking the content, the CSS classes and if the content should be\n * deactivated.\n *\n * @remarks The default slot expects a root element, if it receives a list of elements, it will\n * render the first element.\n *\n * @public\n */\nexport default defineComponent({\n name: 'RenderlessFilter',\n xModule: facetsXModule.name,\n inheritAttrs: false,\n props: {\n /** The filter data to render. */\n filter: {\n type: Object as PropType<BooleanFilter>,\n required: true,\n },\n /** Additional events with its payload to emit when the filter is clicked. */\n clickEvents: Object as PropType<Partial<XEventsTypes>>,\n /** Inheritance CSS classes. */\n cssClasses: {\n type: Array as PropType<(string | Dictionary<boolean>)[]>,\n default: () => [],\n },\n },\n setup(props, { slots }) {\n const xBus = useXBus()\n\n /** Returns `true` when the filter should be disabled. */\n const isDisabled = computed(() => props.filter.totalResults === 0)\n\n /** CSS classes to apply to the element. */\n const innerCssClasses = computed(() => [\n 'xds:filter-facet',\n { 'xds:selected': props.filter.selected },\n ...props.cssClasses,\n ])\n\n /** The events that will be emitted when the filter is clicked. */\n const innerClickEvents = computed(() => ({\n UserClickedAFilter: props.filter,\n ...props.clickEvents,\n }))\n\n /** Emit filter click events to the bus. */\n function emitClickEvents() {\n Object.entries(innerClickEvents.value).forEach(([event, payload]) => {\n xBus.emit(event as XEvent, payload)\n })\n }\n\n return () =>\n slots.default?.({\n filter: props.filter,\n clickFilter: emitClickEvents,\n cssClasses: innerCssClasses.value,\n isDisabled: isDisabled.value,\n }) ?? ''\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\nRenders default slot content. It binds to the default slot a filter, the events that will be emitted\nwhen clicking the content, the CSS classes and if the content should be deactivated.\n\n### Basic usage\n\n```vue\n<template>\n <RenderlessFilter :filter=\"filter\" />\n</template>\n\n<script setup>\nimport { RenderlessFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filter = ref({\n id: 'color:red',\n modelName: 'SimpleFilter',\n label: 'Red',\n facetId: 'color',\n selected: false,\n totalResults: 10,\n})\n</script>\n```\n\n### Customizing its contents and adding new events\n\n```vue\n<template>\n <RenderlessFilter\n :filter=\"filter\"\n :clickEvents=\"clickEvents\"\n v-slot=\"{ filter, clickFilter, cssClasses, isDisabled }\"\n >\n <button @click=\"clickFilter\" :class=\"cssClasses\" :disabled=\"isDisabled\">\n {{ filter.label }}\n </button>\n </RenderlessFilter>\n</template>\n\n<script setup>\nimport { RenderlessFilter } from '@empathyco/x-components/facets'\nimport { ref, computed } from 'vue'\n\nconst filter = ref({\n id: 'color:red',\n modelName: 'SimpleFilter',\n label: 'Red',\n facetId: 'color',\n selected: false,\n totalResults: 10,\n})\nconst clickEvents = computed(() => ({ UserClickedAHierarchicalFilter: filter.value }))\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AASA;;;;;;;;;;AAUE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,aAAa,CAAC,IAAI;AAC3B,IAAA,YAAY,EAAE,KAAK;AACnB,IAAA,KAAK,EAAE;;AAEL,QAAA,MAAM,EAAE;AACN,YAAA,IAAI,EAAE,MAAiC;AACvC,YAAA,QAAQ,EAAE,IAAI;AACf,SAAA;;AAED,QAAA,WAAW,EAAE,MAAyC;;AAEtD,QAAA,UAAU,EAAE;AACV,YAAA,IAAI,EAAE,KAAmD;AACzD,YAAA,OAAO,EAAE,MAAM,EAAE;AAClB,SAAA;AACF,KAAA;AACD,IAAA,KAAK,CAAC,KAAK,EAAE,EAAE,KAAI,EAAG,EAAA;AACpB,QAAA,MAAM,IAAG,GAAI,OAAO,EAAC;;AAGrB,QAAA,MAAM,aAAa,QAAQ,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,YAAW,KAAM,CAAC,CAAA;;AAGjE,QAAA,MAAM,eAAc,GAAI,QAAQ,CAAC,MAAM;YACrC,kBAAkB;AAClB,YAAA,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;YACzC,GAAG,KAAK,CAAC,UAAU;AACpB,SAAA,CAAA;;AAGD,QAAA,MAAM,gBAAe,GAAI,QAAQ,CAAC,OAAO;YACvC,kBAAkB,EAAE,KAAK,CAAC,MAAM;YAChC,GAAG,KAAK,CAAC,WAAW;AACrB,SAAA,CAAC,CAAA;;AAGF,QAAA,SAAS,eAAe,GAAA;AACtB,YAAA,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,KAAG;AACjE,gBAAA,IAAI,CAAC,IAAI,CAAC,KAAe,EAAE,OAAO,CAAA;AACpC,YAAA,CAAC,CAAA;QACH;AAEA,QAAA,OAAO,MACL,KAAK,CAAC,OAAO,GAAG;YACd,MAAM,EAAE,KAAK,CAAC,MAAM;AACpB,YAAA,WAAW,EAAE,eAAe;YAC5B,UAAU,EAAE,eAAe,CAAC,KAAK;YACjC,UAAU,EAAE,UAAU,CAAC,KAAK;SAC7B,CAAA,IAAK,EAAC;IACX,CAAC;AACF,CAAA,CAAA;;;;"}
|
|
@@ -16,7 +16,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16
16
|
createElementVNode("input", {
|
|
17
17
|
value: _ctx.query,
|
|
18
18
|
type: "search",
|
|
19
|
-
class: "x-filters-search__input
|
|
19
|
+
class: "x-filters-search__input xds:input",
|
|
20
20
|
"data-test": "filters-search-input",
|
|
21
21
|
"aria-label": "search into the filter values",
|
|
22
22
|
onInput: _cache[0] || (_cache[0] = ($event) => _ctx.setQuery($event?.target?.value))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filters-search.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/filters-search.vue"],"sourcesContent":["<template>\n <div class=\"x-filters-search\" :class=\"cssClasses\" data-test=\"filters-search\">\n <!--\n @slot Search content. It is the content which triggers the filters sifting.\n @binding {string} query - The query to search in filters.\n @binding {Function} setQuery - The function to set the query. The query is passed as\n parameter.\n @binding {Function} clearQuery - The function to clear the query.\n -->\n <slot name=\"search\" v-bind=\"{ query, setQuery, clearQuery }\">\n <input\n :value=\"query\"\n type=\"search\"\n class=\"x-filters-search__input
|
|
1
|
+
{"version":3,"file":"filters-search.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/filters-search.vue"],"sourcesContent":["<template>\n <div class=\"x-filters-search\" :class=\"cssClasses\" data-test=\"filters-search\">\n <!--\n @slot Search content. It is the content which triggers the filters sifting.\n @binding {string} query - The query to search in filters.\n @binding {Function} setQuery - The function to set the query. The query is passed as\n parameter.\n @binding {Function} clearQuery - The function to clear the query.\n -->\n <slot name=\"search\" v-bind=\"{ query, setQuery, clearQuery }\">\n <input\n :value=\"query\"\n type=\"search\"\n class=\"x-filters-search__input xds:input\"\n data-test=\"filters-search-input\"\n aria-label=\"search into the filter values\"\n @input=\"setQuery(($event?.target as HTMLInputElement)?.value)\"\n />\n </slot>\n <!--\n @slot (Required) Sifted filters content.\n @binding {Filter[]} siftedFilters - Sifted filters data.\n -->\n <slot :sifted-filters=\"siftedFilters\"></slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { DebouncedFunction, VueCSSClasses } from '../../../../utils/types'\nimport { isBooleanFilter } from '@empathyco/x-types'\nimport { computed, defineComponent, provide, ref, watch } from 'vue'\nimport { debounce } from '../../../../utils/debounce'\nimport { normalizeString } from '../../../../utils/normalize'\nimport { useFiltersInjection } from '../../composables/use-filters-injection'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders the filters sifted with the input query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'FiltersSearch',\n xModule: facetsXModule.name,\n props: {\n /**\n * The list of filters to be rendered as slots.\n *\n * @public\n */\n filters: Array as PropType<Filter[]>,\n\n /**\n * This prop is used in the `HierarchicalFilter` component and only in that case. It is necessary\n * to make the `renderedFilters` to return only the filters of each level of the hierarchy.\n *\n * @public\n */\n parentId: {\n type: String as PropType<Filter['id']>,\n required: false,\n },\n\n /** The debounce time for applying the filter sifting. */\n debounceInMs: {\n type: Number,\n default: 200,\n },\n },\n setup(props) {\n const renderedFilters = useFiltersInjection(props)\n\n const query = ref('')\n let setQueryDebounced: DebouncedFunction<[string]>\n\n const debounceInMs = computed(() => props.debounceInMs)\n\n /**\n * Set the debounce function for setting the query debounced.\n *\n * @internal\n */\n const updateSetQueryDebounced = () => {\n setQueryDebounced = debounce(queryDebounced => {\n query.value = queryDebounced\n }, props.debounceInMs)\n }\n watch(debounceInMs, updateSetQueryDebounced, { immediate: true })\n\n /**\n * Sift the array of filters which matches with the query.\n *\n * @returns Array of sifted filters.\n * @internal\n */\n const siftedFilters = computed((): Filter[] => {\n const normalizedQuery = normalizeString(query.value)\n return renderedFilters.value.filter(\n filter =>\n isBooleanFilter(filter) && normalizeString(filter.label).includes(normalizedQuery),\n )\n })\n provide('filters', siftedFilters)\n\n /**\n * Adds the dynamic css classes to the component.\n *\n * @returns The class to be added to the component.\n * @internal\n */\n const cssClasses = computed((): VueCSSClasses => {\n return { 'x-filters-search--is-sifted': !!query.value }\n })\n\n /**\n * Set the query through the debounced function.\n *\n * @param query - The query to sift filters.\n * @internal\n */\n const setQuery = (query: string): void => {\n setQueryDebounced(query)\n }\n\n /**\n * Clear the query.\n *\n * @internal\n */\n const clearQuery = (): void => {\n query.value = ''\n }\n\n return {\n clearQuery,\n setQuery,\n cssClasses,\n siftedFilters,\n query,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-filters-search {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-filters-search__input::-ms-clear {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-ms-reveal {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-webkit-search-decoration,\n.x-filters-search__input::-webkit-search-cancel-button,\n.x-filters-search__input::-webkit-search-results-button,\n.x-filters-search__input::-webkit-search-results-decoration {\n display: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nIt renders an input and a list of filters passed as prop or being injected. The list of filters can\nbe sifted with the query typed in the input. This component has also a debounce prop to set the time\nin milliseconds to apply the filters search. Moreover, it has two scoped slots. The first one for\ncustomize the search triggering with three slot props; the query, a function to set the query by\nsifting and a third one for cleaning the query. The second scoped slot is required and it is for\ndisplaying the list of filters sifted. It has a slot prop with these filters sifted.\n\n### Important\n\nThe component has two ways of receive the filters list, it can be injected by another component or\nbe send it as a prop. If the component doesnt have a parent component that receive and exposed a\nfilters list to their children, it is mandatory to send it as prop.\n\n### Basic usage\n\nUsing default and required slot:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nSetting debounce time:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" :debounceInMs=\"500\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nReplacing search triggering:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\">\n <template #search=\"{ query, setQuery, clearQuery }\">\n <input\n @input=\"setQuery($event.target.value)\"\n :value=\"query\"\n class=\"x-input x-filters-search__input\"\n :aria-label=\"filtersSearchInputMessage\"\n />\n <button @click=\"clearQuery\">X</button>\n </template>\n <template #default=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </template>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\n> **Using injection**: It can receive the filters list by injection. It only works if it has a\n> parent component that receives and exposes the filters list. Using the injection, It is not\n> necessary to send the prop to the child components, it has to be send it in the parent component,\n> the rest of components will inject this list.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"8\">\n <FiltersSearch>\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" data-test=\"brand-filter\" />\n </Filters>\n </FiltersSearch>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets } from '@empathyco/x-components/facets'\nimport { SlicedFilters, FiltersSearch, Filters, SimpleFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst facet = ref({\n filters: [\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n ],\n})\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_createElementVNode"],"mappings":";;;;;;;AACE,EAAA,OAAAA,SAAA,EAAA,EAAAC,kBAAA;AAAA,IAuBM,KAAA;AAAA,IAAA;AAAA,MAvBD,KAAA,EAAKC,cAAA,CAAA,CAAC,kBAAA,EAA2B,IAAA,CAAA,UAAU,CAAA,CAAA;AAAA,MAAE,WAAA,EAAU;AAAA,KAAA;;AAQ1D,MAAAC,UAAA,CASO,kEATuB,IAAA,CAAA,KAAA,EAAK,QAAA,EAAE,eAAQ,UAAA,EAAE,IAAA,CAAA,UAAA,MAA/C,MASO;AAAA,QARLC,kBAAA,CAOE,OAAA,EAAA;AAAA,UANC,KAAA,EAAO,IAAA,CAAA,KAAA;AAAA,UACR,IAAA,EAAK,QAAA;AAAA,UACL,KAAA,EAAM,mCAAA;AAAA,UACN,WAAA,EAAU,sBAAA;AAAA,UACV,YAAA,EAAW,+BAAA;AAAA,UACV,OAAA,EAAK,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,MAAA,KAAE,IAAA,CAAA,QAAA,CAAU,MAAA,EAAQ,QAA6B,KAAK,CAAA;AAAA,SAAA,EAAA,IAAA,EAAA,EAAA,EAAA,UAAA;;MAOhED,UAAA,CAA6C,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA,EAAtC,eAAgB,IAAA,CAAA,aAAA,EAAa,EAAA,MAAA,EAAA,IAAA;AAAA,KAAA;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filters-search.vue2.js","sources":["../../../../../../src/x-modules/facets/components/lists/filters-search.vue"],"sourcesContent":["<template>\n <div class=\"x-filters-search\" :class=\"cssClasses\" data-test=\"filters-search\">\n <!--\n @slot Search content. It is the content which triggers the filters sifting.\n @binding {string} query - The query to search in filters.\n @binding {Function} setQuery - The function to set the query. The query is passed as\n parameter.\n @binding {Function} clearQuery - The function to clear the query.\n -->\n <slot name=\"search\" v-bind=\"{ query, setQuery, clearQuery }\">\n <input\n :value=\"query\"\n type=\"search\"\n class=\"x-filters-search__input x-input\"\n data-test=\"filters-search-input\"\n aria-label=\"search into the filter values\"\n @input=\"setQuery(($event?.target as HTMLInputElement)?.value)\"\n />\n </slot>\n <!--\n @slot (Required) Sifted filters content.\n @binding {Filter[]} siftedFilters - Sifted filters data.\n -->\n <slot :sifted-filters=\"siftedFilters\"></slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { DebouncedFunction, VueCSSClasses } from '../../../../utils/types'\nimport { isBooleanFilter } from '@empathyco/x-types'\nimport { computed, defineComponent, provide, ref, watch } from 'vue'\nimport { debounce } from '../../../../utils/debounce'\nimport { normalizeString } from '../../../../utils/normalize'\nimport { useFiltersInjection } from '../../composables/use-filters-injection'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders the filters sifted with the input query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'FiltersSearch',\n xModule: facetsXModule.name,\n props: {\n /**\n * The list of filters to be rendered as slots.\n *\n * @public\n */\n filters: Array as PropType<Filter[]>,\n\n /**\n * This prop is used in the `HierarchicalFilter` component and only in that case. It is necessary\n * to make the `renderedFilters` to return only the filters of each level of the hierarchy.\n *\n * @public\n */\n parentId: {\n type: String as PropType<Filter['id']>,\n required: false,\n },\n\n /** The debounce time for applying the filter sifting. */\n debounceInMs: {\n type: Number,\n default: 200,\n },\n },\n setup(props) {\n const renderedFilters = useFiltersInjection(props)\n\n const query = ref('')\n let setQueryDebounced: DebouncedFunction<[string]>\n\n const debounceInMs = computed(() => props.debounceInMs)\n\n /**\n * Set the debounce function for setting the query debounced.\n *\n * @internal\n */\n const updateSetQueryDebounced = () => {\n setQueryDebounced = debounce(queryDebounced => {\n query.value = queryDebounced\n }, props.debounceInMs)\n }\n watch(debounceInMs, updateSetQueryDebounced, { immediate: true })\n\n /**\n * Sift the array of filters which matches with the query.\n *\n * @returns Array of sifted filters.\n * @internal\n */\n const siftedFilters = computed((): Filter[] => {\n const normalizedQuery = normalizeString(query.value)\n return renderedFilters.value.filter(\n filter =>\n isBooleanFilter(filter) && normalizeString(filter.label).includes(normalizedQuery),\n )\n })\n provide('filters', siftedFilters)\n\n /**\n * Adds the dynamic css classes to the component.\n *\n * @returns The class to be added to the component.\n * @internal\n */\n const cssClasses = computed((): VueCSSClasses => {\n return { 'x-filters-search--is-sifted': !!query.value }\n })\n\n /**\n * Set the query through the debounced function.\n *\n * @param query - The query to sift filters.\n * @internal\n */\n const setQuery = (query: string): void => {\n setQueryDebounced(query)\n }\n\n /**\n * Clear the query.\n *\n * @internal\n */\n const clearQuery = (): void => {\n query.value = ''\n }\n\n return {\n clearQuery,\n setQuery,\n cssClasses,\n siftedFilters,\n query,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-filters-search {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-filters-search__input::-ms-clear {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-ms-reveal {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-webkit-search-decoration,\n.x-filters-search__input::-webkit-search-cancel-button,\n.x-filters-search__input::-webkit-search-results-button,\n.x-filters-search__input::-webkit-search-results-decoration {\n display: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nIt renders an input and a list of filters passed as prop or being injected. The list of filters can\nbe sifted with the query typed in the input. This component has also a debounce prop to set the time\nin milliseconds to apply the filters search. Moreover, it has two scoped slots. The first one for\ncustomize the search triggering with three slot props; the query, a function to set the query by\nsifting and a third one for cleaning the query. The second scoped slot is required and it is for\ndisplaying the list of filters sifted. It has a slot prop with these filters sifted.\n\n### Important\n\nThe component has two ways of receive the filters list, it can be injected by another component or\nbe send it as a prop. If the component doesnt have a parent component that receive and exposed a\nfilters list to their children, it is mandatory to send it as prop.\n\n### Basic usage\n\nUsing default and required slot:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nSetting debounce time:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" :debounceInMs=\"500\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nReplacing search triggering:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\">\n <template #search=\"{ query, setQuery, clearQuery }\">\n <input\n @input=\"setQuery($event.target.value)\"\n :value=\"query\"\n class=\"x-input x-filters-search__input\"\n :aria-label=\"filtersSearchInputMessage\"\n />\n <button @click=\"clearQuery\">X</button>\n </template>\n <template #default=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </template>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\n> **Using injection**: It can receive the filters list by injection. It only works if it has a\n> parent component that receives and exposes the filters list. Using the injection, It is not\n> necessary to send the prop to the child components, it has to be send it in the parent component,\n> the rest of components will inject this list.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"8\">\n <FiltersSearch>\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" data-test=\"brand-filter\" />\n </Filters>\n </FiltersSearch>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets } from '@empathyco/x-components/facets'\nimport { SlicedFilters, FiltersSearch, Filters, SimpleFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst facet = ref({\n filters: [\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n ],\n})\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;;;AAsCA;;;;AAIE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,aAAa,CAAC,IAAI;AAC3B,IAAA,KAAK,EAAE;AACL;;;;AAIE;AACF,QAAA,OAAO,EAAE,KAA2B;AAEpC;;;;;AAKE;AACF,QAAA,QAAQ,EAAE;AACR,YAAA,IAAI,EAAE,MAAgC;AACtC,YAAA,QAAQ,EAAE,KAAK;AAChB,SAAA;;AAGD,QAAA,YAAY,EAAE;AACZ,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,OAAO,EAAE,GAAG;AACb,SAAA;AACF,KAAA;AACD,IAAA,KAAK,CAAC,KAAK,EAAA;AACT,QAAA,MAAM,eAAc,GAAI,mBAAmB,CAAC,KAAK,CAAA;AAEjD,QAAA,MAAM,KAAI,GAAI,GAAG,CAAC,EAAE,CAAA;AACpB,QAAA,IAAI,iBAA6C;QAEjD,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,YAAY,CAAA;AAEtD;;;;AAIE;QACF,MAAM,uBAAsB,GAAI,MAAI;AAClC,YAAA,iBAAgB,GAAI,QAAQ,CAAC,cAAa,IAAG;AAC3C,gBAAA,KAAK,CAAC,KAAI,GAAI,cAAa;AAC7B,YAAA,CAAC,EAAE,KAAK,CAAC,YAAY,CAAA;AACvB,QAAA,CAAA;QACA,KAAK,CAAC,YAAY,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAE,IAAG,EAAG,CAAA;AAEhE;;;;;AAKE;AACF,QAAA,MAAM,gBAAgB,QAAQ,CAAC,MAAc;YAC3C,MAAM,eAAc,GAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAA;YACnD,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,CACjC,UACE,eAAe,CAAC,MAAM,CAAA,IAAK,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CACtF;AACF,QAAA,CAAC,CAAA;AACD,QAAA,OAAO,CAAC,SAAS,EAAE,aAAa,CAAA;AAEhC;;;;;AAKE;AACF,QAAA,MAAM,UAAS,GAAI,QAAQ,CAAC,MAAmB;YAC7C,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC,KAAK,CAAC,KAAI,EAAE;AACxD,QAAA,CAAC,CAAA;AAED;;;;;AAKE;AACF,QAAA,MAAM,QAAO,GAAI,CAAC,KAAa,KAAS;YACtC,iBAAiB,CAAC,KAAK,CAAA;AACzB,QAAA,CAAA;AAEA;;;;AAIE;QACF,MAAM,UAAS,GAAI,MAAU;AAC3B,YAAA,KAAK,CAAC,KAAI,GAAI,EAAC;AACjB,QAAA,CAAA;QAEA,OAAO;YACL,UAAU;YACV,QAAQ;YACR,UAAU;YACV,aAAa;YACb,KAAK;SACP;IACF,CAAC;AACF,CAAA,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"filters-search.vue2.js","sources":["../../../../../../src/x-modules/facets/components/lists/filters-search.vue"],"sourcesContent":["<template>\n <div class=\"x-filters-search\" :class=\"cssClasses\" data-test=\"filters-search\">\n <!--\n @slot Search content. It is the content which triggers the filters sifting.\n @binding {string} query - The query to search in filters.\n @binding {Function} setQuery - The function to set the query. The query is passed as\n parameter.\n @binding {Function} clearQuery - The function to clear the query.\n -->\n <slot name=\"search\" v-bind=\"{ query, setQuery, clearQuery }\">\n <input\n :value=\"query\"\n type=\"search\"\n class=\"x-filters-search__input xds:input\"\n data-test=\"filters-search-input\"\n aria-label=\"search into the filter values\"\n @input=\"setQuery(($event?.target as HTMLInputElement)?.value)\"\n />\n </slot>\n <!--\n @slot (Required) Sifted filters content.\n @binding {Filter[]} siftedFilters - Sifted filters data.\n -->\n <slot :sifted-filters=\"siftedFilters\"></slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { DebouncedFunction, VueCSSClasses } from '../../../../utils/types'\nimport { isBooleanFilter } from '@empathyco/x-types'\nimport { computed, defineComponent, provide, ref, watch } from 'vue'\nimport { debounce } from '../../../../utils/debounce'\nimport { normalizeString } from '../../../../utils/normalize'\nimport { useFiltersInjection } from '../../composables/use-filters-injection'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Renders the filters sifted with the input query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'FiltersSearch',\n xModule: facetsXModule.name,\n props: {\n /**\n * The list of filters to be rendered as slots.\n *\n * @public\n */\n filters: Array as PropType<Filter[]>,\n\n /**\n * This prop is used in the `HierarchicalFilter` component and only in that case. It is necessary\n * to make the `renderedFilters` to return only the filters of each level of the hierarchy.\n *\n * @public\n */\n parentId: {\n type: String as PropType<Filter['id']>,\n required: false,\n },\n\n /** The debounce time for applying the filter sifting. */\n debounceInMs: {\n type: Number,\n default: 200,\n },\n },\n setup(props) {\n const renderedFilters = useFiltersInjection(props)\n\n const query = ref('')\n let setQueryDebounced: DebouncedFunction<[string]>\n\n const debounceInMs = computed(() => props.debounceInMs)\n\n /**\n * Set the debounce function for setting the query debounced.\n *\n * @internal\n */\n const updateSetQueryDebounced = () => {\n setQueryDebounced = debounce(queryDebounced => {\n query.value = queryDebounced\n }, props.debounceInMs)\n }\n watch(debounceInMs, updateSetQueryDebounced, { immediate: true })\n\n /**\n * Sift the array of filters which matches with the query.\n *\n * @returns Array of sifted filters.\n * @internal\n */\n const siftedFilters = computed((): Filter[] => {\n const normalizedQuery = normalizeString(query.value)\n return renderedFilters.value.filter(\n filter =>\n isBooleanFilter(filter) && normalizeString(filter.label).includes(normalizedQuery),\n )\n })\n provide('filters', siftedFilters)\n\n /**\n * Adds the dynamic css classes to the component.\n *\n * @returns The class to be added to the component.\n * @internal\n */\n const cssClasses = computed((): VueCSSClasses => {\n return { 'x-filters-search--is-sifted': !!query.value }\n })\n\n /**\n * Set the query through the debounced function.\n *\n * @param query - The query to sift filters.\n * @internal\n */\n const setQuery = (query: string): void => {\n setQueryDebounced(query)\n }\n\n /**\n * Clear the query.\n *\n * @internal\n */\n const clearQuery = (): void => {\n query.value = ''\n }\n\n return {\n clearQuery,\n setQuery,\n cssClasses,\n siftedFilters,\n query,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-filters-search {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-filters-search__input::-ms-clear {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-ms-reveal {\n display: none;\n width: 0;\n height: 0;\n}\n\n.x-filters-search__input::-webkit-search-decoration,\n.x-filters-search__input::-webkit-search-cancel-button,\n.x-filters-search__input::-webkit-search-results-button,\n.x-filters-search__input::-webkit-search-results-decoration {\n display: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nIt renders an input and a list of filters passed as prop or being injected. The list of filters can\nbe sifted with the query typed in the input. This component has also a debounce prop to set the time\nin milliseconds to apply the filters search. Moreover, it has two scoped slots. The first one for\ncustomize the search triggering with three slot props; the query, a function to set the query by\nsifting and a third one for cleaning the query. The second scoped slot is required and it is for\ndisplaying the list of filters sifted. It has a slot prop with these filters sifted.\n\n### Important\n\nThe component has two ways of receive the filters list, it can be injected by another component or\nbe send it as a prop. If the component doesnt have a parent component that receive and exposed a\nfilters list to their children, it is mandatory to send it as prop.\n\n### Basic usage\n\nUsing default and required slot:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nSetting debounce time:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\" :debounceInMs=\"500\" v-slot=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\nReplacing search triggering:\n\n```vue\n<template>\n <FiltersSearch :filters=\"filters\">\n <template #search=\"{ query, setQuery, clearQuery }\">\n <input\n @input=\"setQuery($event.target.value)\"\n :value=\"query\"\n class=\"x-input x-filters-search__input\"\n :aria-label=\"filtersSearchInputMessage\"\n />\n <button @click=\"clearQuery\">X</button>\n </template>\n <template #default=\"{ siftedFilters }\">\n <ul v-for=\"filter in siftedFilters\">\n <li :key=\"filter.id\">{{ filter.label }}</li>\n </ul>\n </template>\n </FiltersSearch>\n</template>\n\n<script setup>\nimport { FiltersSearch } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst filters = ref([\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n])\n</script>\n```\n\n> **Using injection**: It can receive the filters list by injection. It only works if it has a\n> parent component that receives and exposes the filters list. Using the injection, It is not\n> necessary to send the prop to the child components, it has to be send it in the parent component,\n> the rest of components will inject this list.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"8\">\n <FiltersSearch>\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" data-test=\"brand-filter\" />\n </Filters>\n </FiltersSearch>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets } from '@empathyco/x-components/facets'\nimport { SlicedFilters, FiltersSearch, Filters, SimpleFilter } from '@empathyco/x-components/facets'\nimport { ref } from 'vue'\n\nconst facet = ref({\n filters: [\n { id: '1', label: 'Filter 1', modelName: 'SimpleFilter', selected: false },\n { id: '2', label: 'Filter 2', modelName: 'SimpleFilter', selected: false },\n ],\n})\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;;;AAsCA;;;;AAIE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,aAAa,CAAC,IAAI;AAC3B,IAAA,KAAK,EAAE;AACL;;;;AAIE;AACF,QAAA,OAAO,EAAE,KAA2B;AAEpC;;;;;AAKE;AACF,QAAA,QAAQ,EAAE;AACR,YAAA,IAAI,EAAE,MAAgC;AACtC,YAAA,QAAQ,EAAE,KAAK;AAChB,SAAA;;AAGD,QAAA,YAAY,EAAE;AACZ,YAAA,IAAI,EAAE,MAAM;AACZ,YAAA,OAAO,EAAE,GAAG;AACb,SAAA;AACF,KAAA;AACD,IAAA,KAAK,CAAC,KAAK,EAAA;AACT,QAAA,MAAM,eAAc,GAAI,mBAAmB,CAAC,KAAK,CAAA;AAEjD,QAAA,MAAM,KAAI,GAAI,GAAG,CAAC,EAAE,CAAA;AACpB,QAAA,IAAI,iBAA6C;QAEjD,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,YAAY,CAAA;AAEtD;;;;AAIE;QACF,MAAM,uBAAsB,GAAI,MAAI;AAClC,YAAA,iBAAgB,GAAI,QAAQ,CAAC,cAAa,IAAG;AAC3C,gBAAA,KAAK,CAAC,KAAI,GAAI,cAAa;AAC7B,YAAA,CAAC,EAAE,KAAK,CAAC,YAAY,CAAA;AACvB,QAAA,CAAA;QACA,KAAK,CAAC,YAAY,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAE,IAAG,EAAG,CAAA;AAEhE;;;;;AAKE;AACF,QAAA,MAAM,gBAAgB,QAAQ,CAAC,MAAc;YAC3C,MAAM,eAAc,GAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAA;YACnD,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,CACjC,UACE,eAAe,CAAC,MAAM,CAAA,IAAK,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CACtF;AACF,QAAA,CAAC,CAAA;AACD,QAAA,OAAO,CAAC,SAAS,EAAE,aAAa,CAAA;AAEhC;;;;;AAKE;AACF,QAAA,MAAM,UAAS,GAAI,QAAQ,CAAC,MAAmB;YAC7C,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC,KAAK,CAAC,KAAI,EAAE;AACxD,QAAA,CAAC,CAAA;AAED;;;;;AAKE;AACF,QAAA,MAAM,QAAO,GAAI,CAAC,KAAa,KAAS;YACtC,iBAAiB,CAAC,KAAK,CAAA;AACzB,QAAA,CAAA;AAEA;;;;AAIE;QACF,MAAM,UAAS,GAAI,MAAU;AAC3B,YAAA,KAAK,CAAC,KAAI,GAAI,EAAC;AACjB,QAAA,CAAA;QAEA,OAAO;YACL,UAAU;YACV,QAAQ;YACR,UAAU;YACV,aAAa;YACb,KAAK;SACP;IACF,CAAC;AACF,CAAA,CAAA;;;;"}
|
|
@@ -2,7 +2,7 @@ import _sfc_main from './selected-filters-list.vue2.js';
|
|
|
2
2
|
import { resolveComponent, openBlock, createBlock, withCtx, resolveDynamicComponent, createElementBlock, Fragment, renderList, renderSlot, createElementVNode, toDisplayString, createTextVNode } from 'vue';
|
|
3
3
|
import _export_sfc from '../../../../_virtual/_plugin-vue_export-helper.js';
|
|
4
4
|
|
|
5
|
-
const _hoisted_1 = { class: "
|
|
5
|
+
const _hoisted_1 = { class: "xds:tag" };
|
|
6
6
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7
7
|
const _component_SelectedFilters = resolveComponent("SelectedFilters");
|
|
8
8
|
return openBlock(), createBlock(_component_SelectedFilters, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selected-filters-list.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/selected-filters-list.vue"],"sourcesContent":["<template>\n <SelectedFilters :facets-ids=\"facetsIds\" :always-visible=\"alwaysVisible\">\n <component\n :is=\"animation\"\n class=\"x-selected-filters-list\"\n data-test=\"selected-filters-list\"\n tag=\"ul\"\n >\n <li\n v-for=\"{ slotName, selectedFilter } in mapSlot(selectedFilters)\"\n :key=\"selectedFilter.id\"\n class=\"x-selected-filters-list__item\"\n data-test=\"selected-filters-list-item\"\n >\n <!--\n @slot Custom filter rendering. Dynamic slot defined in the template with the filter\n facet id. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-if=\"hasSlot(slotName)\" :name=\"slotName\" :filter=\"selectedFilter\">\n <span class=\"
|
|
1
|
+
{"version":3,"file":"selected-filters-list.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/selected-filters-list.vue"],"sourcesContent":["<template>\n <SelectedFilters :facets-ids=\"facetsIds\" :always-visible=\"alwaysVisible\">\n <component\n :is=\"animation\"\n class=\"x-selected-filters-list\"\n data-test=\"selected-filters-list\"\n tag=\"ul\"\n >\n <li\n v-for=\"{ slotName, selectedFilter } in mapSlot(selectedFilters)\"\n :key=\"selectedFilter.id\"\n class=\"x-selected-filters-list__item\"\n data-test=\"selected-filters-list-item\"\n >\n <!--\n @slot Custom filter rendering. Dynamic slot defined in the template with the filter\n facet id. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-if=\"hasSlot(slotName)\" :name=\"slotName\" :filter=\"selectedFilter\">\n <span class=\"xds:tag\">{{ (selectedFilter as BooleanFilter).label }}</span>\n </slot>\n\n <!--\n @slot Default filter rendering. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-else name=\"default\" :filter=\"selectedFilter\">\n {{ (selectedFilter as BooleanFilter).label }}\n </slot>\n </li>\n </component>\n </SelectedFilters>\n</template>\n\n<script lang=\"ts\">\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { BooleanFilter, Facet, Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { RenderFilter } from './selected-filters-list.types'\nimport { isFacetFilter } from '@empathyco/x-types'\nimport { defineComponent } from 'vue'\nimport { AnimationProp } from '../../../../types'\nimport { toKebabCase } from '../../../../utils/string'\nimport { useFacets } from '../../composables/use-facets'\nimport { facetsXModule } from '../../x-module'\nimport SelectedFilters from './selected-filters.vue'\n\n/**\n * This component renders a list of selected filters from every facet, or from the facet\n * ids passed as property. It uses the SelectedFilters component (state).\n *\n * It provides two slots: a scoped one which name is the filter facet id; and a default one.\n * Both exposes the filter and renders the filter label by default.\n *\n * The property \"alwaysVisible\" handles if the component is rendered if no filters are selected.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SelectedFiltersList',\n xModule: facetsXModule.name,\n components: { SelectedFilters },\n props: {\n /** Array of facets ids used to get the selected filters for those facets. */\n facetsIds: Array as PropType<Array<Facet['id']>>,\n /** Flag to render the component even if there are no filters selected. */\n alwaysVisible: Boolean,\n /** Animation component that will be used to animate the selected filters list. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n },\n setup(props, { slots }) {\n const { selectedFilters } = useFacets(props)\n\n /**\n * Transforms a dictionary of Filters including the slot name.\n *\n * @param selectedFilters - A list of selected filters without slot name.\n *\n * @returns A dictionary of facets with the slot name.\n */\n function mapSlot(selectedFilters: Filter[]): RenderFilter[] {\n return selectedFilters.map(filter => ({\n slotName: isFacetFilter(filter) ? toKebabCase(filter.facetId as string) : 'default',\n selectedFilter: filter,\n }))\n }\n\n /**\n * Whether the slot is present in the template or not.\n *\n * @param name - The slot name.\n *\n * @returns True is the slot is present in the template. False otherwise.\n */\n function hasSlot(name: string): boolean {\n return !!slots[name]\n }\n\n return {\n selectedFilters,\n mapSlot,\n hasSlot,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Example\n\nThis component renders a list of selected filters from every facet, or from the facets which facets\nids are passed as property. It uses the SelectedFilters component (state).\n\nIt provides two slots: a scoped one which name is the filter facet id; and a default one. Both\nexposes the filter and renders the filter label by default.\n\nThe property \"alwaysVisible\" handles if the component is rendered if no filters are selected.\n\n### Default usage\n\n```vue\n<template>\n <SelectedFiltersList />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n### Customized usage\n\n```vue\n<template>\n <SelectedFiltersList #default=\"{ filter }\">Default: {{ filter.label }}</SelectedFiltersList>\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n```vue\n<template>\n <SelectedFiltersList>\n <template #default=\"{ filter }\">Default: {{ filter.label }}</template>\n <template #brand_facet=\"{ filter }\">Brand: {{ filter.label }}</template>\n <template #age_facet=\"{ filter }\">Age: {{ filter.label }}</template>\n <template #price_facet=\"{ filter }\">Price: {{ filter.label }}</template>\n </SelectedFiltersList>\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n#### Always visible\n\nIf \"alwaysVisible\" is true, the component is rendered no matter if there are some filter selected.\nIf \"alwaysVisible\" is false (default), the component is rendered if there are some filter selected.\n\n```vue\n<template>\n <SelectedFiltersList :alwaysVisible=\"true\" />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\nOutput:\n\n```html\n<div class=\"x-selected-filters\">\n <ul class=\"x-selected-filters-list\" data-test=\"selected-filters-list\"></ul>\n</div>\n```\n\n#### Providing an array of facet ids\n\nIn this example, the selected filters computed are the ones that match the facet ids passed as\nproperties.\n\n```vue\n<template>\n <SelectedFiltersList :facetsIds=\"['brand_facet', 'gender_facet']\" />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n</docs>\n"],"names":["_createBlock","_openBlock","_resolveDynamicComponent","_createElementBlock","_Fragment","_renderList","_renderSlot","_createElementVNode","_toDisplayString","_createTextVNode"],"mappings":";;;;AAoBgB,MAAA,UAAA,GAAA,EAAA,KAAA,EAAM,SAAA,EAAS;;;sBAnB7BA,WAAA,CA+BkB,0BAAA,EAAA;AAAA,IA/BA,YAAA,EAAY,IAAA,CAAA,SAAA;AAAA,IAAY,gBAAA,EAAgB,IAAA,CAAA;AAAA,GAAA,EAAA;qBACxD,MA6BY;AAAA,OAAAC,SAAA,EAAA,EA7BZD,WAAA,CA6BYE,wBA5BL,IAAA,CAAA,SAAS,CAAA,EAAA;AAAA,QACd,KAAA,EAAM,yBAAA;AAAA,QACN,WAAA,EAAU,uBAAA;AAAA,QACV,GAAA,EAAI;AAAA,OAAA,EAAA;yBAGF,MAAgE;AAAA,WAAAD,SAAA,CAAA,IAAA,CAAA,EADlEE,kBAAA;AAAA,YAsBKC,QAAA;AAAA,YAAA,IAAA;AAAA,YAAAC,UAAA,CArBoC,IAAA,CAAA,OAAA,CAAQ,IAAA,CAAA,eAAe,CAAA,EAAA,CAAA,EAArD,QAAA,EAAU,cAAA,EAAc,KAAA;kCADnCF,kBAAA,CAsBK,IAAA,EAAA;AAAA,gBApBF,KAAK,cAAA,CAAe,EAAA;AAAA,gBACrB,KAAA,EAAM,+BAAA;AAAA,gBACN,WAAA,EAAU;AAAA,eAAA,EAAA;AAOE,gBAAA,IAAA,CAAA,OAAA,CAAQ,QAAQ,CAAA,GAA5BG,UAAA,CAEO,IAAA,CAAA,MAAA,EAF+B,QAAA,EAAQ;AAAA,kBAAA,GAAA,EAAA,CAAA;kBAAG,MAAA,EAAQ;AAAA,iBAAA,EAAzD,MAEO;AAAA,kBADLC,kBAAA;AAAA,oBAA0E,MAAA;AAAA,oBAA1E,UAAA;AAAA,oBAA0EC,eAAA,CAAhD,eAAiC,KAAK,CAAA;AAAA,oBAAA;AAAA;AAAA;AAAA,iBAAA,CAAA,GAOlEF,UAAA,CAEO,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA;AAAA,kBAAA,GAAA,EAAA,CAAA;kBAFsB,MAAA,EAAQ;AAAA,iBAAA,EAArC,MAEO;AAAA,kBAAAG,eAAA;AADD,oBAAAD,eAAA,CAAA,cAAA,CAAiC,KAAK,CAAA;AAAA,oBAAA;AAAA;AAAA;AAAA,iBAAA;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selected-filters-list.vue2.js","sources":["../../../../../../src/x-modules/facets/components/lists/selected-filters-list.vue"],"sourcesContent":["<template>\n <SelectedFilters :facets-ids=\"facetsIds\" :always-visible=\"alwaysVisible\">\n <component\n :is=\"animation\"\n class=\"x-selected-filters-list\"\n data-test=\"selected-filters-list\"\n tag=\"ul\"\n >\n <li\n v-for=\"{ slotName, selectedFilter } in mapSlot(selectedFilters)\"\n :key=\"selectedFilter.id\"\n class=\"x-selected-filters-list__item\"\n data-test=\"selected-filters-list-item\"\n >\n <!--\n @slot Custom filter rendering. Dynamic slot defined in the template with the filter\n facet id. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-if=\"hasSlot(slotName)\" :name=\"slotName\" :filter=\"selectedFilter\">\n <span class=\"
|
|
1
|
+
{"version":3,"file":"selected-filters-list.vue2.js","sources":["../../../../../../src/x-modules/facets/components/lists/selected-filters-list.vue"],"sourcesContent":["<template>\n <SelectedFilters :facets-ids=\"facetsIds\" :always-visible=\"alwaysVisible\">\n <component\n :is=\"animation\"\n class=\"x-selected-filters-list\"\n data-test=\"selected-filters-list\"\n tag=\"ul\"\n >\n <li\n v-for=\"{ slotName, selectedFilter } in mapSlot(selectedFilters)\"\n :key=\"selectedFilter.id\"\n class=\"x-selected-filters-list__item\"\n data-test=\"selected-filters-list-item\"\n >\n <!--\n @slot Custom filter rendering. Dynamic slot defined in the template with the filter\n facet id. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-if=\"hasSlot(slotName)\" :name=\"slotName\" :filter=\"selectedFilter\">\n <span class=\"xds:tag\">{{ (selectedFilter as BooleanFilter).label }}</span>\n </slot>\n\n <!--\n @slot Default filter rendering. It renders the filter label by default.\n @binding {Filter} filter - Filter to render.\n -->\n <slot v-else name=\"default\" :filter=\"selectedFilter\">\n {{ (selectedFilter as BooleanFilter).label }}\n </slot>\n </li>\n </component>\n </SelectedFilters>\n</template>\n\n<script lang=\"ts\">\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { BooleanFilter, Facet, Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { RenderFilter } from './selected-filters-list.types'\nimport { isFacetFilter } from '@empathyco/x-types'\nimport { defineComponent } from 'vue'\nimport { AnimationProp } from '../../../../types'\nimport { toKebabCase } from '../../../../utils/string'\nimport { useFacets } from '../../composables/use-facets'\nimport { facetsXModule } from '../../x-module'\nimport SelectedFilters from './selected-filters.vue'\n\n/**\n * This component renders a list of selected filters from every facet, or from the facet\n * ids passed as property. It uses the SelectedFilters component (state).\n *\n * It provides two slots: a scoped one which name is the filter facet id; and a default one.\n * Both exposes the filter and renders the filter label by default.\n *\n * The property \"alwaysVisible\" handles if the component is rendered if no filters are selected.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SelectedFiltersList',\n xModule: facetsXModule.name,\n components: { SelectedFilters },\n props: {\n /** Array of facets ids used to get the selected filters for those facets. */\n facetsIds: Array as PropType<Array<Facet['id']>>,\n /** Flag to render the component even if there are no filters selected. */\n alwaysVisible: Boolean,\n /** Animation component that will be used to animate the selected filters list. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n },\n setup(props, { slots }) {\n const { selectedFilters } = useFacets(props)\n\n /**\n * Transforms a dictionary of Filters including the slot name.\n *\n * @param selectedFilters - A list of selected filters without slot name.\n *\n * @returns A dictionary of facets with the slot name.\n */\n function mapSlot(selectedFilters: Filter[]): RenderFilter[] {\n return selectedFilters.map(filter => ({\n slotName: isFacetFilter(filter) ? toKebabCase(filter.facetId as string) : 'default',\n selectedFilter: filter,\n }))\n }\n\n /**\n * Whether the slot is present in the template or not.\n *\n * @param name - The slot name.\n *\n * @returns True is the slot is present in the template. False otherwise.\n */\n function hasSlot(name: string): boolean {\n return !!slots[name]\n }\n\n return {\n selectedFilters,\n mapSlot,\n hasSlot,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Example\n\nThis component renders a list of selected filters from every facet, or from the facets which facets\nids are passed as property. It uses the SelectedFilters component (state).\n\nIt provides two slots: a scoped one which name is the filter facet id; and a default one. Both\nexposes the filter and renders the filter label by default.\n\nThe property \"alwaysVisible\" handles if the component is rendered if no filters are selected.\n\n### Default usage\n\n```vue\n<template>\n <SelectedFiltersList />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n### Customized usage\n\n```vue\n<template>\n <SelectedFiltersList #default=\"{ filter }\">Default: {{ filter.label }}</SelectedFiltersList>\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n```vue\n<template>\n <SelectedFiltersList>\n <template #default=\"{ filter }\">Default: {{ filter.label }}</template>\n <template #brand_facet=\"{ filter }\">Brand: {{ filter.label }}</template>\n <template #age_facet=\"{ filter }\">Age: {{ filter.label }}</template>\n <template #price_facet=\"{ filter }\">Price: {{ filter.label }}</template>\n </SelectedFiltersList>\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\n#### Always visible\n\nIf \"alwaysVisible\" is true, the component is rendered no matter if there are some filter selected.\nIf \"alwaysVisible\" is false (default), the component is rendered if there are some filter selected.\n\n```vue\n<template>\n <SelectedFiltersList :alwaysVisible=\"true\" />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n\nOutput:\n\n```html\n<div class=\"x-selected-filters\">\n <ul class=\"x-selected-filters-list\" data-test=\"selected-filters-list\"></ul>\n</div>\n```\n\n#### Providing an array of facet ids\n\nIn this example, the selected filters computed are the ones that match the facet ids passed as\nproperties.\n\n```vue\n<template>\n <SelectedFiltersList :facetsIds=\"['brand_facet', 'gender_facet']\" />\n</template>\n\n<script setup>\nimport { SelectedFiltersList } from '@empathyco/x-components/facets'\n</script>\n```\n</docs>\n"],"names":["SelectedFilters"],"mappings":";;;;;;;;AAgDA;;;;;;;;;;AAUE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,aAAa,CAAC,IAAI;IAC3B,UAAU,EAAE,mBAAEA,WAAc,EAAG;AAC/B,IAAA,KAAK,EAAE;;AAEL,QAAA,SAAS,EAAE,KAAqC;;AAEhD,QAAA,aAAa,EAAE,OAAO;;AAEtB,QAAA,SAAS,EAAE;AACT,YAAA,IAAI,EAAE,aAAa;AACnB,YAAA,OAAO,EAAE,IAAI;AACd,SAAA;AACF,KAAA;AACD,IAAA,KAAK,CAAC,KAAK,EAAE,EAAE,KAAI,EAAG,EAAA;QACpB,MAAM,EAAE,eAAc,KAAM,SAAS,CAAC,KAAK,CAAA;AAE3C;;;;;;AAME;QACF,SAAS,OAAO,CAAC,eAAyB,EAAA;YACxC,OAAO,eAAe,CAAC,GAAG,CAAC,MAAK,KAAM;AACpC,gBAAA,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAA,GAAI,WAAW,CAAC,MAAM,CAAC,OAAiB,CAAA,GAAI,SAAS;AACnF,gBAAA,cAAc,EAAE,MAAM;AACvB,aAAA,CAAC,CAAA;QACJ;AAEA;;;;;;AAME;QACF,SAAS,OAAO,CAAC,IAAY,EAAA;AAC3B,YAAA,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAA;QACrB;QAEA,OAAO;YACL,eAAe;YACf,OAAO;YACP,OAAO;SACT;IACF,CAAC;AACF,CAAA,CAAA;;;;"}
|
|
@@ -21,7 +21,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
21
21
|
"button",
|
|
22
22
|
{
|
|
23
23
|
key: 0,
|
|
24
|
-
class: normalizeClass(["x-
|
|
24
|
+
class: normalizeClass(["x-sliced-filters__button x-sliced-filters__button--show-more xds:filter-facet", _ctx.buttonClass]),
|
|
25
25
|
"data-test": "sliced-filters-show-more-button",
|
|
26
26
|
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.toggleShowMoreFilters && _ctx.toggleShowMoreFilters(...args))
|
|
27
27
|
},
|
|
@@ -52,7 +52,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
52
52
|
"button",
|
|
53
53
|
{
|
|
54
54
|
key: 1,
|
|
55
|
-
class: normalizeClass(["x-
|
|
55
|
+
class: normalizeClass(["x-sliced-filters__button x-sliced-filters__button--show-less xds:filter-facet", _ctx.buttonClass]),
|
|
56
56
|
"data-test": "sliced-filters-show-less-button",
|
|
57
57
|
onClick: _cache[1] || (_cache[1] = (...args) => _ctx.toggleShowMoreFilters && _ctx.toggleShowMoreFilters(...args))
|
|
58
58
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliced-filters.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/sliced-filters.vue"],"sourcesContent":["<template>\n <div class=\"x-sliced-filters\" :class=\"cssClasses\" data-test=\"filters-show-more\">\n <!--\n @slot (Required) Sliced filters content.\n @binding {Filter[]} slicedFilters - Sliced filters..\n -->\n <slot :sliced-filters=\"slicedFilters\" />\n <template v-if=\"showButton\">\n <button\n v-if=\"showMoreFilters\"\n class=\"x-facet-filter x-sliced-filters__button x-sliced-filters__button--show-more\"\n :class=\"buttonClass\"\n data-test=\"sliced-filters-show-more-button\"\n @click=\"toggleShowMoreFilters\"\n >\n <!--\n @slot Button show more filters.\n @binding {number} difference - The difference between the filters and max to show.\n -->\n <slot name=\"show-more\" :difference=\"difference\">\n Show\n <span data-test=\"show-more-amount\">{{ difference }}</span>\n more filters\n </slot>\n </button>\n <button\n v-else\n class=\"x-facet-filter x-sliced-filters__button x-sliced-filters__button--show-less\"\n :class=\"buttonClass\"\n data-test=\"sliced-filters-show-less-button\"\n @click=\"toggleShowMoreFilters\"\n >\n <!--\n @slot Button show less filters.\n @binding {number} difference - The difference between the filters and max to show.\n -->\n <slot name=\"show-less\" :difference=\"difference\">\n Show\n <span data-test=\"show-less-amount\">{{ difference }}</span>\n less filters\n </slot>\n </button>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { VueCSSClasses } from '../../../../utils'\nimport { computed, defineComponent, provide, ref } from 'vue'\nimport { useFiltersInjection } from '../../composables/use-filters-injection'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Component that slices a list of filters and returns them using the default scoped slot,\n * allowing the user to show the full list of them or slicing them again using the\n * show more/less buttons.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SlicedFilters',\n xModule: facetsXModule.name,\n props: {\n /**\n * The list of filters to be rendered as slots.\n *\n * @public\n */\n filters: Array as PropType<Filter[]>,\n /**\n * This prop is used in the `HierarchicalFilter` component and only in that case. It is necessary\n * to make the `renderedFilters` to return only the filters of each level of the hierarchy.\n */\n parentId: {\n type: String as PropType<Filter['id']>,\n required: false,\n },\n /** The maximum number of filters to show. */\n max: {\n type: Number,\n required: true,\n },\n buttonClass: String,\n },\n emits: ['click:show-less', 'click:show-more'],\n setup(props, { emit }) {\n /** For showing the remaining filters. */\n const showMoreFilters = ref(true)\n\n const renderedFilters = useFiltersInjection(props)\n\n /**\n * Show the buttons template when length filters is greater than property max.\n *\n * @returns Boolean if length filters is greater than property max.\n * @internal\n */\n const showButton = computed(() => renderedFilters.value.length > props.max)\n\n /**\n * Sliced the array of filters depends on click button show more.\n *\n * @returns Array of sliced filters or all filters.\n * @internal\n */\n const slicedFilters = computed((): Filter[] => {\n return showMoreFilters.value\n ? renderedFilters.value.slice(0, props.max)\n : renderedFilters.value\n })\n provide('filters', slicedFilters)\n\n /**\n * The difference between length filters and max to show.\n *\n * @returns Number of remaining filters to show.\n * @internal\n */\n const difference = computed(() => renderedFilters.value.length - props.max)\n\n /**\n * Show or hide the remaining filters. It also emits a Vue event based on the clicked button.\n *\n * @param event - The click event.\n *\n * @internal\n */\n const toggleShowMoreFilters = (event: MouseEvent): void => {\n showMoreFilters.value = !showMoreFilters.value\n emit(showMoreFilters.value ? 'click:show-less' : 'click:show-more', event)\n }\n\n /**\n * Adds the dynamic css classes to the component.\n *\n * @returns The classes to be added to the component.\n * @internal\n */\n const cssClasses = computed((): VueCSSClasses => {\n return {\n 'x-sliced-filters--is-sliced': showButton.value,\n }\n })\n\n return {\n cssClasses,\n toggleShowMoreFilters,\n showButton,\n difference,\n slicedFilters,\n showMoreFilters,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Example\n\nThe sliced filters component, takes a list of filters, and the maximum number of filters to render\nas prop. Then, it slices the list of filters using the `max` prop, and returns this new filters list\nusing the default scoped slot.\n\nThe user can click the show more button if he wants to see the full list of filters, or the show\nless button when he wants to reset the filters. This buttons text or icons can be configured via\nslot too. They receive a `difference` prop which can be useful for writing friendlier messages.\n\nThis component is usually integrated with the `Facets` and `Filters` component. It is useful when\nthere are lots of available filters for a single facet, helping to improve the app performance, as\nless nodes are rendered.\n\n### Important\n\nThe component has two ways of receive the filters list, it can be injected by another component or\nbe send it as a prop. If the component doesnt have a parent component that receive and exposed a\nfilters list to their children, it is mandatory to send it as prop.\n\n### Basic usage\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\">\n <template #default=\"{ slicedFilters }\">\n <Filters :items=\"slicedFilters\" v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n </template>\n <template #show-more=\"{ difference }\">\n Show\n <span data-test=\"show-more-amount\">{{ difference }}</span>\n more filters\n </template>\n <template #show-less=\"{ difference }\">\n Show\n <span data-test=\"show-less-amount\">{{ difference }}</span>\n less filters\n </template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n\n> **Using injection**: It can receive the filters list by injection. It only works if it has a\n> parent component that receives and exposes the filters list. Using the injection, It is not\n> necessary to send the prop to the child components, it has to be send it in the parent component ,\n> the rest of components will inject this list.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\">\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n <template #show-more=\"{ difference }\">Show {{ difference }} more filters</template>\n <template #show-less=\"{ difference }\">Show {{ difference }} less filters</template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonClass` prop can be used to add classes to the show more/less buttons.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\" buttonClass=\"x-facet-filter-lg\">\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n <template #show-more=\"{ difference }\">Show {{ difference }} more filters</template>\n <template #show-less=\"{ difference }\">Show {{ difference }} less filters</template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_Fragment","_createTextVNode","_createElementVNode","_toDisplayString"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sliced-filters.vue.js","sources":["../../../../../../src/x-modules/facets/components/lists/sliced-filters.vue"],"sourcesContent":["<template>\n <div class=\"x-sliced-filters\" :class=\"cssClasses\" data-test=\"filters-show-more\">\n <!--\n @slot (Required) Sliced filters content.\n @binding {Filter[]} slicedFilters - Sliced filters..\n -->\n <slot :sliced-filters=\"slicedFilters\" />\n <template v-if=\"showButton\">\n <button\n v-if=\"showMoreFilters\"\n class=\"x-sliced-filters__button x-sliced-filters__button--show-more xds:filter-facet\"\n :class=\"buttonClass\"\n data-test=\"sliced-filters-show-more-button\"\n @click=\"toggleShowMoreFilters\"\n >\n <!--\n @slot Button show more filters.\n @binding {number} difference - The difference between the filters and max to show.\n -->\n <slot name=\"show-more\" :difference=\"difference\">\n Show\n <span data-test=\"show-more-amount\">{{ difference }}</span>\n more filters\n </slot>\n </button>\n <button\n v-else\n class=\"x-sliced-filters__button x-sliced-filters__button--show-less xds:filter-facet\"\n :class=\"buttonClass\"\n data-test=\"sliced-filters-show-less-button\"\n @click=\"toggleShowMoreFilters\"\n >\n <!--\n @slot Button show less filters.\n @binding {number} difference - The difference between the filters and max to show.\n -->\n <slot name=\"show-less\" :difference=\"difference\">\n Show\n <span data-test=\"show-less-amount\">{{ difference }}</span>\n less filters\n </slot>\n </button>\n </template>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport type { Filter } from '@empathyco/x-types'\nimport type { PropType } from 'vue'\nimport type { VueCSSClasses } from '../../../../utils'\nimport { computed, defineComponent, provide, ref } from 'vue'\nimport { useFiltersInjection } from '../../composables/use-filters-injection'\nimport { facetsXModule } from '../../x-module'\n\n/**\n * Component that slices a list of filters and returns them using the default scoped slot,\n * allowing the user to show the full list of them or slicing them again using the\n * show more/less buttons.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SlicedFilters',\n xModule: facetsXModule.name,\n props: {\n /**\n * The list of filters to be rendered as slots.\n *\n * @public\n */\n filters: Array as PropType<Filter[]>,\n /**\n * This prop is used in the `HierarchicalFilter` component and only in that case. It is necessary\n * to make the `renderedFilters` to return only the filters of each level of the hierarchy.\n */\n parentId: {\n type: String as PropType<Filter['id']>,\n required: false,\n },\n /** The maximum number of filters to show. */\n max: {\n type: Number,\n required: true,\n },\n buttonClass: String,\n },\n emits: ['click:show-less', 'click:show-more'],\n setup(props, { emit }) {\n /** For showing the remaining filters. */\n const showMoreFilters = ref(true)\n\n const renderedFilters = useFiltersInjection(props)\n\n /**\n * Show the buttons template when length filters is greater than property max.\n *\n * @returns Boolean if length filters is greater than property max.\n * @internal\n */\n const showButton = computed(() => renderedFilters.value.length > props.max)\n\n /**\n * Sliced the array of filters depends on click button show more.\n *\n * @returns Array of sliced filters or all filters.\n * @internal\n */\n const slicedFilters = computed((): Filter[] => {\n return showMoreFilters.value\n ? renderedFilters.value.slice(0, props.max)\n : renderedFilters.value\n })\n provide('filters', slicedFilters)\n\n /**\n * The difference between length filters and max to show.\n *\n * @returns Number of remaining filters to show.\n * @internal\n */\n const difference = computed(() => renderedFilters.value.length - props.max)\n\n /**\n * Show or hide the remaining filters. It also emits a Vue event based on the clicked button.\n *\n * @param event - The click event.\n *\n * @internal\n */\n const toggleShowMoreFilters = (event: MouseEvent): void => {\n showMoreFilters.value = !showMoreFilters.value\n emit(showMoreFilters.value ? 'click:show-less' : 'click:show-more', event)\n }\n\n /**\n * Adds the dynamic css classes to the component.\n *\n * @returns The classes to be added to the component.\n * @internal\n */\n const cssClasses = computed((): VueCSSClasses => {\n return {\n 'x-sliced-filters--is-sliced': showButton.value,\n }\n })\n\n return {\n cssClasses,\n toggleShowMoreFilters,\n showButton,\n difference,\n slicedFilters,\n showMoreFilters,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Example\n\nThe sliced filters component, takes a list of filters, and the maximum number of filters to render\nas prop. Then, it slices the list of filters using the `max` prop, and returns this new filters list\nusing the default scoped slot.\n\nThe user can click the show more button if he wants to see the full list of filters, or the show\nless button when he wants to reset the filters. This buttons text or icons can be configured via\nslot too. They receive a `difference` prop which can be useful for writing friendlier messages.\n\nThis component is usually integrated with the `Facets` and `Filters` component. It is useful when\nthere are lots of available filters for a single facet, helping to improve the app performance, as\nless nodes are rendered.\n\n### Important\n\nThe component has two ways of receive the filters list, it can be injected by another component or\nbe send it as a prop. If the component doesnt have a parent component that receive and exposed a\nfilters list to their children, it is mandatory to send it as prop.\n\n### Basic usage\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\">\n <template #default=\"{ slicedFilters }\">\n <Filters :items=\"slicedFilters\" v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n </template>\n <template #show-more=\"{ difference }\">\n Show\n <span data-test=\"show-more-amount\">{{ difference }}</span>\n more filters\n </template>\n <template #show-less=\"{ difference }\">\n Show\n <span data-test=\"show-less-amount\">{{ difference }}</span>\n less filters\n </template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n\n> **Using injection**: It can receive the filters list by injection. It only works if it has a\n> parent component that receives and exposes the filters list. Using the injection, It is not\n> necessary to send the prop to the child components, it has to be send it in the parent component ,\n> the rest of components will inject this list.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\">\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n <template #show-more=\"{ difference }\">Show {{ difference }} more filters</template>\n <template #show-less=\"{ difference }\">Show {{ difference }} less filters</template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n\n### Customizing the items with classes\n\nThe `buttonClass` prop can be used to add classes to the show more/less buttons.\n\n```vue\n<template>\n <Facets v-slot=\"{ facet }\">\n <SlicedFilters :filters=\"facet.filters\" :max=\"4\" buttonClass=\"x-facet-filter-lg\">\n <Filters v-slot=\"{ filter }\">\n <SimpleFilter :filter=\"filter\" />\n </Filters>\n <template #show-more=\"{ difference }\">Show {{ difference }} more filters</template>\n <template #show-less=\"{ difference }\">Show {{ difference }} less filters</template>\n </SlicedFilters>\n </Facets>\n</template>\n\n<script setup>\nimport { Facets, SlicedFilters, Filters, SimpleFilter } from '@empathyco/x-components'\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass","_renderSlot","_Fragment","_createTextVNode","_createElementVNode","_toDisplayString"],"mappings":"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"}
|