@empathyco/x-components 6.0.0-alpha.63 → 6.0.0-alpha.64

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 (163) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/design-system/deprecated-full-theme.css +4697 -4697
  3. package/docs/API-reference/api/x-components.fallbackdisclaimer.md +2 -2
  4. package/docs/API-reference/api/x-components.historyqueriesswitch.md +1 -1
  5. package/docs/API-reference/api/x-components.identifierresult.md +1 -1
  6. package/docs/API-reference/api/x-components.identifierresults.md +1 -1
  7. package/docs/API-reference/api/x-components.md +1 -1
  8. package/docs/API-reference/api/x-components.myhistory.md +1 -1
  9. package/docs/API-reference/api/x-components.partialresultslist.md +1 -1
  10. package/docs/API-reference/api/x-components.querypreview.md +2 -2
  11. package/docs/API-reference/api/x-components.recommendations.md +1 -1
  12. package/docs/API-reference/api/x-components.relatedpromptstaglist.md +2 -2
  13. package/docs/API-reference/api/x-components.relatedtag.md +3 -3
  14. package/docs/API-reference/api/x-components.scrolltotop.md +1 -1
  15. package/docs/API-reference/api/x-components.searchbutton.md +1 -1
  16. package/docs/API-reference/api/x-components.searchinput.md +1 -1
  17. package/docs/API-reference/api/x-components.semanticqueries.md +1 -1
  18. package/docs/API-reference/api/x-components.sortdropdown.md +1 -1
  19. package/docs/API-reference/api/x-components.sortlist.md +1 -1
  20. package/docs/API-reference/api/x-components.sortpickerlist.md +1 -1
  21. package/docs/API-reference/api/x-components.spellcheck.md +2 -2
  22. package/docs/API-reference/api/x-components.spellcheckbutton.md +1 -1
  23. package/docs/API-reference/api/x-components.usestate.md +5 -4
  24. package/js/composables/use-state.js +7 -9
  25. package/js/composables/use-state.js.map +1 -1
  26. package/js/x-modules/extra-params/components/extra-params.vue.js +1 -1
  27. package/js/x-modules/extra-params/components/extra-params.vue.js.map +1 -1
  28. package/js/x-modules/extra-params/components/renderless-extra-param.vue.js +1 -1
  29. package/js/x-modules/extra-params/components/renderless-extra-param.vue.js.map +1 -1
  30. package/js/x-modules/history-queries/components/clear-history-queries.vue.js.map +1 -1
  31. package/js/x-modules/history-queries/components/clear-history-queries.vue2.js +1 -1
  32. package/js/x-modules/history-queries/components/clear-history-queries.vue2.js.map +1 -1
  33. package/js/x-modules/history-queries/components/history-queries-switch.vue.js.map +1 -1
  34. package/js/x-modules/history-queries/components/history-queries-switch.vue2.js +1 -4
  35. package/js/x-modules/history-queries/components/history-queries-switch.vue2.js.map +1 -1
  36. package/js/x-modules/history-queries/components/my-history.vue.js.map +1 -1
  37. package/js/x-modules/history-queries/components/my-history.vue2.js +1 -1
  38. package/js/x-modules/history-queries/components/my-history.vue2.js.map +1 -1
  39. package/js/x-modules/identifier-results/components/identifier-result.vue.js.map +1 -1
  40. package/js/x-modules/identifier-results/components/identifier-result.vue2.js +1 -1
  41. package/js/x-modules/identifier-results/components/identifier-result.vue2.js.map +1 -1
  42. package/js/x-modules/identifier-results/components/identifier-results.vue.js.map +1 -1
  43. package/js/x-modules/identifier-results/components/identifier-results.vue2.js +1 -1
  44. package/js/x-modules/identifier-results/components/identifier-results.vue2.js.map +1 -1
  45. package/js/x-modules/next-queries/components/next-queries-list.vue.js +1 -1
  46. package/js/x-modules/next-queries/components/next-queries-list.vue.js.map +1 -1
  47. package/js/x-modules/next-queries/components/next-query-preview.vue.js.map +1 -1
  48. package/js/x-modules/next-queries/components/next-query-preview.vue2.js +1 -1
  49. package/js/x-modules/next-queries/components/next-query-preview.vue2.js.map +1 -1
  50. package/js/x-modules/queries-preview/components/query-preview-button.vue.js.map +1 -1
  51. package/js/x-modules/queries-preview/components/query-preview-button.vue2.js +1 -1
  52. package/js/x-modules/queries-preview/components/query-preview-button.vue2.js.map +1 -1
  53. package/js/x-modules/queries-preview/components/query-preview-list.vue.js.map +1 -1
  54. package/js/x-modules/queries-preview/components/query-preview-list.vue2.js +1 -1
  55. package/js/x-modules/queries-preview/components/query-preview-list.vue2.js.map +1 -1
  56. package/js/x-modules/queries-preview/components/query-preview.vue.js.map +1 -1
  57. package/js/x-modules/queries-preview/components/query-preview.vue2.js +6 -11
  58. package/js/x-modules/queries-preview/components/query-preview.vue2.js.map +1 -1
  59. package/js/x-modules/recommendations/components/recommendations.vue.js.map +1 -1
  60. package/js/x-modules/recommendations/components/recommendations.vue2.js +1 -3
  61. package/js/x-modules/recommendations/components/recommendations.vue2.js.map +1 -1
  62. package/js/x-modules/related-prompts/components/related-prompts-list.vue.js +1 -4
  63. package/js/x-modules/related-prompts/components/related-prompts-list.vue.js.map +1 -1
  64. package/js/x-modules/related-prompts/components/related-prompts-tag-list.vue.js.map +1 -1
  65. package/js/x-modules/related-prompts/components/related-prompts-tag-list.vue2.js +1 -6
  66. package/js/x-modules/related-prompts/components/related-prompts-tag-list.vue2.js.map +1 -1
  67. package/js/x-modules/related-tags/components/related-tag.vue.js.map +1 -1
  68. package/js/x-modules/related-tags/components/related-tag.vue2.js +1 -1
  69. package/js/x-modules/related-tags/components/related-tag.vue2.js.map +1 -1
  70. package/js/x-modules/scroll/components/main-scroll-item.vue.js.map +1 -1
  71. package/js/x-modules/scroll/components/main-scroll-item.vue2.js +1 -1
  72. package/js/x-modules/scroll/components/main-scroll-item.vue2.js.map +1 -1
  73. package/js/x-modules/scroll/components/main-scroll.vue.js +1 -1
  74. package/js/x-modules/scroll/components/main-scroll.vue.js.map +1 -1
  75. package/js/x-modules/scroll/components/scroll-to-top.vue.js.map +1 -1
  76. package/js/x-modules/scroll/components/scroll-to-top.vue2.js +1 -1
  77. package/js/x-modules/scroll/components/scroll-to-top.vue2.js.map +1 -1
  78. package/js/x-modules/search/components/banners-list.vue.js +1 -1
  79. package/js/x-modules/search/components/banners-list.vue.js.map +1 -1
  80. package/js/x-modules/search/components/fallback-disclaimer.vue.js.map +1 -1
  81. package/js/x-modules/search/components/fallback-disclaimer.vue2.js +1 -4
  82. package/js/x-modules/search/components/fallback-disclaimer.vue2.js.map +1 -1
  83. package/js/x-modules/search/components/partial-results-list.vue.js.map +1 -1
  84. package/js/x-modules/search/components/partial-results-list.vue2.js +1 -3
  85. package/js/x-modules/search/components/partial-results-list.vue2.js.map +1 -1
  86. package/js/x-modules/search/components/promoteds-list.vue.js +1 -1
  87. package/js/x-modules/search/components/promoteds-list.vue.js.map +1 -1
  88. package/js/x-modules/search/components/redirection.vue.js.map +1 -1
  89. package/js/x-modules/search/components/redirection.vue2.js +1 -1
  90. package/js/x-modules/search/components/redirection.vue2.js.map +1 -1
  91. package/js/x-modules/search/components/results-list.vue.js +1 -7
  92. package/js/x-modules/search/components/results-list.vue.js.map +1 -1
  93. package/js/x-modules/search/components/sort-dropdown.vue.js.map +1 -1
  94. package/js/x-modules/search/components/sort-dropdown.vue2.js +1 -1
  95. package/js/x-modules/search/components/sort-dropdown.vue2.js.map +1 -1
  96. package/js/x-modules/search/components/sort-list.vue.js.map +1 -1
  97. package/js/x-modules/search/components/sort-list.vue2.js +1 -1
  98. package/js/x-modules/search/components/sort-list.vue2.js.map +1 -1
  99. package/js/x-modules/search/components/sort-picker-list.vue.js.map +1 -1
  100. package/js/x-modules/search/components/sort-picker-list.vue2.js +1 -1
  101. package/js/x-modules/search/components/sort-picker-list.vue2.js.map +1 -1
  102. package/js/x-modules/search/components/spellcheck-button.vue.js.map +1 -1
  103. package/js/x-modules/search/components/spellcheck-button.vue2.js +1 -1
  104. package/js/x-modules/search/components/spellcheck-button.vue2.js.map +1 -1
  105. package/js/x-modules/search/components/spellcheck.vue.js.map +1 -1
  106. package/js/x-modules/search/components/spellcheck.vue2.js +1 -1
  107. package/js/x-modules/search/components/spellcheck.vue2.js.map +1 -1
  108. package/js/x-modules/search-box/components/clear-search-input.vue.js.map +1 -1
  109. package/js/x-modules/search-box/components/clear-search-input.vue2.js +1 -1
  110. package/js/x-modules/search-box/components/clear-search-input.vue2.js.map +1 -1
  111. package/js/x-modules/search-box/components/search-button.vue.js.map +1 -1
  112. package/js/x-modules/search-box/components/search-button.vue2.js +1 -1
  113. package/js/x-modules/search-box/components/search-button.vue2.js.map +1 -1
  114. package/js/x-modules/search-box/components/search-input-placeholder.vue.js.map +1 -1
  115. package/js/x-modules/search-box/components/search-input-placeholder.vue2.js +1 -1
  116. package/js/x-modules/search-box/components/search-input-placeholder.vue2.js.map +1 -1
  117. package/js/x-modules/search-box/components/search-input.vue.js.map +1 -1
  118. package/js/x-modules/search-box/components/search-input.vue2.js +1 -1
  119. package/js/x-modules/search-box/components/search-input.vue2.js.map +1 -1
  120. package/js/x-modules/semantic-queries/components/semantic-queries.vue.js.map +1 -1
  121. package/js/x-modules/semantic-queries/components/semantic-queries.vue2.js +1 -3
  122. package/js/x-modules/semantic-queries/components/semantic-queries.vue2.js.map +1 -1
  123. package/js/x-modules/url/components/url-handler.vue.js.map +1 -1
  124. package/js/x-modules/url/components/url-handler.vue2.js +1 -1
  125. package/js/x-modules/url/components/url-handler.vue2.js.map +1 -1
  126. package/package.json +2 -2
  127. package/report/x-components.api.json +63 -70
  128. package/report/x-components.api.md +21 -19
  129. package/types/composables/use-state.d.ts +4 -5
  130. package/types/composables/use-state.d.ts.map +1 -1
  131. package/types/x-modules/extra-params/components/extra-params.vue.d.ts.map +1 -1
  132. package/types/x-modules/history-queries/components/history-queries-switch.vue.d.ts +1 -1
  133. package/types/x-modules/history-queries/components/history-queries-switch.vue.d.ts.map +1 -1
  134. package/types/x-modules/history-queries/components/my-history.vue.d.ts +1 -1
  135. package/types/x-modules/identifier-results/components/identifier-result.vue.d.ts +1 -1
  136. package/types/x-modules/identifier-results/components/identifier-results.vue.d.ts +1 -1
  137. package/types/x-modules/queries-preview/components/query-preview.vue.d.ts +3 -3
  138. package/types/x-modules/queries-preview/components/query-preview.vue.d.ts.map +1 -1
  139. package/types/x-modules/recommendations/components/recommendations.vue.d.ts +1 -2
  140. package/types/x-modules/recommendations/components/recommendations.vue.d.ts.map +1 -1
  141. package/types/x-modules/related-prompts/components/related-prompts-list.vue.d.ts.map +1 -1
  142. package/types/x-modules/related-prompts/components/related-prompts-tag-list.vue.d.ts +3 -3
  143. package/types/x-modules/related-prompts/components/related-prompts-tag-list.vue.d.ts.map +1 -1
  144. package/types/x-modules/related-tags/components/related-tag.vue.d.ts +4 -4
  145. package/types/x-modules/related-tags/components/related-tag.vue.d.ts.map +1 -1
  146. package/types/x-modules/scroll/components/scroll-to-top.vue.d.ts +1 -1
  147. package/types/x-modules/search/components/banners-list.vue.d.ts.map +1 -1
  148. package/types/x-modules/search/components/fallback-disclaimer.vue.d.ts +2 -2
  149. package/types/x-modules/search/components/fallback-disclaimer.vue.d.ts.map +1 -1
  150. package/types/x-modules/search/components/partial-results-list.vue.d.ts +1 -3
  151. package/types/x-modules/search/components/partial-results-list.vue.d.ts.map +1 -1
  152. package/types/x-modules/search/components/promoteds-list.vue.d.ts.map +1 -1
  153. package/types/x-modules/search/components/results-list.vue.d.ts.map +1 -1
  154. package/types/x-modules/search/components/sort-dropdown.vue.d.ts +1 -1
  155. package/types/x-modules/search/components/sort-list.vue.d.ts +1 -1
  156. package/types/x-modules/search/components/sort-picker-list.vue.d.ts +1 -1
  157. package/types/x-modules/search/components/spellcheck-button.vue.d.ts +1 -1
  158. package/types/x-modules/search/components/spellcheck.vue.d.ts +2 -2
  159. package/types/x-modules/search-box/components/search-button.vue.d.ts +1 -2
  160. package/types/x-modules/search-box/components/search-button.vue.d.ts.map +1 -1
  161. package/types/x-modules/search-box/components/search-input.vue.d.ts +1 -1
  162. package/types/x-modules/semantic-queries/components/semantic-queries.vue.d.ts +1 -3
  163. package/types/x-modules/semantic-queries/components/semantic-queries.vue.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"spellcheck-button.vue.js","sources":["../../../../../src/x-modules/search/components/spellcheck-button.vue"],"sourcesContent":["<template>\n <button\n v-if=\"spellcheckedQuery\"\n ref=\"el\"\n class=\"x-spellcheck-button\"\n data-test=\"set-spellcheck\"\n @click=\"emitEvents\"\n >\n <slot v-bind=\"{ spellcheckedQuery }\">{{ spellcheckedQuery }}</slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * A button that when pressed emits the {@link XEventsTypes.UserAcceptedAQuery}\n * and {@link XEventsTypes.UserAcceptedSpellcheckQuery} events, expressing the user\n * intention to set the spellchecked query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SpellcheckButton',\n xModule: searchXModule.name,\n setup() {\n const $x = use$x()\n\n const el = ref<HTMLElement>()\n\n /**\n * The spellcheckedQuery from the search state.\n *\n * @public\n */\n const { spellcheckedQuery } = useState('search', ['spellcheckedQuery'])\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => ({\n target: el.value as HTMLElement,\n feature: 'spellcheck',\n })\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n const emitEvents = () => {\n $x.emit('UserAcceptedAQuery', spellcheckedQuery.value as string, createEventMetadata())\n $x.emit(\n 'UserAcceptedSpellcheckQuery',\n spellcheckedQuery.value as string,\n createEventMetadata(),\n )\n }\n\n return {\n el,\n spellcheckedQuery,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits 2 different events:\n\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n- [`UserAcceptedSpellcheckQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n\n## Examples\n\n### Basic example\n\nThe component sets the current spellcheckedQuery as the new query and emits the `UserAcceptedAQuery`\nand `UserAcceptedSpellcheckQuery` events.\n\n```vue\n<SpellcheckButton />\n```\n\n### Customizing its contents\n\n```vue\n<SpellcheckButton>\n <template #default=\"{ spellcheckedQuery }\">\n <span class=\"x-spellcheck__text\">\n Set the Spellcheck as the new query: {{ spellcheckedQuery}}!\n </span>\n </template>\n</SpellcheckButton>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock"],"mappings":";;;;qBACE,IAQS,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;SATX,IAGY,CAAA,iBAAA,IAAAA,SAAA,EAAA,EAAAC,kBAAA;AAAA,IAAA,QAAA;AAAA,IAAA;AAAA,MACR,GAAK,EAAA,CAAA;AAAA,MACL,GAAA,EAAA,IAAA;AAAA,MACC,KAAK,EAAA,qBAAA;AAAA,MAAA,WAAA,EAAA,gBAAA;AAEN,MAAA,OAAA,EAAA,MAAA,CAAmE,CARvE,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,UAAA,IAAA,IAAA,CAAA,UAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;AAAA,OAAA,CAAA;AAAA,KAAA;;;;;;;;;"}
