@empathyco/x-components 8.4.0 → 8.5.0

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/core/index.js.map +1 -1
  3. package/docs/API-reference/api/x-components.hierarchicalfilter.md +1 -0
  4. package/docs/API-reference/api/x-components.md +37 -0
  5. package/docs/API-reference/api/x-components.setbanners.md +13 -0
  6. package/docs/API-reference/api/x-components.simplefilter.md +1 -0
  7. package/docs/API-reference/api/x-components.snippetcallbacks.md +1 -0
  8. package/docs/API-reference/api/x-components.vendorbanner.md +59 -0
  9. package/docs/API-reference/api/x-components.vendorbanner.position.md +11 -0
  10. package/docs/API-reference/api/x-components.vendorbannerslist.md +31 -0
  11. package/docs/API-reference/api/x-components.vendormutations.md +17 -0
  12. package/docs/API-reference/api/x-components.vendormutations.setbanners.md +11 -0
  13. package/docs/API-reference/api/x-components.vendorstate.banners.md +11 -0
  14. package/docs/API-reference/api/x-components.vendorstate.md +17 -0
  15. package/docs/API-reference/api/x-components.vendorxevents.md +19 -0
  16. package/docs/API-reference/api/x-components.vendorxevents.vendorbannerschanged.md +13 -0
  17. package/docs/API-reference/components/vendor/x-components.vendor-banners-list.md +21 -0
  18. package/js/components/base-grid.vue.js.map +1 -1
  19. package/js/components/base-grid.vue2.js +5 -1
  20. package/js/components/base-grid.vue2.js.map +1 -1
  21. package/js/components/base-grid.vue3.js +1 -1
  22. package/js/index.js +2 -1
  23. package/js/index.js.map +1 -1
  24. package/js/x-modules/vendor/components/vendor-banners-list.vue.js +83 -0
  25. package/js/x-modules/vendor/components/vendor-banners-list.vue.js.map +1 -0
  26. package/js/x-modules/vendor/components/vendor-banners-list.vue2.js +6 -0
  27. package/js/x-modules/vendor/components/vendor-banners-list.vue2.js.map +1 -0
  28. package/js/x-modules/vendor/store/module.js +4 -0
  29. package/js/x-modules/vendor/store/module.js.map +1 -1
  30. package/js/x-modules/vendor/wiring.js +20 -1
  31. package/js/x-modules/vendor/wiring.js.map +1 -1
  32. package/package.json +2 -2
  33. package/report/x-components.api.json +497 -5
  34. package/report/x-components.api.md +38 -0
  35. package/types/src/components/base-grid.vue.d.ts.map +1 -1
  36. package/types/src/components/snippet-callbacks.vue.d.ts +1 -0
  37. package/types/src/components/snippet-callbacks.vue.d.ts.map +1 -1
  38. package/types/src/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts +1 -0
  39. package/types/src/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts.map +1 -1
  40. package/types/src/x-modules/facets/components/filters/simple-filter.vue.d.ts +1 -0
  41. package/types/src/x-modules/facets/components/filters/simple-filter.vue.d.ts.map +1 -1
  42. package/types/src/x-modules/vendor/components/index.d.ts +1 -0
  43. package/types/src/x-modules/vendor/components/index.d.ts.map +1 -1
  44. package/types/src/x-modules/vendor/components/vendor-banners-list.vue.d.ts +30 -0
  45. package/types/src/x-modules/vendor/components/vendor-banners-list.vue.d.ts.map +1 -0
  46. package/types/src/x-modules/vendor/events.types.d.ts +7 -1
  47. package/types/src/x-modules/vendor/events.types.d.ts.map +1 -1
  48. package/types/src/x-modules/vendor/store/module.d.ts.map +1 -1
  49. package/types/src/x-modules/vendor/store/types.d.ts +3 -1
  50. package/types/src/x-modules/vendor/store/types.d.ts.map +1 -1
  51. package/types/src/x-modules/vendor/types.d.ts +10 -1
  52. package/types/src/x-modules/vendor/types.d.ts.map +1 -1
  53. package/types/src/x-modules/vendor/wiring.d.ts +10 -0
  54. package/types/src/x-modules/vendor/wiring.d.ts.map +1 -1
  55. package/vendor/index.js +2 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.5.0](https://github.com/empathyco/x/compare/@empathyco/x-components@8.4.0...@empathyco/x-components@8.5.0) (2026-07-16)
7
+
8
+ ### Features
9
+
10
+ * **vendor:** banners (#2136)
11
+
12
+
6
13
  ## [8.4.0](https://github.com/empathyco/x/compare/@empathyco/x-components@8.3.0...@empathyco/x-components@8.4.0) (2026-07-16)
7
14
 
8
15
  ### Features
package/core/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -213,6 +213,7 @@ _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
213
213
  UserViewedAVendorResult?: import("../../../vendor").VendorResult | undefined;
214
214
  UserClickedAVendorResult?: import("../../../vendor").VendorResult | undefined;
215
215
  UserClickedVendorResultAddToCart?: import("../../../vendor").VendorResult | undefined;
216
+ VendorBannersChanged?: Omit<import("../../../vendor").VendorBanner, "modelName">[] | undefined;
216
217
  }>;
217
218
  innerCssClasses: import("vue").ComputedRef<(string | Dictionary<boolean>)[]>;
218
219
  renderedChildrenFilters: import("vue").ComputedRef<HierarchicalFilterModel[]>;
@@ -3384,6 +3384,17 @@ Alias to facilitate retrieving the modules with status.
3384
3384
  </td><td>
3385
3385
 
3386
3386
 
3387
+ </td></tr>
3388
+ <tr><td>
3389
+
3390
+ [VendorBanner](./x-components.vendorbanner.md)
3391
+
3392
+
3393
+ </td><td>
3394
+
3395
+ The interface for a vendor banner, extending the base Banner interface. The optional position means: - If the position is defined, the banner will be displayed in that position inside the grid. - If the position is undefined, the banner will be displayed on top of the grid and full width.
3396
+
3397
+
3387
3398
  </td></tr>
3388
3399
  <tr><td>
3389
3400
 
@@ -6734,6 +6745,17 @@ Default implementation for the [HistoryQueriesGetters.sessionHistoryQueries](./x
6734
6745
  Default implementation setUrlParams.
6735
6746
 
6736
6747
 
6748
+ </td></tr>
6749
+ <tr><td>
6750
+
6751
+ [setBanners](./x-components.setbanners.md)
6752
+
6753
+
6754
+ </td><td>
6755
+
6756
+ Sets the vendor banners of the [VendorXModule](./x-components.vendorxmodule.md)<!-- -->.
6757
+
6758
+
6737
6759
  </td></tr>
6738
6760
  <tr><td>
6739
6761
 
@@ -8111,6 +8133,21 @@ URL [XModule](./x-components.xmodule.md) implementation. This module is auto-reg
8111
8133
  Function which returns the requested getter's properties as a dictionary.
8112
8134
 
8113
8135
 
8136
+ </td></tr>
8137
+ <tr><td>
8138
+
8139
+ [VendorBannersList](./x-components.vendorbannerslist.md)
8140
+
8141
+
8142
+ </td><td>
8143
+
8144
+ It renders a [ItemsList](./x-components.itemslist.md) list of vendor banners from [VendorState.banners](./x-components.vendorstate.banners.md)<!-- -->.
8145
+
8146
+ The component provides a default slot which wraps the whole component with the `vendorBanners` plus the `injectedListItems` which also contains the injected list items from the ancestor.
8147
+
8148
+ It also provides the parent slots to customize the items.
8149
+
8150
+
8114
8151
  </td></tr>
8115
8152
  <tr><td>
8116
8153
 
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [setBanners](./x-components.setbanners.md)
4
+
5
+ ## setBanners variable
6
+
7
+ Sets the vendor banners of the [VendorXModule](./x-components.vendorxmodule.md)<!-- -->.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ setBanners: import("../../wiring").AnyWire
13
+ ```
@@ -210,6 +210,7 @@ _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
210
210
  UserViewedAVendorResult?: import("../../../vendor").VendorResult | undefined;
211
211
  UserClickedAVendorResult?: import("../../../vendor").VendorResult | undefined;
212
212
  UserClickedVendorResultAddToCart?: import("../../../vendor").VendorResult | undefined;
213
+ VendorBannersChanged?: Omit<import("../../../vendor").VendorBanner, "modelName">[] | undefined;
213
214
  }>;
214
215
  innerCssClasses: import("vue").ComputedRef<(string | Dictionary<boolean>)[]>;
215
216
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@@ -200,6 +200,7 @@ _default: import("vue").DefineComponent<{}, {
200
200
  UserViewedAVendorResult: (payload: import("..").VendorResult, metadata: WireMetadata) => unknown;
201
201
  UserClickedAVendorResult: (payload: import("..").VendorResult, metadata: WireMetadata) => unknown;
202
202
  UserClickedVendorResultAddToCart: (payload: import("..").VendorResult, metadata: WireMetadata) => unknown;
203
+ VendorBannersChanged: (payload: Omit<import("..").VendorBanner, "modelName">[], metadata: WireMetadata) => unknown;
203
204
  }>>;
204
205
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {
205
206
  GlobalXBus: import("vue").DefineComponent<{}, {}, any>;
@@ -0,0 +1,59 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorBanner](./x-components.vendorbanner.md)
4
+
5
+ ## VendorBanner interface
6
+
7
+ The interface for a vendor banner, extending the base Banner interface. The optional position means: - If the position is defined, the banner will be displayed in that position inside the grid. - If the position is undefined, the banner will be displayed on top of the grid and full width.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ export interface VendorBanner extends Omit<Banner, 'modelName'>, NamedModel<'VendorBanner'>
13
+ ```
14
+ **Extends:** Omit&lt;Banner, 'modelName'&gt;, NamedModel&lt;'VendorBanner'&gt;
15
+
16
+ ## Properties
17
+
18
+ <table><thead><tr><th>
19
+
20
+ Property
21
+
22
+
23
+ </th><th>
24
+
25
+ Modifiers
26
+
27
+
28
+ </th><th>
29
+
30
+ Type
31
+
32
+
33
+ </th><th>
34
+
35
+ Description
36
+
37
+
38
+ </th></tr></thead>
39
+ <tbody><tr><td>
40
+
41
+ [position?](./x-components.vendorbanner.position.md)
42
+
43
+
44
+ </td><td>
45
+
46
+
47
+ </td><td>
48
+
49
+ number
50
+
51
+
52
+ </td><td>
53
+
54
+ _(Optional)_
55
+
56
+
57
+ </td></tr>
58
+ </tbody></table>
59
+
@@ -0,0 +1,11 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorBanner](./x-components.vendorbanner.md) &gt; [position](./x-components.vendorbanner.position.md)
4
+
5
+ ## VendorBanner.position property
6
+
7
+ **Signature:**
8
+
9
+ ```typescript
10
+ position?: number;
11
+ ```
@@ -0,0 +1,31 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorBannersList](./x-components.vendorbannerslist.md)
4
+
5
+ ## VendorBannersList variable
6
+
7
+ It renders a [ItemsList](./x-components.itemslist.md) list of vendor banners from [VendorState.banners](./x-components.vendorstate.banners.md)<!-- -->.
8
+
9
+ The component provides a default slot which wraps the whole component with the `vendorBanners` plus the `injectedListItems` which also contains the injected list items from the ancestor.
10
+
11
+ It also provides the parent slots to customize the items.
12
+
13
+ **Signature:**
14
+
15
+ ```typescript
16
+ _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
17
+ animation: {
18
+ type: (StringConstructor | ObjectConstructor | FunctionConstructor)[];
19
+ default: string;
20
+ };
21
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
22
+ [key: string]: any;
23
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
24
+ animation: {
25
+ type: (StringConstructor | ObjectConstructor | FunctionConstructor)[];
26
+ default: string;
27
+ };
28
+ }>> & Readonly<{}>, {
29
+ animation: string | Function | Record<string, any>;
30
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>
31
+ ```
@@ -35,6 +35,23 @@ Description
35
35
  </th></tr></thead>
