@empathyco/x-components 3.0.0-alpha.80 → 3.0.0-alpha.83

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 (49) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/design-system/base.css +13 -13
  3. package/design-system/default-theme.css +80 -80
  4. package/docs/API-reference/api/x-components.md +0 -1
  5. package/docs/API-reference/api/x-components.xmoduleoptions.md +1 -1
  6. package/docs/API-reference/api/x-components.xstoremoduleoptions.md +1 -1
  7. package/docs/API-reference/components/history-queries/x-components.clear-history-queries.md +29 -4
  8. package/docs/API-reference/components/history-queries/x-components.history-queries.md +51 -23
  9. package/docs/API-reference/components/history-queries/x-components.history-query.md +67 -17
  10. package/docs/API-reference/components/next-queries/x-components.next-queries-list.md +2 -2
  11. package/docs/API-reference/components/next-queries/x-components.next-queries.md +107 -26
  12. package/docs/API-reference/components/next-queries/x-components.next-query.md +57 -9
  13. package/docs/API-reference/components/popular-searches/x-components.popular-search.md +54 -11
  14. package/docs/API-reference/components/popular-searches/x-components.popular-searches.md +87 -23
  15. package/docs/API-reference/components/query-suggestions/x-components.query-suggestion.md +6 -6
  16. package/docs/API-reference/components/query-suggestions/x-components.query-suggestions.md +15 -14
  17. package/docs/API-reference/components/related-tags/x-components.related-tag.md +14 -20
  18. package/docs/API-reference/components/related-tags/x-components.related-tags.md +25 -23
  19. package/docs/API-reference/components/search-box/x-components.clear-search-input.md +26 -21
  20. package/docs/API-reference/components/search-box/x-components.search-button.md +39 -17
  21. package/docs/API-reference/components/search-box/x-components.search-input.md +18 -18
  22. package/js/x-installer/x-installer/x-installer.js.map +1 -1
  23. package/js/x-modules/history-queries/components/clear-history-queries.vue.js.map +1 -1
  24. package/js/x-modules/history-queries/components/history-queries.vue.js.map +1 -1
  25. package/js/x-modules/history-queries/components/history-query.vue.js.map +1 -1
  26. package/js/x-modules/next-queries/components/next-queries-list.vue.js.map +1 -1
  27. package/js/x-modules/next-queries/components/next-queries.vue.js.map +1 -1
  28. package/js/x-modules/next-queries/components/next-query.vue.js.map +1 -1
  29. package/js/x-modules/popular-searches/components/popular-search.vue.js.map +1 -1
  30. package/js/x-modules/popular-searches/components/popular-searches.vue.js.map +1 -1
  31. package/js/x-modules/query-suggestions/components/query-suggestion.vue.js.map +1 -1
  32. package/js/x-modules/query-suggestions/components/query-suggestions.vue.js.map +1 -1
  33. package/js/x-modules/related-tags/components/related-tag.vue.js +2 -2
  34. package/js/x-modules/related-tags/components/related-tag.vue.js.map +1 -1
  35. package/js/x-modules/related-tags/components/related-tags.vue.js +2 -2
  36. package/js/x-modules/related-tags/components/related-tags.vue.js.map +1 -1
  37. package/js/x-modules/search-box/components/clear-search-input.vue.js.map +1 -1
  38. package/js/x-modules/search-box/components/search-button.vue.js.map +1 -1
  39. package/js/x-modules/search-box/components/search-input.vue.js +2 -2
  40. package/js/x-modules/search-box/components/search-input.vue.js.map +1 -1
  41. package/package.json +5 -5
  42. package/report/x-components.api.json +5 -70
  43. package/report/x-components.api.md +6 -11
  44. package/types/plugins/x-plugin.types.d.ts +2 -1
  45. package/types/plugins/x-plugin.types.d.ts.map +1 -1
  46. package/types/utils/types.d.ts +1 -10
  47. package/types/utils/types.d.ts.map +1 -1
  48. package/types/x-installer/x-installer/x-installer.d.ts.map +1 -1
  49. package/docs/API-reference/api/x-components.deeppartial.md +0 -17
@@ -37,13 +37,13 @@ To use this component, the QuerySignals microservice must be implemented.
37
37
 
38
38
  This example shows how related tags can be rendered without any additional effects.
39
39
 
40
- _Search for a toy and press enter._
40
+ _Search for a fashion term like "sandal" or "lipstick"._
41
41
 
42
- ```vue
42
+ ```vue live
43
43
  <template>
44
44
  <div>
45
- <SearchInput></SearchInput>
46
- <RelatedTags></RelatedTags>
45
+ <SearchInput />
46
+ <RelatedTags />
47
47
  </div>
48
48
  </template>
49
49
 