1
+ {"version":3,"file":"spellcheck-button.vue.js","sources":["../../../../../src/x-modules/search/components/spellcheck-button.vue"],"sourcesContent":["<template>\n <button\n v-if=\"spellcheckedQuery\"\n ref=\"el\"\n class=\"x-spellcheck-button\"\n data-test=\"set-spellcheck\"\n @click=\"emitEvents\"\n >\n <slot v-bind=\"{ spellcheckedQuery }\">{{ spellcheckedQuery }}</slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * A button that when pressed emits the {@link XEventsTypes.UserAcceptedAQuery}\n * and {@link XEventsTypes.UserAcceptedSpellcheckQuery} events, expressing the user\n * intention to set the spellchecked query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SpellcheckButton',\n xModule: searchXModule.name,\n setup() {\n const $x = use$x()\n\n const el = ref<HTMLElement>()\n\n /**\n * The spellcheckedQuery from the search state.\n *\n * @public\n */\n const { spellcheckedQuery } = useState('search')\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => ({\n target: el.value as HTMLElement,\n feature: 'spellcheck',\n })\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n const emitEvents = () => {\n $x.emit('UserAcceptedAQuery', spellcheckedQuery.value as string, createEventMetadata())\n $x.emit(\n 'UserAcceptedSpellcheckQuery',\n spellcheckedQuery.value as string,\n createEventMetadata(),\n )\n }\n\n return {\n el,\n spellcheckedQuery,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits 2 different events:\n\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n- [`UserAcceptedSpellcheckQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n\n## Examples\n\n### Basic example\n\nThe component sets the current spellcheckedQuery as the new query and emits the `UserAcceptedAQuery`\nand `UserAcceptedSpellcheckQuery` events.\n\n```vue\n<SpellcheckButton />\n```\n\n### Customizing its contents\n\n```vue\n<SpellcheckButton>\n <template #default=\"{ spellcheckedQuery }\">\n <span class=\"x-spellcheck__text\">\n Set the Spellcheck as the new query: {{ spellcheckedQuery}}!\n </span>\n </template>\n</SpellcheckButton>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock"],"mappings":";;;;qBACE,IAQS,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;SATX,IAGY,CAAA,iBAAA,IAAAA,SAAA,EAAA,EAAAC,kBAAA;AAAA,IAAA,QAAA;AAAA,IAAA;AAAA,MACR,GAAK,EAAA,CAAA;AAAA,MACL,GAAA,EAAA,IAAA;AAAA,MACC,KAAK,EAAA,qBAAA;AAAA,MAAA,WAAA,EAAA,gBAAA;AAEN,MAAA,OAAA,EAAA,MAAA,CAAmE,CARvE,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,UAAA,IAAA,IAAA,CAAA,UAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;AAAA,OAAA,CAAA;AAAA,KAAA;;;;;;;;;"}
@@ -21,7 +21,7 @@ var _sfc_main = defineComponent({
21
21
  *
22
22
  * @public
23
23
  */
24
- const { spellcheckedQuery } = useState('search', ['spellcheckedQuery']);
24
+ const { spellcheckedQuery } = useState('search');
25
25
  /**
26
26
  * Generates the {@link WireMetadata} object omitting the moduleName.
27
27
  *
@@ -1 +1 @@
1
- {"version":3,"file":"spellcheck-button.vue2.js","sources":["../../../../../src/x-modules/search/components/spellcheck-button.vue"],"sourcesContent":["<template>\n <button\n v-if=\"spellcheckedQuery\"\n ref=\"el\"\n class=\"x-spellcheck-button\"\n data-test=\"set-spellcheck\"\n @click=\"emitEvents\"\n >\n <slot v-bind=\"{ spellcheckedQuery }\">{{ spellcheckedQuery }}</slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * A button that when pressed emits the {@link XEventsTypes.UserAcceptedAQuery}\n * and {@link XEventsTypes.UserAcceptedSpellcheckQuery} events, expressing the user\n * intention to set the spellchecked query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SpellcheckButton',\n xModule: searchXModule.name,\n setup() {\n const $x = use$x()\n\n const el = ref<HTMLElement>()\n\n /**\n * The spellcheckedQuery from the search state.\n *\n * @public\n */\n const { spellcheckedQuery } = useState('search', ['spellcheckedQuery'])\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => ({\n target: el.value as HTMLElement,\n feature: 'spellcheck',\n })\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n const emitEvents = () => {\n $x.emit('UserAcceptedAQuery', spellcheckedQuery.value as string, createEventMetadata())\n $x.emit(\n 'UserAcceptedSpellcheckQuery',\n spellcheckedQuery.value as string,\n createEventMetadata(),\n )\n }\n\n return {\n el,\n spellcheckedQuery,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits 2 different events:\n\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n- [`UserAcceptedSpellcheckQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n\n## Examples\n\n### Basic example\n\nThe component sets the current spellcheckedQuery as the new query and emits the `UserAcceptedAQuery`\nand `UserAcceptedSpellcheckQuery` events.\n\n```vue\n<SpellcheckButton />\n```\n\n### Customizing its contents\n\n```vue\n<SpellcheckButton>\n <template #default=\"{ spellcheckedQuery }\">\n <span class=\"x-spellcheck__text\">\n Set the Spellcheck as the new query: {{ spellcheckedQuery}}!\n </span>\n </template>\n</SpellcheckButton>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAmBA;;;;;;AAME;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,aAAa,CAAC,IAAI;IAC3B,KAAK,GAAA;AACH,QAAA,MAAM,EAAC,GAAI,KAAK,EAAC,CAAA;AAEjB,QAAA,MAAM,EAAG,GAAE,GAAG,EAAc,CAAA;AAE5B;;;;AAIE;AACF,QAAA,MAAM,EAAE,iBAAgB,EAAI,GAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,mBAAmB,CAAC,CAAA,CAAA;AAEtE;;;;;AAKE;AACF,QAAA,MAAM,mBAAoB,GAAE,OAAyC;YACnE,MAAM,EAAE,EAAE,CAAC,KAAoB;AAC/B,YAAA,OAAO,EAAE,YAAY;AACtB,SAAA,CAAA,CAAA;AAED;;;;AAIE;QACF,MAAM,UAAS,GAAI,MAAM;AACvB,YAAA,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,KAAe,EAAE,mBAAmB,EAAE,CAAA,CAAA;AACtF,YAAA,EAAE,CAAC,IAAI,CACL,6BAA6B,EAC7B,iBAAiB,CAAC,KAAe,EACjC,mBAAmB,EAAE,CACvB,CAAA;AACF,SAAA,CAAA;QAEA,OAAO;YACL,EAAE;YACF,iBAAiB;YACjB,UAAU;SACZ,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"spellcheck-button.vue2.js","sources":["../../../../../src/x-modules/search/components/spellcheck-button.vue"],"sourcesContent":["<template>\n <button\n v-if=\"spellcheckedQuery\"\n ref=\"el\"\n class=\"x-spellcheck-button\"\n data-test=\"set-spellcheck\"\n @click=\"emitEvents\"\n >\n <slot v-bind=\"{ spellcheckedQuery }\">{{ spellcheckedQuery }}</slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * A button that when pressed emits the {@link XEventsTypes.UserAcceptedAQuery}\n * and {@link XEventsTypes.UserAcceptedSpellcheckQuery} events, expressing the user\n * intention to set the spellchecked query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SpellcheckButton',\n xModule: searchXModule.name,\n setup() {\n const $x = use$x()\n\n const el = ref<HTMLElement>()\n\n /**\n * The spellcheckedQuery from the search state.\n *\n * @public\n */\n const { spellcheckedQuery } = useState('search')\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => ({\n target: el.value as HTMLElement,\n feature: 'spellcheck',\n })\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n const emitEvents = () => {\n $x.emit('UserAcceptedAQuery', spellcheckedQuery.value as string, createEventMetadata())\n $x.emit(\n 'UserAcceptedSpellcheckQuery',\n spellcheckedQuery.value as string,\n createEventMetadata(),\n )\n }\n\n return {\n el,\n spellcheckedQuery,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits 2 different events:\n\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n- [`UserAcceptedSpellcheckQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts):\n the event is emitted after the user clicks the button. The event payload is the spellchecked query\n data.\n\n## Examples\n\n### Basic example\n\nThe component sets the current spellcheckedQuery as the new query and emits the `UserAcceptedAQuery`\nand `UserAcceptedSpellcheckQuery` events.\n\n```vue\n<SpellcheckButton />\n```\n\n### Customizing its contents\n\n```vue\n<SpellcheckButton>\n <template #default=\"{ spellcheckedQuery }\">\n <span class=\"x-spellcheck__text\">\n Set the Spellcheck as the new query: {{ spellcheckedQuery}}!\n </span>\n </template>\n</SpellcheckButton>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAmBA;;;;;;AAME;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE,aAAa,CAAC,IAAI;IAC3B,KAAK,GAAA;AACH,QAAA,MAAM,EAAC,GAAI,KAAK,EAAC,CAAA;AAEjB,QAAA,MAAM,EAAG,GAAE,GAAG,EAAc,CAAA;AAE5B;;;;AAIE;QACF,MAAM,EAAE,iBAAgB,KAAM,QAAQ,CAAC,QAAQ,CAAA,CAAA;AAE/C;;;;;AAKE;AACF,QAAA,MAAM,mBAAoB,GAAE,OAAyC;YACnE,MAAM,EAAE,EAAE,CAAC,KAAoB;AAC/B,YAAA,OAAO,EAAE,YAAY;AACtB,SAAA,CAAA,CAAA;AAED;;;;AAIE;QACF,MAAM,UAAS,GAAI,MAAM;AACvB,YAAA,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,KAAe,EAAE,mBAAmB,EAAE,CAAA,CAAA;AACtF,YAAA,EAAE,CAAC,IAAI,CACL,6BAA6B,EAC7B,iBAAiB,CAAC,KAAe,EACjC,mBAAmB,EAAE,CACvB,CAAA;AACF,SAAA,CAAA;QAEA,OAAO;YACL,EAAE;YACF,iBAAiB;YACjB,UAAU;SACZ,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"spellcheck.vue.js","sources":["../../../../../src/x-modules/search/components/spellcheck.vue"],"sourcesContent":["<template>\n <div v-if=\"spellcheckedQuery\" class=\"x-spellcheck\" data-test=\"spellcheck\">\n <slot v-bind=\"{ query, spellcheckedQuery }\">{{ query }} - {{ spellcheckedQuery }}</slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * The `Spellcheck` component allows to inform the user with a friendly message that he\n * might have misspelled the search query. This message can be set using the default slot\n * of the component, which gives access to the searched query using the `query` scope property,\n * and the spellchecked query proposal, using the `spellcheckedQuery` scope property.\n *\n * The component will only render itself if the `spellcheckedQuery` property has value.\n *\n * @public\n */\nexport default defineComponent({\n name: 'Spellcheck',\n xModule: searchXModule.name,\n setup() {\n /**\n * The query and the spellcheckedQuery from the search state.\n *\n * @public\n */\n const { query, spellcheckedQuery } = useState('search', ['query', 'spellcheckedQuery'])\n\n return {\n query,\n spellcheckedQuery,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis default spellcheck component expects a query and a spellcheckedQuery to render and pass to its\ndefault slot.\n\nThis two props should be show like a message comparing them.\n\n### Basic usage\n\n```vue\n<Spellcheck />\n```\n\n### Customizing its contents\n\n```vue\n<Spellcheck>\n <template #default=\"{ query, spellcheckedQuery }\">\n No results found for '{{ query }}'. We show you results for '{{ spellcheckedQuery }}'\n </template>\n</Spellcheck>\n\n<script>\nimport { Spellcheck } from '@empathyco/x-components/search'\n\nexport default {\n components: {\n Spellcheck,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","query","_renderSlot","_normalizeProps","_guardReactiveProps","_createCommentVNode"],"mappings":";;;;MACgC,UAAM,GAAA;AAAA,EAAe,GAAA,EAAA,CAAA;AAAA,EAAA,KAAA,EAAA,cAAA;;;AAAnD,SAAA,WAAA,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAEM,QAFN,KAEM,EAAA,QAAA,EAAA;AADJ,EAAA,OAAA,IAAA,CAAA,iBAAA,IAAAA,SAAA,8BAA+CC,UAAQ,EAAA;AAAA,IAAAC,UAAA,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAAC,cAAA,CAAAC,kBAAA,CAAA,EAAA,KAAA,EAAA,IAAA,CAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,CAAA,iBAAA,EAAA,CAAA,CAAA,EAAA,MAAA;;;;;;AAF3D,KAAA,CAAA;AAAA,GAAA,CAAA,IAAAC,kBAAA,CAAA,MAAA,EAAA,IAAA,CAAA,CAAA;;;;;;"}
1
+ {"version":3,"file":"spellcheck.vue.js","sources":["../../../../../src/x-modules/search/components/spellcheck.vue"],"sourcesContent":["<template>\n <div v-if=\"spellcheckedQuery\" class=\"x-spellcheck\" data-test=\"spellcheck\">\n <slot v-bind=\"{ query, spellcheckedQuery }\">{{ query }} - {{ spellcheckedQuery }}</slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * The `Spellcheck` component allows to inform the user with a friendly message that he\n * might have misspelled the search query. This message can be set using the default slot\n * of the component, which gives access to the searched query using the `query` scope property,\n * and the spellchecked query proposal, using the `spellcheckedQuery` scope property.\n *\n * The component will only render itself if the `spellcheckedQuery` property has value.\n *\n * @public\n */\nexport default defineComponent({\n name: 'Spellcheck',\n xModule: searchXModule.name,\n setup() {\n /**\n * The query and the spellcheckedQuery from the search state.\n *\n * @public\n */\n const { query, spellcheckedQuery } = useState('search')\n\n return {\n query,\n spellcheckedQuery,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis default spellcheck component expects a query and a spellcheckedQuery to render and pass to its\ndefault slot.\n\nThis two props should be show like a message comparing them.\n\n### Basic usage\n\n```vue\n<Spellcheck />\n```\n\n### Customizing its contents\n\n```vue\n<Spellcheck>\n <template #default=\"{ query, spellcheckedQuery }\">\n No results found for '{{ query }}'. We show you results for '{{ spellcheckedQuery }}'\n </template>\n</Spellcheck>\n\n<script>\nimport { Spellcheck } from '@empathyco/x-components/search'\n\nexport default {\n components: {\n Spellcheck,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","query","_renderSlot","_normalizeProps","_guardReactiveProps","_createCommentVNode"],"mappings":";;;;MACgC,UAAM,GAAA;AAAA,EAAe,GAAA,EAAA,CAAA;AAAA,EAAA,KAAA,EAAA,cAAA;;;AAAnD,SAAA,WAAA,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAEM,QAFN,KAEM,EAAA,QAAA,EAAA;AADJ,EAAA,OAAA,IAAA,CAAA,iBAAA,IAAAA,SAAA,8BAA+CC,UAAQ,EAAA;AAAA,IAAAC,UAAA,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAAC,cAAA,CAAAC,kBAAA,CAAA,EAAA,KAAA,EAAA,IAAA,CAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,CAAA,iBAAA,EAAA,CAAA,CAAA,EAAA,MAAA;;;;;;AAF3D,KAAA,CAAA;AAAA,GAAA,CAAA,IAAAC,kBAAA,CAAA,MAAA,EAAA,IAAA,CAAA,CAAA;;;;;;"}
@@ -21,7 +21,7 @@ var _sfc_main = defineComponent({
21
21
  *
22
22
  * @public
23
23
  */
24
- const { query, spellcheckedQuery } = useState('search', ['query', 'spellcheckedQuery']);
24
+ const { query, spellcheckedQuery } = useState('search');
25
25
  return {
26
26
  query,
27
27
  spellcheckedQuery,
@@ -1 +1 @@
1
- {"version":3,"file":"spellcheck.vue2.js","sources":["../../../../../src/x-modules/search/components/spellcheck.vue"],"sourcesContent":["<template>\n <div v-if=\"spellcheckedQuery\" class=\"x-spellcheck\" data-test=\"spellcheck\">\n <slot v-bind=\"{ query, spellcheckedQuery }\">{{ query }} - {{ spellcheckedQuery }}</slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * The `Spellcheck` component allows to inform the user with a friendly message that he\n * might have misspelled the search query. This message can be set using the default slot\n * of the component, which gives access to the searched query using the `query` scope property,\n * and the spellchecked query proposal, using the `spellcheckedQuery` scope property.\n *\n * The component will only render itself if the `spellcheckedQuery` property has value.\n *\n * @public\n */\nexport default defineComponent({\n name: 'Spellcheck',\n xModule: searchXModule.name,\n setup() {\n /**\n * The query and the spellcheckedQuery from the search state.\n *\n * @public\n */\n const { query, spellcheckedQuery } = useState('search', ['query', 'spellcheckedQuery'])\n\n return {\n query,\n spellcheckedQuery,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis default spellcheck component expects a query and a spellcheckedQuery to render and pass to its\ndefault slot.\n\nThis two props should be show like a message comparing them.\n\n### Basic usage\n\n```vue\n<Spellcheck />\n```\n\n### Customizing its contents\n\n```vue\n<Spellcheck>\n <template #default=\"{ query, spellcheckedQuery }\">\n No results found for '{{ query }}'. We show you results for '{{ spellcheckedQuery }}'\n </template>\n</Spellcheck>\n\n<script>\nimport { Spellcheck } from '@empathyco/x-components/search'\n\nexport default {\n components: {\n Spellcheck,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAWA;;;;;;;;;AASE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,aAAa,CAAC,IAAI;IAC3B,KAAK,GAAA;AACH;;;;AAIE;AACF,QAAA,MAAM,EAAE,KAAK,EAAE,iBAAgB,EAAI,GAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA,CAAA;QAEtF,OAAO;YACL,KAAK;YACL,iBAAiB;SACnB,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"spellcheck.vue2.js","sources":["../../../../../src/x-modules/search/components/spellcheck.vue"],"sourcesContent":["<template>\n <div v-if=\"spellcheckedQuery\" class=\"x-spellcheck\" data-test=\"spellcheck\">\n <slot v-bind=\"{ query, spellcheckedQuery }\">{{ query }} - {{ spellcheckedQuery }}</slot>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchXModule } from '../x-module'\n\n/**\n * The `Spellcheck` component allows to inform the user with a friendly message that he\n * might have misspelled the search query. This message can be set using the default slot\n * of the component, which gives access to the searched query using the `query` scope property,\n * and the spellchecked query proposal, using the `spellcheckedQuery` scope property.\n *\n * The component will only render itself if the `spellcheckedQuery` property has value.\n *\n * @public\n */\nexport default defineComponent({\n name: 'Spellcheck',\n xModule: searchXModule.name,\n setup() {\n /**\n * The query and the spellcheckedQuery from the search state.\n *\n * @public\n */\n const { query, spellcheckedQuery } = useState('search')\n\n return {\n query,\n spellcheckedQuery,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Examples\n\nThis default spellcheck component expects a query and a spellcheckedQuery to render and pass to its\ndefault slot.\n\nThis two props should be show like a message comparing them.\n\n### Basic usage\n\n```vue\n<Spellcheck />\n```\n\n### Customizing its contents\n\n```vue\n<Spellcheck>\n <template #default=\"{ query, spellcheckedQuery }\">\n No results found for '{{ query }}'. We show you results for '{{ spellcheckedQuery }}'\n </template>\n</Spellcheck>\n\n<script>\nimport { Spellcheck } from '@empathyco/x-components/search'\n\nexport default {\n components: {\n Spellcheck,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;AAWA;;;;;;;;;AASE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,aAAa,CAAC,IAAI;IAC3B,KAAK,GAAA;AACH;;;;AAIE;QACF,MAAM,EAAE,KAAK,EAAE,iBAAkB,EAAA,GAAI,QAAQ,CAAC,QAAQ,CAAA,CAAA;QAEtD,OAAO;YACL,KAAK;YACL,iBAAiB;SACnB,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"clear-search-input.vue.js","sources":["../../../../../src/x-modules/search-box/components/clear-search-input.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-clear-search-input x-button\"\n :class=\"dynamicClasses\"\n :events=\"clearSearchInputEvents\"\n data-test=\"clear-search-input\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport { computed, defineComponent, ref } from 'vue'\nimport BaseEventButton from '../../../components/base-event-button.vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to delete the current query.\n *\n * @remarks\n * A button that when pressed emits the {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * and {@link SearchBoxXEvents.UserClearedQuery} events, expressing the user intention to clear\n * the current query.\n * It also adds `x-clear-search-input--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'ClearSearchInput',\n components: { BaseEventButton },\n xModule: searchBoxXModule.name,\n setup() {\n const { query } = useState('searchBox', ['query'])\n\n /**\n * The events dictionary that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n const clearSearchInputEvents = ref({\n UserPressedClearSearchBoxButton: undefined,\n })\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-clear-search-input--has-empty-query': isQueryEmpty.value,\n }))\n\n return {\n dynamicClasses,\n clearSearchInputEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserPressedClearSearchBoxButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserClearedQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\nHere a basic example of how the clear button is rendered.\n\n_Type any term in the input field and then click the Clear button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nIn this example, a custom text is passed in the default slot instead of the default text to\ncustomize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <ClearSearchInput>Clear</ClearSearchInput>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedClearSearchBoxButton` event is implemented, triggering the message\n“clear” when the clear search input button is clicked.\n\n_Click the Clear button to try it out!_\n\n```vue live\n<template>\n <div>\n <ClearSearchInput @UserPressedClearSearchBoxButton=\"message = 'clear'\">Clear</ClearSearchInput>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `ClearSearchInput`\ncomponent communicates with the [`SearchInput`](./search-input.md), deleting the search term\nentered.\n\n_Type any term in the input field and then click the icon button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_resolveComponent","_openBlock","_createBlock","_withCtx","_renderSlot"],"mappings":";;;;;AASoB,EAAA,MAAA,0BAAA,GAAAA,gBAAA,CAAA,iBAAA,CAAA,CAAA;AALT,EAAA,OAAAC,SAAA,EAAwB,EAAAC,WAAA,CAAA,0BAAA,EAAA;AAAA,IAC/B,sBAAU,CAAoB,+BAAA,EAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,IAAA,MAAA,EAAA,IAAA,CAAA,sBAAA;AALlC,IAAA,WAAA,EAAA,oBAAA;AAAA,GAAA,EAAA;aAAAC,OAQW,CAAA,MAAA;AAAA,MAAAC,UAAA,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA,EAAA,EAAA,MAAA;;AARX,OAAA,CAAA;AAAA,KAAA,CAAA;;;;;;;;;"}
1
+ {"version":3,"file":"clear-search-input.vue.js","sources":["../../../../../src/x-modules/search-box/components/clear-search-input.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-clear-search-input x-button\"\n :class=\"dynamicClasses\"\n :events=\"clearSearchInputEvents\"\n data-test=\"clear-search-input\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport { computed, defineComponent, ref } from 'vue'\nimport BaseEventButton from '../../../components/base-event-button.vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to delete the current query.\n *\n * @remarks\n * A button that when pressed emits the {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * and {@link SearchBoxXEvents.UserClearedQuery} events, expressing the user intention to clear\n * the current query.\n * It also adds `x-clear-search-input--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'ClearSearchInput',\n components: { BaseEventButton },\n xModule: searchBoxXModule.name,\n setup() {\n const { query } = useState('searchBox')\n\n /**\n * The events dictionary that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n const clearSearchInputEvents = ref({\n UserPressedClearSearchBoxButton: undefined,\n })\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-clear-search-input--has-empty-query': isQueryEmpty.value,\n }))\n\n return {\n dynamicClasses,\n clearSearchInputEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserPressedClearSearchBoxButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserClearedQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\nHere a basic example of how the clear button is rendered.\n\n_Type any term in the input field and then click the Clear button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nIn this example, a custom text is passed in the default slot instead of the default text to\ncustomize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <ClearSearchInput>Clear</ClearSearchInput>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedClearSearchBoxButton` event is implemented, triggering the message\n“clear” when the clear search input button is clicked.\n\n_Click the Clear button to try it out!_\n\n```vue live\n<template>\n <div>\n <ClearSearchInput @UserPressedClearSearchBoxButton=\"message = 'clear'\">Clear</ClearSearchInput>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `ClearSearchInput`\ncomponent communicates with the [`SearchInput`](./search-input.md), deleting the search term\nentered.\n\n_Type any term in the input field and then click the icon button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_resolveComponent","_openBlock","_createBlock","_withCtx","_renderSlot"],"mappings":";;;;;AASoB,EAAA,MAAA,0BAAA,GAAAA,gBAAA,CAAA,iBAAA,CAAA,CAAA;AALT,EAAA,OAAAC,SAAA,EAAwB,EAAAC,WAAA,CAAA,0BAAA,EAAA;AAAA,IAC/B,sBAAU,CAAoB,+BAAA,EAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,IAAA,MAAA,EAAA,IAAA,CAAA,sBAAA;AALlC,IAAA,WAAA,EAAA,oBAAA;AAAA,GAAA,EAAA;aAAAC,OAQW,CAAA,MAAA;AAAA,MAAAC,UAAA,CAAA,IAAA,CAAA,MAAA,EAAA,SAAA,EAAA,EAAA,EAAA,MAAA;;AARX,OAAA,CAAA;AAAA,KAAA,CAAA;;;;;;;;;"}
@@ -19,7 +19,7 @@ var _sfc_main = defineComponent({
19
19
  components: { BaseEventButton },
20
20
  xModule: searchBoxXModule.name,
21
21
  setup() {
22
- const { query } = useState('searchBox', ['query']);
22
+ const { query } = useState('searchBox');
23
23
  /**
24
24
  * The events dictionary that are going to be emitted when the button is pressed.
25
25
  *
@@ -1 +1 @@
1
- {"version":3,"file":"clear-search-input.vue2.js","sources":["../../../../../src/x-modules/search-box/components/clear-search-input.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-clear-search-input x-button\"\n :class=\"dynamicClasses\"\n :events=\"clearSearchInputEvents\"\n data-test=\"clear-search-input\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport { computed, defineComponent, ref } from 'vue'\nimport BaseEventButton from '../../../components/base-event-button.vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to delete the current query.\n *\n * @remarks\n * A button that when pressed emits the {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * and {@link SearchBoxXEvents.UserClearedQuery} events, expressing the user intention to clear\n * the current query.\n * It also adds `x-clear-search-input--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'ClearSearchInput',\n components: { BaseEventButton },\n xModule: searchBoxXModule.name,\n setup() {\n const { query } = useState('searchBox', ['query'])\n\n /**\n * The events dictionary that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n const clearSearchInputEvents = ref({\n UserPressedClearSearchBoxButton: undefined,\n })\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-clear-search-input--has-empty-query': isQueryEmpty.value,\n }))\n\n return {\n dynamicClasses,\n clearSearchInputEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserPressedClearSearchBoxButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserClearedQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\nHere a basic example of how the clear button is rendered.\n\n_Type any term in the input field and then click the Clear button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nIn this example, a custom text is passed in the default slot instead of the default text to\ncustomize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <ClearSearchInput>Clear</ClearSearchInput>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedClearSearchBoxButton` event is implemented, triggering the message\n“clear” when the clear search input button is clicked.\n\n_Click the Clear button to try it out!_\n\n```vue live\n<template>\n <div>\n <ClearSearchInput @UserPressedClearSearchBoxButton=\"message = 'clear'\">Clear</ClearSearchInput>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `ClearSearchInput`\ncomponent communicates with the [`SearchInput`](./search-input.md), deleting the search term\nentered.\n\n_Type any term in the input field and then click the icon button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAmBA;;;;;;;;;;AAUE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,kBAAkB;IACxB,UAAU,EAAE,EAAE,eAAc,EAAG;IAC/B,OAAO,EAAE,gBAAgB,CAAC,IAAI;IAC9B,KAAK,GAAA;AACH,QAAA,MAAM,EAAE,KAAM,EAAA,GAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAA,CAAA;AAEjD;;;;AAIE;QACF,MAAM,sBAAuB,GAAE,GAAG,CAAC;AACjC,YAAA,+BAA+B,EAAE,SAAS;AAC3C,SAAA,CAAA,CAAA;AAED,QAAA,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,MAAO,KAAI,CAAC,CAAA,CAAA;AAE5D,QAAA,MAAM,cAAe,GAAE,QAAQ,CAAgB,OAAO;YACpD,uCAAuC,EAAE,YAAY,CAAC,KAAK;AAC5D,SAAA,CAAC,CAAA,CAAA;QAEF,OAAO;YACL,cAAc;YACd,sBAAsB;SACxB,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"clear-search-input.vue2.js","sources":["../../../../../src/x-modules/search-box/components/clear-search-input.vue"],"sourcesContent":["<template>\n <BaseEventButton\n class=\"x-clear-search-input x-button\"\n :class=\"dynamicClasses\"\n :events=\"clearSearchInputEvents\"\n data-test=\"clear-search-input\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot>✕</slot>\n </BaseEventButton>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport { computed, defineComponent, ref } from 'vue'\nimport BaseEventButton from '../../../components/base-event-button.vue'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to delete the current query.\n *\n * @remarks\n * A button that when pressed emits the {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * and {@link SearchBoxXEvents.UserClearedQuery} events, expressing the user intention to clear\n * the current query.\n * It also adds `x-clear-search-input--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'ClearSearchInput',\n components: { BaseEventButton },\n xModule: searchBoxXModule.name,\n setup() {\n const { query } = useState('searchBox')\n\n /**\n * The events dictionary that are going to be emitted when the button is pressed.\n *\n * @internal\n */\n const clearSearchInputEvents = ref({\n UserPressedClearSearchBoxButton: undefined,\n })\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-clear-search-input--has-empty-query': isQueryEmpty.value,\n }))\n\n return {\n dynamicClasses,\n clearSearchInputEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserPressedClearSearchBoxButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserClearedQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\nHere a basic example of how the clear button is rendered.\n\n_Type any term in the input field and then click the Clear button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nIn this example, a custom text is passed in the default slot instead of the default text to\ncustomize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <ClearSearchInput>Clear</ClearSearchInput>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedClearSearchBoxButton` event is implemented, triggering the message\n“clear” when the clear search input button is clicked.\n\n_Click the Clear button to try it out!_\n\n```vue live\n<template>\n <div>\n <ClearSearchInput @UserPressedClearSearchBoxButton=\"message = 'clear'\">Clear</ClearSearchInput>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n ClearSearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `ClearSearchInput`\ncomponent communicates with the [`SearchInput`](./search-input.md), deleting the search term\nentered.\n\n_Type any term in the input field and then click the icon button to try it out!_\n\n```vue live\n<template>\n <div style=\"display: flex;\">\n <SearchInput />\n <ClearSearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'ClearSearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAmBA;;;;;;;;;;AAUE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,kBAAkB;IACxB,UAAU,EAAE,EAAE,eAAc,EAAG;IAC/B,OAAO,EAAE,gBAAgB,CAAC,IAAI;IAC9B,KAAK,GAAA;QACH,MAAM,EAAE,KAAI,EAAI,GAAE,QAAQ,CAAC,WAAW,CAAA,CAAA;AAEtC;;;;AAIE;QACF,MAAM,sBAAuB,GAAE,GAAG,CAAC;AACjC,YAAA,+BAA+B,EAAE,SAAS;AAC3C,SAAA,CAAA,CAAA;AAED,QAAA,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,MAAO,KAAI,CAAC,CAAA,CAAA;AAE5D,QAAA,MAAM,cAAe,GAAE,QAAQ,CAAgB,OAAO;YACpD,uCAAuC,EAAE,YAAY,CAAC,KAAK;AAC5D,SAAA,CAAC,CAAA,CAAA;QAEF,OAAO;YACL,cAAc;YACd,sBAAsB;SACxB,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-button.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-button.vue"],"sourcesContent":["<template>\n <button\n ref=\"buttonRef\"\n class=\"x-search-button x-button\"\n :class=\"dynamicClasses\"\n data-test=\"search-button\"\n @click=\"emitEvents\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot><span class=\"x-icon\">⌕</span></slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { ComputedRef } from 'vue'\nimport type { VueCSSClasses } from '../../../utils/types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { computed, defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to submit the query.\n *\n * @remarks\n * If query is not empty, it emits {@link XEventsTypes.UserAcceptedAQuery} and\n * {@link SearchBoxXEvents.UserPressedSearchButton} events with the query as payload.\n * It also adds `x-search-button--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchButton',\n xModule: searchBoxXModule.name,\n setup() {\n const $x = use$x()\n\n const buttonRef = ref<HTMLElement | null>(null)\n\n const query: ComputedRef<string> = useState('searchBox', ['query']).query\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-search-button--has-empty-query': isQueryEmpty.value,\n }))\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n function createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: buttonRef.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n function emitEvents() {\n if (!isQueryEmpty.value) {\n $x.emit('UserAcceptedAQuery', query.value, createEventMetadata())\n $x.emit('UserPressedSearchButton', query.value, createEventMetadata())\n }\n }\n\n return {\n dynamicClasses,\n buttonRef,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserAcceptedAQuery`]https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedSearchButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n<!-- prettier-ignore-start -->\n:::warning\nNote that no events are emitted if the query is empty.\n:::\n<!-- prettier-ignore-end -->\n\n## Dynamic classes\n\n`SearchButton` uses the `x-search-button--has-empty-query` dynamic CSS class to modify the HTML\nbutton style when the query is empty.\n\n## See it in action\n\nIn this example, a clickable button is rendered.\n\n_Click the Search button to try it out!_\n\n```vue live\n<template>\n <SearchButton />\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nHere text is passed in the default slot instead of an icon to customize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <SearchButton>Search</SearchButton>\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedSearchButton` event has been implemented so that when you enter a\nsearch term and click the Search button, the search term is displayed as a message.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton\n @UserPressedSearchButton=\"\n query => {\n message = query\n }\n \"\n />\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchInput,\n SearchButton,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchButton` component\ncommunicates with the [`SearchInput`](./search-input.md) to submit the query. In this example, when\nyou enter a search term and click the Search button, the “Looking for results” message is displayed.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton @UserAcceptedAQuery=\"message = 'looking for results'\">Search</SearchButton>\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchButton, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n SearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass"],"mappings":";;;;;;;;;;;SAEQ,WAAW,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;SACVA,SAHT,EAAA,EAAAC,kBAAA;AAAA,IAGU,QAAA;AAAA,IAA0B;AAAA,MAEhC,GAAA,EAAA,WAAA;AAAA,MACC,OAAKC,cAAE,CAAA,CAAA,0BAAA,EAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,MAAA,WAAA,EAAA,eAAA;MAGR,OAA0C,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,UAAA,IAAA,IAAA,CAAA,UAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"search-button.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-button.vue"],"sourcesContent":["<template>\n <button\n ref=\"buttonRef\"\n class=\"x-search-button x-button\"\n :class=\"dynamicClasses\"\n data-test=\"search-button\"\n @click=\"emitEvents\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot><span class=\"x-icon\">⌕</span></slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { computed, defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to submit the query.\n *\n * @remarks\n * If query is not empty, it emits {@link XEventsTypes.UserAcceptedAQuery} and\n * {@link SearchBoxXEvents.UserPressedSearchButton} events with the query as payload.\n * It also adds `x-search-button--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchButton',\n xModule: searchBoxXModule.name,\n setup() {\n const $x = use$x()\n\n const buttonRef = ref<HTMLElement | null>(null)\n\n const { query } = useState('searchBox')\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-search-button--has-empty-query': isQueryEmpty.value,\n }))\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n function createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: buttonRef.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n function emitEvents() {\n if (!isQueryEmpty.value) {\n $x.emit('UserAcceptedAQuery', query.value, createEventMetadata())\n $x.emit('UserPressedSearchButton', query.value, createEventMetadata())\n }\n }\n\n return {\n dynamicClasses,\n buttonRef,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserAcceptedAQuery`]https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedSearchButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n<!-- prettier-ignore-start -->\n:::warning\nNote that no events are emitted if the query is empty.\n:::\n<!-- prettier-ignore-end -->\n\n## Dynamic classes\n\n`SearchButton` uses the `x-search-button--has-empty-query` dynamic CSS class to modify the HTML\nbutton style when the query is empty.\n\n## See it in action\n\nIn this example, a clickable button is rendered.\n\n_Click the Search button to try it out!_\n\n```vue live\n<template>\n <SearchButton />\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nHere text is passed in the default slot instead of an icon to customize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <SearchButton>Search</SearchButton>\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedSearchButton` event has been implemented so that when you enter a\nsearch term and click the Search button, the search term is displayed as a message.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton\n @UserPressedSearchButton=\"\n query => {\n message = query\n }\n \"\n />\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchInput,\n SearchButton,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchButton` component\ncommunicates with the [`SearchInput`](./search-input.md) to submit the query. In this example, when\nyou enter a search term and click the Search button, the “Looking for results” message is displayed.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton @UserAcceptedAQuery=\"message = 'looking for results'\">Search</SearchButton>\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchButton, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n SearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock","_normalizeClass"],"mappings":";;;;;;;;;;;SAEQ,WAAW,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;SACVA,SAHT,EAAA,EAAAC,kBAAA;AAAA,IAGU,QAAA;AAAA,IAA0B;AAAA,MAEhC,GAAA,EAAA,WAAA;AAAA,MACC,OAAKC,cAAE,CAAA,CAAA,0BAAA,EAAA,IAAA,CAAA,cAAA,CAAA,CAAA;AAAA,MAAA,WAAA,EAAA,eAAA;MAGR,OAA0C,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,UAAA,IAAA,IAAA,CAAA,UAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;;;;;;;"}
@@ -19,7 +19,7 @@ var _sfc_main = defineComponent({
19
19
  setup() {
20
20
  const $x = use$x();
21
21
  const buttonRef = ref(null);
22
- const query = useState('searchBox', ['query']).query;
22
+ const { query } = useState('searchBox');
23
23
  const isQueryEmpty = computed(() => query.value.length === 0);
24
24
  const dynamicClasses = computed(() => ({
25
25
  'x-search-button--has-empty-query': isQueryEmpty.value,
@@ -1 +1 @@
1
- {"version":3,"file":"search-button.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-button.vue"],"sourcesContent":["<template>\n <button\n ref=\"buttonRef\"\n class=\"x-search-button x-button\"\n :class=\"dynamicClasses\"\n data-test=\"search-button\"\n @click=\"emitEvents\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot><span class=\"x-icon\">⌕</span></slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { ComputedRef } from 'vue'\nimport type { VueCSSClasses } from '../../../utils/types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { computed, defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to submit the query.\n *\n * @remarks\n * If query is not empty, it emits {@link XEventsTypes.UserAcceptedAQuery} and\n * {@link SearchBoxXEvents.UserPressedSearchButton} events with the query as payload.\n * It also adds `x-search-button--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchButton',\n xModule: searchBoxXModule.name,\n setup() {\n const $x = use$x()\n\n const buttonRef = ref<HTMLElement | null>(null)\n\n const query: ComputedRef<string> = useState('searchBox', ['query']).query\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-search-button--has-empty-query': isQueryEmpty.value,\n }))\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n function createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: buttonRef.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n function emitEvents() {\n if (!isQueryEmpty.value) {\n $x.emit('UserAcceptedAQuery', query.value, createEventMetadata())\n $x.emit('UserPressedSearchButton', query.value, createEventMetadata())\n }\n }\n\n return {\n dynamicClasses,\n buttonRef,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserAcceptedAQuery`]https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedSearchButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n<!-- prettier-ignore-start -->\n:::warning\nNote that no events are emitted if the query is empty.\n:::\n<!-- prettier-ignore-end -->\n\n## Dynamic classes\n\n`SearchButton` uses the `x-search-button--has-empty-query` dynamic CSS class to modify the HTML\nbutton style when the query is empty.\n\n## See it in action\n\nIn this example, a clickable button is rendered.\n\n_Click the Search button to try it out!_\n\n```vue live\n<template>\n <SearchButton />\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nHere text is passed in the default slot instead of an icon to customize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <SearchButton>Search</SearchButton>\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedSearchButton` event has been implemented so that when you enter a\nsearch term and click the Search button, the search term is displayed as a message.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton\n @UserPressedSearchButton=\"\n query => {\n message = query\n }\n \"\n />\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchInput,\n SearchButton,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchButton` component\ncommunicates with the [`SearchInput`](./search-input.md) to submit the query. In this example, when\nyou enter a search term and click the Search button, the “Looking for results” message is displayed.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton @UserAcceptedAQuery=\"message = 'looking for results'\">Search</SearchButton>\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchButton, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n SearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAsBA;;;;;;;;;AASE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,gBAAgB,CAAC,IAAI;IAC9B,KAAK,GAAA;AACH,QAAA,MAAM,EAAC,GAAI,KAAK,EAAC,CAAA;AAEjB,QAAA,MAAM,SAAQ,GAAI,GAAG,CAAqB,IAAI,CAAA,CAAA;AAE9C,QAAA,MAAM,KAAK,GAAwB,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,KAAI,CAAA;AAExE,QAAA,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,MAAO,KAAI,CAAC,CAAA,CAAA;AAE5D,QAAA,MAAM,cAAe,GAAE,QAAQ,CAAgB,OAAO;YACpD,kCAAkC,EAAE,YAAY,CAAC,KAAK;AACvD,SAAA,CAAC,CAAA,CAAA;AAEF;;;;;AAKE;AACF,QAAA,SAAS,mBAAmB,GAAA;YAC1B,OAAO;gBACL,MAAM,EAAE,SAAS,CAAC,KAAK;AACvB,gBAAA,OAAO,EAAE,YAAY;aACvB,CAAA;SACF;AAEA;;;;AAIE;AACF,QAAA,SAAS,UAAU,GAAA;AACjB,YAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AACvB,gBAAA,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAA,CAAA;AAChE,gBAAA,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAA,CAAA;AACvE,aAAA;SACF;QAEA,OAAO;YACL,cAAc;YACd,SAAS;YACT,UAAU;SACZ,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
1
+ {"version":3,"file":"search-button.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-button.vue"],"sourcesContent":["<template>\n <button\n ref=\"buttonRef\"\n class=\"x-search-button x-button\"\n :class=\"dynamicClasses\"\n data-test=\"search-button\"\n @click=\"emitEvents\"\n >\n <!-- @slot _Required_. Button content (text, icon, or both) -->\n <slot><span class=\"x-icon\">⌕</span></slot>\n </button>\n</template>\n\n<script lang=\"ts\">\nimport type { VueCSSClasses } from '../../../utils/types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { computed, defineComponent, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders a button to submit the query.\n *\n * @remarks\n * If query is not empty, it emits {@link XEventsTypes.UserAcceptedAQuery} and\n * {@link SearchBoxXEvents.UserPressedSearchButton} events with the query as payload.\n * It also adds `x-search-button--has-empty-query` as class when there is no query.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchButton',\n xModule: searchBoxXModule.name,\n setup() {\n const $x = use$x()\n\n const buttonRef = ref<HTMLElement | null>(null)\n\n const { query } = useState('searchBox')\n\n const isQueryEmpty = computed(() => query.value.length === 0)\n\n const dynamicClasses = computed<VueCSSClasses>(() => ({\n 'x-search-button--has-empty-query': isQueryEmpty.value,\n }))\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n function createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: buttonRef.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits events when the button is clicked.\n *\n * @public\n */\n function emitEvents() {\n if (!isQueryEmpty.value) {\n $x.emit('UserAcceptedAQuery', query.value, createEventMetadata())\n $x.emit('UserPressedSearchButton', query.value, createEventMetadata())\n }\n }\n\n return {\n dynamicClasses,\n buttonRef,\n emitEvents,\n }\n },\n})\n</script>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserAcceptedAQuery`]https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedSearchButton`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n<!-- prettier-ignore-start -->\n:::warning\nNote that no events are emitted if the query is empty.\n:::\n<!-- prettier-ignore-end -->\n\n## Dynamic classes\n\n`SearchButton` uses the `x-search-button--has-empty-query` dynamic CSS class to modify the HTML\nbutton style when the query is empty.\n\n## See it in action\n\nIn this example, a clickable button is rendered.\n\n_Click the Search button to try it out!_\n\n```vue live\n<template>\n <SearchButton />\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with default slot\n\nHere text is passed in the default slot instead of an icon to customize the button content.\n\n_Click the icon button to try it out!_\n\n```vue live\n<template>\n <SearchButton>Search</SearchButton>\n</template>\n\n<script>\nimport { SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, the `UserPressedSearchButton` event has been implemented so that when you enter a\nsearch term and click the Search button, the search term is displayed as a message.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton\n @UserPressedSearchButton=\"\n query => {\n message = query\n }\n \"\n />\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchButton } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchInput,\n SearchButton,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchButton` component\ncommunicates with the [`SearchInput`](./search-input.md) to submit the query. In this example, when\nyou enter a search term and click the Search button, the “Looking for results” message is displayed.\n\n_Type any term in the input field and then click the Search button to try it out!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex;\">\n <SearchInput />\n <SearchButton @UserAcceptedAQuery=\"message = 'looking for results'\">Search</SearchButton>\n </div>\n {{ message }}\n </div>\n</template>\n\n<script>\nimport { SearchButton, SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchButtonDemo',\n components: {\n SearchButton,\n SearchInput,\n },\n data() {\n return {\n message: '',\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAqBA;;;;;;;;;AASE;AACF,gBAAe,eAAe,CAAC;AAC7B,IAAA,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,gBAAgB,CAAC,IAAI;IAC9B,KAAK,GAAA;AACH,QAAA,MAAM,EAAC,GAAI,KAAK,EAAC,CAAA;AAEjB,QAAA,MAAM,SAAQ,GAAI,GAAG,CAAqB,IAAI,CAAA,CAAA;QAE9C,MAAM,EAAE,KAAI,EAAI,GAAE,QAAQ,CAAC,WAAW,CAAA,CAAA;AAEtC,QAAA,MAAM,YAAW,GAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,MAAO,KAAI,CAAC,CAAA,CAAA;AAE5D,QAAA,MAAM,cAAe,GAAE,QAAQ,CAAgB,OAAO;YACpD,kCAAkC,EAAE,YAAY,CAAC,KAAK;AACvD,SAAA,CAAC,CAAA,CAAA;AAEF;;;;;AAKE;AACF,QAAA,SAAS,mBAAmB,GAAA;YAC1B,OAAO;gBACL,MAAM,EAAE,SAAS,CAAC,KAAK;AACvB,gBAAA,OAAO,EAAE,YAAY;aACvB,CAAA;SACF;AAEA;;;;AAIE;AACF,QAAA,SAAS,UAAU,GAAA;AACjB,YAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AACvB,gBAAA,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAA,CAAA;AAChE,gBAAA,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAA,CAAA;AACvE,aAAA;SACF;QAEA,OAAO;YACL,cAAc;YACd,SAAS;YACT,UAAU;SACZ,CAAA;KACD;AACF,CAAA,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-input-placeholder.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input-placeholder.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n v-if=\"isVisible\"\n class=\"x-input-placeholder x-search-input-placeholder\"\n mode=\"out-in\"\n >\n <span :key=\"message\" data-test=\"search-input-placeholder\">\n {{ message }}\n </span>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { computed, defineComponent, onBeforeUnmount, ref, watch } from 'vue'\nimport { animateTranslate } from '../../../components/animations/animate-translate/animate-translate.factory'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { AnimationProp } from '../../../types'\nimport { searchBoxXModule } from '../x-module'\n\n/**.\n * This component renders an animated placeholder for the search input in the shape of a list of\n * iterating messages that can be configured to happen always or only when hovering the input\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInputPlaceholder',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * List of messages to animate.\n *\n * @public\n */\n messages: {\n type: Array as PropType<string[]>,\n required: true,\n },\n /**\n * Animation component used for the messages.\n *\n * @public\n */\n animation: {\n type: AnimationProp,\n default: () => animateTranslate('bottom-to-top'),\n },\n /**\n * Time in milliseconds during which each message is visible.\n *\n * @public\n */\n animationIntervalMs: {\n type: Number,\n default: 1500,\n },\n /**\n * Whether the messages animation is active only when hovering the search input or always.\n *\n * @public\n */\n animateOnlyOnHover: Boolean,\n },\n setup(props) {\n const $x = use$x()\n\n /**.\n * The search box written query\n *\n * @internal\n */\n const { query } = useState('searchBox', ['query'])\n\n /**.\n * The search box hover status\n *\n * @internal\n */\n const isSearchBoxHovered = ref(false)\n\n /**.\n * The search box focus status\n *\n * @internal\n */\n const isSearchBoxFocused = ref(false)\n\n /**\n * The index used to point to the current animation message in the list.\n *\n * @internal\n */\n const animationMessageIndex = ref(0)\n\n /**\n * The interval used for the animation.\n *\n * @internal\n */\n const animationInterval = ref<number | undefined>(undefined)\n\n /**\n * The visibility state of the component.\n *\n * @returns The visibility state based on the search input state (query & focus).\n *\n * @internal\n */\n const isVisible = computed((): boolean => !query.value && !isSearchBoxFocused.value)\n\n /**\n * The animation state of the component.\n *\n * @returns Whether the animation is active or not.\n *\n * @internal\n */\n const isBeingAnimated = computed(\n (): boolean => isVisible.value && (!props.animateOnlyOnHover || isSearchBoxHovered.value),\n )\n\n /**\n * The current placeholder message.\n *\n * @returns The message to display as placeholder at any moment.\n *\n * @internal\n */\n const message = computed((): string | undefined =>\n isBeingAnimated.value ? props.messages[animationMessageIndex.value] : props.messages[0],\n )\n\n /**\n * Clears the interval used for the animation.\n *\n * @internal\n */\n const stopAnimationInterval = (): void => {\n if (animationInterval.value) {\n clearInterval(animationInterval.value)\n animationInterval.value = undefined\n }\n }\n\n /**\n * Increments animation message index; if the new index exceeds the messages list length, it is\n * reset to 0.\n *\n * @internal\n */\n const incrementAnimationMessageIndex = (): void => {\n animationMessageIndex.value = (animationMessageIndex.value + 1) % props.messages.length\n }\n\n $x.on('UserHoveredInSearchBox', false).subscribe(() => (isSearchBoxHovered.value = true))\n\n $x.on('UserHoveredOutSearchBox', false).subscribe(() => (isSearchBoxHovered.value = false))\n\n $x.on('UserFocusedSearchBox', false).subscribe(() => (isSearchBoxFocused.value = true))\n\n $x.on('UserBlurredSearchBox', false).subscribe(() => (isSearchBoxFocused.value = false))\n\n /**\n * Starts or stops the animation depending on the current animation state.\n *\n * @internal\n */\n const resetAnimation = (): void => {\n stopAnimationInterval()\n if (isBeingAnimated.value) {\n animationInterval.value = window.setInterval((): void => {\n incrementAnimationMessageIndex()\n }, props.animationIntervalMs)\n }\n }\n\n watch(() => 'animationIntervalMs', resetAnimation)\n\n /**\n * Resets the animation message index to zero.\n *\n * @internal\n */\n const resetAnimationMessageIndex = (): void => {\n animationMessageIndex.value = 0\n }\n\n watch(\n () => props.messages,\n () => {\n resetAnimationMessageIndex()\n resetAnimation()\n },\n { deep: true },\n )\n\n /**\n * Sets the animation message index with the right value for the next future iteration when the\n * current one stops,assuring the user will see always a new message on each animation state\n * change.\n *\n * @internal\n */\n watch(\n isBeingAnimated,\n () => {\n if (!isBeingAnimated.value) {\n if (props.animateOnlyOnHover) {\n resetAnimationMessageIndex()\n }\n incrementAnimationMessageIndex()\n }\n resetAnimation()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n stopAnimationInterval()\n })\n\n return {\n isVisible,\n message,\n }\n },\n})\n</script>\n\n<style lang=\"css\">\n.x-search-input-placeholder-container {\n position: relative;\n}\n</style>\n\n<style lang=\"css\" scoped>\n.x-search-input-placeholder {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n pointer-events: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## See it in action\n\nHere a basic example of how the animated search input placeholder is rendered.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n\n### Animating only on hover\n\nIn this example, the placeholder is configured to animate only when the user hovers in the search\ninput, showing the first message of the array the rest of the time.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n :animate-only-on-hover=\"true\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":["animation","_openBlock","_createBlock","_resolveDynamicComponent","message","_createElementBlock","_toDisplayString","_createCommentVNode"],"mappings":";;;;;;AACE,SAAA,WAAA,CAAA,IAAA,EAAA,MAAA,EADF,MAESA,EAAAA,MAAAA,EAAAA,KAAAA,EAAAA,QAAAA,EAAAA;AAFT,EAAA,OAAA,IAAA,CAAA,SAAA,IAAAC,SAAA,EAI0D,EAAAC,WAAA,CAAAC,uBAAA,CAAA,IAAA,CAAA,SAAA,CAAA,EAAA;AAAA,IACtD,GAAI,EAAA,CAAA;AAAA,IAAA,KAAA,EAAA,gDAAA;AALR,IAAA,IAAA,EAAA,QAAA;AAAA,GAAA,EAAA;aAOgBC,OAAO,CAAA,MAAA;AAAA,OAAAH,SAAA,EAAY,EAAAI,kBAAA;AAAA,QAAA,MAAA;AAAA,QAA0B;AAAA,UAAA,GAAA,EAAA,IAAA,CAAA,OAAA;;AAP7D,SAAA;AAAA,QAAAC,eAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AAAA,QAAA,CAAA;AAAA;AAAA,OAAA;AAAA,KAAA,CAAA;AAAA,IAAA,CAAA,EAAA,CAAA;AAAA;AAAA,GAAA,CAAA,IAAAC,kBAAA,CAAA,MAAA,EAAA,IAAA,CAAA,CAAA;;;;;;"}
1
+ {"version":3,"file":"search-input-placeholder.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input-placeholder.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n v-if=\"isVisible\"\n class=\"x-input-placeholder x-search-input-placeholder\"\n mode=\"out-in\"\n >\n <span :key=\"message\" data-test=\"search-input-placeholder\">\n {{ message }}\n </span>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { computed, defineComponent, onBeforeUnmount, ref, watch } from 'vue'\nimport { animateTranslate } from '../../../components/animations/animate-translate/animate-translate.factory'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { AnimationProp } from '../../../types'\nimport { searchBoxXModule } from '../x-module'\n\n/**.\n * This component renders an animated placeholder for the search input in the shape of a list of\n * iterating messages that can be configured to happen always or only when hovering the input\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInputPlaceholder',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * List of messages to animate.\n *\n * @public\n */\n messages: {\n type: Array as PropType<string[]>,\n required: true,\n },\n /**\n * Animation component used for the messages.\n *\n * @public\n */\n animation: {\n type: AnimationProp,\n default: () => animateTranslate('bottom-to-top'),\n },\n /**\n * Time in milliseconds during which each message is visible.\n *\n * @public\n */\n animationIntervalMs: {\n type: Number,\n default: 1500,\n },\n /**\n * Whether the messages animation is active only when hovering the search input or always.\n *\n * @public\n */\n animateOnlyOnHover: Boolean,\n },\n setup(props) {\n const $x = use$x()\n\n /**.\n * The search box written query\n *\n * @internal\n */\n const { query } = useState('searchBox')\n\n /**.\n * The search box hover status\n *\n * @internal\n */\n const isSearchBoxHovered = ref(false)\n\n /**.\n * The search box focus status\n *\n * @internal\n */\n const isSearchBoxFocused = ref(false)\n\n /**\n * The index used to point to the current animation message in the list.\n *\n * @internal\n */\n const animationMessageIndex = ref(0)\n\n /**\n * The interval used for the animation.\n *\n * @internal\n */\n const animationInterval = ref<number | undefined>(undefined)\n\n /**\n * The visibility state of the component.\n *\n * @returns The visibility state based on the search input state (query & focus).\n *\n * @internal\n */\n const isVisible = computed((): boolean => !query.value && !isSearchBoxFocused.value)\n\n /**\n * The animation state of the component.\n *\n * @returns Whether the animation is active or not.\n *\n * @internal\n */\n const isBeingAnimated = computed(\n (): boolean => isVisible.value && (!props.animateOnlyOnHover || isSearchBoxHovered.value),\n )\n\n /**\n * The current placeholder message.\n *\n * @returns The message to display as placeholder at any moment.\n *\n * @internal\n */\n const message = computed((): string | undefined =>\n isBeingAnimated.value ? props.messages[animationMessageIndex.value] : props.messages[0],\n )\n\n /**\n * Clears the interval used for the animation.\n *\n * @internal\n */\n const stopAnimationInterval = (): void => {\n if (animationInterval.value) {\n clearInterval(animationInterval.value)\n animationInterval.value = undefined\n }\n }\n\n /**\n * Increments animation message index; if the new index exceeds the messages list length, it is\n * reset to 0.\n *\n * @internal\n */\n const incrementAnimationMessageIndex = (): void => {\n animationMessageIndex.value = (animationMessageIndex.value + 1) % props.messages.length\n }\n\n $x.on('UserHoveredInSearchBox', false).subscribe(() => (isSearchBoxHovered.value = true))\n\n $x.on('UserHoveredOutSearchBox', false).subscribe(() => (isSearchBoxHovered.value = false))\n\n $x.on('UserFocusedSearchBox', false).subscribe(() => (isSearchBoxFocused.value = true))\n\n $x.on('UserBlurredSearchBox', false).subscribe(() => (isSearchBoxFocused.value = false))\n\n /**\n * Starts or stops the animation depending on the current animation state.\n *\n * @internal\n */\n const resetAnimation = (): void => {\n stopAnimationInterval()\n if (isBeingAnimated.value) {\n animationInterval.value = window.setInterval((): void => {\n incrementAnimationMessageIndex()\n }, props.animationIntervalMs)\n }\n }\n\n watch(() => 'animationIntervalMs', resetAnimation)\n\n /**\n * Resets the animation message index to zero.\n *\n * @internal\n */\n const resetAnimationMessageIndex = (): void => {\n animationMessageIndex.value = 0\n }\n\n watch(\n () => props.messages,\n () => {\n resetAnimationMessageIndex()\n resetAnimation()\n },\n { deep: true },\n )\n\n /**\n * Sets the animation message index with the right value for the next future iteration when the\n * current one stops,assuring the user will see always a new message on each animation state\n * change.\n *\n * @internal\n */\n watch(\n isBeingAnimated,\n () => {\n if (!isBeingAnimated.value) {\n if (props.animateOnlyOnHover) {\n resetAnimationMessageIndex()\n }\n incrementAnimationMessageIndex()\n }\n resetAnimation()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n stopAnimationInterval()\n })\n\n return {\n isVisible,\n message,\n }\n },\n})\n</script>\n\n<style lang=\"css\">\n.x-search-input-placeholder-container {\n position: relative;\n}\n</style>\n\n<style lang=\"css\" scoped>\n.x-search-input-placeholder {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n pointer-events: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## See it in action\n\nHere a basic example of how the animated search input placeholder is rendered.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n\n### Animating only on hover\n\nIn this example, the placeholder is configured to animate only when the user hovers in the search\ninput, showing the first message of the array the rest of the time.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n :animate-only-on-hover=\"true\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":["animation","_openBlock","_createBlock","_resolveDynamicComponent","message","_createElementBlock","_toDisplayString","_createCommentVNode"],"mappings":";;;;;;AACE,SAAA,WAAA,CAAA,IAAA,EAAA,MAAA,EADF,MAESA,EAAAA,MAAAA,EAAAA,KAAAA,EAAAA,QAAAA,EAAAA;AAFT,EAAA,OAAA,IAAA,CAAA,SAAA,IAAAC,SAAA,EAI0D,EAAAC,WAAA,CAAAC,uBAAA,CAAA,IAAA,CAAA,SAAA,CAAA,EAAA;AAAA,IACtD,GAAI,EAAA,CAAA;AAAA,IAAA,KAAA,EAAA,gDAAA;AALR,IAAA,IAAA,EAAA,QAAA;AAAA,GAAA,EAAA;aAOgBC,OAAO,CAAA,MAAA;AAAA,OAAAH,SAAA,EAAY,EAAAI,kBAAA;AAAA,QAAA,MAAA;AAAA,QAA0B;AAAA,UAAA,GAAA,EAAA,IAAA,CAAA,OAAA;;AAP7D,SAAA;AAAA,QAAAC,eAAA,CAAA,IAAA,CAAA,OAAA,CAAA;AAAA,QAAA,CAAA;AAAA;AAAA,OAAA;AAAA,KAAA,CAAA;AAAA,IAAA,CAAA,EAAA,CAAA;AAAA;AAAA,GAAA,CAAA,IAAAC,kBAAA,CAAA,MAAA,EAAA,IAAA,CAAA,CAAA;;;;;;"}
@@ -56,7 +56,7 @@ var _sfc_main = defineComponent({
56
56
  *
57
57
  * @internal
58
58
  */
59
- const { query } = useState('searchBox', ['query']);
59
+ const { query } = useState('searchBox');
60
60
  /**.
61
61
  * The search box hover status
62
62
  *
@@ -1 +1 @@
1
- {"version":3,"file":"search-input-placeholder.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-input-placeholder.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n v-if=\"isVisible\"\n class=\"x-input-placeholder x-search-input-placeholder\"\n mode=\"out-in\"\n >\n <span :key=\"message\" data-test=\"search-input-placeholder\">\n {{ message }}\n </span>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { computed, defineComponent, onBeforeUnmount, ref, watch } from 'vue'\nimport { animateTranslate } from '../../../components/animations/animate-translate/animate-translate.factory'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { AnimationProp } from '../../../types'\nimport { searchBoxXModule } from '../x-module'\n\n/**.\n * This component renders an animated placeholder for the search input in the shape of a list of\n * iterating messages that can be configured to happen always or only when hovering the input\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInputPlaceholder',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * List of messages to animate.\n *\n * @public\n */\n messages: {\n type: Array as PropType<string[]>,\n required: true,\n },\n /**\n * Animation component used for the messages.\n *\n * @public\n */\n animation: {\n type: AnimationProp,\n default: () => animateTranslate('bottom-to-top'),\n },\n /**\n * Time in milliseconds during which each message is visible.\n *\n * @public\n */\n animationIntervalMs: {\n type: Number,\n default: 1500,\n },\n /**\n * Whether the messages animation is active only when hovering the search input or always.\n *\n * @public\n */\n animateOnlyOnHover: Boolean,\n },\n setup(props) {\n const $x = use$x()\n\n /**.\n * The search box written query\n *\n * @internal\n */\n const { query } = useState('searchBox', ['query'])\n\n /**.\n * The search box hover status\n *\n * @internal\n */\n const isSearchBoxHovered = ref(false)\n\n /**.\n * The search box focus status\n *\n * @internal\n */\n const isSearchBoxFocused = ref(false)\n\n /**\n * The index used to point to the current animation message in the list.\n *\n * @internal\n */\n const animationMessageIndex = ref(0)\n\n /**\n * The interval used for the animation.\n *\n * @internal\n */\n const animationInterval = ref<number | undefined>(undefined)\n\n /**\n * The visibility state of the component.\n *\n * @returns The visibility state based on the search input state (query & focus).\n *\n * @internal\n */\n const isVisible = computed((): boolean => !query.value && !isSearchBoxFocused.value)\n\n /**\n * The animation state of the component.\n *\n * @returns Whether the animation is active or not.\n *\n * @internal\n */\n const isBeingAnimated = computed(\n (): boolean => isVisible.value && (!props.animateOnlyOnHover || isSearchBoxHovered.value),\n )\n\n /**\n * The current placeholder message.\n *\n * @returns The message to display as placeholder at any moment.\n *\n * @internal\n */\n const message = computed((): string | undefined =>\n isBeingAnimated.value ? props.messages[animationMessageIndex.value] : props.messages[0],\n )\n\n /**\n * Clears the interval used for the animation.\n *\n * @internal\n */\n const stopAnimationInterval = (): void => {\n if (animationInterval.value) {\n clearInterval(animationInterval.value)\n animationInterval.value = undefined\n }\n }\n\n /**\n * Increments animation message index; if the new index exceeds the messages list length, it is\n * reset to 0.\n *\n * @internal\n */\n const incrementAnimationMessageIndex = (): void => {\n animationMessageIndex.value = (animationMessageIndex.value + 1) % props.messages.length\n }\n\n $x.on('UserHoveredInSearchBox', false).subscribe(() => (isSearchBoxHovered.value = true))\n\n $x.on('UserHoveredOutSearchBox', false).subscribe(() => (isSearchBoxHovered.value = false))\n\n $x.on('UserFocusedSearchBox', false).subscribe(() => (isSearchBoxFocused.value = true))\n\n $x.on('UserBlurredSearchBox', false).subscribe(() => (isSearchBoxFocused.value = false))\n\n /**\n * Starts or stops the animation depending on the current animation state.\n *\n * @internal\n */\n const resetAnimation = (): void => {\n stopAnimationInterval()\n if (isBeingAnimated.value) {\n animationInterval.value = window.setInterval((): void => {\n incrementAnimationMessageIndex()\n }, props.animationIntervalMs)\n }\n }\n\n watch(() => 'animationIntervalMs', resetAnimation)\n\n /**\n * Resets the animation message index to zero.\n *\n * @internal\n */\n const resetAnimationMessageIndex = (): void => {\n animationMessageIndex.value = 0\n }\n\n watch(\n () => props.messages,\n () => {\n resetAnimationMessageIndex()\n resetAnimation()\n },\n { deep: true },\n )\n\n /**\n * Sets the animation message index with the right value for the next future iteration when the\n * current one stops,assuring the user will see always a new message on each animation state\n * change.\n *\n * @internal\n */\n watch(\n isBeingAnimated,\n () => {\n if (!isBeingAnimated.value) {\n if (props.animateOnlyOnHover) {\n resetAnimationMessageIndex()\n }\n incrementAnimationMessageIndex()\n }\n resetAnimation()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n stopAnimationInterval()\n })\n\n return {\n isVisible,\n message,\n }\n },\n})\n</script>\n\n<style lang=\"css\">\n.x-search-input-placeholder-container {\n position: relative;\n}\n</style>\n\n<style lang=\"css\" scoped>\n.x-search-input-placeholder {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n pointer-events: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## See it in action\n\nHere a basic example of how the animated search input placeholder is rendered.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n\n### Animating only on hover\n\nIn this example, the placeholder is configured to animate only when the user hovers in the search\ninput, showing the first message of the array the rest of the time.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n :animate-only-on-hover=\"true\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-input-placeholder.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-input-placeholder.vue"],"sourcesContent":["<template>\n <component\n :is=\"animation\"\n v-if=\"isVisible\"\n class=\"x-input-placeholder x-search-input-placeholder\"\n mode=\"out-in\"\n >\n <span :key=\"message\" data-test=\"search-input-placeholder\">\n {{ message }}\n </span>\n </component>\n</template>\n\n<script lang=\"ts\">\nimport type { PropType } from 'vue'\nimport { computed, defineComponent, onBeforeUnmount, ref, watch } from 'vue'\nimport { animateTranslate } from '../../../components/animations/animate-translate/animate-translate.factory'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { AnimationProp } from '../../../types'\nimport { searchBoxXModule } from '../x-module'\n\n/**.\n * This component renders an animated placeholder for the search input in the shape of a list of\n * iterating messages that can be configured to happen always or only when hovering the input\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInputPlaceholder',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * List of messages to animate.\n *\n * @public\n */\n messages: {\n type: Array as PropType<string[]>,\n required: true,\n },\n /**\n * Animation component used for the messages.\n *\n * @public\n */\n animation: {\n type: AnimationProp,\n default: () => animateTranslate('bottom-to-top'),\n },\n /**\n * Time in milliseconds during which each message is visible.\n *\n * @public\n */\n animationIntervalMs: {\n type: Number,\n default: 1500,\n },\n /**\n * Whether the messages animation is active only when hovering the search input or always.\n *\n * @public\n */\n animateOnlyOnHover: Boolean,\n },\n setup(props) {\n const $x = use$x()\n\n /**.\n * The search box written query\n *\n * @internal\n */\n const { query } = useState('searchBox')\n\n /**.\n * The search box hover status\n *\n * @internal\n */\n const isSearchBoxHovered = ref(false)\n\n /**.\n * The search box focus status\n *\n * @internal\n */\n const isSearchBoxFocused = ref(false)\n\n /**\n * The index used to point to the current animation message in the list.\n *\n * @internal\n */\n const animationMessageIndex = ref(0)\n\n /**\n * The interval used for the animation.\n *\n * @internal\n */\n const animationInterval = ref<number | undefined>(undefined)\n\n /**\n * The visibility state of the component.\n *\n * @returns The visibility state based on the search input state (query & focus).\n *\n * @internal\n */\n const isVisible = computed((): boolean => !query.value && !isSearchBoxFocused.value)\n\n /**\n * The animation state of the component.\n *\n * @returns Whether the animation is active or not.\n *\n * @internal\n */\n const isBeingAnimated = computed(\n (): boolean => isVisible.value && (!props.animateOnlyOnHover || isSearchBoxHovered.value),\n )\n\n /**\n * The current placeholder message.\n *\n * @returns The message to display as placeholder at any moment.\n *\n * @internal\n */\n const message = computed((): string | undefined =>\n isBeingAnimated.value ? props.messages[animationMessageIndex.value] : props.messages[0],\n )\n\n /**\n * Clears the interval used for the animation.\n *\n * @internal\n */\n const stopAnimationInterval = (): void => {\n if (animationInterval.value) {\n clearInterval(animationInterval.value)\n animationInterval.value = undefined\n }\n }\n\n /**\n * Increments animation message index; if the new index exceeds the messages list length, it is\n * reset to 0.\n *\n * @internal\n */\n const incrementAnimationMessageIndex = (): void => {\n animationMessageIndex.value = (animationMessageIndex.value + 1) % props.messages.length\n }\n\n $x.on('UserHoveredInSearchBox', false).subscribe(() => (isSearchBoxHovered.value = true))\n\n $x.on('UserHoveredOutSearchBox', false).subscribe(() => (isSearchBoxHovered.value = false))\n\n $x.on('UserFocusedSearchBox', false).subscribe(() => (isSearchBoxFocused.value = true))\n\n $x.on('UserBlurredSearchBox', false).subscribe(() => (isSearchBoxFocused.value = false))\n\n /**\n * Starts or stops the animation depending on the current animation state.\n *\n * @internal\n */\n const resetAnimation = (): void => {\n stopAnimationInterval()\n if (isBeingAnimated.value) {\n animationInterval.value = window.setInterval((): void => {\n incrementAnimationMessageIndex()\n }, props.animationIntervalMs)\n }\n }\n\n watch(() => 'animationIntervalMs', resetAnimation)\n\n /**\n * Resets the animation message index to zero.\n *\n * @internal\n */\n const resetAnimationMessageIndex = (): void => {\n animationMessageIndex.value = 0\n }\n\n watch(\n () => props.messages,\n () => {\n resetAnimationMessageIndex()\n resetAnimation()\n },\n { deep: true },\n )\n\n /**\n * Sets the animation message index with the right value for the next future iteration when the\n * current one stops,assuring the user will see always a new message on each animation state\n * change.\n *\n * @internal\n */\n watch(\n isBeingAnimated,\n () => {\n if (!isBeingAnimated.value) {\n if (props.animateOnlyOnHover) {\n resetAnimationMessageIndex()\n }\n incrementAnimationMessageIndex()\n }\n resetAnimation()\n },\n { immediate: true },\n )\n\n onBeforeUnmount(() => {\n stopAnimationInterval()\n })\n\n return {\n isVisible,\n message,\n }\n },\n})\n</script>\n\n<style lang=\"css\">\n.x-search-input-placeholder-container {\n position: relative;\n}\n</style>\n\n<style lang=\"css\" scoped>\n.x-search-input-placeholder {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n pointer-events: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## See it in action\n\nHere a basic example of how the animated search input placeholder is rendered.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n\n### Animating only on hover\n\nIn this example, the placeholder is configured to animate only when the user hovers in the search\ninput, showing the first message of the array the rest of the time.\n\n```vue live\n<template>\n <div style=\"position: relative; overflow: hidden;\">\n <SearchInputPlaceholder\n style=\"position: absolute; height: 100%; pointer-events: none;\"\n :messages=\"placeholderMessages\"\n :animate-only-on-hover=\"true\"\n />\n <SearchInput />\n </div>\n</template>\n\n<script>\nimport { SearchInput, SearchInputPlaceholder } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputPlaceholderDemo',\n components: {\n SearchInput,\n SearchInputPlaceholder,\n },\n data: function () {\n return {\n placeholderMessages: [\n 'Find shirts',\n 'Find shoes',\n 'Find watches',\n 'Find handbags',\n 'Find sunglasses',\n ],\n }\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue"],"sourcesContent":["<template>\n <input\n ref=\"inputElement\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-search-input x-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n aria-label=\"type your query here\"\n @mouseenter=\"emitUserHoveredInSearchBox\"\n @mouseleave=\"emitUserHoveredOutSearchBox\"\n @blur=\"emitUserBlurredSearchBox\"\n @click=\"emitUserClickedSearchBox\"\n @focus=\"emitUserFocusedSearchBox\"\n @input=\"emitUserIsTypingAQueryEvents\"\n @keydown.enter=\"emitUserPressedEnterKey\"\n @keydown.up.down.prevent=\"emitUserPressedArrowKey\"\n @beforeinput=\"preventSpecialKey\"\n />\n</template>\n\n<script lang=\"ts\">\nimport type { ArrowKey } from '../../../utils'\nimport type { DebouncedFunction } from '../../../utils/types'\nimport type { XEvent } from '../../../wiring/events.types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, onMounted, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { debounce } from '../../../utils/debounce'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders an input field that allows the user to type a query. It also reacts to\n * query changes through event listening.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInput',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * Maximum characters allowed in the input search.\n */\n maxLength: {\n type: Number,\n default: 64,\n },\n /**\n * Allows input autofocus when the search field is rendered.\n */\n autofocus: {\n type: Boolean,\n default: true,\n },\n /**\n * Enables the auto-accept query after debounce.\n */\n instant: {\n type: Boolean,\n default: true,\n },\n /**\n * Debounce time for the instant.\n */\n instantDebounceInMs: {\n type: Number,\n default: 500,\n },\n },\n setup(props) {\n const $x = use$x()\n\n const { query } = useState('searchBox', ['query'])\n\n const inputElement = ref<HTMLInputElement>()\n\n let debouncedUserAcceptedAQuery: DebouncedFunction<[string]>\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => {\n return {\n target: inputElement.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event.\n *\n * @remarks It is necessary in a separated method to use it as the parameter of debounce in\n * emitDebouncedUserAcceptedAQuery method.\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitUserAcceptedAQuery = (query: string): void => {\n $x.emit('UserAcceptedAQuery', query, createEventMetadata())\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event with a debounce configured in\n * `instantDebounceInMs` prop.\n *\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitDebouncedUserAcceptedAQuery = (query: string): void => {\n if (props.instant) {\n if (!debouncedUserAcceptedAQuery) {\n debouncedUserAcceptedAQuery = debounce(emitUserAcceptedAQuery, props.instantDebounceInMs)\n }\n debouncedUserAcceptedAQuery(query)\n }\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredInSearchBox} when search box is hovered in.\n *\n * @internal\n */\n const emitUserHoveredInSearchBox = (): void => {\n $x.emit('UserHoveredInSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredOutSearchBox} when search box is hovered out.\n *\n * @internal\n */\n const emitUserHoveredOutSearchBox = (): void => {\n $x.emit('UserHoveredOutSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n const emitUserBlurredSearchBox = (): void => {\n $x.emit('UserBlurredSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n const emitUserClickedSearchBox = (): void => {\n $x.emit('UserClickedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n const emitUserFocusedSearchBox = (): void => {\n $x.emit('UserFocusedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserIsTypingAQuery} when the user typed/pasted something\n * into the search-box. Also emits event {@link SearchBoxXEvents.UserClearedQuery} when the user\n * removes all characters in the search-box.\n *\n * @internal\n */\n const emitUserIsTypingAQueryEvents = (): void => {\n const query = inputElement.value?.value ?? ''\n\n $x.emit('UserIsTypingAQuery', query, { target: inputElement.value })\n if (query.trim()) {\n emitDebouncedUserAcceptedAQuery(query)\n } else {\n cancelDebouncedUserAcceptedAQuery()\n }\n }\n\n /**\n * Emits event {@link XEventsTypes.UserPressedArrowKey} when the user pressed an arrow key.\n *\n * @param event - The keyboard event with the arrow key pressed.\n * @internal\n */\n const emitUserPressedArrowKey = (event: KeyboardEvent): void => {\n $x.emit('UserPressedArrowKey', event.key as ArrowKey, createEventMetadata())\n }\n\n /**\n * Emits multiple events when the user pressed the enter key.\n *\n * @remarks\n * Emitted events are:\n * {@link SearchBoxXEvents.UserPressedEnterKey}\n * {@link XEventsTypes.UserAcceptedAQuery}\n *\n * @internal\n */\n const emitUserPressedEnterKey = (): void => {\n const query = inputElement.value?.value.trim()\n if (!!query && query.length > 0) {\n $x.emit('UserPressedEnterKey', query, createEventMetadata())\n emitUserAcceptedAQuery(query)\n }\n inputElement.value?.blur()\n }\n\n /**\n * Prevents the user from either typing or pasting special characters in the input field.\n *\n * @internal\n * @param event - The event that will be checked for special characters.\n */\n const preventSpecialKey = (event: InputEvent): void => {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault()\n }\n }\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search input is focused.\n *\n * @internal\n */\n function focusInput(): void {\n inputElement.value?.focus()\n }\n ;['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(focusInput),\n )\n\n /**\n * When event {@link XEventsTypes.UserAcceptedAQuery} or\n * {@link SearchBoxXEvents.UserClearedQuery} are emitted the pending debounced emit\n * {@link XEvent} `UserAcceptedAQuery` is canceled.\n *\n * @internal\n */\n function cancelDebouncedUserAcceptedAQuery(): void {\n debouncedUserAcceptedAQuery?.cancel()\n }\n ;['UserAcceptedAQuery', 'UserClearedQuery'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(cancelDebouncedUserAcceptedAQuery),\n )\n\n onMounted(() => {\n if (props.autofocus) {\n focusInput()\n }\n })\n\n return {\n query,\n inputElement,\n emitUserHoveredInSearchBox,\n emitUserHoveredOutSearchBox,\n emitUserBlurredSearchBox,\n emitUserClickedSearchBox,\n emitUserFocusedSearchBox,\n emitUserIsTypingAQueryEvents,\n emitUserPressedEnterKey,\n emitUserPressedArrowKey,\n preventSpecialKey,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-search-input::-webkit-search-decoration,\n.x-search-input::-webkit-search-cancel-button,\n.x-search-input::-webkit-search-results-button,\n.x-search-input::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserClickedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserBlurredSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserFocusedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserIsTypingAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedEnterKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedArrowKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend service required\nTo use this component, the Search service must be implemented.\n:::\n<!-- prettier-ignore-end -->\n\nHere you have a basic example of how the search input is rendered.\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <SearchInput />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with props\n\nIn this example, the search input has been limited to accept a maximum of 5 characters, including\nspaces, it won't take the focus when it is rendered, and it will emit the `UserAcceptedAQuery` event\nafter 1000 milliseconds without typing.\n\n_Type a term with more than 5 characters to try it out!_\n\n```vue live\n<template>\n <SearchInput :maxLength=\"5\" :autofocus=\"false\" :instant=\"true\" :instantDebounceInMs=\"1000\" />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, a message has been added below the search input to illustrate the action performed.\nFor example, if you select the search input box, the message “focus” appears. When you start to\nenter a search term, the message “typing” appears. If you press Enter after typing a search term,\nthe message “enter” appears.\n\n<!-- prettier-ignore-start -->\n:::warning X Events are only emitted from the root X Component.\nAt the moment, X Events are only emitted from the root X Component. This means that if you wrap\nthe `SearchInput` with another component of another module like the `MainScroll`, you should add\nthe listeners to the `MainScroll` instead of the `SearchInput`. If you need to subscribe to these\nevents, it is recommended to use the [`GlobalXBus`](../common/x-components.global-x-bus.md)\ncomponent instead.\n:::\n<!-- prettier-ignore-end -->\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <div>\n <SearchInput\n @UserPressedEnterKey=\"value = 'enter'\"\n @UserFocusedSearchBox=\"hasFocus = true\"\n @UserBlurredSearchBox=\"hasFocus = false\"\n @UserIsTypingAQuery=\"value = 'typing'\"\n />\n <strong>{{ value }}</strong>\n <span>{{ hasFocus ? 'focused' : 'unfocused' }}</span>\n </div>\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n data() {\n return {\n value: '',\n hasFocus: false,\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchInput` component\ncommunicates with the [`SearchButton`](x-components.search-button.md) and the\n[`ClearSearchInput`](x-components.clear-search-input.md) to offer a full query entry experience.\nFurthermore, you can use it together with the [`QuerySuggestions`](query-suggestions.md) component\nto autocomplete the typed search term.\n\n_Type “trousers” or another fashion term in the input field and then click the clear icon to try it\nout!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex; flex-flow: row nowrap;\">\n <SearchInput />\n <ClearSearchInput>\n <img src=\"/assets/icons/cross.svg\" />\n </ClearSearchInput>\n <SearchButton>Search</SearchButton>\n </div>\n <QuerySuggestions />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box'\nimport { QuerySuggestions } from '@empathyco/x-components/query-suggestions'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock"],"mappings":";;;;;;SAEQ,WAAc,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;AACjB,EAAA,OAAAA,SAAA,EAAoB,EAAAC,kBAAA,CAAA,OAAA,EAAA;AAAA,IACpB,GAAK,EAAA,cAAA;AAAA,IACN,SAAa,EAAA,IAAA,CAAA,SAAA;AAAA,IACb,KAAM,EAAA,IAAA,CAAA,KAAA;AAAA,IACN,YAAa,EAAA,KAAA;AAAA,IACb,KAAA,EAAA,wBAAA;AAAA,IACA,YAAa,EAAA,QAAA;AAAA,IACb,SAAS,EAAA,QAAA;AAAA,IACT,IAAA,EAAA,QAAA;AAAA,IACC,WAAU,EAAA,cAAA;AAAA,IACV,YAAU,EAAA,sBAAA;AAAA,IACV,YAAA,EAAI,uCAAE,IAAwB,CAAA,0BAAA,IAAA,IAAA,CAAA,0BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAC9B,YAAA,EAAK,uCAAE,IAAwB,CAAA,2BAAA,IAAA,IAAA,CAAA,2BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAC/B,QAAK,MAAE,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IACP,SAAK,MAAE,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IACP,OAAO,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,OAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAlBZ,uBAkBoB,4BAAuB,IAAA,IAAA,CAAA,4BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,SAAA,EAAA;;AAEtC,MAAA,MAAA,CAAA,CAAA,CAAA,KAAW,uCAAE,IAAiB,KAAA,IAAA,CAAA,uBAAA,IAAA,IAAA,CAAA,uBAAA,CAAA,GAAA,IAAA,CAAA,EAAA,CAAA,SAAA,CAAA,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;"}
1
+ {"version":3,"file":"search-input.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue"],"sourcesContent":["<template>\n <input\n ref=\"inputElement\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-search-input x-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n aria-label=\"type your query here\"\n @mouseenter=\"emitUserHoveredInSearchBox\"\n @mouseleave=\"emitUserHoveredOutSearchBox\"\n @blur=\"emitUserBlurredSearchBox\"\n @click=\"emitUserClickedSearchBox\"\n @focus=\"emitUserFocusedSearchBox\"\n @input=\"emitUserIsTypingAQueryEvents\"\n @keydown.enter=\"emitUserPressedEnterKey\"\n @keydown.up.down.prevent=\"emitUserPressedArrowKey\"\n @beforeinput=\"preventSpecialKey\"\n />\n</template>\n\n<script lang=\"ts\">\nimport type { ArrowKey } from '../../../utils'\nimport type { DebouncedFunction } from '../../../utils/types'\nimport type { XEvent } from '../../../wiring/events.types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, onMounted, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { debounce } from '../../../utils/debounce'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders an input field that allows the user to type a query. It also reacts to\n * query changes through event listening.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInput',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * Maximum characters allowed in the input search.\n */\n maxLength: {\n type: Number,\n default: 64,\n },\n /**\n * Allows input autofocus when the search field is rendered.\n */\n autofocus: {\n type: Boolean,\n default: true,\n },\n /**\n * Enables the auto-accept query after debounce.\n */\n instant: {\n type: Boolean,\n default: true,\n },\n /**\n * Debounce time for the instant.\n */\n instantDebounceInMs: {\n type: Number,\n default: 500,\n },\n },\n setup(props) {\n const $x = use$x()\n\n const { query } = useState('searchBox')\n\n const inputElement = ref<HTMLInputElement>()\n\n let debouncedUserAcceptedAQuery: DebouncedFunction<[string]>\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => {\n return {\n target: inputElement.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event.\n *\n * @remarks It is necessary in a separated method to use it as the parameter of debounce in\n * emitDebouncedUserAcceptedAQuery method.\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitUserAcceptedAQuery = (query: string): void => {\n $x.emit('UserAcceptedAQuery', query, createEventMetadata())\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event with a debounce configured in\n * `instantDebounceInMs` prop.\n *\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitDebouncedUserAcceptedAQuery = (query: string): void => {\n if (props.instant) {\n if (!debouncedUserAcceptedAQuery) {\n debouncedUserAcceptedAQuery = debounce(emitUserAcceptedAQuery, props.instantDebounceInMs)\n }\n debouncedUserAcceptedAQuery(query)\n }\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredInSearchBox} when search box is hovered in.\n *\n * @internal\n */\n const emitUserHoveredInSearchBox = (): void => {\n $x.emit('UserHoveredInSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredOutSearchBox} when search box is hovered out.\n *\n * @internal\n */\n const emitUserHoveredOutSearchBox = (): void => {\n $x.emit('UserHoveredOutSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n const emitUserBlurredSearchBox = (): void => {\n $x.emit('UserBlurredSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n const emitUserClickedSearchBox = (): void => {\n $x.emit('UserClickedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n const emitUserFocusedSearchBox = (): void => {\n $x.emit('UserFocusedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserIsTypingAQuery} when the user typed/pasted something\n * into the search-box. Also emits event {@link SearchBoxXEvents.UserClearedQuery} when the user\n * removes all characters in the search-box.\n *\n * @internal\n */\n const emitUserIsTypingAQueryEvents = (): void => {\n const query = inputElement.value?.value ?? ''\n\n $x.emit('UserIsTypingAQuery', query, { target: inputElement.value })\n if (query.trim()) {\n emitDebouncedUserAcceptedAQuery(query)\n } else {\n cancelDebouncedUserAcceptedAQuery()\n }\n }\n\n /**\n * Emits event {@link XEventsTypes.UserPressedArrowKey} when the user pressed an arrow key.\n *\n * @param event - The keyboard event with the arrow key pressed.\n * @internal\n */\n const emitUserPressedArrowKey = (event: KeyboardEvent): void => {\n $x.emit('UserPressedArrowKey', event.key as ArrowKey, createEventMetadata())\n }\n\n /**\n * Emits multiple events when the user pressed the enter key.\n *\n * @remarks\n * Emitted events are:\n * {@link SearchBoxXEvents.UserPressedEnterKey}\n * {@link XEventsTypes.UserAcceptedAQuery}\n *\n * @internal\n */\n const emitUserPressedEnterKey = (): void => {\n const query = inputElement.value?.value.trim()\n if (!!query && query.length > 0) {\n $x.emit('UserPressedEnterKey', query, createEventMetadata())\n emitUserAcceptedAQuery(query)\n }\n inputElement.value?.blur()\n }\n\n /**\n * Prevents the user from either typing or pasting special characters in the input field.\n *\n * @internal\n * @param event - The event that will be checked for special characters.\n */\n const preventSpecialKey = (event: InputEvent): void => {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault()\n }\n }\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search input is focused.\n *\n * @internal\n */\n function focusInput(): void {\n inputElement.value?.focus()\n }\n ;['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(focusInput),\n )\n\n /**\n * When event {@link XEventsTypes.UserAcceptedAQuery} or\n * {@link SearchBoxXEvents.UserClearedQuery} are emitted the pending debounced emit\n * {@link XEvent} `UserAcceptedAQuery` is canceled.\n *\n * @internal\n */\n function cancelDebouncedUserAcceptedAQuery(): void {\n debouncedUserAcceptedAQuery?.cancel()\n }\n ;['UserAcceptedAQuery', 'UserClearedQuery'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(cancelDebouncedUserAcceptedAQuery),\n )\n\n onMounted(() => {\n if (props.autofocus) {\n focusInput()\n }\n })\n\n return {\n query,\n inputElement,\n emitUserHoveredInSearchBox,\n emitUserHoveredOutSearchBox,\n emitUserBlurredSearchBox,\n emitUserClickedSearchBox,\n emitUserFocusedSearchBox,\n emitUserIsTypingAQueryEvents,\n emitUserPressedEnterKey,\n emitUserPressedArrowKey,\n preventSpecialKey,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-search-input::-webkit-search-decoration,\n.x-search-input::-webkit-search-cancel-button,\n.x-search-input::-webkit-search-results-button,\n.x-search-input::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserClickedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserBlurredSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserFocusedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserIsTypingAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedEnterKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedArrowKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend service required\nTo use this component, the Search service must be implemented.\n:::\n<!-- prettier-ignore-end -->\n\nHere you have a basic example of how the search input is rendered.\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <SearchInput />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with props\n\nIn this example, the search input has been limited to accept a maximum of 5 characters, including\nspaces, it won't take the focus when it is rendered, and it will emit the `UserAcceptedAQuery` event\nafter 1000 milliseconds without typing.\n\n_Type a term with more than 5 characters to try it out!_\n\n```vue live\n<template>\n <SearchInput :maxLength=\"5\" :autofocus=\"false\" :instant=\"true\" :instantDebounceInMs=\"1000\" />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, a message has been added below the search input to illustrate the action performed.\nFor example, if you select the search input box, the message “focus” appears. When you start to\nenter a search term, the message “typing” appears. If you press Enter after typing a search term,\nthe message “enter” appears.\n\n<!-- prettier-ignore-start -->\n:::warning X Events are only emitted from the root X Component.\nAt the moment, X Events are only emitted from the root X Component. This means that if you wrap\nthe `SearchInput` with another component of another module like the `MainScroll`, you should add\nthe listeners to the `MainScroll` instead of the `SearchInput`. If you need to subscribe to these\nevents, it is recommended to use the [`GlobalXBus`](../common/x-components.global-x-bus.md)\ncomponent instead.\n:::\n<!-- prettier-ignore-end -->\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <div>\n <SearchInput\n @UserPressedEnterKey=\"value = 'enter'\"\n @UserFocusedSearchBox=\"hasFocus = true\"\n @UserBlurredSearchBox=\"hasFocus = false\"\n @UserIsTypingAQuery=\"value = 'typing'\"\n />\n <strong>{{ value }}</strong>\n <span>{{ hasFocus ? 'focused' : 'unfocused' }}</span>\n </div>\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n data() {\n return {\n value: '',\n hasFocus: false,\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchInput` component\ncommunicates with the [`SearchButton`](x-components.search-button.md) and the\n[`ClearSearchInput`](x-components.clear-search-input.md) to offer a full query entry experience.\nFurthermore, you can use it together with the [`QuerySuggestions`](query-suggestions.md) component\nto autocomplete the typed search term.\n\n_Type “trousers” or another fashion term in the input field and then click the clear icon to try it\nout!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex; flex-flow: row nowrap;\">\n <SearchInput />\n <ClearSearchInput>\n <img src=\"/assets/icons/cross.svg\" />\n </ClearSearchInput>\n <SearchButton>Search</SearchButton>\n </div>\n <QuerySuggestions />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box'\nimport { QuerySuggestions } from '@empathyco/x-components/query-suggestions'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions,\n },\n}\n</script>\n```\n</docs>\n"],"names":["_openBlock","_createElementBlock"],"mappings":";;;;;;SAEQ,WAAc,CAAA,IAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,KAAA,EAAA,QAAA,EAAA;AACjB,EAAA,OAAAA,SAAA,EAAoB,EAAAC,kBAAA,CAAA,OAAA,EAAA;AAAA,IACpB,GAAK,EAAA,cAAA;AAAA,IACN,SAAa,EAAA,IAAA,CAAA,SAAA;AAAA,IACb,KAAM,EAAA,IAAA,CAAA,KAAA;AAAA,IACN,YAAa,EAAA,KAAA;AAAA,IACb,KAAA,EAAA,wBAAA;AAAA,IACA,YAAa,EAAA,QAAA;AAAA,IACb,SAAS,EAAA,QAAA;AAAA,IACT,IAAA,EAAA,QAAA;AAAA,IACC,WAAU,EAAA,cAAA;AAAA,IACV,YAAU,EAAA,sBAAA;AAAA,IACV,YAAA,EAAI,uCAAE,IAAwB,CAAA,0BAAA,IAAA,IAAA,CAAA,0BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAC9B,YAAA,EAAK,uCAAE,IAAwB,CAAA,2BAAA,IAAA,IAAA,CAAA,2BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAC/B,QAAK,MAAE,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IACP,SAAK,MAAE,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IACP,OAAO,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,wBAAA,IAAA,IAAA,CAAA,wBAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,OAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAlBZ,uBAkBoB,4BAAuB,IAAA,IAAA,CAAA,4BAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,SAAA,EAAA;;AAEtC,MAAA,MAAA,CAAA,CAAA,CAAA,KAAW,uCAAE,IAAiB,KAAA,IAAA,CAAA,uBAAA,IAAA,IAAA,CAAA,uBAAA,CAAA,GAAA,IAAA,CAAA,EAAA,CAAA,SAAA,CAAA,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,CAAA,CAAA,CAAA;AAAA,KAAA;;;;;;;;"}
@@ -45,7 +45,7 @@ var _sfc_main = defineComponent({
45
45
  },
46
46
  setup(props) {
47
47
  const $x = use$x();
48
- const { query } = useState('searchBox', ['query']);
48
+ const { query } = useState('searchBox');
49
49
  const inputElement = ref();
50
50
  let debouncedUserAcceptedAQuery;
51
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue"],"sourcesContent":["<template>\n <input\n ref=\"inputElement\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-search-input x-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n aria-label=\"type your query here\"\n @mouseenter=\"emitUserHoveredInSearchBox\"\n @mouseleave=\"emitUserHoveredOutSearchBox\"\n @blur=\"emitUserBlurredSearchBox\"\n @click=\"emitUserClickedSearchBox\"\n @focus=\"emitUserFocusedSearchBox\"\n @input=\"emitUserIsTypingAQueryEvents\"\n @keydown.enter=\"emitUserPressedEnterKey\"\n @keydown.up.down.prevent=\"emitUserPressedArrowKey\"\n @beforeinput=\"preventSpecialKey\"\n />\n</template>\n\n<script lang=\"ts\">\nimport type { ArrowKey } from '../../../utils'\nimport type { DebouncedFunction } from '../../../utils/types'\nimport type { XEvent } from '../../../wiring/events.types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, onMounted, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { debounce } from '../../../utils/debounce'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders an input field that allows the user to type a query. It also reacts to\n * query changes through event listening.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInput',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * Maximum characters allowed in the input search.\n */\n maxLength: {\n type: Number,\n default: 64,\n },\n /**\n * Allows input autofocus when the search field is rendered.\n */\n autofocus: {\n type: Boolean,\n default: true,\n },\n /**\n * Enables the auto-accept query after debounce.\n */\n instant: {\n type: Boolean,\n default: true,\n },\n /**\n * Debounce time for the instant.\n */\n instantDebounceInMs: {\n type: Number,\n default: 500,\n },\n },\n setup(props) {\n const $x = use$x()\n\n const { query } = useState('searchBox', ['query'])\n\n const inputElement = ref<HTMLInputElement>()\n\n let debouncedUserAcceptedAQuery: DebouncedFunction<[string]>\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => {\n return {\n target: inputElement.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event.\n *\n * @remarks It is necessary in a separated method to use it as the parameter of debounce in\n * emitDebouncedUserAcceptedAQuery method.\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitUserAcceptedAQuery = (query: string): void => {\n $x.emit('UserAcceptedAQuery', query, createEventMetadata())\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event with a debounce configured in\n * `instantDebounceInMs` prop.\n *\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitDebouncedUserAcceptedAQuery = (query: string): void => {\n if (props.instant) {\n if (!debouncedUserAcceptedAQuery) {\n debouncedUserAcceptedAQuery = debounce(emitUserAcceptedAQuery, props.instantDebounceInMs)\n }\n debouncedUserAcceptedAQuery(query)\n }\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredInSearchBox} when search box is hovered in.\n *\n * @internal\n */\n const emitUserHoveredInSearchBox = (): void => {\n $x.emit('UserHoveredInSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredOutSearchBox} when search box is hovered out.\n *\n * @internal\n */\n const emitUserHoveredOutSearchBox = (): void => {\n $x.emit('UserHoveredOutSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n const emitUserBlurredSearchBox = (): void => {\n $x.emit('UserBlurredSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n const emitUserClickedSearchBox = (): void => {\n $x.emit('UserClickedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n const emitUserFocusedSearchBox = (): void => {\n $x.emit('UserFocusedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserIsTypingAQuery} when the user typed/pasted something\n * into the search-box. Also emits event {@link SearchBoxXEvents.UserClearedQuery} when the user\n * removes all characters in the search-box.\n *\n * @internal\n */\n const emitUserIsTypingAQueryEvents = (): void => {\n const query = inputElement.value?.value ?? ''\n\n $x.emit('UserIsTypingAQuery', query, { target: inputElement.value })\n if (query.trim()) {\n emitDebouncedUserAcceptedAQuery(query)\n } else {\n cancelDebouncedUserAcceptedAQuery()\n }\n }\n\n /**\n * Emits event {@link XEventsTypes.UserPressedArrowKey} when the user pressed an arrow key.\n *\n * @param event - The keyboard event with the arrow key pressed.\n * @internal\n */\n const emitUserPressedArrowKey = (event: KeyboardEvent): void => {\n $x.emit('UserPressedArrowKey', event.key as ArrowKey, createEventMetadata())\n }\n\n /**\n * Emits multiple events when the user pressed the enter key.\n *\n * @remarks\n * Emitted events are:\n * {@link SearchBoxXEvents.UserPressedEnterKey}\n * {@link XEventsTypes.UserAcceptedAQuery}\n *\n * @internal\n */\n const emitUserPressedEnterKey = (): void => {\n const query = inputElement.value?.value.trim()\n if (!!query && query.length > 0) {\n $x.emit('UserPressedEnterKey', query, createEventMetadata())\n emitUserAcceptedAQuery(query)\n }\n inputElement.value?.blur()\n }\n\n /**\n * Prevents the user from either typing or pasting special characters in the input field.\n *\n * @internal\n * @param event - The event that will be checked for special characters.\n */\n const preventSpecialKey = (event: InputEvent): void => {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault()\n }\n }\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search input is focused.\n *\n * @internal\n */\n function focusInput(): void {\n inputElement.value?.focus()\n }\n ;['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(focusInput),\n )\n\n /**\n * When event {@link XEventsTypes.UserAcceptedAQuery} or\n * {@link SearchBoxXEvents.UserClearedQuery} are emitted the pending debounced emit\n * {@link XEvent} `UserAcceptedAQuery` is canceled.\n *\n * @internal\n */\n function cancelDebouncedUserAcceptedAQuery(): void {\n debouncedUserAcceptedAQuery?.cancel()\n }\n ;['UserAcceptedAQuery', 'UserClearedQuery'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(cancelDebouncedUserAcceptedAQuery),\n )\n\n onMounted(() => {\n if (props.autofocus) {\n focusInput()\n }\n })\n\n return {\n query,\n inputElement,\n emitUserHoveredInSearchBox,\n emitUserHoveredOutSearchBox,\n emitUserBlurredSearchBox,\n emitUserClickedSearchBox,\n emitUserFocusedSearchBox,\n emitUserIsTypingAQueryEvents,\n emitUserPressedEnterKey,\n emitUserPressedArrowKey,\n preventSpecialKey,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-search-input::-webkit-search-decoration,\n.x-search-input::-webkit-search-cancel-button,\n.x-search-input::-webkit-search-results-button,\n.x-search-input::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserClickedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserBlurredSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserFocusedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserIsTypingAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedEnterKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedArrowKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend service required\nTo use this component, the Search service must be implemented.\n:::\n<!-- prettier-ignore-end -->\n\nHere you have a basic example of how the search input is rendered.\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <SearchInput />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with props\n\nIn this example, the search input has been limited to accept a maximum of 5 characters, including\nspaces, it won't take the focus when it is rendered, and it will emit the `UserAcceptedAQuery` event\nafter 1000 milliseconds without typing.\n\n_Type a term with more than 5 characters to try it out!_\n\n```vue live\n<template>\n <SearchInput :maxLength=\"5\" :autofocus=\"false\" :instant=\"true\" :instantDebounceInMs=\"1000\" />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, a message has been added below the search input to illustrate the action performed.\nFor example, if you select the search input box, the message “focus” appears. When you start to\nenter a search term, the message “typing” appears. If you press Enter after typing a search term,\nthe message “enter” appears.\n\n<!-- prettier-ignore-start -->\n:::warning X Events are only emitted from the root X Component.\nAt the moment, X Events are only emitted from the root X Component. This means that if you wrap\nthe `SearchInput` with another component of another module like the `MainScroll`, you should add\nthe listeners to the `MainScroll` instead of the `SearchInput`. If you need to subscribe to these\nevents, it is recommended to use the [`GlobalXBus`](../common/x-components.global-x-bus.md)\ncomponent instead.\n:::\n<!-- prettier-ignore-end -->\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <div>\n <SearchInput\n @UserPressedEnterKey=\"value = 'enter'\"\n @UserFocusedSearchBox=\"hasFocus = true\"\n @UserBlurredSearchBox=\"hasFocus = false\"\n @UserIsTypingAQuery=\"value = 'typing'\"\n />\n <strong>{{ value }}</strong>\n <span>{{ hasFocus ? 'focused' : 'unfocused' }}</span>\n </div>\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n data() {\n return {\n value: '',\n hasFocus: false,\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchInput` component\ncommunicates with the [`SearchButton`](x-components.search-button.md) and the\n[`ClearSearchInput`](x-components.clear-search-input.md) to offer a full query entry experience.\nFurthermore, you can use it together with the [`QuerySuggestions`](query-suggestions.md) component\nto autocomplete the typed search term.\n\n_Type “trousers” or another fashion term in the input field and then click the clear icon to try it\nout!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex; flex-flow: row nowrap;\">\n <SearchInput />\n <ClearSearchInput>\n <img src=\"/assets/icons/cross.svg\" />\n </ClearSearchInput>\n <SearchButton>Search</SearchButton>\n </div>\n <QuerySuggestions />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box'\nimport { QuerySuggestions } from '@empathyco/x-components/query-suggestions'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-input.vue2.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue"],"sourcesContent":["<template>\n <input\n ref=\"inputElement\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-search-input x-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n aria-label=\"type your query here\"\n @mouseenter=\"emitUserHoveredInSearchBox\"\n @mouseleave=\"emitUserHoveredOutSearchBox\"\n @blur=\"emitUserBlurredSearchBox\"\n @click=\"emitUserClickedSearchBox\"\n @focus=\"emitUserFocusedSearchBox\"\n @input=\"emitUserIsTypingAQueryEvents\"\n @keydown.enter=\"emitUserPressedEnterKey\"\n @keydown.up.down.prevent=\"emitUserPressedArrowKey\"\n @beforeinput=\"preventSpecialKey\"\n />\n</template>\n\n<script lang=\"ts\">\nimport type { ArrowKey } from '../../../utils'\nimport type { DebouncedFunction } from '../../../utils/types'\nimport type { XEvent } from '../../../wiring/events.types'\nimport type { WireMetadata } from '../../../wiring/wiring.types'\nimport { defineComponent, onMounted, ref } from 'vue'\nimport { use$x } from '../../../composables/use-$x'\nimport { useState } from '../../../composables/use-state'\nimport { debounce } from '../../../utils/debounce'\nimport { searchBoxXModule } from '../x-module'\n\n/**\n * This component renders an input field that allows the user to type a query. It also reacts to\n * query changes through event listening.\n *\n * @public\n */\nexport default defineComponent({\n name: 'SearchInput',\n xModule: searchBoxXModule.name,\n props: {\n /**\n * Maximum characters allowed in the input search.\n */\n maxLength: {\n type: Number,\n default: 64,\n },\n /**\n * Allows input autofocus when the search field is rendered.\n */\n autofocus: {\n type: Boolean,\n default: true,\n },\n /**\n * Enables the auto-accept query after debounce.\n */\n instant: {\n type: Boolean,\n default: true,\n },\n /**\n * Debounce time for the instant.\n */\n instantDebounceInMs: {\n type: Number,\n default: 500,\n },\n },\n setup(props) {\n const $x = use$x()\n\n const { query } = useState('searchBox')\n\n const inputElement = ref<HTMLInputElement>()\n\n let debouncedUserAcceptedAQuery: DebouncedFunction<[string]>\n\n /**\n * Generates the {@link WireMetadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n const createEventMetadata = (): Omit<WireMetadata, 'moduleName'> => {\n return {\n target: inputElement.value,\n feature: 'search_box',\n }\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event.\n *\n * @remarks It is necessary in a separated method to use it as the parameter of debounce in\n * emitDebouncedUserAcceptedAQuery method.\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitUserAcceptedAQuery = (query: string): void => {\n $x.emit('UserAcceptedAQuery', query, createEventMetadata())\n }\n\n /**\n * Emits {@link XEventsTypes.UserAcceptedAQuery} event with a debounce configured in\n * `instantDebounceInMs` prop.\n *\n * @internal\n * @param query - The query that will be emitted.\n */\n const emitDebouncedUserAcceptedAQuery = (query: string): void => {\n if (props.instant) {\n if (!debouncedUserAcceptedAQuery) {\n debouncedUserAcceptedAQuery = debounce(emitUserAcceptedAQuery, props.instantDebounceInMs)\n }\n debouncedUserAcceptedAQuery(query)\n }\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredInSearchBox} when search box is hovered in.\n *\n * @internal\n */\n const emitUserHoveredInSearchBox = (): void => {\n $x.emit('UserHoveredInSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserHoveredOutSearchBox} when search box is hovered out.\n *\n * @internal\n */\n const emitUserHoveredOutSearchBox = (): void => {\n $x.emit('UserHoveredOutSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n const emitUserBlurredSearchBox = (): void => {\n $x.emit('UserBlurredSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n const emitUserClickedSearchBox = (): void => {\n $x.emit('UserClickedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n const emitUserFocusedSearchBox = (): void => {\n $x.emit('UserFocusedSearchBox', undefined, { target: inputElement.value })\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserIsTypingAQuery} when the user typed/pasted something\n * into the search-box. Also emits event {@link SearchBoxXEvents.UserClearedQuery} when the user\n * removes all characters in the search-box.\n *\n * @internal\n */\n const emitUserIsTypingAQueryEvents = (): void => {\n const query = inputElement.value?.value ?? ''\n\n $x.emit('UserIsTypingAQuery', query, { target: inputElement.value })\n if (query.trim()) {\n emitDebouncedUserAcceptedAQuery(query)\n } else {\n cancelDebouncedUserAcceptedAQuery()\n }\n }\n\n /**\n * Emits event {@link XEventsTypes.UserPressedArrowKey} when the user pressed an arrow key.\n *\n * @param event - The keyboard event with the arrow key pressed.\n * @internal\n */\n const emitUserPressedArrowKey = (event: KeyboardEvent): void => {\n $x.emit('UserPressedArrowKey', event.key as ArrowKey, createEventMetadata())\n }\n\n /**\n * Emits multiple events when the user pressed the enter key.\n *\n * @remarks\n * Emitted events are:\n * {@link SearchBoxXEvents.UserPressedEnterKey}\n * {@link XEventsTypes.UserAcceptedAQuery}\n *\n * @internal\n */\n const emitUserPressedEnterKey = (): void => {\n const query = inputElement.value?.value.trim()\n if (!!query && query.length > 0) {\n $x.emit('UserPressedEnterKey', query, createEventMetadata())\n emitUserAcceptedAQuery(query)\n }\n inputElement.value?.blur()\n }\n\n /**\n * Prevents the user from either typing or pasting special characters in the input field.\n *\n * @internal\n * @param event - The event that will be checked for special characters.\n */\n const preventSpecialKey = (event: InputEvent): void => {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault()\n }\n }\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search input is focused.\n *\n * @internal\n */\n function focusInput(): void {\n inputElement.value?.focus()\n }\n ;['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(focusInput),\n )\n\n /**\n * When event {@link XEventsTypes.UserAcceptedAQuery} or\n * {@link SearchBoxXEvents.UserClearedQuery} are emitted the pending debounced emit\n * {@link XEvent} `UserAcceptedAQuery` is canceled.\n *\n * @internal\n */\n function cancelDebouncedUserAcceptedAQuery(): void {\n debouncedUserAcceptedAQuery?.cancel()\n }\n ;['UserAcceptedAQuery', 'UserClearedQuery'].forEach(event =>\n $x.on(event as XEvent, false).subscribe(cancelDebouncedUserAcceptedAQuery),\n )\n\n onMounted(() => {\n if (props.autofocus) {\n focusInput()\n }\n })\n\n return {\n query,\n inputElement,\n emitUserHoveredInSearchBox,\n emitUserHoveredOutSearchBox,\n emitUserBlurredSearchBox,\n emitUserClickedSearchBox,\n emitUserFocusedSearchBox,\n emitUserIsTypingAQueryEvents,\n emitUserPressedEnterKey,\n emitUserPressedArrowKey,\n preventSpecialKey,\n }\n },\n})\n</script>\n\n<style lang=\"css\" scoped>\n.x-search-input::-webkit-search-decoration,\n.x-search-input::-webkit-search-cancel-button,\n.x-search-input::-webkit-search-results-button,\n.x-search-input::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}\n</style>\n\n<docs lang=\"mdx\">\n## Events\n\nThis component emits the following events:\n\n- [`UserClickedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserBlurredSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserFocusedSearchBox`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserIsTypingAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedEnterKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserPressedArrowKey`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n- [`UserAcceptedAQuery`](https://github.com/empathyco/x/blob/main/packages/x-components/src/wiring/events.types.ts)\n\n## See it in action\n\n<!-- prettier-ignore-start -->\n:::warning Backend service required\nTo use this component, the Search service must be implemented.\n:::\n<!-- prettier-ignore-end -->\n\nHere you have a basic example of how the search input is rendered.\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <SearchInput />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with props\n\nIn this example, the search input has been limited to accept a maximum of 5 characters, including\nspaces, it won't take the focus when it is rendered, and it will emit the `UserAcceptedAQuery` event\nafter 1000 milliseconds without typing.\n\n_Type a term with more than 5 characters to try it out!_\n\n```vue live\n<template>\n <SearchInput :maxLength=\"5\" :autofocus=\"false\" :instant=\"true\" :instantDebounceInMs=\"1000\" />\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n}\n</script>\n```\n\n### Play with events\n\nIn this example, a message has been added below the search input to illustrate the action performed.\nFor example, if you select the search input box, the message “focus” appears. When you start to\nenter a search term, the message “typing” appears. If you press Enter after typing a search term,\nthe message “enter” appears.\n\n<!-- prettier-ignore-start -->\n:::warning X Events are only emitted from the root X Component.\nAt the moment, X Events are only emitted from the root X Component. This means that if you wrap\nthe `SearchInput` with another component of another module like the `MainScroll`, you should add\nthe listeners to the `MainScroll` instead of the `SearchInput`. If you need to subscribe to these\nevents, it is recommended to use the [`GlobalXBus`](../common/x-components.global-x-bus.md)\ncomponent instead.\n:::\n<!-- prettier-ignore-end -->\n\n_Type any term in the input field to try it out!_\n\n```vue live\n<template>\n <div>\n <SearchInput\n @UserPressedEnterKey=\"value = 'enter'\"\n @UserFocusedSearchBox=\"hasFocus = true\"\n @UserBlurredSearchBox=\"hasFocus = false\"\n @UserIsTypingAQuery=\"value = 'typing'\"\n />\n <strong>{{ value }}</strong>\n <span>{{ hasFocus ? 'focused' : 'unfocused' }}</span>\n </div>\n</template>\n\n<script>\nimport { SearchInput } from '@empathyco/x-components/search-box'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n },\n data() {\n return {\n value: '',\n hasFocus: false,\n }\n },\n}\n</script>\n```\n\n## Extending the component\n\nComponents can be combined and communicate with each other. Commonly, the `SearchInput` component\ncommunicates with the [`SearchButton`](x-components.search-button.md) and the\n[`ClearSearchInput`](x-components.clear-search-input.md) to offer a full query entry experience.\nFurthermore, you can use it together with the [`QuerySuggestions`](query-suggestions.md) component\nto autocomplete the typed search term.\n\n_Type “trousers” or another fashion term in the input field and then click the clear icon to try it\nout!_\n\n```vue live\n<template>\n <div>\n <div style=\"display: flex; flex-flow: row nowrap;\">\n <SearchInput />\n <ClearSearchInput>\n <img src=\"/assets/icons/cross.svg\" />\n </ClearSearchInput>\n <SearchButton>Search</SearchButton>\n </div>\n <QuerySuggestions />\n </div>\n</template>\n\n<script>\nimport { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box'\nimport { QuerySuggestions } from '@empathyco/x-components/query-suggestions'\n\nexport default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions,\n },\n}\n</script>\n```\n</docs>\n"],"names":[],"mappings":"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"}