36
36
  <tbody><tr><td>
37
37
 
38
+ [setBanners](./x-components.vendormutations.setbanners.md)
39
+
40
+
41
+ </td><td>
42
+
43
+
44
+ </td><td>
45
+
46
+ (banners: [VendorBanner](./x-components.vendorbanner.md)<!-- -->\[\]) =&gt; void
47
+
48
+
49
+ </td><td>
50
+
51
+
52
+ </td></tr>
53
+ <tr><td>
54
+
38
55
  [setResults](./x-components.vendormutations.setresults.md)
39
56
 
40
57
 
@@ -0,0 +1,11 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorMutations](./x-components.vendormutations.md) &gt; [setBanners](./x-components.vendormutations.setbanners.md)
4
+
5
+ ## VendorMutations.setBanners property
6
+
7
+ **Signature:**
8
+
9
+ ```typescript
10
+ setBanners: (banners: VendorBanner[]) => void;
11
+ ```
@@ -0,0 +1,11 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorState](./x-components.vendorstate.md) &gt; [banners](./x-components.vendorstate.banners.md)
4
+
5
+ ## VendorState.banners property
6
+
7
+ **Signature:**
8
+
9
+ ```typescript
10
+ banners: VendorBanner[];
11
+ ```
@@ -35,6 +35,23 @@ Description
35
35
  </th></tr></thead>
36
36
  <tbody><tr><td>
37
37
 
38
+ [banners](./x-components.vendorstate.banners.md)
39
+
40
+
41
+ </td><td>
42
+
43
+
44
+ </td><td>
45
+
46
+ [VendorBanner](./x-components.vendorbanner.md)<!-- -->\[\]
47
+
48
+
49
+ </td><td>
50
+
51
+
52
+ </td></tr>
53
+ <tr><td>
54
+
38
55
  [results](./x-components.vendorstate.results.md)
39
56
 
40
57
 