@@ -66,16 +66,13 @@ export default {
66
66
  In this example, the number of related tags rendered has been limited to 3. A fade and slide effect
67
67
  has been added so that the related tags appear with a delay, then slide upwards and fade.
68
68
 
69
- _Search for a toy and press Enter to see the related tags with the animation effect._
69
+ _Search for a fashion term and see the related tags with the animation effect._
70
70
 
71
- ```vue
71
+ ```vue live
72
72
  <template>
73
73
  <div>
74
- <SearchInput></SearchInput>
75
- <RelatedTags
76
- animation="StaggeredFadeAndSlide"
77
- :maxItemsToRender="3"
78
- ></RelatedTags>
74
+ <SearchInput />
75
+ <RelatedTags :animation="'StaggeredFadeAndSlide'" :maxItemsToRender="3" />
79
76
  </div>
80
77
  </template>
81
78
 
@@ -85,6 +82,7 @@ import { SearchInput } from "@empathyco/x-components/search-box";
85
82
  import { RelatedTags } from "@empathyco/x-components/related-tags";
86
83
  import { StaggeredFadeAndSlide } from "@empathyco/x-components";
87
84
 
85
+ // Registering the animation as a global component
88
86
  Vue.component("StaggeredFadeAndSlide", StaggeredFadeAndSlide);
89
87
  export default {
90
88
  name: "RelatedTagsDemo",
@@ -101,14 +99,14 @@ export default {
101
99
  In this example, the [`RelatedTag`](./x-components.related-tag.md) component is passed in the
102
100
  `related-tag` slot (although any other component could potentially be passed).
103
101
 
104
- _Search for a toy and see how the related tags can be rendered._
102
+ _Search for a fashion term and see how the related tags can be rendered._
105
103
 
106
- ```vue
104
+ ```vue live
107
105
  <template>
108
106
  <div>
109
- <SearchInput></SearchInput>
107
+ <SearchInput />
110
108
  <RelatedTags #related-tag="{ relatedTag }">
111
- <RelatedTag :relatedTag="relatedTag"></RelatedTag>
109
+ <RelatedTag :relatedTag="relatedTag" />
112
110
  </RelatedTags>
113
111
  </div>
114
112
  </template>
@@ -134,12 +132,12 @@ To continue the previous example, the [`RelatedTag`](./x-components.related-tag.
134
132
  passed in the `related-tag-content` slot, but in addition, an HTML span tag for the text are also
135
133
  passed.
136
134
 
137
- _Search for a toy and see how the related tags are rendered._
135
+ _Search for a fashion term and see how the related tags are rendered._
138
136
 
139
- ```vue
137
+ ```vue live
140
138
  <template>
141
139
  <div>
142
- <SearchInput></SearchInput>
140
+ <SearchInput />
143
141
  <RelatedTags #related-tag-content="{ relatedTag }">
144
142
  <span>{{ relatedTag.tag }}</span>
145
143
  </RelatedTags>
@@ -165,14 +163,18 @@ export default {
165
163
  Components can be combined and communicate with each other. The `RelatedTags` component can
166
164
  communicate with the [`SearchInput`](../search-box/x-components.search-input.md) as follows:
167
165
 
168
- _Search for a toy and see how the related tags can be rendered._
166
+ _Search for a fashion term and see how the related tags can be rendered._
169
167
 
170
- ```vue
168
+ ```vue live
171
169
  <template>
172
170
  <div>
173
- <SearchInput></SearchInput>
174
- <RelatedTags></RelatedTags>
175
- <ResultsList></ResultsList>
171
+ <SearchInput />
172
+ <RelatedTags />
173
+ <ResultsList #result="{ item }">
174
+ <span class="result">
175
+ {{ item.name }}
176
+ </span>
177
+ </ResultsList>
176
178
  </div>
177
179
  </template>
178
180
 
@@ -32,10 +32,12 @@ Here a basic example of how the clear button is rendered.
32
32
 
33
33
  _Type any term in the input field and then click the Clear button to try it out!_
34
34
 
35
- ```vue
35
+ ```vue live
36
36
  <template>
37
- <SearchInput />
38
- <ClearSearchInput />
37
+ <div style="display: flex;">
38
+ <SearchInput />
39
+ <ClearSearchInput />
40
+ </div>
39
41
  </template>
40
42
 
41
43
  <script>
@@ -61,7 +63,7 @@ customize the button content.
61
63
 
62
64
  _Click the icon button to try it out!_
63
65
 
64
- ```vue
66
+ ```vue live
65
67
  <template>
66
68
  <ClearSearchInput>Clear</ClearSearchInput>
67
69
  </template>
@@ -85,13 +87,14 @@ In this example, the `UserPressedClearSearchBoxButton` event is implemented, tri
85
87
 
86
88
  _Click the Clear button to try it out!_
87
89
 
88
- ```vue
90
+ ```vue live
89
91
  <template>
90
- <ClearSearchInput
91
- @UserPressedClearSearchBoxButton="logUserPressedClearSearchBoxButton"
92
- >
93
- Clear
94
- </ClearSearchInput>
92
+ <div>
93
+ <ClearSearchInput @UserPressedClearSearchBoxButton="message = 'clear'"
94
+ >Clear</ClearSearchInput
95
+ >
96
+ {{ message }}
97
+ </div>
95
98
  </template>
96
99
 
97
100
  <script>
@@ -102,10 +105,10 @@ export default {
102
105
  components: {
103
106
  ClearSearchInput
104
107
  },
105
- methods: {
106
- logUserPressedClearSearchBoxButton() {
107
- console.log("User pressed clear search box button");
108
- }
108
+ data() {
109
+ return {
110
+ message: ""
111
+ };
109
112
  }
110
113
  };
111
114
  </script>
@@ -119,23 +122,25 @@ entered.
119
122
 
120
123
  _Type any term in the input field and then click the icon button to try it out!_
121
124
 
122
- ```vue
125
+ ```vue live
123
126
  <template>
124
- <SearchInput />
125
- <ClearSearchInput />
127
+ <div style="display: flex;">
128
+ <SearchInput />
129
+ <ClearSearchInput />
130
+ </div>
126
131
  </template>
127
132
 
128
133
  <script>
129
134
  import {
130
- ClearSearchInput,
131
- SearchInput
135
+ SearchInput,
136
+ ClearSearchInput
132
137
  } from "@empathyco/x-components/search-box";
133
138
 
134
139
  export default {
135
140
  name: "ClearSearchInputDemo",
136
141
  components: {
137
- ClearSearchInput,
138
- SearchInput
142
+ SearchInput,
143
+ ClearSearchInput
139
144
  }
140
145
  };
141
146
  </script>
@@ -42,7 +42,7 @@ In this example, a clickable button is rendered.
42
42
 
43
43
  _Click the Search button to try it out!_
44
44
 
45
- ```vue
45
+ ```vue live
46
46
  <template>
47
47
  <SearchButton />
48
48
  </template>
@@ -61,11 +61,11 @@ export default {
61
61
 
62
62
  ### Play with default slot
63
63
 
64
- Here an icon is passed in the default slot instead of text to customize the button content.
64
+ Here text is passed in the default slot instead of an icon to customize the button content.
65
65
 
66
66
  _Click the icon button to try it out!_
67
67
 
68
- ```vue
68
+ ```vue live
69
69
  <template>
70
70
  <SearchButton>Search</SearchButton>
71
71
  </template>
@@ -89,24 +89,36 @@ search term and click the Search button, the search term is displayed as a messa
89
89
 
90
90
  _Type any term in the input field and then click the Search button to try it out!_
91
91
 
92
- ```vue
92
+ ```vue live
93
93
  <template>
94
- <SearchButton
95
- @UserPressedSearchButton="
96
- query => {
97
- message = query;
98
- }
99
- "
100
- />
94
+ <div>
95
+ <div style="display: flex;">
96
+ <SearchInput />
97
+ <SearchButton
98
+ @UserPressedSearchButton="
99
+ query => {
100
+ message = query;
101
+ }
102
+ "
103
+ />
104
+ </div>
105
+ {{ message }}
106
+ </div>
101
107
  </template>
102
108
 
103
109
  <script>
104
- import { SearchButton } from "@empathyco/x-components/search-box";
110
+ import { SearchInput, SearchButton } from "@empathyco/x-components/search-box";
105
111
 
106
112
  export default {
107
113
  name: "SearchButtonDemo",
108
114
  components: {
115
+ SearchInput,
109
116
  SearchButton
117
+ },
118
+ data() {
119
+ return {
120
+ message: ""
121
+ };
110
122
  }
111
123
  };
112
124
  </script>
@@ -120,12 +132,17 @@ you enter a search term and click the Search button, the “Looking for results
120
132
 
121
133
  _Type any term in the input field and then click the Search button to try it out!_
122
134
 
123
- ```vue
135
+ ```vue live
124
136
  <template>
125
- <SearchInput />
126
- <SearchButton @UserAcceptedAQuery="message = 'looking for results'"
127
- >Search</SearchButton
128
- >
137
+ <div>
138
+ <div style="display: flex;">
139
+ <SearchInput />
140
+ <SearchButton @UserAcceptedAQuery="message = 'looking for results'"
141
+ >Search</SearchButton
142
+ >
143
+ </div>
144
+ {{ message }}
145
+ </div>
129
146
  </template>
130
147
 
131
148
  <script>
@@ -136,6 +153,11 @@ export default {
136
153
  components: {
137
154
  SearchButton,
138
155
  SearchInput
156
+ },
157
+ data() {
158
+ return {
159
+ message: ""
160
+ };
139
161
  }
140
162
  };
141
163
  </script>
@@ -44,7 +44,7 @@ Here you have a basic example of how the search input is rendered.
44
44
 
45
45
  _Type any term in the input field to try it out!_
46
46
 
47
- ```vue
47
+ ```vue live
48
48
  <template>
49
49
  <SearchInput />
50
50
  </template>
@@ -69,7 +69,7 @@ after 1000 milliseconds without typing.
69
69
 
70
70
  _Type a term with more than 5 characters to try it out!_
71
71
 
72
- ```vue
72
+ ```vue live
73
73
  <template>
74
74
  <SearchInput
75
75
  :maxLength="5"
@@ -100,14 +100,18 @@ the message “enter” appears.
100
100
 
101
101
  _Type any term in the input field to try it out!_
102
102
 
103
- ```vue
103
+ ```vue live
104
104
  <template>
105
- <SearchInput
106
- @UserPressedEnterKey="logUserPressedEnter"
107
- @UserFocusedSearchBox="hasFocus = true"
108
- @UserBlurredSearchBox="hasFocus = false"
109
- @UserIsTypingAQuery="value = 'focus'"
110
- />
105
+ <div>
106
+ <SearchInput
107
+ @UserPressedEnterKey="value = 'enter'"
108
+ @UserFocusedSearchBox="hasFocus = true"
109
+ @UserBlurredSearchBox="hasFocus = false"
110
+ @UserIsTypingAQuery="value = 'typing'"
111
+ />
112
+ <strong>{{ value }}</strong>
113
+ <span>{{ hasFocus ? "focused" : "unfocused" }}</span>
114
+ </div>
111
115
  </template>
112
116
 
113
117
  <script>
@@ -123,11 +127,6 @@ export default {
123
127
  value: "",
124
128
  hasFocus: false
125
129
  };
126
- },
127
- methods: {
128
- logUserPressedEnter() {
129
- console.log("User pressed enter");
130
- }
131
130
  }
132
131
  };
133
132
  </script>
@@ -141,9 +140,10 @@ communicates with the [`SearchButton`](x-components.search-button.md) and the
141
140
  Furthermore, you can use it together with the [`QuerySuggestions`](query-suggestions.md) component
142
141
  to autocomplete the typed search term.
143
142
 
144
- _Type “puzzle” or another toy in the input field and then click the clear icon to try it out!_
143
+ _Type “trousers” or another fashion term in the input field and then click the clear icon to try it
144
+ out!_
145
145
 
146
- ```vue
146
+ ```vue live
147
147
  <template>
148
148
  <div>
149
149
  <div style="display: flex; flex-flow: row nowrap;">
@@ -161,7 +161,7 @@ _Type “puzzle” or another toy in the input field and then click the clear ic
161
161
  import {
162
162
  SearchInput,
163
163
  ClearSearchInput,
164
- ClearSearchButton
164
+ SearchButton
165
165
  } from "@empathyco/x-components/search-box";
166
166
  import { QuerySuggestions } from "@empathyco/x-components/query-suggestions";
167
167
 
@@ -170,7 +170,7 @@ export default {
170
170
  components: {
171
171
  SearchInput,
172
172
  ClearSearchInput,
173
- ClearSearchButton,
173
+ SearchButton,
174
174
  QuerySuggestions
175
175
  }
176
176
  };
@@ -1 +1 @@
1
- {"version":3,"file":"x-installer.js","sources":["../../../../src/x-installer/x-installer/x-installer.ts"],"sourcesContent":["import { EmpathyAdapterConfig } from '@empathyco/x-adapter';\nimport { deepMerge } from '@empathyco/x-deep-merge';\nimport { cleanUndefined, forEach } from '@empathyco/x-utils';\nimport Vue, { PluginObject, VueConstructor } from 'vue';\nimport { BaseXBus } from '../../plugins/x-bus';\nimport { XBus } from '../../plugins/x-bus.types';\nimport { XPlugin } from '../../plugins/x-plugin';\nimport { XPluginOptions } from '../../plugins/x-plugin.types';\nimport { DeepPartial } from '../../utils/types';\nimport { SnippetConfig, XAPI } from '../api/api.types';\nimport { BaseXAPI } from '../api/base-api';\nimport { InitWrapper, InstallXOptions, VueConstructorPartialArgument } from './types';\n\ndeclare global {\n interface Window {\n X?: XAPI;\n initX?: (() => SnippetConfig) | SnippetConfig;\n }\n}\n\nconst defaultAdapterConfig: DeepPartial<EmpathyAdapterConfig> = {\n env: 'live',\n requestParams: {\n lang: 'es',\n scope: 'default'\n }\n};\n\n/**\n * The purpose of this class is to offer a quick way to initialize the XComponents in a setup\n * project. It allows to receive all the options in {@link InstallXOptions} which is an extension\n * of {@link XPluginOptions} with all the options for the plugin and some options more.\n *\n * This class does multiple things:\n * 1. Install the {@link XPlugin} with the {@link XPluginOptions}.\n * 2. Creates the public {@link XAPI} and add it to global window.\n * 3. Creates the Vue Application for the customer project.\n *\n * The steps 2 & 3 are optional and depends on the options passed in {@link InstallXOptions}.\n *\n * @example The way to use this class is the next:\n * 1. Create the installer passing in the {@link InstallXOptions}. This only save the options:\n *\n * ```\n * const installer = new XInstaller(installXOptions)\n * ```\n *\n * 2. Initialize passing the {@link SnippetConfig}. This installs the plugin and creates the App.\n * There are 3 different ways to do this:\n *\n * 2.1 Using the created installer:\n *\n * ```\n * installer.init(snippetConfig)\n * ```\n *\n * 2.2 If the API option is enabled (`createAPI` is `true` in {@link InstallXOptions}, or\n * is not present as the default value is `true`) then this init step can be done with\n * the Public API:\n *\n * ```\n * window.X.init(snippetConfig)\n * ```\n *\n * 2.3 When the script of the project build is loaded it searches for a global `initX`\n * variable that the customer must have in their web site. This variable can be a\n * function that returns the {@link SnippetConfig} or an object that contains the\n * {@link SnippetConfig} itself:\n *\n * ```\n * window.initX = function() {\n * return {\n * instance,\n * env,\n * scope,\n * lang,\n * searchLang,\n * currency,\n * consent,\n * documentDirection\n * };\n * };\n * ```\n *\n * ```\n * window.initX = {\n * instance,\n * env,\n * scope,\n * lang,\n * searchLang,\n * currency,\n * consent,\n * documentDirection\n * };\n * ```\n *\n * @public\n */\nexport class XInstaller {\n private api?: XAPI;\n\n /**\n * The configuration coming from the snippet {@link SnippetConfig}.\n *\n * @internal\n */\n protected snippetConfig!: SnippetConfig;\n\n /**\n * Receives the {@link InstallXOptions} and merges it with the default fallback options. Also\n * creates the public {@link XAPI}.\n *\n * @remarks Auto initializes the Vue application if window.initX is defined as a function or\n * object specifying the {@link SnippetConfig | snippet config}.\n *\n *\n * @param options - The {@link InstallXOptions}.\n *\n * @public\n */\n public constructor(protected readonly options: InstallXOptions) {\n this.createAPI();\n }\n\n /**\n * Creates the public {@link XAPI} using the `api` option from {@link InstallXOptions}. If this\n * `api` option is not passed, then a default {@link BaseXAPI} is created. To disable the API\n * creation the value `false` must be passed in the `api` option.\n *\n * @internal\n */\n protected createAPI(): void {\n const { api } = this.options;\n if (api !== false) {\n this.api = api ?? new BaseXAPI();\n this.api.setInitCallback(this.init.bind(this));\n this.api.setSnippetConfigCallback(this.updateSnippetConfig.bind(this));\n window.X = this.api;\n }\n }\n\n /**\n * Retrieves the {@link SnippetConfig | snippet config} it is defined in the window.initX.\n *\n * @returns The snippet config if it is defined or undefined otherwise.\n *\n * @internal\n */\n private retrieveSnippetConfig(): SnippetConfig | undefined {\n if (typeof window.initX === 'function') {\n return window.initX();\n } else if (typeof window.initX === 'object') {\n return window.initX;\n }\n }\n\n /**\n * Receives the {@link SnippetConfig | snippet config} or retrieves it from window.initX and\n * installs the plugin and initializes the Vue application.\n *\n * @param snippetConfig - The {@link SnippetConfig} that receives from snippet integration.\n *\n * @returns If {@link SnippetConfig | snippet config} is passed or configured in window.initX,\n * returns an object with the {@link XAPI}, the {@link XBus}, the {@link XPlugin} and the Vue App\n * used in the application. Else, a rejected promise is returned.\n *\n * @public\n */\n init(snippetConfig: SnippetConfig): Promise<InitWrapper>;\n init(): Promise<InitWrapper | void>;\n async init(snippetConfig = this.retrieveSnippetConfig()): Promise<InitWrapper | void> {\n if (snippetConfig) {\n const adapterConfig = this.getAdapterConfig(snippetConfig);\n this.applyConfigToAdapter(adapterConfig);\n const bus = this.createBus();\n const pluginOptions = this.getPluginOptions();\n const plugin = this.installPlugin(pluginOptions, bus);\n const extraPlugins = await this.installExtraPlugins(snippetConfig, bus);\n const app = this.createApp(extraPlugins, snippetConfig);\n this.api?.setBus(bus);\n\n return {\n api: this.api,\n app,\n bus,\n plugin\n };\n }\n\n return Promise.resolve();\n }\n\n /**\n * Creates the Adapter Config object using the {@link SnippetConfig} to do it. It also\n * merges the default configuration.\n *\n * @param options - The {@link SnippetConfig}.\n *\n * @returns The Adapter Config object.\n *\n * @internal\n */\n protected getAdapterConfig({ instance, env, lang, searchLang, scope }: SnippetConfig): unknown {\n return deepMerge(\n defaultAdapterConfig,\n cleanUndefined<DeepPartial<EmpathyAdapterConfig>>({\n instance,\n env,\n requestParams: {\n lang: searchLang ?? lang,\n scope\n }\n })\n );\n }\n\n /**\n * Creates the {@link XPluginOptions} object.\n *\n * @returns The {@link XPluginOptions} object.\n *\n * @internal\n */\n protected getPluginOptions(): XPluginOptions {\n const { adapter, store, initialXModules, xModules, __PRIVATE__xModules } = this.options;\n return {\n adapter,\n store,\n xModules,\n initialXModules,\n __PRIVATE__xModules\n };\n }\n\n /**\n * It applies the snippet configuration to the Adapter. Not all the parameters are for the Adapter\n * but they appear destructured to not include them in the `extraParams` parameter.\n *\n * @param adapterConfig - The Adapter config object.\n *\n * @internal\n */\n protected applyConfigToAdapter(adapterConfig: any): void {\n this.options.adapter.setConfig?.(adapterConfig);\n }\n\n /**\n * This method returns the bus instance to be used in the {@link XPlugin} and in the {@link XAPI}.\n * It returns the `bus` parameter in the {@link InstallXOptions} or if not provided, then\n * creates a new instance of {@link BaseXBus}.\n *\n * @returns XBus - The bus instance.\n *\n * @internal\n */\n protected createBus(): XBus {\n return this.options.bus ?? new BaseXBus();\n }\n\n /**\n * This method returns the VueConstructor to use to create the App instance.\n * It returns the `vue` parameter in the {@link InstallXOptions} or if not provided, then\n * returns the default Vue.\n *\n * @remarks The purpose of this option is mainly the testing. In a test we can use this option\n * to pass the local vue instance created by `createLocalVue` method.\n *\n * @returns VueConstructor - The vue constructor to create the App instance.\n *\n * @internal\n */\n protected getVue(): VueConstructor {\n return this.options.vue ?? Vue;\n }\n\n /**\n * Creates and install the Vue Plugin. If `plugin` parameter is passed in the\n * {@link InstallXOptions}, then it is used. If not, then a new instance of {@link XPlugin} is\n * created and installed.\n *\n * @param pluginOptions - The {@link XPluginOptions} to passed as parameter to the install method\n * of the plugin.\n * @param bus - The {@link XBus} to be used to create the XPlugin.\n *\n * @returns PluginObject<XPluginOption> - The plugin instance.\n * @internal\n */\n protected installPlugin(pluginOptions: XPluginOptions, bus: XBus): PluginObject<XPluginOptions> {\n const plugin = this.options.plugin ?? new XPlugin(bus);\n const vue = this.getVue();\n vue.use(plugin, pluginOptions);\n return plugin;\n }\n\n /**\n * Install more plugins to Vue defined by the user.\n *\n * @param snippet - The snippet configuration.\n * @param bus - The events bus used in the application.\n * @returns The arguments from the plugins installation to be used in Vue's constructor.\n * @internal\n */\n protected installExtraPlugins(\n snippet: SnippetConfig,\n bus: XBus\n ): Promise<VueConstructorPartialArgument> {\n const vue = this.getVue();\n return Promise.resolve(this.options.installExtraPlugins?.({ vue, snippet, bus }));\n }\n\n /**\n * In the case that the `app` parameter is present in the {@link InstallXOptions}, then a new Vue\n * application is created using that app.\n *\n * @param extraPlugins - Vue plugins initialisation data.\n * @param snippetConfig - Configuration from the client snippet.\n * @returns The Created Vue application or undefined if not created.\n *\n * @internal\n */\n protected createApp(\n extraPlugins: VueConstructorPartialArgument,\n snippetConfig: SnippetConfig\n ): Vue | undefined {\n if (this.options.app !== undefined) {\n const vue = this.getVue();\n this.snippetConfig = vue.observable(snippetConfig);\n return new vue({\n ...extraPlugins,\n ...this.options.vueOptions,\n provide() {\n return {\n snippetConfig\n };\n },\n store: this.options.store,\n el: this.getMountingTarget(this.options.domElement),\n render: h => h(this.options.app)\n });\n }\n }\n\n /**\n * It returns the HTML element to mount the Vue Application. If the `domElement` parameter in the\n * {@link InstallXOptions} is an Element or a string, then it is used. If it is\n * not present then a new <div> Element is created and append to the body to be used.\n *\n * @param elementOrSelector - String or Element used to mount the Vue App.\n *\n * @returns The Element to use as mounting point for the Vue App.\n * @internal\n */\n protected getMountingTarget(elementOrSelector?: string | Element): Element {\n if (typeof elementOrSelector === 'string') {\n const target = document.querySelector(elementOrSelector);\n if (!target) {\n throw Error(\n `XComponents app couldn't be mounted: Element \"${elementOrSelector}\" couldn't be found`\n );\n }\n return target;\n } else if (elementOrSelector !== undefined) {\n return elementOrSelector;\n } else {\n return document.body.appendChild(document.createElement('div'));\n }\n }\n\n /**\n * It updates all the provided properties from the current snippet config.\n *\n * @param snippetConfig - All the properties to be updated in the {@link SnippetConfig}.\n *\n * @internal\n */\n protected updateSnippetConfig(snippetConfig: Partial<SnippetConfig>): void {\n forEach(snippetConfig, (name, value) => {\n this.getVue().set(this.snippetConfig, name, value);\n });\n }\n}\n"],"names":[],"mappings":";;;;;;;AAoBA,MAAM,oBAAoB,GAAsC;IAC9D,GAAG,EAAE,MAAM;IACX,aAAa,EAAE;QACb,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,SAAS;KACjB;CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuEa,UAAU;;;;;;;;;;;;;IAsBrB,YAAsC,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;QAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;KAClB;;;;;;;;IASS,SAAS;QACjB,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,GAAG,KAAK,KAAK,EAAE;YACjB,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/C,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC;SACrB;KACF;;;;;;;;IASO,qBAAqB;QAC3B,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,UAAU,EAAE;YACtC,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC;SACvB;aAAM,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE;YAC3C,OAAO,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;IAgBD,MAAM,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,EAAE;QACrD,IAAI,aAAa,EAAE;YACjB,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;YAC3D,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;YACxD,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAEtB,OAAO;gBACL,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,GAAG;gBACH,GAAG;gBACH,MAAM;aACP,CAAC;SACH;QAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;KAC1B;;;;;;;;;;;IAYS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAiB;QAClF,OAAO,SAAS,CACd,oBAAoB,EACpB,cAAc,CAAoC;YAChD,QAAQ;YACR,GAAG;YACH,aAAa,EAAE;gBACb,IAAI,EAAE,UAAU,IAAI,IAAI;gBACxB,KAAK;aACN;SACF,CAAC,CACH,CAAC;KACH;;;;;;;;IASS,gBAAgB;QACxB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QACxF,OAAO;YACL,OAAO;YACP,KAAK;YACL,QAAQ;YACR,eAAe;YACf,mBAAmB;SACpB,CAAC;KACH;;;;;;;;;IAUS,oBAAoB,CAAC,aAAkB;QAC/C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,GAAG,aAAa,CAAC,CAAC;KACjD;;;;;;;;;;IAWS,SAAS;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC;KAC3C;;;;;;;;;;;;;IAcS,MAAM;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC;KAChC;;;;;;;;;;;;;IAcS,aAAa,CAAC,aAA6B,EAAE,GAAS;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC;KACf;;;;;;;;;IAUS,mBAAmB,CAC3B,OAAsB,EACtB,GAAS;QAET,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;KACnF;;;;;;;;;;;IAYS,SAAS,CACjB,YAA2C,EAC3C,aAA4B;QAE5B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YACnD,OAAO,IAAI,GAAG,CAAC;gBACb,GAAG,YAAY;gBACf,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU;gBAC1B,OAAO;oBACL,OAAO;wBACL,aAAa;qBACd,CAAC;iBACH;gBACD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;gBACzB,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;gBACnD,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;aACjC,CAAC,CAAC;SACJ;KACF;;;;;;;;;;;IAYS,iBAAiB,CAAC,iBAAoC;QAC9D,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE;YACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,EAAE;gBACX,MAAM,KAAK,CACT,iDAAiD,iBAAiB,qBAAqB,CACxF,CAAC;aACH;YACD,OAAO,MAAM,CAAC;SACf;aAAM,IAAI,iBAAiB,KAAK,SAAS,EAAE;YAC1C,OAAO,iBAAiB,CAAC;SAC1B;aAAM;YACL,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;SACjE;KACF;;;;;;;;IASS,mBAAmB,CAAC,aAAqC;QACjE,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,KAAK;YACjC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;SACpD,CAAC,CAAC;KACJ;;;;;"}
1
+ {"version":3,"file":"x-installer.js","sources":["../../../../src/x-installer/x-installer/x-installer.ts"],"sourcesContent":["import { EmpathyAdapterConfig } from '@empathyco/x-adapter';\nimport { deepMerge } from '@empathyco/x-deep-merge';\nimport { cleanUndefined, DeepPartial, forEach } from '@empathyco/x-utils';\nimport Vue, { PluginObject, VueConstructor } from 'vue';\nimport { BaseXBus } from '../../plugins/x-bus';\nimport { XBus } from '../../plugins/x-bus.types';\nimport { XPlugin } from '../../plugins/x-plugin';\nimport { XPluginOptions } from '../../plugins/x-plugin.types';\nimport { SnippetConfig, XAPI } from '../api/api.types';\nimport { BaseXAPI } from '../api/base-api';\nimport { InitWrapper, InstallXOptions, VueConstructorPartialArgument } from './types';\n\ndeclare global {\n interface Window {\n X?: XAPI;\n initX?: (() => SnippetConfig) | SnippetConfig;\n }\n}\n\nconst defaultAdapterConfig: DeepPartial<EmpathyAdapterConfig> = {\n env: 'live',\n requestParams: {\n lang: 'es',\n scope: 'default'\n }\n};\n\n/**\n * The purpose of this class is to offer a quick way to initialize the XComponents in a setup\n * project. It allows to receive all the options in {@link InstallXOptions} which is an extension\n * of {@link XPluginOptions} with all the options for the plugin and some options more.\n *\n * This class does multiple things:\n * 1. Install the {@link XPlugin} with the {@link XPluginOptions}.\n * 2. Creates the public {@link XAPI} and add it to global window.\n * 3. Creates the Vue Application for the customer project.\n *\n * The steps 2 & 3 are optional and depends on the options passed in {@link InstallXOptions}.\n *\n * @example The way to use this class is the next:\n * 1. Create the installer passing in the {@link InstallXOptions}. This only save the options:\n *\n * ```\n * const installer = new XInstaller(installXOptions)\n * ```\n *\n * 2. Initialize passing the {@link SnippetConfig}. This installs the plugin and creates the App.\n * There are 3 different ways to do this:\n *\n * 2.1 Using the created installer:\n *\n * ```\n * installer.init(snippetConfig)\n * ```\n *\n * 2.2 If the API option is enabled (`createAPI` is `true` in {@link InstallXOptions}, or\n * is not present as the default value is `true`) then this init step can be done with\n * the Public API:\n *\n * ```\n * window.X.init(snippetConfig)\n * ```\n *\n * 2.3 When the script of the project build is loaded it searches for a global `initX`\n * variable that the customer must have in their web site. This variable can be a\n * function that returns the {@link SnippetConfig} or an object that contains the\n * {@link SnippetConfig} itself:\n *\n * ```\n * window.initX = function() {\n * return {\n * instance,\n * env,\n * scope,\n * lang,\n * searchLang,\n * currency,\n * consent,\n * documentDirection\n * };\n * };\n * ```\n *\n * ```\n * window.initX = {\n * instance,\n * env,\n * scope,\n * lang,\n * searchLang,\n * currency,\n * consent,\n * documentDirection\n * };\n * ```\n *\n * @public\n */\nexport class XInstaller {\n private api?: XAPI;\n\n /**\n * The configuration coming from the snippet {@link SnippetConfig}.\n *\n * @internal\n */\n protected snippetConfig!: SnippetConfig;\n\n /**\n * Receives the {@link InstallXOptions} and merges it with the default fallback options. Also\n * creates the public {@link XAPI}.\n *\n * @remarks Auto initializes the Vue application if window.initX is defined as a function or\n * object specifying the {@link SnippetConfig | snippet config}.\n *\n *\n * @param options - The {@link InstallXOptions}.\n *\n * @public\n */\n public constructor(protected readonly options: InstallXOptions) {\n this.createAPI();\n }\n\n /**\n * Creates the public {@link XAPI} using the `api` option from {@link InstallXOptions}. If this\n * `api` option is not passed, then a default {@link BaseXAPI} is created. To disable the API\n * creation the value `false` must be passed in the `api` option.\n *\n * @internal\n */\n protected createAPI(): void {\n const { api } = this.options;\n if (api !== false) {\n this.api = api ?? new BaseXAPI();\n this.api.setInitCallback(this.init.bind(this));\n this.api.setSnippetConfigCallback(this.updateSnippetConfig.bind(this));\n window.X = this.api;\n }\n }\n\n /**\n * Retrieves the {@link SnippetConfig | snippet config} it is defined in the window.initX.\n *\n * @returns The snippet config if it is defined or undefined otherwise.\n *\n * @internal\n */\n private retrieveSnippetConfig(): SnippetConfig | undefined {\n if (typeof window.initX === 'function') {\n return window.initX();\n } else if (typeof window.initX === 'object') {\n return window.initX;\n }\n }\n\n /**\n * Receives the {@link SnippetConfig | snippet config} or retrieves it from window.initX and\n * installs the plugin and initializes the Vue application.\n *\n * @param snippetConfig - The {@link SnippetConfig} that receives from snippet integration.\n *\n * @returns If {@link SnippetConfig | snippet config} is passed or configured in window.initX,\n * returns an object with the {@link XAPI}, the {@link XBus}, the {@link XPlugin} and the Vue App\n * used in the application. Else, a rejected promise is returned.\n *\n * @public\n */\n init(snippetConfig: SnippetConfig): Promise<InitWrapper>;\n init(): Promise<InitWrapper | void>;\n async init(snippetConfig = this.retrieveSnippetConfig()): Promise<InitWrapper | void> {\n if (snippetConfig) {\n const adapterConfig = this.getAdapterConfig(snippetConfig);\n this.applyConfigToAdapter(adapterConfig);\n const bus = this.createBus();\n const pluginOptions = this.getPluginOptions();\n const plugin = this.installPlugin(pluginOptions, bus);\n const extraPlugins = await this.installExtraPlugins(snippetConfig, bus);\n const app = this.createApp(extraPlugins, snippetConfig);\n this.api?.setBus(bus);\n\n return {\n api: this.api,\n app,\n bus,\n plugin\n };\n }\n\n return Promise.resolve();\n }\n\n /**\n * Creates the Adapter Config object using the {@link SnippetConfig} to do it. It also\n * merges the default configuration.\n *\n * @param options - The {@link SnippetConfig}.\n *\n * @returns The Adapter Config object.\n *\n * @internal\n */\n protected getAdapterConfig({ instance, env, lang, searchLang, scope }: SnippetConfig): unknown {\n return deepMerge(\n defaultAdapterConfig,\n cleanUndefined<DeepPartial<EmpathyAdapterConfig>>({\n instance,\n env,\n requestParams: {\n lang: searchLang ?? lang,\n scope\n }\n })\n );\n }\n\n /**\n * Creates the {@link XPluginOptions} object.\n *\n * @returns The {@link XPluginOptions} object.\n *\n * @internal\n */\n protected getPluginOptions(): XPluginOptions {\n const { adapter, store, initialXModules, xModules, __PRIVATE__xModules } = this.options;\n return {\n adapter,\n store,\n xModules,\n initialXModules,\n __PRIVATE__xModules\n };\n }\n\n /**\n * It applies the snippet configuration to the Adapter. Not all the parameters are for the Adapter\n * but they appear destructured to not include them in the `extraParams` parameter.\n *\n * @param adapterConfig - The Adapter config object.\n *\n * @internal\n */\n protected applyConfigToAdapter(adapterConfig: any): void {\n this.options.adapter.setConfig?.(adapterConfig);\n }\n\n /**\n * This method returns the bus instance to be used in the {@link XPlugin} and in the {@link XAPI}.\n * It returns the `bus` parameter in the {@link InstallXOptions} or if not provided, then\n * creates a new instance of {@link BaseXBus}.\n *\n * @returns XBus - The bus instance.\n *\n * @internal\n */\n protected createBus(): XBus {\n return this.options.bus ?? new BaseXBus();\n }\n\n /**\n * This method returns the VueConstructor to use to create the App instance.\n * It returns the `vue` parameter in the {@link InstallXOptions} or if not provided, then\n * returns the default Vue.\n *\n * @remarks The purpose of this option is mainly the testing. In a test we can use this option\n * to pass the local vue instance created by `createLocalVue` method.\n *\n * @returns VueConstructor - The vue constructor to create the App instance.\n *\n * @internal\n */\n protected getVue(): VueConstructor {\n return this.options.vue ?? Vue;\n }\n\n /**\n * Creates and install the Vue Plugin. If `plugin` parameter is passed in the\n * {@link InstallXOptions}, then it is used. If not, then a new instance of {@link XPlugin} is\n * created and installed.\n *\n * @param pluginOptions - The {@link XPluginOptions} to passed as parameter to the install method\n * of the plugin.\n * @param bus - The {@link XBus} to be used to create the XPlugin.\n *\n * @returns PluginObject<XPluginOption> - The plugin instance.\n * @internal\n */\n protected installPlugin(pluginOptions: XPluginOptions, bus: XBus): PluginObject<XPluginOptions> {\n const plugin = this.options.plugin ?? new XPlugin(bus);\n const vue = this.getVue();\n vue.use(plugin, pluginOptions);\n return plugin;\n }\n\n /**\n * Install more plugins to Vue defined by the user.\n *\n * @param snippet - The snippet configuration.\n * @param bus - The events bus used in the application.\n * @returns The arguments from the plugins installation to be used in Vue's constructor.\n * @internal\n */\n protected installExtraPlugins(\n snippet: SnippetConfig,\n bus: XBus\n ): Promise<VueConstructorPartialArgument> {\n const vue = this.getVue();\n return Promise.resolve(this.options.installExtraPlugins?.({ vue, snippet, bus }));\n }\n\n /**\n * In the case that the `app` parameter is present in the {@link InstallXOptions}, then a new Vue\n * application is created using that app.\n *\n * @param extraPlugins - Vue plugins initialisation data.\n * @param snippetConfig - Configuration from the client snippet.\n * @returns The Created Vue application or undefined if not created.\n *\n * @internal\n */\n protected createApp(\n extraPlugins: VueConstructorPartialArgument,\n snippetConfig: SnippetConfig\n ): Vue | undefined {\n if (this.options.app !== undefined) {\n const vue = this.getVue();\n this.snippetConfig = vue.observable(snippetConfig);\n return new vue({\n ...extraPlugins,\n ...this.options.vueOptions,\n provide() {\n return {\n snippetConfig\n };\n },\n store: this.options.store,\n el: this.getMountingTarget(this.options.domElement),\n render: h => h(this.options.app)\n });\n }\n }\n\n /**\n * It returns the HTML element to mount the Vue Application. If the `domElement` parameter in the\n * {@link InstallXOptions} is an Element or a string, then it is used. If it is\n * not present then a new <div> Element is created and append to the body to be used.\n *\n * @param elementOrSelector - String or Element used to mount the Vue App.\n *\n * @returns The Element to use as mounting point for the Vue App.\n * @internal\n */\n protected getMountingTarget(elementOrSelector?: string | Element): Element {\n if (typeof elementOrSelector === 'string') {\n const target = document.querySelector(elementOrSelector);\n if (!target) {\n throw Error(\n `XComponents app couldn't be mounted: Element \"${elementOrSelector}\" couldn't be found`\n );\n }\n return target;\n } else if (elementOrSelector !== undefined) {\n return elementOrSelector;\n } else {\n return document.body.appendChild(document.createElement('div'));\n }\n }\n\n /**\n * It updates all the provided properties from the current snippet config.\n *\n * @param snippetConfig - All the properties to be updated in the {@link SnippetConfig}.\n *\n * @internal\n */\n protected updateSnippetConfig(snippetConfig: Partial<SnippetConfig>): void {\n forEach(snippetConfig, (name, value) => {\n this.getVue().set(this.snippetConfig, name, value);\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clear-history-queries.vue.js","sources":["../../../../../src/x-modules/history-queries/components/clear-history-queries.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-button x-clear-history-queries\"\n :class=\"dynamicClasses\"\n :disabled=\"isHistoryQueriesEmpty\"\n :events=\"clearHistoryQueriesEvents\"\n data-test=\"clear-history-queries\"\n >\n <!-- @slot (Required) Button content with a message, an icon or both -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component } from 'vue-property-decorator';\n import { State } from '../../../components/decorators/store.decorators';\n import BaseEventButton from '../../../components/base-event-button.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { VueCSSClasses } from '../../../utils/types';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { historyQueriesXModule } from '../x-module';\n\n /**\n * A button that when is pressed, emits the\n * {@link HistoryQueriesXEvents.UserPressedClearHistoryQueries} event, expressing the user\n * intention to clear the whole history of queries.\n *\n * @public\n */\n @Component({\n components: { BaseEventButton },\n mixins: [xComponentMixin(historyQueriesXModule)]\n })\n export default class ClearHistoryQueries extends Vue {\n /**\n * The whole history queries.\n *\n * @internal\n */\n @State('historyQueries', 'historyQueries')\n public historyQueries!: HistoryQuery[];\n\n /**\n * Returns if the array of history queries is empty.\n *\n * @returns `true` if the {@link historyQueries} array is empty, `false` otherwise.\n * @internal\n */\n protected get isHistoryQueriesEmpty(): boolean {\n return this.historyQueries.length === 0;\n }\n\n /**\n * Dynamic CSS classes to add to the root element of this component.\n *\n * @returns A booleans dictionary where each key is the class name to add, and the boolean value\n * tells if it should be added or not.\n * @internal\n */\n protected get dynamicClasses(): VueCSSClasses {\n return {\n 'x-clear-history-queries--is-empty': this.isHistoryQueriesEmpty\n };\n }\n\n /**\n * The list of events that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n protected clearHistoryQueriesEvents: Partial<XEventsTypes> = {\n UserPressedClearHistoryQueries: undefined\n };\n }\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\n### Basic example\n\nThe component exposes a single default slot, where you can add icons or text.\n\n```vue\n<ClearHistoryQueries>\n <img class=\"x-history-query__icon\" src=\"./my-icon.svg\"/>\n</ClearHistoryQueries>\n```\n\n## Events\n\nA list of events that the component will emit:\n\n- `UserPressedClearHistoryQueries`: the event is emitted after the user clicks the button.\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"clear-history-queries.vue.js","sources":["../../../../../src/x-modules/history-queries/components/clear-history-queries.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-button x-clear-history-queries\"\n :class=\"dynamicClasses\"\n :disabled=\"isHistoryQueriesEmpty\"\n :events=\"clearHistoryQueriesEvents\"\n data-test=\"clear-history-queries\"\n >\n <!-- @slot (Required) Button content with a message, an icon or both -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component } from 'vue-property-decorator';\n import { State } from '../../../components/decorators/store.decorators';\n import BaseEventButton from '../../../components/base-event-button.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { VueCSSClasses } from '../../../utils/types';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { historyQueriesXModule } from '../x-module';\n\n /**\n * A button that when is pressed, emits the\n * {@link HistoryQueriesXEvents.UserPressedClearHistoryQueries} event, expressing the user\n * intention to clear the whole history of queries.\n *\n * @public\n */\n @Component({\n components: { BaseEventButton },\n mixins: [xComponentMixin(historyQueriesXModule)]\n })\n export default class ClearHistoryQueries extends Vue {\n /**\n * The whole history queries.\n *\n * @internal\n */\n @State('historyQueries', 'historyQueries')\n public historyQueries!: HistoryQuery[];\n\n /**\n * Returns if the array of history queries is empty.\n *\n * @returns `true` if the {@link historyQueries} array is empty, `false` otherwise.\n * @internal\n */\n protected get isHistoryQueriesEmpty(): boolean {\n return this.historyQueries.length === 0;\n }\n\n /**\n * Dynamic CSS classes to add to the root element of this component.\n *\n * @returns A booleans dictionary where each key is the class name to add, and the boolean value\n * tells if it should be added or not.\n * @internal\n */\n protected get dynamicClasses(): VueCSSClasses {\n return {\n 'x-clear-history-queries--is-empty': this.isHistoryQueriesEmpty\n };\n }\n\n /**\n * The list of events that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n protected clearHistoryQueriesEvents: Partial<XEventsTypes> = {\n UserPressedClearHistoryQueries: undefined\n };\n }\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\n### Basic example\n\nThe component exposes a single default slot, where you can add icons or text.\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <ClearHistoryQueries>Clear history queries</ClearHistoryQueries>\n <HistoryQueries :animation=\"'FadeAndSlide'\" :maxItemsToRender=\"10\" />\n </div>\n</template>\n\n<script>\n import Vue from 'vue';\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries, ClearHistoryQueries } from '@empathyco/x-components/history-queries';\n import { FadeAndSlide } from '@empathyco/x-components';\n\n // Registering the animation as a global component\n Vue.component('FadeAndSlide', FadeAndSlide);\n export default {\n name: 'ClearHistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries,\n ClearHistoryQueries\n }\n };\n</script>\n```\n\n## Events\n\nA list of events that the component will emit:\n\n- `UserPressedClearHistoryQueries`: the event is emitted after the user clicks the button.\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"history-queries.vue.js","sources":["../../../../../src/x-modules/history-queries/components/history-queries.vue"],"sourcesContent":["<template>\n <BaseSuggestions\n :suggestions=\"historyQueries\"\n class=\"x-history-queries\"\n data-test=\"history-queries\"\n :animation=\"animation\"\n :maxItemsToRender=\"maxItemsToRender\"\n >\n <template #default=\"{ suggestion, index }\">\n <!--\n @slot History Query item\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {number} index - History Query suggestion index\n -->\n <slot name=\"suggestion\" v-bind=\"{ suggestion, index }\">\n <HistoryQuery\n :suggestion=\"suggestion\"\n data-test=\"history-query-item\"\n class=\"x-history-queries__item\"\n >\n <template #default=\"{ queryHTML }\">\n <!-- eslint-disable max-len -->\n <!--\n @slot History Query content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {string} queryHTML - Suggestion's query with the matching part inside a span tag\n @binding {number} index - History Query suggestion index\n -->\n <!-- eslint-enable max-len -->\n <slot name=\"suggestion-content\" v-bind=\"{ suggestion, index, queryHTML }\" />\n </template>\n <template #remove-button-content>\n <!--\n @slot History Query remove button content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {number} index - History Query suggestion index\n -->\n <slot name=\"suggestion-remove-content\" v-bind=\"{ suggestion, index }\" />\n </template>\n </HistoryQuery>\n </slot>\n </template>\n </BaseSuggestions>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery as HistoryQueryModel } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import BaseSuggestions from '../../../components/suggestions/base-suggestions.vue';\n import { Getter } from '../../../components/decorators/store.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { historyQueriesXModule } from '../x-module';\n import HistoryQuery from './history-query.vue';\n\n /**\n * This component renders a list of suggestions coming from the user queries history.\n *\n * @remarks\n *\n * Allows the user to select one of them, emitting the needed events.\n * A history query is just another type of suggestion that contains a query that the user has\n * made in the past.\n *\n * @public\n */\n @Component({\n components: { BaseSuggestions, HistoryQuery },\n mixins: [xComponentMixin(historyQueriesXModule)]\n })\n export default class HistoryQueries extends Vue {\n /**\n * Animation component that will be used to animate the suggestions.\n *\n * @public\n */\n @Prop()\n protected animation!: Vue;\n\n /**\n * Maximum number of history queries to show. It should be a lower number than the\n * {@link HistoryQueriesConfig.maxItemsToStore}. If it is not provided, it will show\n * all the stored `HistoryQueries`.\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * The filtered list of history queries.\n *\n * @internal\n */\n @Getter('historyQueries', 'historyQueries')\n public historyQueries!: HistoryQueryModel[];\n }\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component doesn't emit events.\n\n## See it in action\n\nHere you have a basic example of how the HistoryQueries is rendered.\n\n```vue\n<template>\n <HistoryQueries />\n</template>\n\n<script>\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with props\n\nIn this example, the history queries have been limited to render a maximum of 10 queries (by default\nit is 5).\n\n```vue\n<template>\n <HistoryQueries :maxItemsToRender=\"10\" />\n</template>\n\n<script>\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with the animation\n\n```vue\n<template>\n <HistoryQueries :animation=\"fadeAndSlide\" />\n</template>\n\n<script>\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n import { FadeAndSlide } from '@empathyco/x-components';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries\n },\n data() {\n return {\n fadeAndSlide: FadeAndSlide\n };\n }\n };\n</script>\n```\n\n### Play with suggestion slot\n\nIn this example, the [`HistoryQuery`](./x-components.history-query.md) component is passed in the\n`suggestion` slot (although any other component could potentially be passed).\n\n```vue\n<template>\n <HistoryQueries #suggestion=\"{ suggestion }\">\n <HistoryQuery :suggestion=\"suggestion\"></HistoryQuery>\n </HistoryQueries>\n</template>\n\n<script>\n import { HistoryQueries, HistoryQuery } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries,\n HistoryQuery\n }\n };\n</script>\n```\n\n### Play with suggestion-content slot\n\nTo continue the previous example, the [`HistoryQuery`](./x-components.history-query.md) component is\npassed in the `suggestion-content` slot, but in addition, an HTML span tag for the text are also\npassed.\n\n```vue\n<template>\n <HistoryQueries #suggestion-content=\"{ suggestion }\">\n <span>{{ suggestion.query }}</span>\n </HistoryQueries>\n</template>\n\n<script>\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with suggestion-content-remove slot\n\nTo continue the previous example, the [`HistoryQuery`](./x-components.history-query.md) component is\npassed in the `suggestion-content` slot, but in addition, a cross icon is also passed to change the\nicon to remove the history query.\n\n```vue\n<template>\n <HistoryQueries #suggestion-content-remove=\"{ suggestion }\">\n <CrossIcon />\n </HistoryQueries>\n</template>\n\n<script>\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n import { CrossIcon } from '@empathyco/x-components';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n HistoryQueries,\n CrossIcon\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"history-queries.vue.js","sources":["../../../../../src/x-modules/history-queries/components/history-queries.vue"],"sourcesContent":["<template>\n <BaseSuggestions\n :suggestions=\"historyQueries\"\n class=\"x-history-queries\"\n data-test=\"history-queries\"\n :animation=\"animation\"\n :maxItemsToRender=\"maxItemsToRender\"\n >\n <template #default=\"{ suggestion, index }\">\n <!--\n @slot History Query item\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {number} index - History Query suggestion index\n -->\n <slot name=\"suggestion\" v-bind=\"{ suggestion, index }\">\n <HistoryQuery\n :suggestion=\"suggestion\"\n data-test=\"history-query-item\"\n class=\"x-history-queries__item\"\n >\n <template #default=\"{ queryHTML }\">\n <!-- eslint-disable max-len -->\n <!--\n @slot History Query content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {string} queryHTML - Suggestion's query with the matching part inside a span tag\n @binding {number} index - History Query suggestion index\n -->\n <!-- eslint-enable max-len -->\n <slot name=\"suggestion-content\" v-bind=\"{ suggestion, index, queryHTML }\" />\n </template>\n <template #remove-button-content>\n <!--\n @slot History Query remove button content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {number} index - History Query suggestion index\n -->\n <slot name=\"suggestion-remove-content\" v-bind=\"{ suggestion, index }\" />\n </template>\n </HistoryQuery>\n </slot>\n </template>\n </BaseSuggestions>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery as HistoryQueryModel } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import BaseSuggestions from '../../../components/suggestions/base-suggestions.vue';\n import { Getter } from '../../../components/decorators/store.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { historyQueriesXModule } from '../x-module';\n import HistoryQuery from './history-query.vue';\n\n /**\n * This component renders a list of suggestions coming from the user queries history.\n *\n * @remarks\n *\n * Allows the user to select one of them, emitting the needed events.\n * A history query is just another type of suggestion that contains a query that the user has\n * made in the past.\n *\n * @public\n */\n @Component({\n components: { BaseSuggestions, HistoryQuery },\n mixins: [xComponentMixin(historyQueriesXModule)]\n })\n export default class HistoryQueries extends Vue {\n /**\n * Animation component that will be used to animate the suggestions.\n *\n * @public\n */\n @Prop()\n protected animation!: Vue;\n\n /**\n * Maximum number of history queries to show. It should be a lower number than the\n * {@link HistoryQueriesConfig.maxItemsToStore}. If it is not provided, it will show\n * all the stored `HistoryQueries`.\n */\n @Prop()\n protected maxItemsToRender?: number;\n\n /**\n * The filtered list of history queries.\n *\n * @internal\n */\n @Getter('historyQueries', 'historyQueries')\n public historyQueries!: HistoryQueryModel[];\n }\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component doesn't emit events.\n\n## See it in action\n\nHere you have a basic example of how the HistoryQueries is rendered.\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries />\n </div>\n</template>\n\n<script>\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with props\n\nIn this example, the history queries have been limited to render a maximum of 10 queries (by default\nit is 5).\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries :maxItemsToRender=\"10\" />\n </div>\n</template>\n\n<script>\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with the animation\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries :animation=\"'FadeAndSlide'\" />\n </div>\n</template>\n\n<script>\n import Vue from 'vue';\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n import { FadeAndSlide } from '@empathyco/x-components';\n\n // Registering the animation as a global component\n Vue.component('FadeAndSlide', FadeAndSlide);\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with suggestion slot\n\nIn this example, the [`HistoryQuery`](./x-components.history-query.md) component is passed in the\n`suggestion` slot (although any other component could potentially be passed).\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries #suggestion=\"{ suggestion }\">\n <HistoryQuery :suggestion=\"suggestion\" />\n </HistoryQueries>\n </div>\n</template>\n\n<script>\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries, HistoryQuery } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries,\n HistoryQuery\n }\n };\n</script>\n```\n\n### Play with suggestion-content slot\n\nTo continue the previous example, the [`HistoryQuery`](./x-components.history-query.md) component is\npassed in the `suggestion-content` slot, but in addition, an HTML span tag for the text are also\npassed.\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries #suggestion-content=\"{ suggestion }\">\n <span>{{ suggestion.query }}</span>\n </HistoryQueries>\n </div>\n</template>\n\n<script>\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries\n }\n };\n</script>\n```\n\n### Play with suggestion-content-remove slot\n\nTo continue the previous example, the [`HistoryQuery`](./x-components.history-query.md) component is\npassed in the `suggestion-content` slot, but in addition, a cross icon is also passed to change the\nicon to remove the history query.\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <HistoryQueries #suggestion-remove-content=\"{ suggestion }\">\n <CrossIcon />\n </HistoryQueries>\n </div>\n</template>\n\n<script>\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { HistoryQueries } from '@empathyco/x-components/history-queries';\n import { CrossIcon } from '@empathyco/x-components';\n\n export default {\n name: 'HistoryQueriesDemo',\n components: {\n SearchInput,\n HistoryQueries,\n CrossIcon\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"history-query.vue.js","sources":["../../../../../src/x-modules/history-queries/components/history-query.vue"],"sourcesContent":["<template>\n <div class=\"x-suggestion-group x-history-query\">\n <BaseSuggestion\n class=\"x-history-query__suggestion\"\n v-bind=\"{ suggestion, suggestionSelectedEvents, query }\"\n data-test=\"history-query\"\n feature=\"history_query\"\n >\n <template #default=\"{ suggestion, queryHTML }\">\n <!-- eslint-disable max-len -->\n <!--\n @slot History Query content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {string} queryHTML - Suggestion's query with the matching part inside a span tag\n -->\n <!-- eslint-enable max-len -->\n <slot v-bind=\"{ suggestion, queryHTML }\" />\n </template>\n </BaseSuggestion>\n <RemoveHistoryQuery\n class=\"x-history-query__remove\"\n :historyQuery=\"suggestion\"\n data-test=\"remove-history-query\"\n >\n <!--\n @slot History Query remove button content\n @binding {Suggestion} suggestion - History Query suggestion data\n -->\n <slot name=\"remove-button-content\" v-bind=\"{ suggestion }\">✕</slot>\n </RemoveHistoryQuery>\n </div>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery as HistoryQueryModel } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { Getter } from '../../../components/decorators/store.decorators';\n import BaseSuggestion from '../../../components/suggestions/base-suggestion.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { historyQueriesXModule } from '../x-module';\n import RemoveHistoryQuery from './remove-history-query.vue';\n\n /**\n * This component renders a history query suggestion combining two buttons: one for selecting this\n * suggestion as the search query, and another one to remove this query suggestion from the\n * history queries.\n *\n * @public\n */\n @Component({\n mixins: [xComponentMixin(historyQueriesXModule)],\n components: { RemoveHistoryQuery, BaseSuggestion }\n })\n export default class HistoryQuery extends Vue {\n /**\n * The history query suggestion to render.\n *\n * @public\n */\n @Prop({ required: true })\n protected suggestion!: HistoryQueryModel;\n\n /**\n * The normalized query of the history-queries module.\n *\n * @internal\n */\n @Getter('historyQueries', 'normalizedQuery')\n public query!: string;\n\n /**\n * The list of events that are going to be emitted when the suggestion button is pressed.\n *\n * @internal\n * @returns The {@link XEvent | XEvents} to emit.\n */\n protected get suggestionSelectedEvents(): Partial<XEventsTypes> {\n return {\n UserSelectedAHistoryQuery: this.suggestion\n };\n }\n }\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\n### Basic usage\n\nThis component only requires a prop called `suggestion`\n\n```vue\n<HistoryQuery :suggestion=\"historyQuery\" />\n```\n\n### Customizing slots content\n\nSuggestion and remove buttons contents can be customized.\n\nThe default slot allows you to replace the content of the suggestion button. It has two properties,\nthe suggestion itself, and a `string` of HTML with the matched query.\n\nThe other slot is called `remove-button-content`, and allows you to set the content of the button\nthat serves to remove this query from the history. This slot only has one property, the suggestion.\n\n````vue\n<HistoryQuery :suggestion=\"historyQuery\">\n <template #default=\"{ suggestion, queryHTML }\">\n <img class=\"x-history-query__history-icon\" src=\"./history-icon.svg\"/>\n <span class=\"x-history-query__matching-part\" v-html=\"queryHTML\"/>\n </template>\n\n <template #remove-button-content=\"{ suggestion }\">\n <img class=\"x-history-query__remove-icon\" src=\"./remove-icon.svg\"/>\n </template>\n</HistoryQuery>\n``` ## Events A list of events that the component will emit: - `UserSelectedAHistoryQuery`: the\nevent is emitted after the user clicks the button. The event payload is the history query data.\n````\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"history-query.vue.js","sources":["../../../../../src/x-modules/history-queries/components/history-query.vue"],"sourcesContent":["<template>\n <div class=\"x-suggestion-group x-history-query\">\n <BaseSuggestion\n class=\"x-history-query__suggestion\"\n v-bind=\"{ suggestion, suggestionSelectedEvents, query }\"\n data-test=\"history-query\"\n feature=\"history_query\"\n >\n <template #default=\"{ suggestion, queryHTML }\">\n <!-- eslint-disable max-len -->\n <!--\n @slot History Query content\n @binding {Suggestion} suggestion - History Query suggestion data\n @binding {string} queryHTML - Suggestion's query with the matching part inside a span tag\n -->\n <!-- eslint-enable max-len -->\n <slot v-bind=\"{ suggestion, queryHTML }\" />\n </template>\n </BaseSuggestion>\n <RemoveHistoryQuery\n class=\"x-history-query__remove\"\n :historyQuery=\"suggestion\"\n data-test=\"remove-history-query\"\n >\n <!--\n @slot History Query remove button content\n @binding {Suggestion} suggestion - History Query suggestion data\n -->\n <slot name=\"remove-button-content\" v-bind=\"{ suggestion }\">✕</slot>\n </RemoveHistoryQuery>\n </div>\n</template>\n\n<script lang=\"ts\">\n import { HistoryQuery as HistoryQueryModel } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { Getter } from '../../../components/decorators/store.decorators';\n import BaseSuggestion from '../../../components/suggestions/base-suggestion.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { historyQueriesXModule } from '../x-module';\n import RemoveHistoryQuery from './remove-history-query.vue';\n\n /**\n * This component renders a history query suggestion combining two buttons: one for selecting this\n * suggestion as the search query, and another one to remove this query suggestion from the\n * history queries.\n *\n * @public\n */\n @Component({\n mixins: [xComponentMixin(historyQueriesXModule)],\n components: { RemoveHistoryQuery, BaseSuggestion }\n })\n export default class HistoryQuery extends Vue {\n /**\n * The history query suggestion to render.\n *\n * @public\n */\n @Prop({ required: true })\n protected suggestion!: HistoryQueryModel;\n\n /**\n * The normalized query of the history-queries module.\n *\n * @internal\n */\n @Getter('historyQueries', 'normalizedQuery')\n public query!: string;\n\n /**\n * The list of events that are going to be emitted when the suggestion button is pressed.\n *\n * @internal\n * @returns The {@link XEvent | XEvents} to emit.\n */\n protected get suggestionSelectedEvents(): Partial<XEventsTypes> {\n return {\n UserSelectedAHistoryQuery: this.suggestion\n };\n }\n }\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\n### Basic usage\n\nThis component only requires a prop called `suggestion`\n\n```vue live\n<template>\n <HistoryQuery :suggestion=\"suggestion\" />\n</template>\n\n<script>\n import { HistoryQuery } from '@empathyco/x-components/history-queries';\n export default {\n name: 'HistoryQueryDemo',\n components: {\n HistoryQuery\n },\n data() {\n return {\n suggestion: {\n modelName: 'HistoryQuery',\n query: 'trousers',\n facets: []\n }\n };\n }\n };\n</script>\n```\n\n### Customizing slots content\n\nSuggestion and remove buttons contents can be customized.\n\nThe default slot allows you to replace the content of the suggestion button. It has two properties,\nthe suggestion itself, and a `string` of HTML with the matched query.\n\nThe other slot is called `remove-button-content`, and allows you to set the content of the button\nthat serves to remove this query from the history. This slot only has one property, the suggestion.\n\n```vue live\n<template>\n <HistoryQuery :suggestion=\"suggestion\">\n <template #default=\"{ suggestion, queryHTML }\">\n <HistoryIcon />\n <span class=\"x-history-query__matching-part\" v-html=\"queryHTML\" />\n </template>\n\n <template #remove-button-content=\"{ suggestion }\">\n <CrossIcon />\n </template>\n </HistoryQuery>\n</template>\n\n<script>\n import { HistoryQuery } from '@empathyco/x-components/history-queries';\n import { HistoryIcon, CrossIcon } from '@empathyco/x-components';\n\n export default {\n name: 'HistoryQueryDemo',\n components: {\n HistoryQuery,\n HistoryIcon,\n CrossIcon\n },\n data() {\n return {\n suggestion: {\n modelName: 'HistoryQuery',\n query: 'trousers',\n facets: []\n }\n };\n }\n };\n</script>\n```\n\n## Events\n\nA list of events that the component will emit:\n\n- `UserSelectedAHistoryQuery`: the event is emitted after the user clicks the button. The event\n payload is the history query data.\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"next-queries-list.vue.js","sources":["../../../../../src/x-modules/next-queries/components/next-queries-list.vue"],"sourcesContent":["<template>\n <NoElement>\n <!--\n @slot Next queries list layout.\n @binding {SearchItem[]} items - Next queries groups plus the injected list items to\n render.\n @binding {Vue | string} animation - Animation to animate the elements.\n -->\n <slot v-bind=\"{ items, animation }\">\n <ItemsList :animation=\"animation\" :items=\"items\">\n <template v-for=\"(_, slotName) in $scopedSlots\" v-slot:[slotName]=\"{ item }\">\n <slot :name=\"slotName\" :item=\"item\" />\n </template>\n </ItemsList>\n </slot>\n </NoElement>\n</template>\n\n<script lang=\"ts\">\n import { NextQuery } from '@empathyco/x-types';\n import { mixins } from 'vue-class-component';\n import { Component, Prop } from 'vue-property-decorator';\n import { Getter } from '../../../components/decorators/store.decorators';\n import { NoElement } from '../../../components/no-element';\n import { ItemsListInjectionMixin } from '../../../components/items-list-injection.mixin';\n import ItemsList from '../../../components/items-list.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { groupItemsBy } from '../../../utils/array';\n import { ListItem } from '../../../utils/types';\n import ResultsList from '../../search/components/results-list.vue';\n import { NextQueriesGroup } from '../types';\n import { nextQueriesXModule } from '../x-module';\n\n /**\n * Component that inserts groups of next queries in different positions of the injected search\n * items list, based on the provided configuration.\n *\n * @public\n */\n @Component({\n components: {\n ResultsList,\n NoElement,\n ItemsList\n },\n mixins: [xComponentMixin(nextQueriesXModule)]\n })\n export default class NextQueriesList extends mixins(ItemsListInjectionMixin) {\n /**\n * Animation component that will be used to animate the next queries groups.\n *\n * @public\n */\n @Prop()\n protected animation?: Vue | string;\n\n /**\n * The first index to insert a group of next queries at.\n *\n * @public\n */\n @Prop({ default: 24 })\n public offset!: number;\n\n /**\n * The items cycle size to keep inserting next queries groups at.\n *\n * @public\n */\n @Prop({ default: 24 })\n public frequency!: number;\n\n /**\n * The maximum amount of next queries to add in a single group.\n *\n * @public\n */\n @Prop({ default: 4 })\n public maxNextQueriesPerGroup!: number;\n\n /**\n * The maximum number of groups to insert into the injected list items list.\n *\n * @public\n */\n @Prop()\n public maxGroups!: number;\n\n /**\n * The state next queries.\n *\n * @internal\n */\n @Getter('nextQueries', 'nextQueries')\n public nextQueries!: NextQuery[];\n\n /**\n * The grouped next queries based on the given config.\n *\n * @returns A list of next queries groups.\n * @internal\n */\n protected get nextQueriesGroups(): NextQueriesGroup[] {\n return Object.values(\n groupItemsBy(this.nextQueries, (_, index) =>\n Math.floor(index / this.maxNextQueriesPerGroup)\n )\n )\n .slice(0, this.maxGroups)\n .map(nextQueries => ({\n modelName: 'NextQueriesGroup' as const,\n id: nextQueries.map(nextQuery => nextQuery.query).join(','),\n nextQueries\n }));\n }\n\n /**\n * New list of {@link ListItem}s to render.\n *\n * @returns The new list of {@link ListItem}s with the next queries groups inserted.\n * @internal\n */\n public override get items(): ListItem[] {\n if (!this.injectedListItems) {\n return this.nextQueriesGroups;\n }\n\n return this.nextQueriesGroups.reduce(\n (items, nextQueriesGroup, index) => {\n const targetIndex = this.offset + this.frequency * index;\n if (targetIndex <= items.length) {\n items.splice(targetIndex, 0, nextQueriesGroup);\n }\n return items;\n },\n [...this.injectedListItems]\n );\n }\n }\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits no events.\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend microservice required\nTo use this component, the <b>QuerySignals</b> microservice must be\nimplemented.\n:::\n<!-- prettier-ignore-end -->\n\nUsually, this component is going to be used together with the `ResultsList` one. Next queries groups\nwill be inserted between the results, guiding users to discover new searches directly from the\nresults list.\n\n```vue\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList />\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n SearchInput\n }\n };\n</script>\n```\n\n### Play with the index that next queries groups are inserted at\n\nThe component allows to customise where are the next queries groups inserted. In the following\nexample, the first group of next queries will be inserted at the index `48` (`offset`), and then a\nsecond group will be inserted at index `120` because of the `frequency` prop configured to `72`.\nFinally, a third group will be inserted at index `192`. Because `maxGroups` is configured to `3`, no\nmore groups will be inserted. Each one of this groups will have up to `6` next queries\n(`maxNextQueriesPerGroup`).\n\n```vue\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList :offset=\"48\" :frequency=\"72\" :maxNextQueriesPerGroup=\"6\" :maxGroups=\"3\" />\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n SearchInput\n }\n };\n</script>\n```\n\n### Customise the layout of the component\n\nThis component will render by default the `id` of each search item, both the injected, and for the\ngroups of next queries generated, but the common case is to integrate it with another layout\ncomponent, for example the `BaseGrid`. To do so, you can use the `default` slot\n\n```vue\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList\n :offset=\"48\"\n :frequency=\"72\"\n :maxNextQueriesPerGroup=\"6\"\n :maxGroups=\"3\"\n #default=\"{ items }\"\n >\n <BaseGrid :items=\"items\" :animation=\"animation\">\n <template #next-queries-group=\"{ item }\">\n <span>NextQueriesGroup: {{ item.queries.join(', ') }}</span>\n </template>\n <template #result=\"{ item }\">\n <span>Result: {{ item.name }}</span>\n </template>\n <template #default=\"{ item }\">\n <span>Default: {{ item }}</span>\n </template>\n </BaseGrid>\n </NextQueriesList>\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { BaseGrid } from '@empathyco/x-components';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n BaseGrid,\n SearchInput\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"next-queries-list.vue.js","sources":["../../../../../src/x-modules/next-queries/components/next-queries-list.vue"],"sourcesContent":["<template>\n <NoElement>\n <!--\n @slot Next queries list layout.\n @binding {SearchItem[]} items - Next queries groups plus the injected list items to\n render.\n @binding {Vue | string} animation - Animation to animate the elements.\n -->\n <slot v-bind=\"{ items, animation }\">\n <ItemsList :animation=\"animation\" :items=\"items\">\n <template v-for=\"(_, slotName) in $scopedSlots\" v-slot:[slotName]=\"{ item }\">\n <slot :name=\"slotName\" :item=\"item\" />\n </template>\n </ItemsList>\n </slot>\n </NoElement>\n</template>\n\n<script lang=\"ts\">\n import { NextQuery } from '@empathyco/x-types';\n import { mixins } from 'vue-class-component';\n import { Component, Prop } from 'vue-property-decorator';\n import { Getter } from '../../../components/decorators/store.decorators';\n import { NoElement } from '../../../components/no-element';\n import { ItemsListInjectionMixin } from '../../../components/items-list-injection.mixin';\n import ItemsList from '../../../components/items-list.vue';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { groupItemsBy } from '../../../utils/array';\n import { ListItem } from '../../../utils/types';\n import ResultsList from '../../search/components/results-list.vue';\n import { NextQueriesGroup } from '../types';\n import { nextQueriesXModule } from '../x-module';\n\n /**\n * Component that inserts groups of next queries in different positions of the injected search\n * items list, based on the provided configuration.\n *\n * @public\n */\n @Component({\n components: {\n ResultsList,\n NoElement,\n ItemsList\n },\n mixins: [xComponentMixin(nextQueriesXModule)]\n })\n export default class NextQueriesList extends mixins(ItemsListInjectionMixin) {\n /**\n * Animation component that will be used to animate the next queries groups.\n *\n * @public\n */\n @Prop()\n protected animation?: Vue | string;\n\n /**\n * The first index to insert a group of next queries at.\n *\n * @public\n */\n @Prop({ default: 24 })\n public offset!: number;\n\n /**\n * The items cycle size to keep inserting next queries groups at.\n *\n * @public\n */\n @Prop({ default: 24 })\n public frequency!: number;\n\n /**\n * The maximum amount of next queries to add in a single group.\n *\n * @public\n */\n @Prop({ default: 4 })\n public maxNextQueriesPerGroup!: number;\n\n /**\n * The maximum number of groups to insert into the injected list items list.\n *\n * @public\n */\n @Prop()\n public maxGroups!: number;\n\n /**\n * The state next queries.\n *\n * @internal\n */\n @Getter('nextQueries', 'nextQueries')\n public nextQueries!: NextQuery[];\n\n /**\n * The grouped next queries based on the given config.\n *\n * @returns A list of next queries groups.\n * @internal\n */\n protected get nextQueriesGroups(): NextQueriesGroup[] {\n return Object.values(\n groupItemsBy(this.nextQueries, (_, index) =>\n Math.floor(index / this.maxNextQueriesPerGroup)\n )\n )\n .slice(0, this.maxGroups)\n .map(nextQueries => ({\n modelName: 'NextQueriesGroup' as const,\n id: nextQueries.map(nextQuery => nextQuery.query).join(','),\n nextQueries\n }));\n }\n\n /**\n * New list of {@link ListItem}s to render.\n *\n * @returns The new list of {@link ListItem}s with the next queries groups inserted.\n * @internal\n */\n public override get items(): ListItem[] {\n if (!this.injectedListItems) {\n return this.nextQueriesGroups;\n }\n\n return this.nextQueriesGroups.reduce(\n (items, nextQueriesGroup, index) => {\n const targetIndex = this.offset + this.frequency * index;\n if (targetIndex <= items.length) {\n items.splice(targetIndex, 0, nextQueriesGroup);\n }\n return items;\n },\n [...this.injectedListItems]\n );\n }\n }\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits no events.\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend microservice required\nTo use this component, the <b>QuerySignals</b> microservice must be\nimplemented.\n:::\n<!-- prettier-ignore-end -->\n\nUsually, this component is going to be used together with the `ResultsList` one. Next queries groups\nwill be inserted between the results, guiding users to discover new searches directly from the\nresults list.\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList />\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n SearchInput\n }\n };\n</script>\n```\n\n### Play with the index that next queries groups are inserted at\n\nThe component allows to customise where are the next queries groups inserted. In the following\nexample, the first group of next queries will be inserted at the index `48` (`offset`), and then a\nsecond group will be inserted at index `120` because of the `frequency` prop configured to `72`.\nFinally, a third group will be inserted at index `192`. Because `maxGroups` is configured to `3`, no\nmore groups will be inserted. Each one of this groups will have up to `6` next queries\n(`maxNextQueriesPerGroup`).\n\n```vue live\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList :offset=\"48\" :frequency=\"72\" :maxNextQueriesPerGroup=\"6\" :maxGroups=\"3\" />\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n SearchInput\n }\n };\n</script>\n```\n\n### Customise the layout of the component\n\nThis component will render by default the `id` of each search item, both the injected, and for the\ngroups of next queries generated, but the common case is to integrate it with another layout\ncomponent, for example the `BaseGrid`. To do so, you can use the `default` slot\n\n```vue\n<template>\n <div>\n <SearchInput />\n <ResultsList>\n <NextQueriesList\n :offset=\"48\"\n :frequency=\"72\"\n :maxNextQueriesPerGroup=\"6\"\n :maxGroups=\"3\"\n #default=\"{ items }\"\n >\n <BaseGrid :items=\"items\" :animation=\"animation\">\n <template #next-queries-group=\"{ item }\">\n <span>NextQueriesGroup: {{ item.queries.join(', ') }}</span>\n </template>\n <template #result=\"{ item }\">\n <span>Result: {{ item.name }}</span>\n </template>\n <template #default=\"{ item }\">\n <span>Default: {{ item }}</span>\n </template>\n </BaseGrid>\n </NextQueriesList>\n </ResultsList>\n </div>\n</template>\n\n<script>\n import { NextQueriesList } from '@empathyco/x-components/next-queries';\n import { ResultsList } from '@empathyco/x-components/search';\n import { SearchInput } from '@empathyco/x-components/search-box';\n import { BaseGrid } from '@empathyco/x-components';\n\n export default {\n name: 'NextQueriesListDemo',\n components: {\n NextQueriesList,\n ResultsList,\n BaseGrid,\n SearchInput\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}