@empathyco/x-components 3.0.0-alpha.176 → 3.0.0-alpha.178

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,32 @@
3
3
  All notable changes to this project will be documented in this file. See
4
4
  [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.0.0-alpha.178](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.177...@empathyco/x-components@3.0.0-alpha.178) (2022-09-21)
7
+
8
+ ### Features
9
+
10
+ - Improve `tailwindcss` types (#730)
11
+ ([b7ab20c](https://github.com/empathyco/x/commit/b7ab20cfb0faa7f21fdf4aaaa4ae3e6d44bc6a79)),
12
+ closes [EX-7041](https://searchbroker.atlassian.net/browse/EX-7041)
13
+
14
+ # Change Log
15
+
16
+ All notable changes to this project will be documented in this file. See
17
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
18
+
19
+ ## [3.0.0-alpha.177](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.176...@empathyco/x-components@3.0.0-alpha.177) (2022-09-21)
20
+
21
+ ### Features
22
+
23
+ - **search-input:** prevent `<` or `>` input (#433)
24
+ ([afc865f](https://github.com/empathyco/x/commit/afc865f2e13d775e5ee4a602536dfd2ee8b474b8)),
25
+ closes [EX-7035](https://searchbroker.atlassian.net/browse/EX-7035)
26
+
27
+ # Change Log
28
+
29
+ All notable changes to this project will be documented in this file. See
30
+ [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
31
+
6
32
  ## [3.0.0-alpha.176](https://github.com/empathyco/x/compare/@empathyco/x-components@3.0.0-alpha.175...@empathyco/x-components@3.0.0-alpha.176) (2022-09-20)
7
33
 
8
34
  ### Features
@@ -283,6 +283,16 @@
283
283
  --x-size-border-radius-bottom-right-button-round: var(--x-size-border-radius-button-round);
284
284
  --x-size-border-radius-bottom-left-button-round: var(--x-size-border-radius-button-round);
285
285
  }
286
+ .x-button--secondary.x-button,
287
+ .x-button--secondary .x-button {
288
+ --x-color-background-button-default: var(--x-color-background-button-secondary);
289
+ --x-color-border-button-default: var(--x-color-border-button-secondary);
290
+ --x-color-text-button-default: var(--x-color-text-button-secondary);
291
+ --x-size-border-width-top-button-default: var(--x-size-border-width-top-button-secondary);
292
+ --x-size-border-width-right-button-default: var(--x-size-border-width-right-button-secondary);
293
+ --x-size-border-width-bottom-button-default: var(--x-size-border-width-bottom-button-secondary);
294
+ --x-size-border-width-left-button-default: var(--x-size-border-width-left-button-secondary);
295
+ }
286
296
  :root {
287
297
  --x-color-background-button-secondary: transparent;
288
298
  --x-color-border-button-secondary: var(--x-color-border-button-default);
@@ -303,16 +313,6 @@
303
313
  --x-size-border-width-bottom-button-default: var(--x-size-border-width-bottom-button-tertiary);
304
314
  --x-size-border-width-left-button-default: var(--x-size-border-width-left-button-tertiary);
305
315
  }
306
- .x-button--secondary.x-button,
307
- .x-button--secondary .x-button {
308
- --x-color-background-button-default: var(--x-color-background-button-secondary);
309
- --x-color-border-button-default: var(--x-color-border-button-secondary);
310
- --x-color-text-button-default: var(--x-color-text-button-secondary);
311
- --x-size-border-width-top-button-default: var(--x-size-border-width-top-button-secondary);
312
- --x-size-border-width-right-button-default: var(--x-size-border-width-right-button-secondary);
313
- --x-size-border-width-bottom-button-default: var(--x-size-border-width-bottom-button-secondary);
314
- --x-size-border-width-left-button-default: var(--x-size-border-width-left-button-secondary);
315
- }
316
316
  :root {
317
317
  --x-color-background-button-tertiary: var(--x-color-base-neutral-95);
318
318
  --x-color-border-button-tertiary: var(--x-color-base-neutral-70);
@@ -58,6 +58,7 @@ var __vue_render__ = function () {
58
58
  return _vm.emitUserPressedArrowKey.apply(null, arguments)
59
59
  },
60
60
  ],
61
+ beforeinput: _vm.preventSpecialKey,
61
62
  },
62
63
  },
63
64
  _vm.$listeners
@@ -70,7 +71,7 @@ __vue_render__._withStripped = true;
70
71
  /* style */
71
72
  const __vue_inject_styles__ = undefined;
72
73
  /* scoped */
73
- const __vue_scope_id__ = "data-v-5d3fc332";
74
+ const __vue_scope_id__ = "data-v-513330ca";
74
75
  /* module identifier */
75
76
  const __vue_module_identifier__ = undefined;
76
77
  /* functional template */
@@ -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=\"input\"\n @blur=\"emitUserBlurredSearchBox\"\n @click=\"emitUserClickedSearchBox\"\n @focus=\"emitUserFocusedSearchBox\"\n @input=\"emitUserIsTypingAQueryEvents\"\n @keydown.enter=\"emitUserPressedEnterKey\"\n @keydown.up.down.prevent=\"emitUserPressedArrowKey\"\n v-on=\"$listeners\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-input x-search-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n :aria-label=\"searchInputMessage\"\n />\n</template>\n\n<script lang=\"ts\">\n import { Suggestion } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { XOn } from '../../../components/decorators/bus.decorators';\n import { State } from '../../../components/decorators/store.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { ArrowKey, PropsWithType } from '../../../utils';\n import { debounce } from '../../../utils/debounce';\n import { DebouncedFunction } from '../../../utils/types';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { WireMetadata } from '../../../wiring/wiring.types';\n import { 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 */\n @Component({\n mixins: [xComponentMixin(searchBoxXModule)]\n })\n export default class SearchInput extends Vue {\n public $refs!: { input: HTMLInputElement };\n\n protected searchInputMessage = 'type your query here';\n\n /**\n * Maximum characters allowed in the input search.\n */\n @Prop({ default: 64 })\n protected maxLength!: number;\n\n /**\n * Allows input autofocus when the search field is rendered.\n */\n @Prop({ default: true })\n protected autofocus!: boolean;\n\n /**\n * Enables the auto-accept query after debounce.\n */\n @Prop({ default: true })\n protected instant!: boolean;\n\n /**\n * Debounce time for the instant.\n */\n @Prop({ default: 500 })\n protected instantDebounceInMs!: number;\n\n /**\n * Keyboard keys to accept the autocomplete suggestion.\n */\n @Prop({ default: () => ['ArrowRight'] })\n protected autocompleteKeyboardKeys!: string[]; // https://keycode.info/\n\n /**\n * Event that retrieves the autocomplete suggestion.\n */\n @Prop({ default: 'QuerySuggestionsChanged' })\n protected autocompleteSuggestionsEvent!: PropsWithType<XEventsTypes, Suggestion[]>;\n\n @State('searchBox', 'query')\n public query!: string;\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search in put is focused.\n *\n * @internal\n */\n @XOn(['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'])\n focusInput(): void {\n this.$refs.input?.focus();\n }\n\n protected debouncedUserAcceptedAQuery!: DebouncedFunction<[string]>;\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 @XOn(['UserAcceptedAQuery', 'UserClearedQuery'])\n cancelDebouncedUserAcceptedAQuery(): void {\n this.debouncedUserAcceptedAQuery?.cancel();\n }\n\n mounted(): void {\n if (this.autofocus) {\n this.focusInput();\n }\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 emitDebouncedUserAcceptedAQuery(query: string): void {\n if (this.instant) {\n if (!this.debouncedUserAcceptedAQuery) {\n this.debouncedUserAcceptedAQuery = debounce(\n this.emitUserAcceptedAQuery.bind(this),\n this.instantDebounceInMs\n );\n }\n this.debouncedUserAcceptedAQuery(query);\n }\n }\n\n /**\n * Generates the {@link WireMetadata | event metadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n protected createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: this.$refs.input,\n feature: 'search_box'\n };\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n protected emitUserBlurredSearchBox(): void {\n this.$x.emit('UserBlurredSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n protected emitUserClickedSearchBox(): void {\n this.$x.emit('UserClickedSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n protected emitUserFocusedSearchBox(): void {\n this.$x.emit('UserFocusedSearchBox', undefined, { target: this.$refs.input });\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 protected emitUserIsTypingAQueryEvents(): void {\n const query = this.$refs.input.value;\n this.$x.emit('UserIsTypingAQuery', query, { target: this.$refs.input });\n if (query.trim()) {\n this.emitDebouncedUserAcceptedAQuery(query);\n } else {\n this.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 protected emitUserPressedArrowKey(event: KeyboardEvent): void {\n this.$x.emit('UserPressedArrowKey', event.key as ArrowKey, this.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 protected emitUserPressedEnterKey(): void {\n const query = this.$refs.input.value.trim();\n if (query.length > 0) {\n this.$x.emit('UserPressedEnterKey', query, this.createEventMetadata());\n this.emitUserAcceptedAQuery(query);\n }\n this.$refs.input?.blur();\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 protected emitUserAcceptedAQuery(query: string): void {\n this.$x.emit('UserAcceptedAQuery', query, this.createEventMetadata());\n }\n }\n</script>\n\n<style lang=\"scss\" 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`](./../../api/x-components.searchboxxevents.md)\n- [`UserBlurredSearchBox`](./../../api/x-components.searchboxxevents.md)\n- [`UserFocusedSearchBox`](./../../api/x-components.searchboxxevents.md)\n- [`UserIsTypingAQuery`](./../../api/x-components.searchboxxevents.md)\n- [`UserPressedEnterKey`](./../../api/x-components.searchboxxevents.md)\n- [`UserPressedArrowKey`](./../../api/x-components.xeventstypes.md)\n- [`UserAcceptedAQuery`](./../../api/x-components.xeventstypes.md)\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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box';\n import { QuerySuggestions } from '@empathyco/x-components/query-suggestions';\n\n export default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"search-input.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue"],"sourcesContent":["<template>\n <input\n ref=\"input\"\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 v-on=\"$listeners\"\n :maxlength=\"maxLength\"\n :value=\"query\"\n autocomplete=\"off\"\n class=\"x-input x-search-input\"\n enterkeyhint=\"search\"\n inputmode=\"search\"\n type=\"search\"\n data-test=\"search-input\"\n :aria-label=\"searchInputMessage\"\n />\n</template>\n\n<script lang=\"ts\">\n import { Suggestion } from '@empathyco/x-types';\n import Vue from 'vue';\n import { Component, Prop } from 'vue-property-decorator';\n import { XOn } from '../../../components/decorators/bus.decorators';\n import { State } from '../../../components/decorators/store.decorators';\n import { xComponentMixin } from '../../../components/x-component.mixin';\n import { ArrowKey, PropsWithType } from '../../../utils';\n import { debounce } from '../../../utils/debounce';\n import { DebouncedFunction } from '../../../utils/types';\n import { XEventsTypes } from '../../../wiring/events.types';\n import { WireMetadata } from '../../../wiring/wiring.types';\n import { 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 */\n @Component({\n mixins: [xComponentMixin(searchBoxXModule)]\n })\n export default class SearchInput extends Vue {\n public $refs!: { input: HTMLInputElement };\n\n protected searchInputMessage = 'type your query here';\n\n /**\n * Maximum characters allowed in the input search.\n */\n @Prop({ default: 64 })\n protected maxLength!: number;\n\n /**\n * Allows input autofocus when the search field is rendered.\n */\n @Prop({ default: true })\n protected autofocus!: boolean;\n\n /**\n * Enables the auto-accept query after debounce.\n */\n @Prop({ default: true })\n protected instant!: boolean;\n\n /**\n * Debounce time for the instant.\n */\n @Prop({ default: 500 })\n protected instantDebounceInMs!: number;\n\n /**\n * Keyboard keys to accept the autocomplete suggestion.\n */\n @Prop({ default: () => ['ArrowRight'] })\n protected autocompleteKeyboardKeys!: string[]; // https://keycode.info/\n\n /**\n * Event that retrieves the autocomplete suggestion.\n */\n @Prop({ default: 'QuerySuggestionsChanged' })\n protected autocompleteSuggestionsEvent!: PropsWithType<XEventsTypes, Suggestion[]>;\n\n @State('searchBox', 'query')\n public query!: string;\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 @XOn(['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'])\n focusInput(): void {\n this.$refs.input?.focus();\n }\n\n protected debouncedUserAcceptedAQuery!: DebouncedFunction<[string]>;\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 @XOn(['UserAcceptedAQuery', 'UserClearedQuery'])\n cancelDebouncedUserAcceptedAQuery(): void {\n this.debouncedUserAcceptedAQuery?.cancel();\n }\n\n mounted(): void {\n if (this.autofocus) {\n this.focusInput();\n }\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 emitDebouncedUserAcceptedAQuery(query: string): void {\n if (this.instant) {\n if (!this.debouncedUserAcceptedAQuery) {\n this.debouncedUserAcceptedAQuery = debounce(\n this.emitUserAcceptedAQuery.bind(this),\n this.instantDebounceInMs\n );\n }\n this.debouncedUserAcceptedAQuery(query);\n }\n }\n\n /**\n * Generates the {@link WireMetadata | event metadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n protected createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: this.$refs.input,\n feature: 'search_box'\n };\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n protected emitUserBlurredSearchBox(): void {\n this.$x.emit('UserBlurredSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n protected emitUserClickedSearchBox(): void {\n this.$x.emit('UserClickedSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n protected emitUserFocusedSearchBox(): void {\n this.$x.emit('UserFocusedSearchBox', undefined, { target: this.$refs.input });\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 protected emitUserIsTypingAQueryEvents(): void {\n const query = this.$refs.input.value;\n this.$x.emit('UserIsTypingAQuery', query, { target: this.$refs.input });\n if (query.trim()) {\n this.emitDebouncedUserAcceptedAQuery(query);\n } else {\n this.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 protected emitUserPressedArrowKey(event: KeyboardEvent): void {\n this.$x.emit('UserPressedArrowKey', event.key as ArrowKey, this.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 protected emitUserPressedEnterKey(): void {\n const query = this.$refs.input.value.trim();\n if (query.length > 0) {\n this.$x.emit('UserPressedEnterKey', query, this.createEventMetadata());\n this.emitUserAcceptedAQuery(query);\n }\n this.$refs.input?.blur();\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 protected emitUserAcceptedAQuery(query: string): void {\n this.$x.emit('UserAcceptedAQuery', query, this.createEventMetadata());\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 protected preventSpecialKey(event: InputEvent): void {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault();\n }\n }\n }\n</script>\n\n<style lang=\"scss\" 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`](./../../api/x-components.searchboxxevents.md)\n- [`UserBlurredSearchBox`](./../../api/x-components.searchboxxevents.md)\n- [`UserFocusedSearchBox`](./../../api/x-components.searchboxxevents.md)\n- [`UserIsTypingAQuery`](./../../api/x-components.searchboxxevents.md)\n- [`UserPressedEnterKey`](./../../api/x-components.searchboxxevents.md)\n- [`UserPressedArrowKey`](./../../api/x-components.xeventstypes.md)\n- [`UserAcceptedAQuery`](./../../api/x-components.xeventstypes.md)\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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput } from '@empathyco/x-components/search-box';\n\n export 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>\n import { SearchInput, ClearSearchInput, SearchButton } from '@empathyco/x-components/search-box';\n import { QuerySuggestions } from '@empathyco/x-components/query-suggestions';\n\n export default {\n name: 'SearchInputDemo',\n components: {\n SearchInput,\n ClearSearchInput,\n SearchButton,\n QuerySuggestions\n }\n };\n</script>\n```\n</docs>\n"],"names":[],"mappings":";;;;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -21,7 +21,7 @@ let SearchInput = class SearchInput extends Vue {
21
21
  /**
22
22
  * When event {@link XEventsTypes.UserReachedEmpathizeTop} or
23
23
  * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}
24
- * are emitted the search in put is focused.
24
+ * are emitted the search input is focused.
25
25
  *
26
26
  * @internal
27
27
  */
@@ -149,6 +149,17 @@ let SearchInput = class SearchInput extends Vue {
149
149
  emitUserAcceptedAQuery(query) {
150
150
  this.$x.emit('UserAcceptedAQuery', query, this.createEventMetadata());
151
151
  }
152
+ /**
153
+ * Prevents the user from either typing or pasting special characters in the input field.
154
+ *
155
+ * @internal
156
+ * @param event - The event that will be checked for special characters.
157
+ */
158
+ preventSpecialKey(event) {
159
+ if (/[<>]/.test(event.data ?? '')) {
160
+ event.preventDefault();
161
+ }
162
+ }
152
163
  };
153
164
  __decorate([
154
165
  Prop({ default: 64 })
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport { Suggestion } from '@empathyco/x-types';\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\nimport { XOn } from '../../../components/decorators/bus.decorators';\nimport { State } from '../../../components/decorators/store.decorators';\nimport { xComponentMixin } from '../../../components/x-component.mixin';\nimport { ArrowKey, PropsWithType } from '../../../utils';\nimport { debounce } from '../../../utils/debounce';\nimport { DebouncedFunction } from '../../../utils/types';\nimport { XEventsTypes } from '../../../wiring/events.types';\nimport { WireMetadata } from '../../../wiring/wiring.types';\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 */\n@Component({\n mixins: [xComponentMixin(searchBoxXModule)]\n})\nexport default class SearchInput extends Vue {\n public $refs!: { input: HTMLInputElement };\n\n protected searchInputMessage = 'type your query here';\n\n /**\n * Maximum characters allowed in the input search.\n */\n @Prop({ default: 64 })\n protected maxLength!: number;\n\n /**\n * Allows input autofocus when the search field is rendered.\n */\n @Prop({ default: true })\n protected autofocus!: boolean;\n\n /**\n * Enables the auto-accept query after debounce.\n */\n @Prop({ default: true })\n protected instant!: boolean;\n\n /**\n * Debounce time for the instant.\n */\n @Prop({ default: 500 })\n protected instantDebounceInMs!: number;\n\n /**\n * Keyboard keys to accept the autocomplete suggestion.\n */\n @Prop({ default: () => ['ArrowRight'] })\n protected autocompleteKeyboardKeys!: string[]; // https://keycode.info/\n\n /**\n * Event that retrieves the autocomplete suggestion.\n */\n @Prop({ default: 'QuerySuggestionsChanged' })\n protected autocompleteSuggestionsEvent!: PropsWithType<XEventsTypes, Suggestion[]>;\n\n @State('searchBox', 'query')\n public query!: string;\n\n /**\n * When event {@link XEventsTypes.UserReachedEmpathizeTop} or\n * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}\n * are emitted the search in put is focused.\n *\n * @internal\n */\n @XOn(['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'])\n focusInput(): void {\n this.$refs.input?.focus();\n }\n\n protected debouncedUserAcceptedAQuery!: DebouncedFunction<[string]>;\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 @XOn(['UserAcceptedAQuery', 'UserClearedQuery'])\n cancelDebouncedUserAcceptedAQuery(): void {\n this.debouncedUserAcceptedAQuery?.cancel();\n }\n\n mounted(): void {\n if (this.autofocus) {\n this.focusInput();\n }\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 emitDebouncedUserAcceptedAQuery(query: string): void {\n if (this.instant) {\n if (!this.debouncedUserAcceptedAQuery) {\n this.debouncedUserAcceptedAQuery = debounce(\n this.emitUserAcceptedAQuery.bind(this),\n this.instantDebounceInMs\n );\n }\n this.debouncedUserAcceptedAQuery(query);\n }\n }\n\n /**\n * Generates the {@link WireMetadata | event metadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n protected createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: this.$refs.input,\n feature: 'search_box'\n };\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n protected emitUserBlurredSearchBox(): void {\n this.$x.emit('UserBlurredSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n protected emitUserClickedSearchBox(): void {\n this.$x.emit('UserClickedSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n protected emitUserFocusedSearchBox(): void {\n this.$x.emit('UserFocusedSearchBox', undefined, { target: this.$refs.input });\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 protected emitUserIsTypingAQueryEvents(): void {\n const query = this.$refs.input.value;\n this.$x.emit('UserIsTypingAQuery', query, { target: this.$refs.input });\n if (query.trim()) {\n this.emitDebouncedUserAcceptedAQuery(query);\n } else {\n this.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 protected emitUserPressedArrowKey(event: KeyboardEvent): void {\n this.$x.emit('UserPressedArrowKey', event.key as ArrowKey, this.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 protected emitUserPressedEnterKey(): void {\n const query = this.$refs.input.value.trim();\n if (query.length > 0) {\n this.$x.emit('UserPressedEnterKey', query, this.createEventMetadata());\n this.emitUserAcceptedAQuery(query);\n }\n this.$refs.input?.blur();\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 protected emitUserAcceptedAQuery(query: string): void {\n this.$x.emit('UserAcceptedAQuery', query, this.createEventMetadata());\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-input.vue_rollup-plugin-vue_script.vue.js","sources":["../../../../../src/x-modules/search-box/components/search-input.vue?rollup-plugin-vue=script.ts"],"sourcesContent":["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport { Suggestion } from '@empathyco/x-types';\nimport Vue from 'vue';\nimport { Component, Prop } from 'vue-property-decorator';\nimport { XOn } from '../../../components/decorators/bus.decorators';\nimport { State } from '../../../components/decorators/store.decorators';\nimport { xComponentMixin } from '../../../components/x-component.mixin';\nimport { ArrowKey, PropsWithType } from '../../../utils';\nimport { debounce } from '../../../utils/debounce';\nimport { DebouncedFunction } from '../../../utils/types';\nimport { XEventsTypes } from '../../../wiring/events.types';\nimport { WireMetadata } from '../../../wiring/wiring.types';\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 */\n@Component({\n mixins: [xComponentMixin(searchBoxXModule)]\n})\nexport default class SearchInput extends Vue {\n public $refs!: { input: HTMLInputElement };\n\n protected searchInputMessage = 'type your query here';\n\n /**\n * Maximum characters allowed in the input search.\n */\n @Prop({ default: 64 })\n protected maxLength!: number;\n\n /**\n * Allows input autofocus when the search field is rendered.\n */\n @Prop({ default: true })\n protected autofocus!: boolean;\n\n /**\n * Enables the auto-accept query after debounce.\n */\n @Prop({ default: true })\n protected instant!: boolean;\n\n /**\n * Debounce time for the instant.\n */\n @Prop({ default: 500 })\n protected instantDebounceInMs!: number;\n\n /**\n * Keyboard keys to accept the autocomplete suggestion.\n */\n @Prop({ default: () => ['ArrowRight'] })\n protected autocompleteKeyboardKeys!: string[]; // https://keycode.info/\n\n /**\n * Event that retrieves the autocomplete suggestion.\n */\n @Prop({ default: 'QuerySuggestionsChanged' })\n protected autocompleteSuggestionsEvent!: PropsWithType<XEventsTypes, Suggestion[]>;\n\n @State('searchBox', 'query')\n public query!: string;\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 @XOn(['UserReachedEmpathizeTop', 'UserPressedClearSearchBoxButton'])\n focusInput(): void {\n this.$refs.input?.focus();\n }\n\n protected debouncedUserAcceptedAQuery!: DebouncedFunction<[string]>;\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 @XOn(['UserAcceptedAQuery', 'UserClearedQuery'])\n cancelDebouncedUserAcceptedAQuery(): void {\n this.debouncedUserAcceptedAQuery?.cancel();\n }\n\n mounted(): void {\n if (this.autofocus) {\n this.focusInput();\n }\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 emitDebouncedUserAcceptedAQuery(query: string): void {\n if (this.instant) {\n if (!this.debouncedUserAcceptedAQuery) {\n this.debouncedUserAcceptedAQuery = debounce(\n this.emitUserAcceptedAQuery.bind(this),\n this.instantDebounceInMs\n );\n }\n this.debouncedUserAcceptedAQuery(query);\n }\n }\n\n /**\n * Generates the {@link WireMetadata | event metadata} object omitting the moduleName.\n *\n * @returns The {@link WireMetadata} object omitting the moduleName.\n * @internal\n */\n protected createEventMetadata(): Omit<WireMetadata, 'moduleName'> {\n return {\n target: this.$refs.input,\n feature: 'search_box'\n };\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserBlurredSearchBox} when search box loses focus.\n *\n * @internal\n */\n protected emitUserBlurredSearchBox(): void {\n this.$x.emit('UserBlurredSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserClickedSearchBox} when user clicks the search input.\n *\n * @internal\n */\n protected emitUserClickedSearchBox(): void {\n this.$x.emit('UserClickedSearchBox', undefined, { target: this.$refs.input });\n }\n\n /**\n * Emits event {@link SearchBoxXEvents.UserFocusedSearchBox} when search box gains focus.\n *\n * @internal\n */\n protected emitUserFocusedSearchBox(): void {\n this.$x.emit('UserFocusedSearchBox', undefined, { target: this.$refs.input });\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 protected emitUserIsTypingAQueryEvents(): void {\n const query = this.$refs.input.value;\n this.$x.emit('UserIsTypingAQuery', query, { target: this.$refs.input });\n if (query.trim()) {\n this.emitDebouncedUserAcceptedAQuery(query);\n } else {\n this.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 protected emitUserPressedArrowKey(event: KeyboardEvent): void {\n this.$x.emit('UserPressedArrowKey', event.key as ArrowKey, this.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 protected emitUserPressedEnterKey(): void {\n const query = this.$refs.input.value.trim();\n if (query.length > 0) {\n this.$x.emit('UserPressedEnterKey', query, this.createEventMetadata());\n this.emitUserAcceptedAQuery(query);\n }\n this.$refs.input?.blur();\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 protected emitUserAcceptedAQuery(query: string): void {\n this.$x.emit('UserAcceptedAQuery', query, this.createEventMetadata());\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 protected preventSpecialKey(event: InputEvent): void {\n if (/[<>]/.test(event.data ?? '')) {\n event.preventDefault();\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createInjector, createInjectorSSR } from 'vue-runtime-helpers';
2
2
 
3
- var css = ".x-search-input[data-v-5d3fc332]::-webkit-search-decoration,\n.x-search-input[data-v-5d3fc332]::-webkit-search-cancel-button,\n.x-search-input[data-v-5d3fc332]::-webkit-search-results-button,\n.x-search-input[data-v-5d3fc332]::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}";
3
+ var css = ".x-search-input[data-v-513330ca]::-webkit-search-decoration,\n.x-search-input[data-v-513330ca]::-webkit-search-cancel-button,\n.x-search-input[data-v-513330ca]::-webkit-search-results-button,\n.x-search-input[data-v-513330ca]::-webkit-search-results-decoration {\n -webkit-appearance: none;\n}";
4
4
  const isBrowser = /*#__PURE__*/ (function () {
5
5
  return (
6
6
  Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) !==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empathyco/x-components",
3
- "version": "3.0.0-alpha.176",
3
+ "version": "3.0.0-alpha.178",
4
4
  "description": "Empathy X Components",
5
5
  "author": "Empathy Systems Corporation S.L.",
6
6
  "license": "Apache-2.0",
@@ -82,7 +82,7 @@
82
82
  "@cypress/vue": "~2.2.4",
83
83
  "@cypress/webpack-dev-server": "~1.8.4",
84
84
  "@empathyco/x-adapter-platform": "^1.0.0-alpha.35",
85
- "@empathyco/x-tailwindcss": "^0.2.0-alpha.15",
85
+ "@empathyco/x-tailwindcss": "^0.2.0-alpha.16",
86
86
  "@microsoft/api-documenter": "~7.15.3",
87
87
  "@microsoft/api-extractor": "~7.19.4",
88
88
  "@rollup/plugin-commonjs": "~21.0.1",
@@ -132,5 +132,5 @@
132
132
  "access": "public",
133
133
  "directory": "dist"
134
134
  },
135
- "gitHead": "318099db44f7ed6065627cc2e2cd5274f873bbd4"
135
+ "gitHead": "814421fcb4d4c5b6a5003adb543adccfee90d1eb"
136
136
  }
@@ -3942,6 +3942,8 @@ export class SearchInput extends Vue_2 {
3942
3942
  protected maxLength: number;
3943
3943
  // (undocumented)
3944
3944
  mounted(): void;
3945
+ // @internal
3946
+ protected preventSpecialKey(event: InputEvent): void;
3945
3947
  // (undocumented)
3946
3948
  query: string;
3947
3949
  // (undocumented)
@@ -43,7 +43,7 @@ export default class SearchInput extends Vue {
43
43
  /**
44
44
  * When event {@link XEventsTypes.UserReachedEmpathizeTop} or
45
45
  * {@link SearchBoxXEvents.UserPressedClearSearchBoxButton}
46
- * are emitted the search in put is focused.
46
+ * are emitted the search input is focused.
47
47
  *
48
48
  * @internal
49
49
  */
@@ -126,5 +126,12 @@ export default class SearchInput extends Vue {
126
126
  * @param query - The query that will be emitted.
127
127
  */
128
128
  protected emitUserAcceptedAQuery(query: string): void;
129
+ /**
130
+ * Prevents the user from either typing or pasting special characters in the input field.
131
+ *
132
+ * @internal
133
+ * @param event - The event that will be checked for special characters.
134
+ */
135
+ protected preventSpecialKey(event: InputEvent): void;
129
136
  }
130
137
  //# sourceMappingURL=search-input.vue?rollup-plugin-vue=script.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../../src/x-modules/search-box/components/search-input.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,GAAG,MAAM,KAAK,CAAC;AAKtB,OAAO,EAAY,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D;;;;;GAKG;AAIH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,GAAG;IACnC,KAAK,EAAG;QAAE,KAAK,EAAE,gBAAgB,CAAA;KAAE,CAAC;IAE3C,SAAS,CAAC,kBAAkB,SAA0B;IAEtD;;OAEG;IAEH,SAAS,CAAC,SAAS,EAAG,MAAM,CAAC;IAE7B;;OAEG;IAEH,SAAS,CAAC,SAAS,EAAG,OAAO,CAAC;IAE9B;;OAEG;IAEH,SAAS,CAAC,OAAO,EAAG,OAAO,CAAC;IAE5B;;OAEG;IAEH,SAAS,CAAC,mBAAmB,EAAG,MAAM,CAAC;IAEvC;;OAEG;IAEH,SAAS,CAAC,wBAAwB,EAAG,MAAM,EAAE,CAAC;IAE9C;;OAEG;IAEH,SAAS,CAAC,4BAA4B,EAAG,aAAa,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;IAG5E,KAAK,EAAG,MAAM,CAAC;IAEtB;;;;;;OAMG;IAEH,UAAU,IAAI,IAAI;IAIlB,SAAS,CAAC,2BAA2B,EAAG,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpE;;;;;;OAMG;IAEH,iCAAiC,IAAI,IAAI;IAIzC,OAAO,IAAI,IAAI;IAMf;;;;;;OAMG;IACH,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAYpD;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;IAOjE;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;;;OAMG;IACH,SAAS,CAAC,4BAA4B,IAAI,IAAI;IAU9C;;;;;OAKG;IACH,SAAS,CAAC,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI7D;;;;;;;;;OASG;IACH,SAAS,CAAC,uBAAuB,IAAI,IAAI;IASzC;;;;;;;OAOG;IACH,SAAS,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAGtD"}
1
+ {"version":3,"file":"search-input.vue?rollup-plugin-vue=script.d.ts","sourceRoot":"","sources":["../../../../../src/x-modules/search-box/components/search-input.vue?rollup-plugin-vue=script.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,GAAG,MAAM,KAAK,CAAC;AAKtB,OAAO,EAAY,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D;;;;;GAKG;AAIH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,GAAG;IACnC,KAAK,EAAG;QAAE,KAAK,EAAE,gBAAgB,CAAA;KAAE,CAAC;IAE3C,SAAS,CAAC,kBAAkB,SAA0B;IAEtD;;OAEG;IAEH,SAAS,CAAC,SAAS,EAAG,MAAM,CAAC;IAE7B;;OAEG;IAEH,SAAS,CAAC,SAAS,EAAG,OAAO,CAAC;IAE9B;;OAEG;IAEH,SAAS,CAAC,OAAO,EAAG,OAAO,CAAC;IAE5B;;OAEG;IAEH,SAAS,CAAC,mBAAmB,EAAG,MAAM,CAAC;IAEvC;;OAEG;IAEH,SAAS,CAAC,wBAAwB,EAAG,MAAM,EAAE,CAAC;IAE9C;;OAEG;IAEH,SAAS,CAAC,4BAA4B,EAAG,aAAa,CAAC,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;IAG5E,KAAK,EAAG,MAAM,CAAC;IAEtB;;;;;;OAMG;IAEH,UAAU,IAAI,IAAI;IAIlB,SAAS,CAAC,2BAA2B,EAAG,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpE;;;;;;OAMG;IAEH,iCAAiC,IAAI,IAAI;IAIzC,OAAO,IAAI,IAAI;IAMf;;;;;;OAMG;IACH,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAYpD;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;IAOjE;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;OAIG;IACH,SAAS,CAAC,wBAAwB,IAAI,IAAI;IAI1C;;;;;;OAMG;IACH,SAAS,CAAC,4BAA4B,IAAI,IAAI;IAU9C;;;;;OAKG;IACH,SAAS,CAAC,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAI7D;;;;;;;;;OASG;IACH,SAAS,CAAC,uBAAuB,IAAI,IAAI;IASzC;;;;;;;OAOG;IACH,SAAS,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrD;;;;;OAKG;IACH,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;CAKrD"}