@@ -91,6 +91,25 @@ The user clicked on the add to cart button of a vendor result. Payload: The [ven
91
91
  The user viewed a vendor result. Payload: The [vendor result](./x-components.vendorresult.md) that was viewed.
92
92
 
93
93
 
94
+ </td></tr>
95
+ <tr><td>
96
+
97
+ [VendorBannersChanged](./x-components.vendorxevents.vendorbannerschanged.md)
98
+
99
+
100
+ </td><td>
101
+
102
+
103
+ </td><td>
104
+
105
+ Omit&lt;[VendorBanner](./x-components.vendorbanner.md)<!-- -->, 'modelName'&gt;\[\]
106
+
107
+
108
+ </td><td>
109
+
110
+ The x consumer has provided vendor banners to be inserted in the result grid. Payload: The array of vendor banner inputs with their items and positions. modelName is excluded since it is an internal field, and we will assign it under the hood.
111
+
112
+
94
113
  </td></tr>
95
114
  <tr><td>
96
115
 
@@ -0,0 +1,13 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@empathyco/x-components](./x-components.md) &gt; [VendorXEvents](./x-components.vendorxevents.md) &gt; [VendorBannersChanged](./x-components.vendorxevents.vendorbannerschanged.md)
4
+
5
+ ## VendorXEvents.VendorBannersChanged property
6
+
7
+ The x consumer has provided vendor banners to be inserted in the result grid. Payload: The array of vendor banner inputs with their items and positions. modelName is excluded since it is an internal field, and we will assign it under the hood.
8
+
9
+ **Signature:**
10
+
11
+ ```typescript
12
+ VendorBannersChanged: Omit<VendorBanner, 'modelName'>[];
13
+ ```
@@ -0,0 +1,21 @@
1
+ ---
2
+
3
+ title: VendorBannersList
4
+
5
+ ---
6
+
7
+ # VendorBannersList
8
+
9
+ It renders a ItemsList list of vendor banners from VendorState.banners.
10
+
11
+ The component provides a default slot which wraps the whole component with the `vendorBanners`
12
+ plus the `injectedListItems` which also contains the injected list items from
13
+ the ancestor.
14
+
15
+ It also provides the parent slots to customize the items.
16
+
17
+ ## Props
18
+
19
+ | Name | Description | Type | Default |
20
+ | ---------------------- | -------------------------------------------------------------------- | -------------------------- | ----------------- |
21
+ | <code>animation</code> | Animation component that will be used to animate the vendor banners. | <code>AnimationProp</code> | <code>'ul'</code> |
@@ -1 +1 @@
1
- {"version":3,"file":"base-grid.vue.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n ref=\"gridEl\"\n :style=\"style\"\n class=\"x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ item, cssClass, slotName } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-base-grid__item\"\n >\n <!--\n @slot Customized item rendering. Specifying a slot with the item's modelName will result in\n the item using that slot composition to render.\n @binding {item} item - Item to render\n -->\n <slot v-if=\"slots[slotName]\" :name=\"slotName\" :item=\"item\" />\n <!--\n @slot (required) Default item rendering. This slot will be used by default for rendering\n the item without an specific slot implementation.\n @binding {item} item - Item to render\n -->\n <slot v-else :item=\"item\">{{ (item as any).name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { MaybeComputedElementRef, UseResizeObserverReturn } from '@vueuse/core'\nimport type { PropType, Ref } from 'vue'\nimport type { ListItem } from '../utils/types'\nimport type { GridItem } from './base-grid.types'\nimport { useResizeObserver } from '@vueuse/core'\nimport { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useXBus } from '../composables/use-x-bus'\nimport { AnimationProp } from '../types/animation-prop'\nimport { toKebabCase } from '../utils/string'\nimport { LIST_ITEMS_KEY } from './decorators/injection.consts'\n\n/**\n * Grid component that is able to render different items based on their modelName value. In order\n * to achieve this, it exposes a scopedSlot for each different modelName. In case the items used\n * do not have modelName property, the default slot is used instead. It has a required property:\n * the `items` to render; and an optional one: the number `columns` the grid is divided in. If the\n * number of columns is not specified, the grid automatically fills the rows with as many columns\n * as it can fit.\n *\n * @public\n */\nexport default defineComponent({\n name: 'BaseGrid',\n props: {\n /** Animation component that will be used to animate the base grid. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n /**\n * Number of columns the grid is divided into. By default, its value is 0, setting the grid\n * columns mode to auto-fill.\n */\n columns: {\n type: Number,\n default: 0,\n },\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an ID property.\n */\n items: {\n type: Array as PropType<ListItem[]>,\n },\n },\n setup(props, { slots }) {\n // eslint-disable-next-line ts/consistent-type-definitions\n type ElementRef = {\n $el: HTMLElement\n }\n\n const xBus = useXBus()\n\n /** It injects {@link ListItem} provided by an ancestor. */\n const injectedListItems = inject<Ref<ListItem[]>>(LIST_ITEMS_KEY as string)\n const gridEl = ref<ElementRef | HTMLElement>()\n const renderedColumnsNumber = ref(0)\n\n /**\n * Emits the {@link XEventsTypes.RenderedColumnsNumberChanged}\n * event whenever the number of columns rendered inside the grid changes.\n */\n watch(\n renderedColumnsNumber,\n () => xBus.emit('RenderedColumnsNumberChanged', renderedColumnsNumber.value),\n { immediate: false },\n )\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n */\n const computedItems = computed<ListItem[] | void>(() => {\n return (\n props.items ??\n injectedListItems?.value ??\n console.warn('It is necessary to pass a prop or inject the list of filters')\n )\n })\n\n /**\n * CSS class based on the column property value so items inside the grid can fill different\n * amount of columns or rows based on how many columns the grid is divided into.\n *\n * @returns CSS class with the column property value.\n */\n const cssClasses = computed(() => `x-base-grid--cols-${props.columns || 'auto'}`)\n\n /**\n * CSSStyleDeclaration object specifying the number of columns the grid is divided into based on\n * the column property value.\n *\n * @returns A CSSStyleDeclaration to use as the style attribute.\n */\n const style = computed<Partial<CSSStyleDeclaration>>(() => ({\n gridTemplateColumns: props.columns\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))',\n }))\n\n /**\n * Maps the item to an object containing: the `item`, its `CSS class` and its slot name.\n *\n * @returns An array of objects containing the item and its CSS class.\n */\n const gridItems = computed<GridItem[]>(() =>\n (computedItems.value as ListItem[]).map(item => {\n const slotName = toKebabCase(item.modelName)\n return {\n slotName,\n item,\n cssClass: `x-base-grid__${slotName}`,\n }\n }),\n )\n\n /**\n * Checks if a given value is an `ElementRef` object.\n *\n * @param value - The value to check.\n * @returns `true` if the value is an `ElementRef` object, `false` otherwise.\n */\n const isElementRef = (value: any): value is ElementRef => {\n return value && value.$el instanceof HTMLElement\n }\n\n /** Updates the number of columns rendered inside the grid. */\n function updateRenderedColumnsNumber() {\n const { gridTemplateColumns } = getComputedStyle(\n isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element),\n )\n renderedColumnsNumber.value = gridTemplateColumns.split(' ').length\n }\n\n /** Initialises the rendered columns number and sets a ResizeObserver to keep it updated. */\n let resizeObserver: UseResizeObserverReturn\n onMounted(() => {\n resizeObserver = useResizeObserver(\n gridEl as MaybeComputedElementRef,\n updateRenderedColumnsNumber,\n )\n })\n onBeforeUnmount(() => resizeObserver?.stop())\n\n return {\n gridItems,\n cssClasses,\n style,\n gridEl,\n slots,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-base-grid {\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n align-items: stretch;\n}\n\n.x-base-grid__banner,\n.x-base-grid__next-queries-group,\n.x-base-grid__related-prompts-group {\n grid-column-start: 1;\n grid-column-end: -1;\n}\n\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active,\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active {\n transition: none;\n position: relative;\n}\n\n.x-base-grid__item {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-base-grid__item > * {\n flex-grow: 1;\n}\n\n.x-base-grid--cols-auto .x-base-grid__item {\n min-width: var(--x-size-min-width-grid-item);\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis component renders a list of elements in different slots depending on their modelName. In order\nto achieve this, it exposes a scopedSlot for each different modelName. In case the items used do not\nhave modelName property, the default slot is used instead. It has a required property, the `items`\nto render, and an optional one, the number of `columns` the grid is divided in. If the number of\ncolumns is not specified, the grid automatically fills the rows with as many columns as it can fit.\n\n### Basic example\n\nIt renders a list of items using the default slot:\n\n```vue\n<template>\n <BaseGrid :items=\"items\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Configuring the number of columns\n\nIt renders a grid with 12 columns instead of 6, which is the default value:\n\n```vue\n<template>\n <BaseGrid :items=\"items\" :columns=\"12\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Rendering usage\n\nConfiguring the number of columns.\n\nIt renders a list of items using the different scopedSlots created by the item's modelName. For\nexample, if you want to use this component as the search grid, you pass the search results (results,\nbanners, promoted, next queries...etc) as items. Each of these results have a different modelName\nand are rendered in different slots.\n\n```vue\n<template>\n <BaseGrid :animation=\"animation\" :items=\"items\">\n <template #banner=\"{ item }\">\n <span class=\"banner\">\n {{ `${item.title} banner` }}\n </span>\n </template>\n <template #next-queries=\"{ item }\">\n <span>\n {{ `${item.totalResults} next queries` }}\n </span>\n </template>\n <template #promoted=\"{ item }\">\n <span class=\"promoted\">\n {{ `${item.title} promoted` }}\n </span>\n </template>\n <template #result=\"{ item }\">\n <BaseResultLink :result=\"item\">\n {{ item.name }}\n </BaseResultLink>\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nimport BaseResultLink from './BaseResultLink.vue'\nconst animation = 'ul'\nconst items = [\n { id: 1, modelName: 'banner', title: 'Banner 1' },\n { id: 2, modelName: 'next-queries', totalResults: 5 },\n { id: 3, modelName: 'promoted', title: 'Promo 1' },\n { id: 4, modelName: 'result', name: 'Result 1' },\n]\n</script>\n```\n\n### Customizing the items width\n\nThe `--x-size-min-width-grid-item` variable can be used to customize the min width of the grid\nitems.\n\n```vue\n<template>\n <BaseGrid :items=\"items\" style=\"--x-size-min-width-grid-item: 150px\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_createElementBlock","_Fragment","_renderList","_renderSlot","_createTextVNode","_toDisplayString"],"mappings":";;;;;;AACE,EAAA,OAAAA,SAAA,EAAA,EAAAC,WAAA,CA4BYC,wBA3BL,IAAA,CAAA,SAAS,CAAA,EAAA;AAAA,IACd,GAAA,EAAI,QAAA;AAAA,IACH,KAAA,EAAKC,eAAE,IAAA,CAAA,KAAK,CAAA;AAAA,IACb,KAAA,EAAKC,cAAA,CAAA,CAAC,aAAA,EACE,IAAA,CAAA,UAAU,CAAA,CAAA;AAAA,IAClB,GAAA,EAAI,IAAA;AAAA,IACJ,WAAA,EAAU;AAAA,GAAA,EAAA;qBAGR,MAAiD;AAAA,OAAAJ,SAAA,CAAA,IAAA,CAAA,EADnDK,kBAAA;AAAA,QAkBKC,QAAA;AAAA,QAAA,IAAA;AAAA,QAAAC,UAAA,CAjBoC,IAAA,CAAA,SAAA,EAAS,CAAA,EAAvC,IAAA,EAAM,QAAA,EAAU,QAAA,EAAQ,KAAA;AADnC,UAAA,OAAAP,SAAA,EAAA,EAAAK,kBAAA;AAAA,YAkBK,IAAA;AAAA,YAAA;AAAA,cAhBF,KAAK,IAAA,CAAK,EAAA;AAAA,cACV,KAAA,EAAKD,cAAA,CAAA,CAAE,QAAA,EACF,mBAAmB,CAAA;AAAA,aAAA;;AAOb,cAAA,IAAA,CAAA,KAAA,CAAM,QAAQ,CAAA,GAA1BI,UAAA,CAA6D,IAAA,CAAA,MAAA,EAAzB,QAAA,EAAQ;AAAA,gBAAA,GAAA,EAAA,CAAA;AAAG,gBAAA;AAAA,eAAA,EAAA,MAAA,EAAA,IAAA,CAAA,GAM/CA,UAAA,CAA8F,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA;AAAA,gBAAA,GAAA,EAAA,CAAA;AAAhF,gBAAA;AAAA,eAAA,EAAd,MAA8F;AAAA,gBAAAC,eAAA;AAAhE,kBAAAC,eAAA,CAAA,IAAA,CAAa,IAAA,IAAQ,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,kBAAA;AAAA;AAAA;AAAA,eAAA,EAAA,IAAA;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"base-grid.vue.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n ref=\"gridEl\"\n :style=\"style\"\n class=\"x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ item, cssClass, slotName } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-base-grid__item\"\n >\n <!--\n @slot Customized item rendering. Specifying a slot with the item's modelName will result in\n the item using that slot composition to render.\n @binding {item} item - Item to render\n -->\n <slot v-if=\"slots[slotName]\" :name=\"slotName\" :item=\"item\" />\n <!--\n @slot (required) Default item rendering. This slot will be used by default for rendering\n the item without an specific slot implementation.\n @binding {item} item - Item to render\n -->\n <slot v-else :item=\"item\">{{ (item as any).name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { MaybeComputedElementRef, UseResizeObserverReturn } from '@vueuse/core'\nimport type { PropType, Ref } from 'vue'\nimport type { ListItem } from '../utils/types'\nimport type { GridItem } from './base-grid.types'\nimport { useResizeObserver } from '@vueuse/core'\nimport { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useXBus } from '../composables/use-x-bus'\nimport { AnimationProp } from '../types/animation-prop'\nimport { toKebabCase } from '../utils/string'\nimport { LIST_ITEMS_KEY } from './decorators/injection.consts'\n\n/**\n * Grid component that is able to render different items based on their modelName value. In order\n * to achieve this, it exposes a scopedSlot for each different modelName. In case the items used\n * do not have modelName property, the default slot is used instead. It has a required property:\n * the `items` to render; and an optional one: the number `columns` the grid is divided in. If the\n * number of columns is not specified, the grid automatically fills the rows with as many columns\n * as it can fit.\n *\n * @public\n */\nexport default defineComponent({\n name: 'BaseGrid',\n props: {\n /** Animation component that will be used to animate the base grid. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n /**\n * Number of columns the grid is divided into. By default, its value is 0, setting the grid\n * columns mode to auto-fill.\n */\n columns: {\n type: Number,\n default: 0,\n },\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an ID property.\n */\n items: {\n type: Array as PropType<ListItem[]>,\n },\n },\n setup(props, { slots }) {\n // eslint-disable-next-line ts/consistent-type-definitions\n type ElementRef = {\n $el: HTMLElement\n }\n\n const xBus = useXBus()\n\n /** It injects {@link ListItem} provided by an ancestor. */\n const injectedListItems = inject<Ref<ListItem[]>>(LIST_ITEMS_KEY as string)\n const gridEl = ref<ElementRef | HTMLElement>()\n const renderedColumnsNumber = ref(0)\n\n /**\n * Emits the {@link XEventsTypes.RenderedColumnsNumberChanged}\n * event whenever the number of columns rendered inside the grid changes.\n */\n watch(\n renderedColumnsNumber,\n () => xBus.emit('RenderedColumnsNumberChanged', renderedColumnsNumber.value),\n { immediate: false },\n )\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n */\n const computedItems = computed<ListItem[] | void>(() => {\n return (\n props.items ??\n injectedListItems?.value ??\n console.warn('It is necessary to pass a prop or inject the list of filters')\n )\n })\n\n /**\n * CSS class based on the column property value so items inside the grid can fill different\n * amount of columns or rows based on how many columns the grid is divided into.\n *\n * @returns CSS class with the column property value.\n */\n const cssClasses = computed(() => `x-base-grid--cols-${props.columns || 'auto'}`)\n\n /**\n * CSSStyleDeclaration object specifying the number of columns the grid is divided into based on\n * the column property value.\n *\n * @returns A CSSStyleDeclaration to use as the style attribute.\n */\n const style = computed<Partial<CSSStyleDeclaration>>(() => ({\n gridTemplateColumns: props.columns\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))',\n }))\n\n /**\n * Maps the item to an object containing: the `item`, its `CSS class` and its slot name.\n *\n * @returns An array of objects containing the item and its CSS class.\n */\n const gridItems = computed<GridItem[]>(() =>\n (computedItems.value as ListItem[]).map(item => {\n const slotName = toKebabCase(item.modelName)\n let cssClass = `x-base-grid__${slotName}`\n if (item.modelName === 'VendorBanner' && (item as any).position === undefined) {\n cssClass += ` x-base-grid__${slotName}--row`\n }\n return {\n slotName,\n item,\n cssClass,\n }\n }),\n )\n\n /**\n * Checks if a given value is an `ElementRef` object.\n *\n * @param value - The value to check.\n * @returns `true` if the value is an `ElementRef` object, `false` otherwise.\n */\n const isElementRef = (value: any): value is ElementRef => {\n return value && value.$el instanceof HTMLElement\n }\n\n /** Updates the number of columns rendered inside the grid. */\n function updateRenderedColumnsNumber() {\n const { gridTemplateColumns } = getComputedStyle(\n isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element),\n )\n renderedColumnsNumber.value = gridTemplateColumns.split(' ').length\n }\n\n /** Initialises the rendered columns number and sets a ResizeObserver to keep it updated. */\n let resizeObserver: UseResizeObserverReturn\n onMounted(() => {\n resizeObserver = useResizeObserver(\n gridEl as MaybeComputedElementRef,\n updateRenderedColumnsNumber,\n )\n })\n onBeforeUnmount(() => resizeObserver?.stop())\n\n return {\n gridItems,\n cssClasses,\n style,\n gridEl,\n slots,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-base-grid {\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n align-items: stretch;\n}\n\n.x-base-grid__banner,\n.x-base-grid__vendor-banner--row,\n.x-base-grid__next-queries-group,\n.x-base-grid__related-prompts-group {\n grid-column-start: 1;\n grid-column-end: -1;\n}\n\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active,\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active {\n transition: none;\n position: relative;\n}\n\n.x-base-grid__item {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-base-grid__item > * {\n flex-grow: 1;\n}\n\n.x-base-grid--cols-auto .x-base-grid__item {\n min-width: var(--x-size-min-width-grid-item);\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis component renders a list of elements in different slots depending on their modelName. In order\nto achieve this, it exposes a scopedSlot for each different modelName. In case the items used do not\nhave modelName property, the default slot is used instead. It has a required property, the `items`\nto render, and an optional one, the number of `columns` the grid is divided in. If the number of\ncolumns is not specified, the grid automatically fills the rows with as many columns as it can fit.\n\n### Basic example\n\nIt renders a list of items using the default slot:\n\n```vue\n<template>\n <BaseGrid :items=\"items\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Configuring the number of columns\n\nIt renders a grid with 12 columns instead of 6, which is the default value:\n\n```vue\n<template>\n <BaseGrid :items=\"items\" :columns=\"12\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Rendering usage\n\nConfiguring the number of columns.\n\nIt renders a list of items using the different scopedSlots created by the item's modelName. For\nexample, if you want to use this component as the search grid, you pass the search results (results,\nbanners, promoted, next queries...etc) as items. Each of these results have a different modelName\nand are rendered in different slots.\n\n```vue\n<template>\n <BaseGrid :animation=\"animation\" :items=\"items\">\n <template #banner=\"{ item }\">\n <span class=\"banner\">\n {{ `${item.title} banner` }}\n </span>\n </template>\n <template #next-queries=\"{ item }\">\n <span>\n {{ `${item.totalResults} next queries` }}\n </span>\n </template>\n <template #promoted=\"{ item }\">\n <span class=\"promoted\">\n {{ `${item.title} promoted` }}\n </span>\n </template>\n <template #result=\"{ item }\">\n <BaseResultLink :result=\"item\">\n {{ item.name }}\n </BaseResultLink>\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nimport BaseResultLink from './BaseResultLink.vue'\nconst animation = 'ul'\nconst items = [\n { id: 1, modelName: 'banner', title: 'Banner 1' },\n { id: 2, modelName: 'next-queries', totalResults: 5 },\n { id: 3, modelName: 'promoted', title: 'Promo 1' },\n { id: 4, modelName: 'result', name: 'Result 1' },\n]\n</script>\n```\n\n### Customizing the items width\n\nThe `--x-size-min-width-grid-item` variable can be used to customize the min width of the grid\nitems.\n\n```vue\n<template>\n <BaseGrid :items=\"items\" style=\"--x-size-min-width-grid-item: 150px\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createBlock","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_createElementBlock","_Fragment","_renderList","_renderSlot","_createTextVNode","_toDisplayString"],"mappings":";;;;;;AACE,EAAA,OAAAA,SAAA,EAAA,EAAAC,WAAA,CA4BYC,wBA3BL,IAAA,CAAA,SAAS,CAAA,EAAA;AAAA,IACd,GAAA,EAAI,QAAA;AAAA,IACH,KAAA,EAAKC,eAAE,IAAA,CAAA,KAAK,CAAA;AAAA,IACb,KAAA,EAAKC,cAAA,CAAA,CAAC,aAAA,EACE,IAAA,CAAA,UAAU,CAAA,CAAA;AAAA,IAClB,GAAA,EAAI,IAAA;AAAA,IACJ,WAAA,EAAU;AAAA,GAAA,EAAA;qBAGR,MAAiD;AAAA,OAAAJ,SAAA,CAAA,IAAA,CAAA,EADnDK,kBAAA;AAAA,QAkBKC,QAAA;AAAA,QAAA,IAAA;AAAA,QAAAC,UAAA,CAjBoC,IAAA,CAAA,SAAA,EAAS,CAAA,EAAvC,IAAA,EAAM,QAAA,EAAU,QAAA,EAAQ,KAAA;AADnC,UAAA,OAAAP,SAAA,EAAA,EAAAK,kBAAA;AAAA,YAkBK,IAAA;AAAA,YAAA;AAAA,cAhBF,KAAK,IAAA,CAAK,EAAA;AAAA,cACV,KAAA,EAAKD,cAAA,CAAA,CAAE,QAAA,EACF,mBAAmB,CAAA;AAAA,aAAA;;AAOb,cAAA,IAAA,CAAA,KAAA,CAAM,QAAQ,CAAA,GAA1BI,UAAA,CAA6D,IAAA,CAAA,MAAA,EAAzB,QAAA,EAAQ;AAAA,gBAAA,GAAA,EAAA,CAAA;AAAG,gBAAA;AAAA,eAAA,EAAA,MAAA,EAAA,IAAA,CAAA,GAM/CA,UAAA,CAA8F,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA;AAAA,gBAAA,GAAA,EAAA,CAAA;AAAhF,gBAAA;AAAA,eAAA,EAAd,MAA8F;AAAA,gBAAAC,eAAA;AAAhE,kBAAAC,eAAA,CAAA,IAAA,CAAa,IAAA,IAAQ,IAAA,CAAK,SAAA,IAAa,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,kBAAA;AAAA;AAAA;AAAA,eAAA,EAAA,IAAA;;;;;;;;;;;;;;;;;;"}
@@ -86,10 +86,14 @@ var _sfc_main = defineComponent({
86
86
  */
87
87
  const gridItems = computed(() => computedItems.value.map(item => {
88
88
  const slotName = toKebabCase(item.modelName);
89
+ let cssClass = `x-base-grid__${slotName}`;
90
+ if (item.modelName === 'VendorBanner' && item.position === undefined) {
91
+ cssClass += ` x-base-grid__${slotName}--row`;
92
+ }
89
93
  return {
90
94
  slotName,
91
95
  item,
92
- cssClass: `x-base-grid__${slotName}`,
96
+ cssClass,
93
97
  };
94
98
  }));
95
99
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"base-grid.vue2.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n ref=\"gridEl\"\n :style=\"style\"\n class=\"x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ item, cssClass, slotName } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-base-grid__item\"\n >\n <!--\n @slot Customized item rendering. Specifying a slot with the item's modelName will result in\n the item using that slot composition to render.\n @binding {item} item - Item to render\n -->\n <slot v-if=\"slots[slotName]\" :name=\"slotName\" :item=\"item\" />\n <!--\n @slot (required) Default item rendering. This slot will be used by default for rendering\n the item without an specific slot implementation.\n @binding {item} item - Item to render\n -->\n <slot v-else :item=\"item\">{{ (item as any).name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { MaybeComputedElementRef, UseResizeObserverReturn } from '@vueuse/core'\nimport type { PropType, Ref } from 'vue'\nimport type { ListItem } from '../utils/types'\nimport type { GridItem } from './base-grid.types'\nimport { useResizeObserver } from '@vueuse/core'\nimport { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useXBus } from '../composables/use-x-bus'\nimport { AnimationProp } from '../types/animation-prop'\nimport { toKebabCase } from '../utils/string'\nimport { LIST_ITEMS_KEY } from './decorators/injection.consts'\n\n/**\n * Grid component that is able to render different items based on their modelName value. In order\n * to achieve this, it exposes a scopedSlot for each different modelName. In case the items used\n * do not have modelName property, the default slot is used instead. It has a required property:\n * the `items` to render; and an optional one: the number `columns` the grid is divided in. If the\n * number of columns is not specified, the grid automatically fills the rows with as many columns\n * as it can fit.\n *\n * @public\n */\nexport default defineComponent({\n name: 'BaseGrid',\n props: {\n /** Animation component that will be used to animate the base grid. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n /**\n * Number of columns the grid is divided into. By default, its value is 0, setting the grid\n * columns mode to auto-fill.\n */\n columns: {\n type: Number,\n default: 0,\n },\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an ID property.\n */\n items: {\n type: Array as PropType<ListItem[]>,\n },\n },\n setup(props, { slots }) {\n // eslint-disable-next-line ts/consistent-type-definitions\n type ElementRef = {\n $el: HTMLElement\n }\n\n const xBus = useXBus()\n\n /** It injects {@link ListItem} provided by an ancestor. */\n const injectedListItems = inject<Ref<ListItem[]>>(LIST_ITEMS_KEY as string)\n const gridEl = ref<ElementRef | HTMLElement>()\n const renderedColumnsNumber = ref(0)\n\n /**\n * Emits the {@link XEventsTypes.RenderedColumnsNumberChanged}\n * event whenever the number of columns rendered inside the grid changes.\n */\n watch(\n renderedColumnsNumber,\n () => xBus.emit('RenderedColumnsNumberChanged', renderedColumnsNumber.value),\n { immediate: false },\n )\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n */\n const computedItems = computed<ListItem[] | void>(() => {\n return (\n props.items ??\n injectedListItems?.value ??\n console.warn('It is necessary to pass a prop or inject the list of filters')\n )\n })\n\n /**\n * CSS class based on the column property value so items inside the grid can fill different\n * amount of columns or rows based on how many columns the grid is divided into.\n *\n * @returns CSS class with the column property value.\n */\n const cssClasses = computed(() => `x-base-grid--cols-${props.columns || 'auto'}`)\n\n /**\n * CSSStyleDeclaration object specifying the number of columns the grid is divided into based on\n * the column property value.\n *\n * @returns A CSSStyleDeclaration to use as the style attribute.\n */\n const style = computed<Partial<CSSStyleDeclaration>>(() => ({\n gridTemplateColumns: props.columns\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))',\n }))\n\n /**\n * Maps the item to an object containing: the `item`, its `CSS class` and its slot name.\n *\n * @returns An array of objects containing the item and its CSS class.\n */\n const gridItems = computed<GridItem[]>(() =>\n (computedItems.value as ListItem[]).map(item => {\n const slotName = toKebabCase(item.modelName)\n return {\n slotName,\n item,\n cssClass: `x-base-grid__${slotName}`,\n }\n }),\n )\n\n /**\n * Checks if a given value is an `ElementRef` object.\n *\n * @param value - The value to check.\n * @returns `true` if the value is an `ElementRef` object, `false` otherwise.\n */\n const isElementRef = (value: any): value is ElementRef => {\n return value && value.$el instanceof HTMLElement\n }\n\n /** Updates the number of columns rendered inside the grid. */\n function updateRenderedColumnsNumber() {\n const { gridTemplateColumns } = getComputedStyle(\n isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element),\n )\n renderedColumnsNumber.value = gridTemplateColumns.split(' ').length\n }\n\n /** Initialises the rendered columns number and sets a ResizeObserver to keep it updated. */\n let resizeObserver: UseResizeObserverReturn\n onMounted(() => {\n resizeObserver = useResizeObserver(\n gridEl as MaybeComputedElementRef,\n updateRenderedColumnsNumber,\n )\n })\n onBeforeUnmount(() => resizeObserver?.stop())\n\n return {\n gridItems,\n cssClasses,\n style,\n gridEl,\n slots,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-base-grid {\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n align-items: stretch;\n}\n\n.x-base-grid__banner,\n.x-base-grid__next-queries-group,\n.x-base-grid__related-prompts-group {\n grid-column-start: 1;\n grid-column-end: -1;\n}\n\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active,\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active {\n transition: none;\n position: relative;\n}\n\n.x-base-grid__item {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-base-grid__item > * {\n flex-grow: 1;\n}\n\n.x-base-grid--cols-auto .x-base-grid__item {\n min-width: var(--x-size-min-width-grid-item);\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis component renders a list of elements in different slots depending on their modelName. In order\nto achieve this, it exposes a scopedSlot for each different modelName. In case the items used do not\nhave modelName property, the default slot is used instead. It has a required property, the `items`\nto render, and an optional one, the number of `columns` the grid is divided in. If the number of\ncolumns is not specified, the grid automatically fills the rows with as many columns as it can fit.\n\n### Basic example\n\nIt renders a list of items using the default slot:\n\n```vue\n<template>\n <BaseGrid :items=\"items\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Configuring the number of columns\n\nIt renders a grid with 12 columns instead of 6, which is the default value:\n\n```vue\n<template>\n <BaseGrid :items=\"items\" :columns=\"12\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Rendering usage\n\nConfiguring the number of columns.\n\nIt renders a list of items using the different scopedSlots created by the item's modelName. For\nexample, if you want to use this component as the search grid, you pass the search results (results,\nbanners, promoted, next queries...etc) as items. Each of these results have a different modelName\nand are rendered in different slots.\n\n```vue\n<template>\n <BaseGrid :animation=\"animation\" :items=\"items\">\n <template #banner=\"{ item }\">\n <span class=\"banner\">\n {{ `${item.title} banner` }}\n </span>\n </template>\n <template #next-queries=\"{ item }\">\n <span>\n {{ `${item.totalResults} next queries` }}\n </span>\n </template>\n <template #promoted=\"{ item }\">\n <span class=\"promoted\">\n {{ `${item.title} promoted` }}\n </span>\n </template>\n <template #result=\"{ item }\">\n <BaseResultLink :result=\"item\">\n {{ item.name }}\n </BaseResultLink>\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nimport BaseResultLink from './BaseResultLink.vue'\nconst animation = 'ul'\nconst items = [\n { id: 1, modelName: 'banner', title: 'Banner 1' },\n { id: 2, modelName: 'next-queries', totalResults: 5 },\n { id: 3, modelName: 'promoted', title: 'Promo 1' },\n { id: 4, modelName: 'result', name: 'Result 1' },\n]\n</script>\n```\n\n### Customizing the items width\n\nThe `--x-size-min-width-grid-item` variable can be used to customize the min width of the grid\nitems.\n\n```vue\n<template>\n <BaseGrid :items=\"items\" style=\"--x-size-min-width-grid-item: 150px\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-grid.vue2.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n ref=\"gridEl\"\n :style=\"style\"\n class=\"x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ item, cssClass, slotName } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-base-grid__item\"\n >\n <!--\n @slot Customized item rendering. Specifying a slot with the item's modelName will result in\n the item using that slot composition to render.\n @binding {item} item - Item to render\n -->\n <slot v-if=\"slots[slotName]\" :name=\"slotName\" :item=\"item\" />\n <!--\n @slot (required) Default item rendering. This slot will be used by default for rendering\n the item without an specific slot implementation.\n @binding {item} item - Item to render\n -->\n <slot v-else :item=\"item\">{{ (item as any).name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { MaybeComputedElementRef, UseResizeObserverReturn } from '@vueuse/core'\nimport type { PropType, Ref } from 'vue'\nimport type { ListItem } from '../utils/types'\nimport type { GridItem } from './base-grid.types'\nimport { useResizeObserver } from '@vueuse/core'\nimport { computed, defineComponent, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useXBus } from '../composables/use-x-bus'\nimport { AnimationProp } from '../types/animation-prop'\nimport { toKebabCase } from '../utils/string'\nimport { LIST_ITEMS_KEY } from './decorators/injection.consts'\n\n/**\n * Grid component that is able to render different items based on their modelName value. In order\n * to achieve this, it exposes a scopedSlot for each different modelName. In case the items used\n * do not have modelName property, the default slot is used instead. It has a required property:\n * the `items` to render; and an optional one: the number `columns` the grid is divided in. If the\n * number of columns is not specified, the grid automatically fills the rows with as many columns\n * as it can fit.\n *\n * @public\n */\nexport default defineComponent({\n name: 'BaseGrid',\n props: {\n /** Animation component that will be used to animate the base grid. */\n animation: {\n type: AnimationProp,\n default: 'ul',\n },\n /**\n * Number of columns the grid is divided into. By default, its value is 0, setting the grid\n * columns mode to auto-fill.\n */\n columns: {\n type: Number,\n default: 0,\n },\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an ID property.\n */\n items: {\n type: Array as PropType<ListItem[]>,\n },\n },\n setup(props, { slots }) {\n // eslint-disable-next-line ts/consistent-type-definitions\n type ElementRef = {\n $el: HTMLElement\n }\n\n const xBus = useXBus()\n\n /** It injects {@link ListItem} provided by an ancestor. */\n const injectedListItems = inject<Ref<ListItem[]>>(LIST_ITEMS_KEY as string)\n const gridEl = ref<ElementRef | HTMLElement>()\n const renderedColumnsNumber = ref(0)\n\n /**\n * Emits the {@link XEventsTypes.RenderedColumnsNumberChanged}\n * event whenever the number of columns rendered inside the grid changes.\n */\n watch(\n renderedColumnsNumber,\n () => xBus.emit('RenderedColumnsNumberChanged', renderedColumnsNumber.value),\n { immediate: false },\n )\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n */\n const computedItems = computed<ListItem[] | void>(() => {\n return (\n props.items ??\n injectedListItems?.value ??\n console.warn('It is necessary to pass a prop or inject the list of filters')\n )\n })\n\n /**\n * CSS class based on the column property value so items inside the grid can fill different\n * amount of columns or rows based on how many columns the grid is divided into.\n *\n * @returns CSS class with the column property value.\n */\n const cssClasses = computed(() => `x-base-grid--cols-${props.columns || 'auto'}`)\n\n /**\n * CSSStyleDeclaration object specifying the number of columns the grid is divided into based on\n * the column property value.\n *\n * @returns A CSSStyleDeclaration to use as the style attribute.\n */\n const style = computed<Partial<CSSStyleDeclaration>>(() => ({\n gridTemplateColumns: props.columns\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))',\n }))\n\n /**\n * Maps the item to an object containing: the `item`, its `CSS class` and its slot name.\n *\n * @returns An array of objects containing the item and its CSS class.\n */\n const gridItems = computed<GridItem[]>(() =>\n (computedItems.value as ListItem[]).map(item => {\n const slotName = toKebabCase(item.modelName)\n let cssClass = `x-base-grid__${slotName}`\n if (item.modelName === 'VendorBanner' && (item as any).position === undefined) {\n cssClass += ` x-base-grid__${slotName}--row`\n }\n return {\n slotName,\n item,\n cssClass,\n }\n }),\n )\n\n /**\n * Checks if a given value is an `ElementRef` object.\n *\n * @param value - The value to check.\n * @returns `true` if the value is an `ElementRef` object, `false` otherwise.\n */\n const isElementRef = (value: any): value is ElementRef => {\n return value && value.$el instanceof HTMLElement\n }\n\n /** Updates the number of columns rendered inside the grid. */\n function updateRenderedColumnsNumber() {\n const { gridTemplateColumns } = getComputedStyle(\n isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element),\n )\n renderedColumnsNumber.value = gridTemplateColumns.split(' ').length\n }\n\n /** Initialises the rendered columns number and sets a ResizeObserver to keep it updated. */\n let resizeObserver: UseResizeObserverReturn\n onMounted(() => {\n resizeObserver = useResizeObserver(\n gridEl as MaybeComputedElementRef,\n updateRenderedColumnsNumber,\n )\n })\n onBeforeUnmount(() => resizeObserver?.stop())\n\n return {\n gridItems,\n cssClasses,\n style,\n gridEl,\n slots,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-base-grid {\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n align-items: stretch;\n}\n\n.x-base-grid__banner,\n.x-base-grid__vendor-banner--row,\n.x-base-grid__next-queries-group,\n.x-base-grid__related-prompts-group {\n grid-column-start: 1;\n grid-column-end: -1;\n}\n\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active,\n.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active {\n transition: none;\n position: relative;\n}\n\n.x-base-grid__item {\n display: flex;\n flex-flow: column nowrap;\n}\n\n.x-base-grid__item > * {\n flex-grow: 1;\n}\n\n.x-base-grid--cols-auto .x-base-grid__item {\n min-width: var(--x-size-min-width-grid-item);\n}\n</style>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis component renders a list of elements in different slots depending on their modelName. In order\nto achieve this, it exposes a scopedSlot for each different modelName. In case the items used do not\nhave modelName property, the default slot is used instead. It has a required property, the `items`\nto render, and an optional one, the number of `columns` the grid is divided in. If the number of\ncolumns is not specified, the grid automatically fills the rows with as many columns as it can fit.\n\n### Basic example\n\nIt renders a list of items using the default slot:\n\n```vue\n<template>\n <BaseGrid :items=\"items\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Configuring the number of columns\n\nIt renders a grid with 12 columns instead of 6, which is the default value:\n\n```vue\n<template>\n <BaseGrid :items=\"items\" :columns=\"12\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n\n### Rendering usage\n\nConfiguring the number of columns.\n\nIt renders a list of items using the different scopedSlots created by the item's modelName. For\nexample, if you want to use this component as the search grid, you pass the search results (results,\nbanners, promoted, next queries...etc) as items. Each of these results have a different modelName\nand are rendered in different slots.\n\n```vue\n<template>\n <BaseGrid :animation=\"animation\" :items=\"items\">\n <template #banner=\"{ item }\">\n <span class=\"banner\">\n {{ `${item.title} banner` }}\n </span>\n </template>\n <template #next-queries=\"{ item }\">\n <span>\n {{ `${item.totalResults} next queries` }}\n </span>\n </template>\n <template #promoted=\"{ item }\">\n <span class=\"promoted\">\n {{ `${item.title} promoted` }}\n </span>\n </template>\n <template #result=\"{ item }\">\n <BaseResultLink :result=\"item\">\n {{ item.name }}\n </BaseResultLink>\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nimport BaseResultLink from './BaseResultLink.vue'\nconst animation = 'ul'\nconst items = [\n { id: 1, modelName: 'banner', title: 'Banner 1' },\n { id: 2, modelName: 'next-queries', totalResults: 5 },\n { id: 3, modelName: 'promoted', title: 'Promo 1' },\n { id: 4, modelName: 'result', name: 'Result 1' },\n]\n</script>\n```\n\n### Customizing the items width\n\nThe `--x-size-min-width-grid-item` variable can be used to customize the min width of the grid\nitems.\n\n```vue\n<template>\n <BaseGrid :items=\"items\" style=\"--x-size-min-width-grid-item: 150px\">\n <template #default=\"{ item }\">\n {{ `Default slot content: ${item.id}` }}\n </template>\n </BaseGrid>\n</template>\n\n<script setup>\nimport { BaseGrid } from '@empathyco/x-components'\nconst items = [\n { id: 1, name: 'Item 1' },\n { id: 2, name: 'Item 2' },\n { id: 3, name: 'Item 3' },\n]\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import injectCss from '../../tools/inject-css.js';
2
2
 
3
- var css = ".x-base-grid[data-v-070eaadb]{align-items:stretch;display:grid;grid-auto-flow:dense;list-style:none}.x-base-grid__banner[data-v-070eaadb],.x-base-grid__next-queries-group[data-v-070eaadb],.x-base-grid__related-prompts-group[data-v-070eaadb]{grid-column-end:-1;grid-column-start:1}.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active[data-v-070eaadb],.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active[data-v-070eaadb]{position:relative;transition:none}.x-base-grid__item[data-v-070eaadb]{display:flex;flex-flow:column nowrap}.x-base-grid__item[data-v-070eaadb]>*{flex-grow:1}.x-base-grid--cols-auto .x-base-grid__item[data-v-070eaadb]{min-width:var(--x-size-min-width-grid-item)}";
3
+ var css = ".x-base-grid[data-v-070eaadb]{align-items:stretch;display:grid;grid-auto-flow:dense;list-style:none}.x-base-grid__banner[data-v-070eaadb],.x-base-grid__next-queries-group[data-v-070eaadb],.x-base-grid__related-prompts-group[data-v-070eaadb],.x-base-grid__vendor-banner--row[data-v-070eaadb]{grid-column-end:-1;grid-column-start:1}.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-enter-active[data-v-070eaadb],.x-base-grid__related-prompts-group.x-staggered-fade-and-slide-leave-active[data-v-070eaadb]{position:relative;transition:none}.x-base-grid__item[data-v-070eaadb]{display:flex;flex-flow:column nowrap}.x-base-grid__item[data-v-070eaadb]>*{flex-grow:1}.x-base-grid--cols-auto .x-base-grid__item[data-v-070eaadb]{min-width:var(--x-size-min-width-grid-item)}";
4
4
  injectCss(css);
5
5
 
6
6
  export { css };
package/js/index.js CHANGED
@@ -458,9 +458,10 @@ export { replaceableParams, urlEmitters } from './x-modules/url/store/emitters.j
458
458
  export { urlXStoreModule } from './x-modules/url/store/module.js';
459
459
  export { resetUrlBrowseCategory, resetUrlQuery, setInitialExtraParams, setParams, setUrlBrowseCategory, setUrlFilters, setUrlPage, setUrlParamsFromPreview, setUrlPrompt, setUrlQuery, setUrlQueryFromPreview, setUrlRelatedTags, setUrlScroll, setUrlSelectedFiltersFromPreview, setUrlSort, urlWiring } from './x-modules/url/wiring.js';
460
460
  export { urlXModule } from './x-modules/url/x-module.js';
461
+ export { default as VendorBannersList } from './x-modules/vendor/components/vendor-banners-list.vue.js';
461
462
  export { default as VendorResultsList } from './x-modules/vendor/components/vendor-results-list.vue.js';
462
463
  export { vendorEmitters } from './x-modules/vendor/store/emitters.js';
463
464
  export { vendorXStoreModule } from './x-modules/vendor/store/module.js';
464
- export { setResults, vendorWiring } from './x-modules/vendor/wiring.js';
465
+ export { setBanners, setResults, vendorWiring } from './x-modules/vendor/wiring.js';
465
466
  export { vendorXModule } from './x-modules/vendor/x-module.js';
466
467
  //# sourceMappingURL=index.js.map
package/js/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,83 @@
1
+ import { defineComponent, inject, computed, provide, h } from 'vue';
2
+ import { LIST_ITEMS_KEY } from '../../../components/decorators/injection.consts.js';
3
+ import ItemsList from '../../../components/items-list.vue.js';
4
+ import { use$x } from '../../../composables/use-_x.js';
5
+ import { useState } from '../../../composables/use-state.js';
6
+ import { AnimationProp } from '../../../types/animation-prop.js';
7
+ import { vendorXModule } from '../x-module.js';
8
+
9
+ /**
10
+ * It renders a {@link ItemsList} list of vendor banners from {@link VendorState.banners}.
11
+ *
12
+ * The component provides a default slot which wraps the whole component with the `vendorBanners`
13
+ * plus the `injectedListItems` which also contains the injected list items from
14
+ * the ancestor.
15
+ *
16
+ * It also provides the parent slots to customize the items.
17
+ *
18
+ * @public
19
+ */
20
+ var _sfc_main = defineComponent({
21
+ name: 'VendorBannersList',
22
+ xModule: vendorXModule.name,
23
+ props: {
24
+ /** Animation component that will be used to animate the vendor banners. */
25
+ animation: {
26
+ type: AnimationProp,
27
+ default: 'ul',
28
+ },
29
+ },
30
+ setup(props, { slots }) {
31
+ const $x = use$x();
32
+ /** The vendor banners to render from the state. */
33
+ const stateItems = useState('vendor').banners;
34
+ /** It injects {@link ListItem} provided by an ancestor as injectedListItems. */
35
+ const injectedListItems = inject(LIST_ITEMS_KEY);
36
+ /**
37
+ * The `stateItems` concatenated with the `injectedListItems` if there are.
38
+ *
39
+ * @remarks This computed defines the merging strategy of the `stateItems` and the
40
+ * `injectedListItems`.
41
+ *
42
+ * @returns List of {@link ListItem}.
43
+ */
44
+ const items = computed(() => {
45
+ if (!injectedListItems?.value.length) {
46
+ return stateItems.value;
47
+ }
48
+ const items = [...injectedListItems.value];
49
+ const positionedBanners = stateItems.value.filter(item => item.position != null);
50
+ const unpositionedBanners = stateItems.value.filter(item => item.position == null);
51
+ for (const item of positionedBanners) {
52
+ let index = item.position - 1;
53
+ while (items.at(index)?.modelName === 'VendorBanner') {
54
+ index++;
55
+ }
56
+ const isIndexInLoadedPages = index <= items.length;
57
+ const areAllPagesLoaded = $x.results.length === $x.totalResults;
58
+ if (!isIndexInLoadedPages && !areAllPagesLoaded) {
59
+ break;
60
+ }
61
+ items.splice(index, 0, item);
62
+ }
63
+ items.unshift(...unpositionedBanners);
64
+ return items;
65
+ });
66
+ /**
67
+ * The computed list items of the entity that uses the mixin.
68
+ *
69
+ * @remarks It should be overridden in the component that uses the mixin and it's intended to be
70
+ * filled with items from the state. Vue doesn't allow mixins as abstract classes.
71
+ * @returns An empty array as fallback in case it is not overridden.
72
+ */
73
+ provide(LIST_ITEMS_KEY, items);
74
+ return () => {
75
+ const innerProps = { items: items.value, animation: props.animation };
76
+ // https://vue-land.github.io/faq/forwarding-slots#passing-all-slots
77
+ return slots.default?.(innerProps)[0] ?? h(ItemsList, innerProps, slots);
78
+ };
79
+ },
80
+ });
81
+
82
+ export { _sfc_main as default };
83
+ //# sourceMappingURL=vendor-banners-list.vue.js.map