@empathyco/x-components 3.0.0-alpha.145 → 3.0.0-alpha.148

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 (124) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/core/index.js +1 -1
  3. package/core/index.js.map +1 -1
  4. package/design-system/full-theme.css +59 -58
  5. package/docs/API-reference/api/x-adapter-platform.md +0 -1
  6. package/docs/API-reference/api/x-adapter-platform.searchresponsemapper.md +1 -11
  7. package/docs/API-reference/api/x-components.facetsmutations.md +1 -1
  8. package/docs/API-reference/api/x-components.facetsmutations.mutatefilter.md +24 -0
  9. package/docs/API-reference/api/x-components.flathierarchicalfilters.md +26 -0
  10. package/docs/API-reference/api/x-components.md +3 -0
  11. package/docs/API-reference/api/x-components.mutatefilterpayload.filter.md +13 -0
  12. package/docs/API-reference/api/x-components.mutatefilterpayload.md +21 -0
  13. package/docs/API-reference/api/x-components.mutatefilterpayload.newfilterstate.md +13 -0
  14. package/docs/API-reference/api/x-components.nextquerieslist.injectedquery.md +13 -0
  15. package/docs/API-reference/api/x-components.nextquerieslist.md +1 -0
  16. package/docs/API-reference/api/x-components.nextquerypreview.md +29 -0
  17. package/docs/API-reference/api/x-components.nextquerypreview.mounted.md +17 -0
  18. package/docs/API-reference/api/x-components.nextquerypreview.previewresults.md +13 -0
  19. package/docs/API-reference/api/x-components.nextquerypreview.suggestion.md +13 -0
  20. package/docs/API-reference/api/x-components.nextquerypreview.suggestionresults.md +13 -0
  21. package/docs/API-reference/api/x-components.resultslist.md +9 -0
  22. package/docs/API-reference/api/x-components.resultslist.providedquery.md +13 -0
  23. package/docs/API-reference/api/x-components.resultslist.searchquery.md +13 -0
  24. package/docs/API-reference/api/x-components.resultslist.searchstatus.md +13 -0
  25. package/docs/API-reference/api/x-components.resultslist.updatequery.md +24 -0
  26. package/docs/API-reference/api/x-types.hierarchicalfilter.children.md +2 -2
  27. package/docs/API-reference/api/x-types.hierarchicalfilter.md +2 -2
  28. package/docs/API-reference/api/x-types.hierarchicalfilter.parentid.md +1 -1
  29. package/docs/API-reference/components/next-queries/x-components.next-query-preview.md +155 -0
  30. package/docs/experience-search-&-discovery/README.md +119 -0
  31. package/docs/experience-search-&-discovery/empathize.md +102 -0
  32. package/docs/experience-search-&-discovery/facets-and-filters.md +138 -0
  33. package/docs/experience-search-&-discovery/history-queries.md +56 -0
  34. package/docs/experience-search-&-discovery/id-results.md +40 -0
  35. package/docs/experience-search-&-discovery/next-queries.md +52 -0
  36. package/docs/experience-search-&-discovery/popular-searches.md +32 -0
  37. package/docs/experience-search-&-discovery/product-results-ui.md +68 -0
  38. package/docs/experience-search-&-discovery/query-suggestions.md +32 -0
  39. package/docs/experience-search-&-discovery/recommendations.md +32 -0
  40. package/docs/experience-search-&-discovery/related-tags.md +41 -0
  41. package/docs/experience-search-&-discovery/search-box.md +81 -0
  42. package/docs/experience-search-&-discovery/serp-ui.md +109 -0
  43. package/docs/experience-search-&-discovery/web-local-storage.md +25 -0
  44. package/facets/index.js +1 -1
  45. package/js/components/base-grid.vue.js +2 -2
  46. package/js/components/base-grid.vue.js.map +1 -1
  47. package/js/components/decorators/injection.consts.js +8 -2
  48. package/js/components/decorators/injection.consts.js.map +1 -1
  49. package/js/index.js +4 -3
  50. package/js/index.js.map +1 -1
  51. package/js/x-modules/facets/components/facets/facets-provider.vue.js +2 -2
  52. package/js/x-modules/facets/components/facets/facets-provider.vue.js.map +1 -1
  53. package/js/x-modules/facets/components/facets/facets-provider.vue_rollup-plugin-vue_script.vue.js +7 -2
  54. package/js/x-modules/facets/components/facets/facets-provider.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  55. package/js/x-modules/facets/components/filters/hierarchical-filter.vue.js.map +1 -1
  56. package/js/x-modules/facets/components/filters/hierarchical-filter.vue_rollup-plugin-vue_script.vue.js +2 -130
  57. package/js/x-modules/facets/components/filters/hierarchical-filter.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  58. package/js/x-modules/facets/entities/editable-number-range-filter.entity.js +11 -10
  59. package/js/x-modules/facets/entities/editable-number-range-filter.entity.js.map +1 -1
  60. package/js/x-modules/facets/entities/hierarchical-filter.entity.js +9 -11
  61. package/js/x-modules/facets/entities/hierarchical-filter.entity.js.map +1 -1
  62. package/js/x-modules/facets/entities/number-range-filter.entity.js +2 -2
  63. package/js/x-modules/facets/entities/number-range-filter.entity.js.map +1 -1
  64. package/js/x-modules/facets/entities/raw-filter.entity.js +1 -1
  65. package/js/x-modules/facets/entities/raw-filter.entity.js.map +1 -1
  66. package/js/x-modules/facets/entities/simple-filter.entity.js +2 -2
  67. package/js/x-modules/facets/entities/simple-filter.entity.js.map +1 -1
  68. package/js/x-modules/facets/entities/single-select.modifier.js +1 -1
  69. package/js/x-modules/facets/entities/single-select.modifier.js.map +1 -1
  70. package/js/x-modules/facets/service/facets.service.js +18 -2
  71. package/js/x-modules/facets/service/facets.service.js.map +1 -1
  72. package/js/x-modules/facets/store/module.js +4 -3
  73. package/js/x-modules/facets/store/module.js.map +1 -1
  74. package/js/x-modules/facets/utils.js +16 -1
  75. package/js/x-modules/facets/utils.js.map +1 -1
  76. package/js/x-modules/next-queries/components/next-queries-list.vue.js.map +1 -1
  77. package/js/x-modules/next-queries/components/next-queries-list.vue_rollup-plugin-vue_script.vue.js +19 -0
  78. package/js/x-modules/next-queries/components/next-queries-list.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  79. package/js/x-modules/next-queries/components/next-query-preview.vue.js +94 -0
  80. package/js/x-modules/next-queries/components/next-query-preview.vue.js.map +1 -0
  81. package/js/x-modules/next-queries/components/next-query-preview.vue_rollup-plugin-vue_script.vue.js +48 -0
  82. package/js/x-modules/next-queries/components/next-query-preview.vue_rollup-plugin-vue_script.vue.js.map +1 -0
  83. package/js/x-modules/next-queries/store/actions/fetch-and-save-next-query-preview.action.js.map +1 -1
  84. package/js/x-modules/search/components/results-list.vue.js.map +1 -1
  85. package/js/x-modules/search/components/results-list.vue_rollup-plugin-vue_script.vue.js +33 -2
  86. package/js/x-modules/search/components/results-list.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  87. package/js/x-modules/search-box/components/search-input.vue.js +54 -45
  88. package/js/x-modules/search-box/components/search-input.vue.js.map +1 -1
  89. package/js/x-modules/search-box/components/search-input.vue_rollup-plugin-vue_script.vue.js.map +1 -1
  90. package/next-queries/index.js +2 -1
  91. package/package.json +4 -4
  92. package/report/x-adapter-platform.api.json +5 -133
  93. package/report/x-components.api.json +491 -45
  94. package/report/x-components.api.md +32 -5
  95. package/report/x-types.api.json +5 -5
  96. package/types/components/decorators/injection.consts.d.ts +6 -0
  97. package/types/components/decorators/injection.consts.d.ts.map +1 -1
  98. package/types/x-modules/facets/components/facets/facets-provider.vue.d.ts.map +1 -1
  99. package/types/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts +0 -6
  100. package/types/x-modules/facets/components/filters/hierarchical-filter.vue.d.ts.map +1 -1
  101. package/types/x-modules/facets/entities/editable-number-range-filter.entity.d.ts +1 -1
  102. package/types/x-modules/facets/entities/editable-number-range-filter.entity.d.ts.map +1 -1
  103. package/types/x-modules/facets/entities/hierarchical-filter.entity.d.ts +2 -1
  104. package/types/x-modules/facets/entities/hierarchical-filter.entity.d.ts.map +1 -1
  105. package/types/x-modules/facets/entities/single-select.modifier.d.ts.map +1 -1
  106. package/types/x-modules/facets/service/facets.service.d.ts +13 -0
  107. package/types/x-modules/facets/service/facets.service.d.ts.map +1 -1
  108. package/types/x-modules/facets/store/module.d.ts.map +1 -1
  109. package/types/x-modules/facets/store/types.d.ts +22 -6
  110. package/types/x-modules/facets/store/types.d.ts.map +1 -1
  111. package/types/x-modules/facets/utils.d.ts +11 -0
  112. package/types/x-modules/facets/utils.d.ts.map +1 -1
  113. package/types/x-modules/next-queries/components/index.d.ts +2 -1
  114. package/types/x-modules/next-queries/components/index.d.ts.map +1 -1
  115. package/types/x-modules/next-queries/components/next-queries-list.vue.d.ts +11 -0
  116. package/types/x-modules/next-queries/components/next-queries-list.vue.d.ts.map +1 -1
  117. package/types/x-modules/next-queries/components/next-query-preview.vue.d.ts +35 -0
  118. package/types/x-modules/next-queries/components/next-query-preview.vue.d.ts.map +1 -0
  119. package/types/x-modules/search/components/results-list.vue.d.ts +21 -0
  120. package/types/x-modules/search/components/results-list.vue.d.ts.map +1 -1
  121. package/types/x-modules/search-box/components/search-input.vue.d.ts.map +1 -1
  122. package/docs/API-reference/api/x-adapter-platform.searchresponsefacetsmapper.md +0 -27
  123. package/docs/API-reference/api/x-components.facetsmutations.setfilter.md +0 -24
  124. package/docs/functional-doc/web-local-storage.md +0 -22
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Popular Searches UI
3
+ ---
4
+
5
+ # Popular Searches UI
6
+
7
+ The Popular Searches UI component displays what are the top search queries during a specific time.
8
+ This type of suggestion can show up even before shoppers have started entering a query or when there
9
+ are no search results to show.
10
+
11
+ ![Popular Searches](/assets/media/xcomponents_func_popularsearches.gif)
12
+
13
+ :::warning Popular Searches are generated using shopper behavior to determine the top searches for a
14
+ given period. For a correct performance, make sure that your current search service supports this
15
+ type of feature. :::
16
+
17
+ ::: interact Can't quite capture the concept? Learn about
18
+ [Popular Searches](../features/popular-searches-overview.md). :::
19
+
20
+ ## Tailor the web experience
21
+
22
+ - Configure the position and place it wherever you prefer. Combine it with the
23
+ [Empathize](empathize.md) container to display Popular Searches below the search bar on shopper
24
+ interaction.
25
+ - Show as many popular search terms results as you want.
26
+ - Animate the display of Popular Searches at your ease.
27
+ - Customize content. Show whatever you need: text, images, icons.
28
+
29
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
30
+ your web experience. :::
31
+
32
+ [//]: # 'To see Popular Searches in action, play with our showcase'
@@ -0,0 +1,68 @@
1
+ ---
2
+ title: Product results UI
3
+ ---
4
+
5
+ # Product results UI
6
+
7
+ After launching a search, some shoppers may just want to take a quick look around, reviewing only
8
+ product thumbnails and quick info on the SERP. While others will prefer to have a more detailed
9
+ overview of the product results with large and multiple images. That’s why the display of results is
10
+ really issue.
11
+
12
+ Results are rendered thanks to the combination of different X Components. This way, you can
13
+ tailor the display to create the best product discovery experience for your shoppers. Decide the
14
+ elements and product-related information you want to include when displaying product results such as
15
+ the price, a picture, or even an add-to-cart button.
16
+
17
+ ![X Components for results display](/assets/media/overview_product_card.svg)
18
+
19
+ <FootNote>
20
+
21
+ **X&nbsp;Components for results display** <br/> (A) Image, (B) Product information, (C) Price, (D)
22
+ PDP Link, (E) Rating, (F) Add to cart
23
+
24
+ </FootNote>
25
+
26
+ ::: interact To learn more about the display of results, see
27
+ [Product results](/explore-empathy-platform/overview/product-results-overview.md). :::
28
+
29
+ **A bunch of components for comprehensive product information** Decide whether you want to include
30
+ the description for the resulting product, a picture, or even rating information:
31
+
32
+ - **Image**. Include a picture of the product for better product recognition.&nbsp;(A)
33
+ - **Result data and product variants**. Retrieve the information to display about the product –name,
34
+ description, reference, brand, category, season, colors, types, sizes, or any data from your
35
+ catalogue.&nbsp;(B)
36
+ - **Pricing**. Indicate the original price of the product, discounts, and special prices.&nbsp;(C)
37
+ - **Product details**. Link your shoppers to the product detail page (PDP).&nbsp;(D)
38
+ - **Rating**. Show how valued a product is among your shoppers.&nbsp;(E)
39
+ - **Add to cart**. Allow your shoppers to add a product to the cart from the search engine results
40
+ page (SERP), without going through the PDP.&nbsp;(F)
41
+
42
+ :::warning To include rating and add-to-cart options in results, rating and add-to-cart features
43
+ must be implemented in your product catalogue. :::
44
+
45
+ ## Tailor the web experience
46
+
47
+ - Customize content. Choose and display the product-related information available in your catalogue.
48
+ - Add a PDP link to the product name or description, the picture, or to the entire product result.
49
+ - Format the price of products with integers and decimals. Decide the length of decimals or whether
50
+ decimals should be rendered or not.
51
+ - Select the desired currency for prices.
52
+ - Customize the default rendering behavior of pictures when loading or broken.
53
+ - Animate the display of product results.
54
+
55
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
56
+ your web experience. :::
57
+
58
+ ## Extend the performance
59
+
60
+ Traditionally, search results are displayed on the SERP after the query is launched or instantly as
61
+ you type. However, result data is also used by features such as
62
+ [Recommendations](/explore-empathy-platform/experience-search-&-discovery/recommendations.md) and
63
+ [ID Results](/explore-empathy-platform/experience-search-&-discovery/id-results.md). You can combine
64
+ results-related components with these modules to get advanced display options. Include additional
65
+ product information in Recommendations and Identifier Results such as prices and pictures for better
66
+ recognition and understanding of the products displayed.
67
+
68
+ [//]: # 'TIP: To see the product results in action, play with our showcase.'
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Query Suggestions UI
3
+ ---
4
+
5
+ # Query Suggestions UI
6
+
7
+ The Query Suggestions UI component helps your shoppers with hints of what to look for to get
8
+ relevant results. They complete and nail down the query as shoppers type without needing to keep
9
+ typing.
10
+
11
+ ![Query Suggestions](/assets/media/xcomponents_func_querysuggestions.gif)
12
+
13
+ :::warning Query Suggestions are generated using collective shopper behavior, extracting the
14
+ keywords used on a specific query. For a correct performance, make sure that your current search
15
+ service supports this type of feature. :::
16
+
17
+ ::: interact Can't quite capture the concept? Learn more about
18
+ [Query Suggestions](../features/query-suggestions-overview.md). :::
19
+
20
+ ## Tailor the web experience
21
+
22
+ - Configure the position and place it wherever you prefer. Combine it with the
23
+ [Empathize](empathize.md) container to display suggestions below the search bar on shopper
24
+ interaction.
25
+ - Show as many suggestions as you want.
26
+ - Animate the display of Query Suggestions at your ease.
27
+ - Customize content. Show whatever you need: text, images, icons.
28
+
29
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
30
+ your web experience. :::
31
+
32
+ [//]: # 'To see Query Suggestions in action, play with our showcase'
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Recommendations UI
3
+ ---
4
+
5
+ # Recommendations UI
6
+
7
+ The Recommendations UI component shows the most clicked products on the SERP, based on shopper
8
+ interaction within a defined period. They help your shoppers to explore your product catalogue,
9
+ guiding them to specific products without the need to launch any queries.
10
+
11
+ <img :src="$withBase('/assets/media/xcomponents_func_recommendations.gif')" alt="Recommendations]">
12
+
13
+ :::warning Recommendations are generated using collective shopper behavior, generating a feed with
14
+ the most clicked products. For a correct performance, make sure that your current search service
15
+ supports this type of feature. :::
16
+
17
+ ::: interact Can't quite capture the concept? Learn more about
18
+ [Recommendations](../search/recommendations-overview.md). :::
19
+
20
+ ## Tailor the web experience
21
+
22
+ - Configure the position and place it wherever you prefer, although they usually appear on the
23
+ results page.
24
+ - Show as many recommendations as you want.
25
+ - Animate the display of the component at your ease.
26
+ - Customize content. Show whatever you need: text, images, icons.
27
+ - Extend the performance with results-related components.
28
+
29
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
30
+ your web experience. :::
31
+
32
+ [//]: # 'TIP To see Recommendations in action, play with our showcase.'
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Related Tags UI
3
+ ---
4
+
5
+ # Related Tags UI
6
+
7
+ The Related Tags UI component helps your shoppers to refine a specific search query and find what
8
+ they’re looking for with just one click. They only appear after the search process is completed, and
9
+ the results appear to fine-tune the search with extra information and get highly relevant results.
10
+ They are shown as labels usually at the top of the results page, but can be displayed anywhere
11
+ instead.
12
+
13
+ ![Related Tags](/assets/media/xcomponents_func_relatedtags.gif)
14
+
15
+ :::warning Related Tags are generated using collective shopper behavior to identify associated terms
16
+ used to refine a search query. For a correct performance, make sure that your current search service
17
+ supports this type of feature. :::
18
+
19
+ ::: interact Can't quite capture the concept? Learn more about
20
+ [Related Tags](../features/related-tags-overview.md). :::
21
+
22
+ [//]:
23
+ #
24
+ 'You can configure the behaviour of Related Tags and decide whether they’re selectable or not. If Related Tags aren’t selectable, they modify the initial query syntax by adding the related-search keywords to the query term initially typed in the search bar. Otherwise, the initial query syntax will still remain so that shoppers can select or deselect Related Tags at their ease, exploring different options and combinations.'
25
+
26
+ ## Tailor the web experience
27
+
28
+ - Configure the position and place it wherever you prefer, although Related Tags usually appear
29
+ below the search bar after completing the search.
30
+ - Show as many Related Tags as you want.
31
+ - Animate the display of Related Tags at your ease.
32
+ - Customize content. Show whatever you need: text, images, icons.
33
+
34
+ [//]:
35
+ #
36
+ '* Choose if Related Tags are selectable or change the syntax of the initial query in the search box.'
37
+
38
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
39
+ your web experience. :::
40
+
41
+ [//]: # 'tip To see Related Tags in action, play with our showcase'
@@ -0,0 +1,81 @@
1
+ ---
2
+ title: Search Box UI
3
+ ---
4
+
5
+ # Search Box UI
6
+
7
+ The Search&nbsp;Box UI Component is the main entry point for search where shoppers can type what
8
+ they're looking for in your shop. It usually includes an input field, a search button, and a clear
9
+ button.
10
+
11
+ <img :src="$withBase('/assets/media/xcomponents_func_searchbox.svg')" alt="Search Box"> <br>
12
+
13
+ ::: interact Can't quite capture the concept? Learn more about
14
+ [Search Box](../overview/search-box-overview.md). :::
15
+
16
+ It can be combined with other X&nbsp;Components, such as [Query Suggestions](query-suggestions.md)
17
+ or [Next Queries](next-queries.md), to update the query according to shoppers’ intent or
18
+ behaviour. For example, if a shopper selects a query suggestion, the query is instantly updated in
19
+ the input field to the selected suggestion and the search is launched.
20
+
21
+ :::warning To modify the query syntax using
22
+ [Query Suggestions](../features/query-suggestions-overview.md) or
23
+ [Next Queries](../features/next-queries-overview.md), make sure that your current search service
24
+ supports this type of feature. :::
25
+
26
+ ## Power-up behavior
27
+
28
+ Every component has a power-up behavior under the hood that is visible to the user but not glaringly
29
+ obvious. For example, in Interface X Components for web, see what happens when:
30
+
31
+ - _A query with results is **submitted**_:
32
+
33
+ - Results are displayed
34
+ - Related tags are displayed
35
+ - Next queries are displayed
36
+ - The query can be displayed in the History Queries or Query Suggestions lists upon configuration
37
+
38
+ - _A query with results is **cleared** using the clear button_:
39
+
40
+ - Any text in the search input is cleared
41
+ - The results are cleared
42
+ - The query suggestions are cleared
43
+ - The next queries are not cleared
44
+ - The related tags are cleared
45
+ - The searched query is displayed in history queries
46
+
47
+ - _Using **instant search and a query is being typed** that has results_:
48
+
49
+ - No results are displayed before debounce time
50
+ - Results are displayed after debounce time
51
+ - Next queries are displayed after debounce time
52
+ - Related tags are displayed after debounce time
53
+
54
+ - _Using **instant search and modifying the initial query**_:
55
+ - No results related to the second query are displayed before debounce time
56
+ - Results related to the second query are displayed after debounce time
57
+ - Displayed results are different from the previous ones
58
+
59
+ ::: warning Deactivating instant search means History Queries are not updated until the search
60
+ button or Enter key is pressed, since the typed query is not submitted until one of these two
61
+ actions is performed. :::
62
+
63
+ ## Tailor the web experience
64
+
65
+ - Configure the position and place it wherever you prefer.
66
+ - Customize content. Allow shoppers to search or clear their search using text or icons.
67
+ - Determine the number of characters shoppers can enter in the search input.
68
+ - Autofocus the input field when the search&nbsp;box is displayed.
69
+ - Auto-accept the query without the need of using a search button or the Enter key. Determine the
70
+ debounce time to wait before instant search.
71
+ - Configure what will happen after the search is triggered; for example, display Related Tags or
72
+ Next Queries.
73
+
74
+ [//]:
75
+ #
76
+ 'TO BE PUBLISHED IN FUTURE ITERATIONS WHEN THE SEARCH BOX POWER-UP ARE IMPLEMENTED: * Automatically suggest search terms to guide shoppers in constructing their search query. * Prompt shoppers to start their search with animated custom hint messages. '
77
+
78
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
79
+ your web experience. :::
80
+
81
+ [//]: # 'TIP: To see Search Box in action, play with our showcase.'
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: SERP UI
3
+ ---
4
+
5
+ # SERP UI
6
+
7
+ To handle and display search results, the layout of results and other related discovery features is
8
+ paramount. For example, how to arrange results on the SERP or the features shoppers expect to easily
9
+ navigate and organize results are key points to have in mind. <br/>
10
+
11
+ ![X Components for results layout](/assets/media/xcomponents_func_results_layout.svg)
12
+
13
+ <FootNote>
14
+
15
+ **X&nbsp;Components for results layout** <br/> (A) Grid, (B) Number of results, (C) Column Picker,
16
+ (D) Sorting, and (E) Scrolling
17
+
18
+ </FootNote>
19
+ <br/>
20
+
21
+ **Choice of the layout view** Your shoppers should be able to select how they’d like the products
22
+ displayed and how the number of products they’d like to see per page, for example.
23
+
24
+ That’s why the **grid** (A) is the core element of the SERP. It displays the results returned by the
25
+ search service using a grid layout. Its value relies on having a configurable and flexible space to
26
+ place all types of results or even other layout components such as a carousel visualization for
27
+ [Next Queries](next-queries.md) or [Recommendations](recommendations.md).
28
+
29
+ However, the grid is not the only element to consider when designing the SERP:
30
+
31
+ [//]:
32
+ #
33
+ 'To add when ready: Include **pagination** options to browse results throughout the different result pages available or apply **infinite scroll** to ease navigation.'
34
+
35
+ - Show the **number of results** (B).
36
+ - Allow your shoppers to select the **number of columns** (C) to showcase results.
37
+ - Provide a **[sorting system](/explore-empathy-platform/overview/sorting-overview.md)** (D) so that
38
+ your shoppers can arrange results according to different criteria such as relevance, price,
39
+ alphabetical order…
40
+ - Include **[pagination](/explore-empathy-platform/overview/pagination-overview.md)** options to
41
+ browse results throughout the different result pages available or apply infinite scroll to ease
42
+ navigation.
43
+ - Apply **infinite scroll** to ease navigation and add a **scroll-to-top button** (E) to quickly
44
+ move to the top of the results page.
45
+ - Indicate your shoppers whether the
46
+ **[spellcheck](/explore-empathy-platform/features/spellcheck-overview.md)** feature is applied or
47
+ not.
48
+
49
+ ::: note Enhance the search experience, adding [Related Tags](related-tags.md) to the SERP so that
50
+ your shoppers can select descriptive keywords to refine the initial query and get highly relevant
51
+ results. :::
52
+
53
+ ::: design As most shoppers don’t like to spend time scrolling and moving between pages, a crucial
54
+ element on the SERP for a great experience is to offer **faceted search**, letting shoppers specify
55
+ the kind of product attributes they’re interested in. :::
56
+
57
+ ::: interact To learn more about the SERP, results display, and their layout, see
58
+ [Results on the SERP](../overview/results-overview.md). :::
59
+
60
+ ## Tailor the web experience
61
+
62
+ **Grid**
63
+
64
+ - Customize the layout of the results. Decide whether to display results using a grid or the default
65
+ list layout.
66
+ - Configure what to display: product results, promotion banners, promoted results, or even next
67
+ queries and recommendations.
68
+ - Customize the location, style, and content for each type of result.
69
+ - Automatically fill the grid rows with as many columns as it can fit or set the number of columns
70
+ to divide the grid.
71
+ - Indicate the number of product results to render per page.
72
+ - Animate the display of the grid at your ease.
73
+ - Allow your users to select the number of columns to display. Define if your shoppers will be
74
+ provided with a dropdown menu or a list with the columns to pick for the grid.
75
+ - Show the total number of product results displayed. Configure the content with text, images, or
76
+ icons.
77
+
78
+ **Sorting**
79
+
80
+ - Choose and configure the sorting options available. Highlight the selected sorting option.
81
+ - Select the display of the sorting system: dropdown menu or a simple list with the sorting options
82
+ available.
83
+ - Animate the display of the sorting dropdown menu.
84
+ - Set a default sorting option.
85
+ <!-- TBC: Decide which sorting option to display based on product category. -->
86
+
87
+ **Pagination & scrolling**
88
+
89
+ - Customize the content and style for the controls to move between pages.
90
+ - Include an infinite scroll to load more results when reaching the end of the page.
91
+
92
+ **Scrolling to top**
93
+
94
+ - Decide when it will be displayed: when reached a defined threshold or the page end.
95
+ - Configure the position and place it wherever you prefer.
96
+ - Customize content. Show whatever you need: text, images, icons.
97
+ - Animate the display of the scroll-to-top button at your ease.
98
+
99
+ **Spellcheck**
100
+
101
+ - Display a message to inform your shoppers that the
102
+ [spellcheck](../features/spellcheck-overview.md) feature has been used to provide results for the
103
+ current query.
104
+ - Customize the message content at your ease.
105
+
106
+ ::: interact Want to know more? Learn how to [configure](/develop-empathy-platform/ui-reference/)
107
+ your web experience. :::
108
+
109
+ [//]: # 'TIP: To see the SERP-related components in action, play with our showcase.'
@@ -0,0 +1,25 @@
1
+ ---
2
+ title: Interface X data privacy and browser local storage
3
+ tags:
4
+ - x components
5
+ - interface x
6
+ - cookies
7
+ - local storage
8
+ - history queries
9
+ ---
10
+
11
+ # Interface X data privacy and browser local storage
12
+
13
+ Interface&nbsp;X for web _doesn't use cookies_ for storing data. The
14
+ Interface&nbsp;X&nbsp;Components use the web browser's local storage to save the technical data
15
+ required to provide the services associated with the search & discovery experience. The data remains
16
+ in the shopper's device until the expiration time is reached or the shopper chooses to delete it.
17
+
18
+ More specifically, Interface&nbsp;X&nbsp;Components store the following elements in the browser's
19
+ local storage:
20
+
21
+ | Key | Duration | Purpose |
22
+ | ---------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
+ | `x-session-id` | 30 minutes | Short-term session ID to be sent to the Tagging API. It identifies short sessions in a device. It does not identify individual shoppers in any way. It is required for [Analytics](https://docs.empathy.co/explore-empathy-platform/understand-data-privacy/), [Next Queries](https://docs.empathy.co/explore-empathy-platform/features/history-queries-overview.html), and [Related Tags](https://docs.empathy.co/explore-empathy-platform/features/related-tags-overview.html) features |
24
+ | `x-session-time-stamp` | 30 minutes | Timestamp for the current session ID |
25
+ | `x-history-queries` | Stored until the shopper clears/disables the feature | List of the searches performed that the shopper has chosen to store, which are shown in different steps of the search journey. |
package/facets/index.js CHANGED
@@ -32,5 +32,5 @@ export { default as SelectedFiltersList } from '../js/x-modules/facets/component
32
32
  export { default as SlicedFilters } from '../js/x-modules/facets/components/lists/sliced-filters.vue.js';
33
33
  export { default as SortedFilters } from '../js/x-modules/facets/components/lists/sorted-filters.vue.js';
34
34
  export { default as ClearFilters } from '../js/x-modules/facets/components/clear-filters.vue.js';
35
- export { isNewQuery } from '../js/x-modules/facets/utils.js';
35
+ export { flatHierarchicalFilters, isNewQuery } from '../js/x-modules/facets/utils.js';
36
36
  export { default as FacetsMixin } from '../js/x-modules/facets/components/facets.mixin.js';
@@ -57,11 +57,11 @@ __vue_render__._withStripped = true;
57
57
  /* style */
58
58
  const __vue_inject_styles__ = function (inject) {
59
59
  if (!inject) return
60
- inject("data-v-22d07af6_0", { source: ".x-base-grid[data-v-22d07af6] {\n padding: var(--x-size-padding-grid, 0);\n margin: 0;\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n}\n.x-base-grid__banner[data-v-22d07af6] {\n grid-column-start: 1;\n grid-column-end: -1;\n}", map: undefined, media: undefined });
60
+ inject("data-v-604592d3_0", { source: ".x-base-grid[data-v-604592d3] {\n padding: var(--x-size-padding-grid, 0);\n margin: 0;\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n}\n.x-base-grid__banner[data-v-604592d3], .x-base-grid__next-queries-group[data-v-604592d3] {\n grid-column-start: 1;\n grid-column-end: -1;\n}", map: undefined, media: undefined });
61
61
 
62
62
  };
63
63
  /* scoped */
64
- const __vue_scope_id__ = "data-v-22d07af6";
64
+ const __vue_scope_id__ = "data-v-604592d3";
65
65
  /* module identifier */
66
66
  const __vue_module_identifier__ = undefined;
67
67
  /* functional template */
@@ -1 +1 @@
1
- {"version":3,"file":"base-grid.vue.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n :style=\"style\"\n class=\"x-grid x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ slotName, item, cssClass } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-grid__item 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=\"$scopedSlots[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.name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { toKebabCase } from '../utils/string';\n import { ListItem, VueCSSClasses } from '../utils/types';\n import { XInject } from './decorators/injection.decorators';\n import { LIST_ITEMS_KEY } from './decorators/injection.consts';\n\n /**\n * The type returned by the gridItems function. Basically it's a list of items with its CSS\n * classes and a slotName.\n *\n * @internal\n */\n interface GridItem {\n slotName: string;\n item: ListItem;\n cssClass: VueCSSClasses;\n }\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 */\n @Component({})\n export default class BaseGrid extends Vue {\n /**\n * Animation component that will be used to animate the base grid.\n *\n * @public\n */\n @Prop({ default: 'ul' })\n protected animation!: Vue | string;\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 * @public\n */\n @Prop({ default: 0 })\n protected columns!: number;\n\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an id property.\n *\n * @public\n */\n @Prop()\n protected items!: ListItem[];\n\n /**\n * It injects {@link ListItem} provided by an ancestor.\n *\n * @internal\n */\n @XInject(LIST_ITEMS_KEY)\n public injectedListItems!: ListItem[];\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n *\n * @public\n */\n protected get computedItems(): ListItem[] {\n return (\n this.items ??\n this.injectedListItems ??\n //TODO: add here logger\n //eslint-disable-next-line no-console\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 * @internal\n */\n protected get cssClasses(): VueCSSClasses {\n return this.columns ? `x-grid--cols-${this.columns}` : 'x-grid--cols-auto';\n }\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 * @internal\n */\n protected get style(): Partial<CSSStyleDeclaration> {\n return {\n gridTemplateColumns: this.columns\n ? `repeat(${this.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))'\n };\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 * @internal\n */\n protected get gridItems(): GridItem[] {\n return this.computedItems.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</script>\n\n<style lang=\"scss\" scoped>\n .x-base-grid {\n padding: var(--x-size-padding-grid, 0);\n margin: 0;\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n\n &__banner {\n grid-column-start: 1;\n grid-column-end: -1;\n }\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\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\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</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"base-grid.vue.js","sources":["../../../src/components/base-grid.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n :style=\"style\"\n class=\"x-grid x-base-grid\"\n :class=\"cssClasses\"\n tag=\"ul\"\n data-test=\"grid\"\n >\n <li\n v-for=\"{ slotName, item, cssClass } in gridItems\"\n :key=\"item.id\"\n :class=\"cssClass\"\n class=\"x-grid__item 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=\"$scopedSlots[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.name || item.modelName || item.id || item }}</slot>\n </li>\n </component>\n</template>\n\n<script lang=\"ts\">\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { toKebabCase } from '../utils/string';\n import { ListItem, VueCSSClasses } from '../utils/types';\n import { XInject } from './decorators/injection.decorators';\n import { LIST_ITEMS_KEY } from './decorators/injection.consts';\n\n /**\n * The type returned by the gridItems function. Basically it's a list of items with its CSS\n * classes and a slotName.\n *\n * @internal\n */\n interface GridItem {\n slotName: string;\n item: ListItem;\n cssClass: VueCSSClasses;\n }\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 */\n @Component({})\n export default class BaseGrid extends Vue {\n /**\n * Animation component that will be used to animate the base grid.\n *\n * @public\n */\n @Prop({ default: 'ul' })\n protected animation!: Vue | string;\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 * @public\n */\n @Prop({ default: 0 })\n protected columns!: number;\n\n /**\n * The list of items to be rendered.\n *\n * @remarks The items must have an id property.\n *\n * @public\n */\n @Prop()\n protected items!: ListItem[];\n\n /**\n * It injects {@link ListItem} provided by an ancestor.\n *\n * @internal\n */\n @XInject(LIST_ITEMS_KEY)\n public injectedListItems!: ListItem[];\n\n /**\n * It returns the items passed as props or the injected ones.\n *\n * @returns List of grid items.\n *\n * @public\n */\n protected get computedItems(): ListItem[] {\n return (\n this.items ??\n this.injectedListItems ??\n //TODO: add here logger\n //eslint-disable-next-line no-console\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 * @internal\n */\n protected get cssClasses(): VueCSSClasses {\n return this.columns ? `x-grid--cols-${this.columns}` : 'x-grid--cols-auto';\n }\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 * @internal\n */\n protected get style(): Partial<CSSStyleDeclaration> {\n return {\n gridTemplateColumns: this.columns\n ? `repeat(${this.columns}, minmax(0, 1fr))`\n : 'repeat(auto-fill, minmax(var(--x-size-min-width-grid-item, 150px), 1fr))'\n };\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 * @internal\n */\n protected get gridItems(): GridItem[] {\n return this.computedItems.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</script>\n\n<style lang=\"scss\" scoped>\n .x-base-grid {\n padding: var(--x-size-padding-grid, 0);\n margin: 0;\n display: grid;\n grid-auto-flow: dense;\n list-style: none;\n\n &__banner,\n &__next-queries-group {\n grid-column-start: 1;\n grid-column-end: -1;\n }\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\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\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</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,7 +3,13 @@
3
3
  *
4
4
  * @internal
5
5
  */
6
- const LIST_ITEMS_KEY = 'listItems';
6
+ const LIST_ITEMS_KEY = 'listItems';
7
+ /**
8
+ * It's used to identify the provided and injected `query`.
9
+ *
10
+ * @internal
11
+ */
12
+ const QUERY_KEY = 'query';
7
13
 
8
- export { LIST_ITEMS_KEY };
14
+ export { LIST_ITEMS_KEY, QUERY_KEY };
9
15
  //# sourceMappingURL=injection.consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"injection.consts.js","sources":["../../../../src/components/decorators/injection.consts.ts"],"sourcesContent":["import { ListItem } from '../../utils/types';\nimport { XInjectKey } from './injection.decorators';\n\n/**\n * It's used to identify the provided and injected `items`.\n *\n * @internal\n */\nexport const LIST_ITEMS_KEY: XInjectKey<ListItem[] | undefined> = 'listItems';\n"],"names":[],"mappings":"AAGA;;;;;MAKa,cAAc,GAAuC;;;;"}
1
+ {"version":3,"file":"injection.consts.js","sources":["../../../../src/components/decorators/injection.consts.ts"],"sourcesContent":["import { ListItem } from '../../utils/types';\nimport { XInjectKey } from './injection.decorators';\n\n/**\n * It's used to identify the provided and injected `items`.\n *\n * @internal\n */\nexport const LIST_ITEMS_KEY: XInjectKey<ListItem[] | undefined> = 'listItems';\n\n/**\n * It's used to identify the provided and injected `query`.\n *\n * @internal\n */\nexport const QUERY_KEY: XInjectKey<string | undefined> = 'query';\n"],"names":[],"mappings":"AAGA;;;;;MAKa,cAAc,GAAuC,YAAY;AAE9E;;;;;MAKa,SAAS,GAAmC;;;;"}
package/js/index.js CHANGED
@@ -118,7 +118,7 @@ export { default as SlidingPanel } from './components/sliding-panel.vue.js';
118
118
  export { default as SnippetCallbacks } from './components/snippet-callbacks.vue.js';
119
119
  export { XEmit, XOn } from './components/decorators/bus.decorators.js';
120
120
  export { Debounce } from './components/decorators/debounce.decorators.js';
121
- export { LIST_ITEMS_KEY } from './components/decorators/injection.consts.js';
121
+ export { LIST_ITEMS_KEY, QUERY_KEY } from './components/decorators/injection.consts.js';
122
122
  export { XInject, XProvide } from './components/decorators/injection.decorators.js';
123
123
  export { Getter, State } from './components/decorators/store.decorators.js';
124
124
  export { ItemsListInjectionMixin } from './components/items-list-injection.mixin.js';
@@ -207,7 +207,7 @@ export { default as SelectedFiltersList } from './x-modules/facets/components/li
207
207
  export { default as SlicedFilters } from './x-modules/facets/components/lists/sliced-filters.vue.js';
208
208
  export { default as SortedFilters } from './x-modules/facets/components/lists/sorted-filters.vue.js';
209
209
  export { default as ClearFilters } from './x-modules/facets/components/clear-filters.vue.js';
210
- export { isNewQuery } from './x-modules/facets/utils.js';
210
+ export { flatHierarchicalFilters, isNewQuery } from './x-modules/facets/utils.js';
211
211
  export { default as FacetsMixin } from './x-modules/facets/components/facets.mixin.js';
212
212
  export { default as ClearHistoryQueries } from './x-modules/history-queries/components/clear-history-queries.vue.js';
213
213
  export { default as HistoryQueries } from './x-modules/history-queries/components/history-queries.vue.js';
@@ -241,8 +241,9 @@ export { identifierResultsXStoreModule } from './x-modules/identifier-results/st
241
241
  export { cancelFetchAndSaveIdentifierResultsWire, clearIdentifierResultsQuery, fetchAndSaveIdentifierResultsWire, identifierResultsWiring, saveIdentifierResultsOriginWire, setIdentifierResultsExtraParams, setIdentifierResultsQuery } from './x-modules/identifier-results/wiring.js';
242
242
  export { identifierResultsXModule } from './x-modules/identifier-results/x-module.js';
243
243
  export { default as NextQueries } from './x-modules/next-queries/components/next-queries.vue.js';
244
- export { default as NextQuery } from './x-modules/next-queries/components/next-query.vue.js';
245
244
  export { default as NextQueriesList } from './x-modules/next-queries/components/next-queries-list.vue.js';
245
+ export { default as NextQuery } from './x-modules/next-queries/components/next-query.vue.js';
246
+ export { default as NextQueryPreview } from './x-modules/next-queries/components/next-query-preview.vue.js';
246
247
  export { cancelFetchAndSaveNextQueries, fetchAndSaveNextQueries } from './x-modules/next-queries/store/actions/fetch-and-save-next-queries.action.js';
247
248
  export { fetchNextQueries } from './x-modules/next-queries/store/actions/fetch-next-queries.action.js';
248
249
  export { setQueryFromLastHistoryQuery } from './x-modules/next-queries/store/actions/set-query-from-last-history-query.action.js';
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -10,11 +10,11 @@ const __vue_script__ = script;
10
10
  /* style */
11
11
  const __vue_inject_styles__ = function (inject) {
12
12
  if (!inject) return
13
- inject("data-v-8b95797a_0", { source: ".x-facets-list[data-v-8b95797a] {\n list-style-type: none;\n}", map: undefined, media: undefined });
13
+ inject("data-v-7e46f769_0", { source: ".x-facets-list[data-v-7e46f769] {\n list-style-type: none;\n}", map: undefined, media: undefined });
14
14
 
15
15
  };
16
16
  /* scoped */
17
- const __vue_scope_id__ = "data-v-8b95797a";
17
+ const __vue_scope_id__ = "data-v-7e46f769";
18
18
  /* module identifier */
19
19
  const __vue_module_identifier__ = undefined;
20
20
  /* functional template */
@@ -1 +1 @@
1
- {"version":3,"file":"facets-provider.vue.js","sources":["../../../../../../src/x-modules/facets/components/facets/facets-provider.vue"],"sourcesContent":["<script lang=\"ts\">\n import { Facet, Filter } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop, Watch } from 'vue-property-decorator';\n import { XOn } from '../../../../components';\n import { xComponentMixin } from '../../../../components/x-component.mixin';\n import { areFiltersDifferent } from '../../../../utils/filters';\n import { FacetsGroup } from '../../service/types';\n import { GroupId } from '../../store/types';\n import { facetsXModule } from '../../x-module';\n\n /**\n * This component allows to provide facets by prop, to add them to the state of the\n * `Facets X-Module`. These facets will be added to the `Facets X-Module` state together with\n * the facets emitted by the `Search X-Module` through the {@link SearchXEvents.FacetsChanged}\n * event.\n *\n * @public\n */\n @Component({\n mixins: [xComponentMixin(facetsXModule)]\n })\n export default class FacetsProvider extends Vue {\n /**\n * An facet group identifier to distinguish the provided facets from other facets like the\n * `Search X-Module` facets.\n *\n * @public\n */\n @Prop({ default: 'provided-facets' })\n public groupId!: GroupId;\n\n /**\n * The facets to provide to the `Facets X-Module` state. They have to include the\n * {@link @empathyco/x-types#Filter | filters}.\n *\n * @internal\n */\n @Prop({ required: true })\n public facets!: Facet[];\n\n /**\n * Temporarily stores the selected filters from the {@link FacetsProvider.facets} prop.\n * This is necessary to handle the {@link FacetsXEvents.UserChangedSelectedFilters} event.\n *\n * @internal\n */\n protected selectedFilters: Filter[] | null = null;\n\n /**\n * A computed property to group the facets and the groupId. This is used by the watcher.\n *\n * @returns The FacetGroup with the facets and the group id.\n *\n * @internal\n */\n protected get facetsGroup(): FacetsGroup {\n return { id: this.groupId, facets: this.facets };\n }\n\n /**\n * Emits the {@link FacetsXEvents.UserChangedSelectedFilters} event when the user changes\n * the selected filters.\n *\n * @param selectedFilters - The new list of selected filters.\n * @internal\n */\n @XOn('SelectedFiltersChanged')\n emitSelectedFiltersChanged(selectedFilters: Filter[]): void {\n if (\n this.selectedFilters === null ||\n areFiltersDifferent(this.selectedFilters, selectedFilters)\n ) {\n this.$x.emit('UserChangedSelectedFilters', selectedFilters);\n }\n this.selectedFilters = null;\n }\n\n /**\n * Emits the {@link FacetsXEvents.FacetsGroupProvided} event with the\n * {@link FacetsProvider.facetsGroup} as payload. It also extracts and saves the selected\n * filters.\n */\n @Watch('facetsGroup', { immediate: true })\n provideFacets(): void {\n if (this.facetsGroup.facets) {\n this.$x.emit('FacetsGroupProvided', this.facetsGroup);\n this.extractSelectedFilters(this.facets);\n }\n }\n\n /**\n * Extracts the selected filters from the facets and stores them in the\n * {@link FacetsProvider.selectedFilters} property.\n *\n * @param facets - The facets from whom extract the selected filters.\n * @internal\n */\n protected extractSelectedFilters(facets: Facet[]): void {\n this.selectedFilters = facets\n .flatMap(facet => facet.filters)\n .filter(filter => filter.selected);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n render(): void {}\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-facets-list {\n list-style-type: none;\n }\n</style>\n\n<docs lang=\"mdx\">\n## Example\n\nThis component allows to provide facets by prop, to add them to the state of the `Facets X-Module`.\nThese facets will be added to the `Facets X-Module` state together with the facets emitted by the\n`Search X-Module` through the {@link SearchXEvents.FacetsChanged} event.\n\n```vue\n<template>\n <FacetsProvider :facets=\"myFacets\" />\n</template>\n\n<script>\n import { FacetsProvider } from '@empathyco/x-components/facets';\n\n export default {\n components: {\n FacetsProvider\n },\n data() {\n return {\n myFacets: [\n {\n modelName: 'SimpleFacet',\n id: 'color-facet',\n label: 'Color',\n filters: [\n {\n modelName: 'SimpleFilter',\n id: 'color:red',\n facetId: 'color-facet',\n label: 'Red',\n selected: false,\n value: 'color:red',\n totalResults: 10\n },\n {\n modelName: 'SimpleFilter',\n id: 'color:blue',\n facetId: 'color-facet',\n label: 'Blue',\n selected: false,\n value: 'color:blue',\n totalResults: 10\n }\n ]\n }\n ]\n };\n }\n };\n</script>\n```\n\n## Events\n\nA list of events that the component will emit:\n\n- `UserChangedSelectedFilters`: the event is emitted after the user performed an action that changed\n the selected filters. The payload is the new list of selected filters.\n- `FacetsGroupProvided`: the event is emitted after updating the facets prop with a new list of\n facets. The payload contains a Facets Group with the facets and the group id.\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"facets-provider.vue.js","sources":["../../../../../../src/x-modules/facets/components/facets/facets-provider.vue"],"sourcesContent":["<script lang=\"ts\">\n import { Facet, Filter, isHierarchicalFacet } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop, Watch } from 'vue-property-decorator';\n import { XOn } from '../../../../components';\n import { xComponentMixin } from '../../../../components/x-component.mixin';\n import { clone } from '../../../../utils';\n import { areFiltersDifferent } from '../../../../utils/filters';\n import { FacetsGroup } from '../../service/types';\n import { GroupId } from '../../store/types';\n import { flatHierarchicalFilters } from '../../utils';\n import { facetsXModule } from '../../x-module';\n\n /**\n * This component allows to provide facets by prop, to add them to the state of the\n * `Facets X-Module`. These facets will be added to the `Facets X-Module` state together with\n * the facets emitted by the `Search X-Module` through the {@link SearchXEvents.FacetsChanged}\n * event.\n *\n * @public\n */\n @Component({\n mixins: [xComponentMixin(facetsXModule)]\n })\n export default class FacetsProvider extends Vue {\n /**\n * An facet group identifier to distinguish the provided facets from other facets like the\n * `Search X-Module` facets.\n *\n * @public\n */\n @Prop({ default: 'provided-facets' })\n public groupId!: GroupId;\n\n /**\n * The facets to provide to the `Facets X-Module` state. They have to include the\n * {@link @empathyco/x-types#Filter | filters}.\n *\n * @internal\n */\n @Prop({ required: true })\n public facets!: Facet[];\n\n /**\n * Temporarily stores the selected filters from the {@link FacetsProvider.facets} prop.\n * This is necessary to handle the {@link FacetsXEvents.UserChangedSelectedFilters} event.\n *\n * @internal\n */\n protected selectedFilters: Filter[] | null = null;\n\n /**\n * A computed property to group the facets and the groupId. This is used by the watcher.\n *\n * @returns The FacetGroup with the facets and the group id.\n *\n * @internal\n */\n protected get facetsGroup(): FacetsGroup {\n return { id: this.groupId, facets: this.facets };\n }\n\n /**\n * Emits the {@link FacetsXEvents.UserChangedSelectedFilters} event when the user changes\n * the selected filters.\n *\n * @param selectedFilters - The new list of selected filters.\n * @internal\n */\n @XOn('SelectedFiltersChanged')\n emitSelectedFiltersChanged(selectedFilters: Filter[]): void {\n if (\n this.selectedFilters === null ||\n areFiltersDifferent(this.selectedFilters, selectedFilters)\n ) {\n this.$x.emit('UserChangedSelectedFilters', selectedFilters);\n }\n this.selectedFilters = null;\n }\n\n /**\n * Emits the {@link FacetsXEvents.FacetsGroupProvided} event with the\n * {@link FacetsProvider.facetsGroup} as payload. It also extracts and saves the selected\n * filters.\n */\n @Watch('facetsGroup', { immediate: true })\n provideFacets(): void {\n if (this.facetsGroup.facets) {\n const facetsGroupClone = clone(this.facetsGroup);\n this.$x.emit('FacetsGroupProvided', facetsGroupClone);\n this.extractSelectedFilters(this.facets);\n }\n }\n\n /**\n * Extracts the selected filters from the facets and stores them in the\n * {@link FacetsProvider.selectedFilters} property.\n *\n * @param facets - The facets from whom extract the selected filters.\n * @internal\n */\n protected extractSelectedFilters(facets: Facet[]): void {\n this.selectedFilters = facets\n .flatMap(facet =>\n isHierarchicalFacet(facet) ? flatHierarchicalFilters(facet.filters) : facet.filters\n )\n .filter(filter => filter.selected);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n render(): void {}\n }\n</script>\n\n<style lang=\"scss\" scoped>\n .x-facets-list {\n list-style-type: none;\n }\n</style>\n\n<docs lang=\"mdx\">\n## Example\n\nThis component allows to provide facets by prop, to add them to the state of the `Facets X-Module`.\nThese facets will be added to the `Facets X-Module` state together with the facets emitted by the\n`Search X-Module` through the {@link SearchXEvents.FacetsChanged} event.\n\n```vue\n<template>\n <FacetsProvider :facets=\"myFacets\" />\n</template>\n\n<script>\n import { FacetsProvider } from '@empathyco/x-components/facets';\n\n export default {\n components: {\n FacetsProvider\n },\n data() {\n return {\n myFacets: [\n {\n modelName: 'SimpleFacet',\n id: 'color-facet',\n label: 'Color',\n filters: [\n {\n modelName: 'SimpleFilter',\n id: 'color:red',\n facetId: 'color-facet',\n label: 'Red',\n selected: false,\n value: 'color:red',\n totalResults: 10\n },\n {\n modelName: 'SimpleFilter',\n id: 'color:blue',\n facetId: 'color-facet',\n label: 'Blue',\n selected: false,\n value: 'color:blue',\n totalResults: 10\n }\n ]\n }\n ]\n };\n }\n };\n</script>\n```\n\n## Events\n\nA list of events that the component will emit:\n\n- `UserChangedSelectedFilters`: the event is emitted after the user performed an action that changed\n the selected filters. The payload is the new list of selected filters.\n- `FacetsGroupProvided`: the event is emitted after updating the facets prop with a new list of\n facets. The payload contains a Facets Group with the facets and the group id.\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}