@haiilo/catalyst 6.3.2 → 6.3.3

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 (50) hide show
  1. package/dist/catalyst/catalyst.esm.js +1 -1
  2. package/dist/catalyst/p-2ecedf97.entry.js +10 -0
  3. package/dist/catalyst/p-2ecedf97.entry.js.map +1 -0
  4. package/dist/catalyst/scss/_snippets/_form-label.scss +12 -4
  5. package/dist/cjs/cat-alert_26.cjs.entry.js +45 -45
  6. package/dist/cjs/cat-alert_26.cjs.entry.js.map +1 -1
  7. package/dist/collection/components/cat-datepicker/cat-datepicker.js +2 -11
  8. package/dist/collection/components/cat-datepicker/cat-datepicker.js.map +1 -1
  9. package/dist/collection/components/cat-dropdown/cat-dropdown.js +20 -20
  10. package/dist/collection/components/cat-dropdown/cat-dropdown.js.map +1 -1
  11. package/dist/collection/components/cat-input/cat-input.css +24 -8
  12. package/dist/collection/components/cat-input/cat-input.js +2 -2
  13. package/dist/collection/components/cat-input/cat-input.js.map +1 -1
  14. package/dist/collection/components/cat-select/cat-select.css +24 -8
  15. package/dist/collection/components/cat-select/cat-select.js +3 -6
  16. package/dist/collection/components/cat-select/cat-select.js.map +1 -1
  17. package/dist/collection/components/cat-select/cat-select.spec.js +1 -1
  18. package/dist/collection/components/cat-select/cat-select.spec.js.map +1 -1
  19. package/dist/collection/components/cat-select-demo/cat-select-demo.js +1 -1
  20. package/dist/collection/components/cat-select-demo/cat-select-demo.js.map +1 -1
  21. package/dist/collection/components/cat-tabs/cat-tabs.js +1 -1
  22. package/dist/collection/components/cat-tabs/cat-tabs.js.map +1 -1
  23. package/dist/collection/components/cat-textarea/cat-textarea.css +24 -8
  24. package/dist/collection/components/cat-textarea/cat-textarea.js +1 -1
  25. package/dist/collection/components/cat-textarea/cat-textarea.js.map +1 -1
  26. package/dist/collection/scss/_snippets/_form-label.scss +12 -4
  27. package/dist/collection/utils/find-closest.js +13 -0
  28. package/dist/collection/utils/find-closest.js.map +1 -0
  29. package/dist/components/cat-datepicker.js +14 -11
  30. package/dist/components/cat-datepicker.js.map +1 -1
  31. package/dist/components/cat-dropdown2.js +20 -20
  32. package/dist/components/cat-dropdown2.js.map +1 -1
  33. package/dist/components/cat-input2.js +3 -3
  34. package/dist/components/cat-input2.js.map +1 -1
  35. package/dist/components/cat-select-demo.js +1 -1
  36. package/dist/components/cat-select-demo.js.map +1 -1
  37. package/dist/components/cat-select2.js +4 -7
  38. package/dist/components/cat-select2.js.map +1 -1
  39. package/dist/components/cat-tabs.js +1 -1
  40. package/dist/components/cat-tabs.js.map +1 -1
  41. package/dist/components/cat-textarea.js +2 -2
  42. package/dist/components/cat-textarea.js.map +1 -1
  43. package/dist/esm/cat-alert_26.entry.js +45 -45
  44. package/dist/esm/cat-alert_26.entry.js.map +1 -1
  45. package/dist/types/components/cat-datepicker/cat-datepicker.d.ts +0 -1
  46. package/dist/types/components/cat-dropdown/cat-dropdown.d.ts +1 -0
  47. package/dist/types/utils/find-closest.d.ts +5 -0
  48. package/package.json +2 -2
  49. package/dist/catalyst/p-2257ac13.entry.js +0 -10
  50. package/dist/catalyst/p-2257ac13.entry.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { h } from "@stencil/core";
2
2
  import flatpickr from "flatpickr";
3
+ import { findClosest } from "../../utils/find-closest";
3
4
  import { catI18nRegistry as i18n } from "../cat-i18n/cat-i18n-registry";
4
5
  import { getConfig } from "./cat-datepicker.config";
5
6
  import { getFormat } from "./cat-datepicker.format";
@@ -91,7 +92,7 @@ export class CatDatepickerFlat {
91
92
  return;
92
93
  }
93
94
  // avoid dropdown closing if datepicker is part of a dropdown
94
- const withinDropdown = !!this.findClosest('cat-dropdown', input);
95
+ const withinDropdown = !!findClosest('cat-dropdown', input);
95
96
  const nativePickerAttributes = withinDropdown ? { 'data-dropdown-no-close': '' } : {};
96
97
  return flatpickr(input, getConfig({
97
98
  locale: getLocale(i18n.getLocale()),
@@ -106,16 +107,6 @@ export class CatDatepickerFlat {
106
107
  applyChange: value => (this.value = value)
107
108
  }));
108
109
  }
109
- findClosest(selector, element) {
110
- if (element instanceof Element && element.matches(selector)) {
111
- return element;
112
- }
113
- // Search in parent element or Shadow DOM host
114
- const nextElement = element instanceof ShadowRoot
115
- ? element.host
116
- : element.parentElement || element.getRootNode().host;
117
- return nextElement ? this.findClosest(selector, nextElement) : null;
118
- }
119
110
  static get is() { return "cat-datepicker"; }
120
111
  static get encapsulation() { return "shadow"; }
121
112
  static get originalStyleUrls() {
@@ -1 +1 @@
1
- {"version":3,"file":"cat-datepicker.js","sourceRoot":"","sources":["../../../src/components/cat-datepicker/cat-datepicker.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, Method, Prop, Watch, h } from '@stencil/core';\nimport flatpickr from 'flatpickr';\nimport { ErrorMap } from '../cat-form-hint/cat-form-hint';\nimport { catI18nRegistry as i18n } from '../cat-i18n/cat-i18n-registry';\nimport { getConfig } from './cat-datepicker.config';\nimport { getFormat } from './cat-datepicker.format';\nimport { getLocale } from './cat-datepicker.locale';\nimport { CatDatepickerMode } from './cat-datepicker.mode';\n\n@Component({\n tag: 'cat-datepicker',\n styleUrl: 'cat-datepicker.scss',\n shadow: true\n})\nexport class CatDatepickerFlat {\n private pickr?: flatpickr.Instance;\n private _input?: HTMLCatInputElement;\n private get input(): HTMLInputElement | undefined {\n return this._input?.shadowRoot?.querySelector('input') ?? undefined;\n }\n\n /**\n * Whether the label need a marker to shown if the input is required or optional.\n */\n @Prop() requiredMarker: 'none' | 'required' | 'optional' | 'none!' | 'optional!' | 'required!' = 'optional';\n\n /**\n * Whether the label is on top or left.\n */\n @Prop() horizontal = false;\n\n /**\n * Hint for form autofill feature.\n */\n @Prop() autoComplete?: string;\n\n /**\n * Whether the input should show a clear button.\n */\n @Prop() clearable = false;\n\n /**\n * Whether the input is disabled.\n */\n @Prop() disabled = false;\n\n /**\n * Optional hint text(s) to be displayed with the input.\n */\n @Prop() hint?: string | string[];\n\n /**\n * The name of an icon to be displayed in the input.\n */\n @Prop() icon?: string;\n\n /**\n * Display the icon on the right.\n */\n @Prop() iconRight = false;\n\n /**\n * A unique identifier for the input.\n */\n @Prop() identifier?: string;\n\n /**\n * The label for the input.\n */\n @Prop() label = '';\n\n /**\n * Visually hide the label, but still show it to assistive technologies like screen readers.\n */\n @Prop() labelHidden = false;\n\n /**\n * A maximum value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z.\n */\n @Prop() max?: string;\n\n /**\n * A minimum value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z.\n */\n @Prop() min?: string;\n\n /**\n * The mode of the datepicker, to select a date, time, both, a date range or a week number.\n */\n @Prop() mode: CatDatepickerMode = 'date';\n\n /**\n * The name of the form control. Submitted with the form as part of a name/value pair.\n */\n @Prop() name?: string;\n\n /**\n * The placeholder text to display within the input.\n */\n @Prop() placeholder?: string;\n\n /**\n * A textual prefix to be displayed in the input.\n */\n @Prop() textPrefix?: string;\n\n /**\n * A textual suffix to be displayed in the input.\n */\n @Prop() textSuffix?: string;\n\n /**\n * The value is not editable.\n */\n @Prop() readonly = false;\n\n /**\n * A value is required or must be check for the form to be submittable.\n */\n @Prop() required = false;\n\n /**\n * The step size to use when changing the time.\n */\n @Prop() step = 5;\n\n /**\n * The value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z or as a week number string.\n */\n @Prop({ mutable: true }) value?: string;\n\n /**\n * The validation errors for this input. Will render a hint under the input\n * with the translated error message(s) `error.${key}`. If an object is\n * passed, the keys will be used as error keys and the values translation\n * parameters.\n * If the value is `true`, the input will be marked as invalid without any\n * hints under the input.\n */\n @Prop() errors?: boolean | string[] | ErrorMap;\n\n /**\n * Fine-grained control over when the errors are shown. Can be `false` to\n * never show errors, `true` to show errors on blur, or a number to show\n * errors on change with the given delay in milliseconds.\n */\n @Prop() errorUpdate: boolean | number = 0;\n\n /**\n * Attributes that will be added to the native HTML input element.\n */\n @Prop() nativeAttributes?: { [key: string]: string };\n\n /**\n * Attributes that will be added to the rendered HTML datepicker element.\n */\n @Prop() nativePickerAttributes?: { [key: string]: string };\n\n /**\n * Emitted when the value is changed.\n */\n @Event() catChange!: EventEmitter<string>;\n\n /**\n * Emitted when the input received focus.\n */\n @Event() catFocus!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() catBlur!: EventEmitter<FocusEvent>;\n\n @Watch('value')\n onValueChanged(value: string) {\n if (value) {\n this.pickr?.setDate(value, false);\n this.catChange.emit(value);\n } else {\n this.pickr?.clear(false);\n this.catChange.emit(undefined);\n }\n }\n\n @Watch('disabled')\n @Watch('readonly')\n onDisabledChanged() {\n // Dynamically changing 'disabled' value is not working due to a bug in the\n // library. We thus need to fully recreate the date picker after the value\n // has been updated.\n this.pickr?.destroy();\n this.pickr = undefined;\n setTimeout(() => (this.pickr = this.initDatepicker(this.input)));\n }\n\n componentDidLoad() {\n this.pickr = this.initDatepicker(this.input);\n }\n\n /**\n * Programmatically move focus to the datepicker. Use this method instead of\n * `input.focus()`.\n *\n * @param options An optional object providing options to control aspects of\n * the focusing process.\n */\n @Method()\n async doFocus(options?: FocusOptions): Promise<void> {\n this._input?.doFocus(options);\n }\n\n /**\n * Programmatically remove focus from the datepicker. Use this method instead of\n * `input.blur()`.\n */\n @Method()\n async doBlur(): Promise<void> {\n this._input?.doBlur();\n }\n\n render() {\n return (\n <cat-input\n ref={el => (this._input = el)}\n requiredMarker={this.requiredMarker}\n horizontal={this.horizontal}\n autoComplete={this.autoComplete}\n clearable={this.clearable}\n disabled={this.disabled}\n hint={this.hint}\n icon={this.icon}\n iconRight={this.iconRight}\n identifier={this.identifier}\n label={this.label}\n labelHidden={this.labelHidden}\n name={this.name}\n placeholder={this.placeholder}\n textPrefix={this.textPrefix}\n textSuffix={this.textSuffix}\n readonly={this.readonly}\n required={this.required}\n value={this.value}\n errors={this.errors}\n errorUpdate={this.errorUpdate}\n nativeAttributes={this.nativeAttributes}\n onCatChange={e => {\n e.stopPropagation();\n this.value = e.detail || undefined;\n }}\n onCatFocus={e => {\n e.stopPropagation();\n this.catFocus.emit(e.detail);\n }}\n onCatBlur={e => {\n e.stopPropagation();\n this.catBlur.emit(e.detail);\n }}\n ></cat-input>\n );\n }\n\n private initDatepicker(input?: HTMLInputElement): flatpickr.Instance | undefined {\n if (this.disabled || this.readonly || !input) {\n return;\n }\n\n // avoid dropdown closing if datepicker is part of a dropdown\n const withinDropdown = !!this.findClosest('cat-dropdown', input);\n const nativePickerAttributes: { [key: string]: string } = withinDropdown ? { 'data-dropdown-no-close': '' } : {};\n\n return flatpickr(\n input,\n getConfig({\n locale: getLocale(i18n.getLocale()),\n format: getFormat(i18n.getLocale(), this.mode),\n mode: this.mode,\n min: this.min,\n max: this.max,\n step: this.step,\n disabled: this.disabled,\n readonly: this.readonly,\n nativePickerAttributes: { ...nativePickerAttributes, ...this.nativePickerAttributes },\n applyChange: value => (this.value = value)\n })\n );\n }\n\n private findClosest(selector: string, element: Element | ShadowRoot): Element | null {\n if (element instanceof Element && element.matches(selector)) {\n return element;\n }\n\n // Search in parent element or Shadow DOM host\n const nextElement =\n element instanceof ShadowRoot\n ? element.host\n : element.parentElement || (element.getRootNode() as ShadowRoot).host;\n return nextElement ? this.findClosest(selector, nextElement) : null;\n }\n}\n"]}
1
+ {"version":3,"file":"cat-datepicker.js","sourceRoot":"","sources":["../../../src/components/cat-datepicker/cat-datepicker.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, Method, Prop, Watch, h } from '@stencil/core';\nimport flatpickr from 'flatpickr';\nimport { findClosest } from '../../utils/find-closest';\nimport { ErrorMap } from '../cat-form-hint/cat-form-hint';\nimport { catI18nRegistry as i18n } from '../cat-i18n/cat-i18n-registry';\nimport { getConfig } from './cat-datepicker.config';\nimport { getFormat } from './cat-datepicker.format';\nimport { getLocale } from './cat-datepicker.locale';\nimport { CatDatepickerMode } from './cat-datepicker.mode';\n\n@Component({\n tag: 'cat-datepicker',\n styleUrl: 'cat-datepicker.scss',\n shadow: true\n})\nexport class CatDatepickerFlat {\n private pickr?: flatpickr.Instance;\n private _input?: HTMLCatInputElement;\n private get input(): HTMLInputElement | undefined {\n return this._input?.shadowRoot?.querySelector('input') ?? undefined;\n }\n\n /**\n * Whether the label need a marker to shown if the input is required or optional.\n */\n @Prop() requiredMarker: 'none' | 'required' | 'optional' | 'none!' | 'optional!' | 'required!' = 'optional';\n\n /**\n * Whether the label is on top or left.\n */\n @Prop() horizontal = false;\n\n /**\n * Hint for form autofill feature.\n */\n @Prop() autoComplete?: string;\n\n /**\n * Whether the input should show a clear button.\n */\n @Prop() clearable = false;\n\n /**\n * Whether the input is disabled.\n */\n @Prop() disabled = false;\n\n /**\n * Optional hint text(s) to be displayed with the input.\n */\n @Prop() hint?: string | string[];\n\n /**\n * The name of an icon to be displayed in the input.\n */\n @Prop() icon?: string;\n\n /**\n * Display the icon on the right.\n */\n @Prop() iconRight = false;\n\n /**\n * A unique identifier for the input.\n */\n @Prop() identifier?: string;\n\n /**\n * The label for the input.\n */\n @Prop() label = '';\n\n /**\n * Visually hide the label, but still show it to assistive technologies like screen readers.\n */\n @Prop() labelHidden = false;\n\n /**\n * A maximum value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z.\n */\n @Prop() max?: string;\n\n /**\n * A minimum value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z.\n */\n @Prop() min?: string;\n\n /**\n * The mode of the datepicker, to select a date, time, both, a date range or a week number.\n */\n @Prop() mode: CatDatepickerMode = 'date';\n\n /**\n * The name of the form control. Submitted with the form as part of a name/value pair.\n */\n @Prop() name?: string;\n\n /**\n * The placeholder text to display within the input.\n */\n @Prop() placeholder?: string;\n\n /**\n * A textual prefix to be displayed in the input.\n */\n @Prop() textPrefix?: string;\n\n /**\n * A textual suffix to be displayed in the input.\n */\n @Prop() textSuffix?: string;\n\n /**\n * The value is not editable.\n */\n @Prop() readonly = false;\n\n /**\n * A value is required or must be check for the form to be submittable.\n */\n @Prop() required = false;\n\n /**\n * The step size to use when changing the time.\n */\n @Prop() step = 5;\n\n /**\n * The value as ISO Date string, e.g. 2017-03-04T01:23:43.000Z or as a week number string.\n */\n @Prop({ mutable: true }) value?: string;\n\n /**\n * The validation errors for this input. Will render a hint under the input\n * with the translated error message(s) `error.${key}`. If an object is\n * passed, the keys will be used as error keys and the values translation\n * parameters.\n * If the value is `true`, the input will be marked as invalid without any\n * hints under the input.\n */\n @Prop() errors?: boolean | string[] | ErrorMap;\n\n /**\n * Fine-grained control over when the errors are shown. Can be `false` to\n * never show errors, `true` to show errors on blur, or a number to show\n * errors on change with the given delay in milliseconds.\n */\n @Prop() errorUpdate: boolean | number = 0;\n\n /**\n * Attributes that will be added to the native HTML input element.\n */\n @Prop() nativeAttributes?: { [key: string]: string };\n\n /**\n * Attributes that will be added to the rendered HTML datepicker element.\n */\n @Prop() nativePickerAttributes?: { [key: string]: string };\n\n /**\n * Emitted when the value is changed.\n */\n @Event() catChange!: EventEmitter<string>;\n\n /**\n * Emitted when the input received focus.\n */\n @Event() catFocus!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() catBlur!: EventEmitter<FocusEvent>;\n\n @Watch('value')\n onValueChanged(value: string) {\n if (value) {\n this.pickr?.setDate(value, false);\n this.catChange.emit(value);\n } else {\n this.pickr?.clear(false);\n this.catChange.emit(undefined);\n }\n }\n\n @Watch('disabled')\n @Watch('readonly')\n onDisabledChanged() {\n // Dynamically changing 'disabled' value is not working due to a bug in the\n // library. We thus need to fully recreate the date picker after the value\n // has been updated.\n this.pickr?.destroy();\n this.pickr = undefined;\n setTimeout(() => (this.pickr = this.initDatepicker(this.input)));\n }\n\n componentDidLoad() {\n this.pickr = this.initDatepicker(this.input);\n }\n\n /**\n * Programmatically move focus to the datepicker. Use this method instead of\n * `input.focus()`.\n *\n * @param options An optional object providing options to control aspects of\n * the focusing process.\n */\n @Method()\n async doFocus(options?: FocusOptions): Promise<void> {\n this._input?.doFocus(options);\n }\n\n /**\n * Programmatically remove focus from the datepicker. Use this method instead of\n * `input.blur()`.\n */\n @Method()\n async doBlur(): Promise<void> {\n this._input?.doBlur();\n }\n\n render() {\n return (\n <cat-input\n ref={el => (this._input = el)}\n requiredMarker={this.requiredMarker}\n horizontal={this.horizontal}\n autoComplete={this.autoComplete}\n clearable={this.clearable}\n disabled={this.disabled}\n hint={this.hint}\n icon={this.icon}\n iconRight={this.iconRight}\n identifier={this.identifier}\n label={this.label}\n labelHidden={this.labelHidden}\n name={this.name}\n placeholder={this.placeholder}\n textPrefix={this.textPrefix}\n textSuffix={this.textSuffix}\n readonly={this.readonly}\n required={this.required}\n value={this.value}\n errors={this.errors}\n errorUpdate={this.errorUpdate}\n nativeAttributes={this.nativeAttributes}\n onCatChange={e => {\n e.stopPropagation();\n this.value = e.detail || undefined;\n }}\n onCatFocus={e => {\n e.stopPropagation();\n this.catFocus.emit(e.detail);\n }}\n onCatBlur={e => {\n e.stopPropagation();\n this.catBlur.emit(e.detail);\n }}\n ></cat-input>\n );\n }\n\n private initDatepicker(input?: HTMLInputElement): flatpickr.Instance | undefined {\n if (this.disabled || this.readonly || !input) {\n return;\n }\n\n // avoid dropdown closing if datepicker is part of a dropdown\n const withinDropdown = !!findClosest('cat-dropdown', input);\n const nativePickerAttributes: { [key: string]: string } = withinDropdown ? { 'data-dropdown-no-close': '' } : {};\n\n return flatpickr(\n input,\n getConfig({\n locale: getLocale(i18n.getLocale()),\n format: getFormat(i18n.getLocale(), this.mode),\n mode: this.mode,\n min: this.min,\n max: this.max,\n step: this.step,\n disabled: this.disabled,\n readonly: this.readonly,\n nativePickerAttributes: { ...nativePickerAttributes, ...this.nativePickerAttributes },\n applyChange: value => (this.value = value)\n })\n );\n }\n}\n"]}
@@ -14,7 +14,7 @@ class CatDropdown {
14
14
  this.overflow = false;
15
15
  }
16
16
  clickHandler(event) {
17
- // we need to delay the initialization of the trigger until first,
17
+ // we need to delay the initialization of the trigger until first
18
18
  // interaction because the element might still be hidden (and thus not
19
19
  // tabbable) if contained in another Stencil web component
20
20
  if (!this.trigger) {
@@ -22,10 +22,14 @@ class CatDropdown {
22
22
  this.toggle();
23
23
  }
24
24
  // hide dropdown on button clicks inside the dropdown content
25
+ const path = event.composedPath();
25
26
  if (!this.noAutoClose &&
26
- event.composedPath().includes(this.content) &&
27
- event.target instanceof Element &&
28
- event.target.slot !== 'trigger') {
27
+ // check if click was inside of the dropdown content
28
+ path.includes(this.content) &&
29
+ // check if click was not on a trigger for a sub-dropdown
30
+ event.target?.slot !== 'trigger' &&
31
+ // check if click was not an element marked with data-dropdown-no-close
32
+ !path.slice(0, path.indexOf(this.content)).find(el => this.hasAttribute(el, 'data-dropdown-no-close'))) {
29
33
  this.close();
30
34
  }
31
35
  }
@@ -39,8 +43,8 @@ class CatDropdown {
39
43
  * Opens the dropdown.
40
44
  */
41
45
  async open() {
42
- if (this.isOpen === null) {
43
- return; // busy
46
+ if (this.isOpen === null || this.isOpen) {
47
+ return; // busy or open
44
48
  }
45
49
  this.isOpen = null;
46
50
  this.content.style.display = 'block';
@@ -57,18 +61,11 @@ class CatDropdown {
57
61
  getShadowRoot: true
58
62
  },
59
63
  allowOutsideClick: true,
60
- clickOutsideDeactivates: event => {
61
- const shouldClose = !this.noAutoClose &&
62
- !event.composedPath().includes(this.content) &&
63
- !event
64
- .composedPath()
65
- .find(el => el instanceof HTMLElement && el.hasAttribute('data-dropdown-no-close')) &&
66
- (!this.trigger || !event.composedPath().includes(this.trigger));
67
- if (shouldClose) {
68
- this.close();
69
- }
70
- return shouldClose;
71
- },
64
+ clickOutsideDeactivates: event => !this.noAutoClose &&
65
+ // check if click was outside of the dropdown content
66
+ !event.composedPath().includes(this.content) &&
67
+ // check if click was not on an element marked with data-dropdown-no-close
68
+ !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close')),
72
69
  onPostDeactivate: () => this.close()
73
70
  });
74
71
  this.trap.activate();
@@ -78,8 +75,8 @@ class CatDropdown {
78
75
  * Closes the dropdown.
79
76
  */
80
77
  async close() {
81
- if (this.isOpen === null) {
82
- return; // busy
78
+ if (!this.isOpen) {
79
+ return; // busy or closed
83
80
  }
84
81
  this.isOpen = null;
85
82
  this.content.classList.remove('show');
@@ -170,6 +167,9 @@ class CatDropdown {
170
167
  });
171
168
  }
172
169
  }
170
+ hasAttribute(elem, attr) {
171
+ return elem instanceof HTMLElement && elem.hasAttribute(attr);
172
+ }
173
173
  static get is() { return "cat-dropdown"; }
174
174
  static get encapsulation() { return "shadow"; }
175
175
  static get originalStyleUrls() {
@@ -1 +1 @@
1
- {"version":3,"file":"cat-dropdown.js","sourceRoot":"","sources":["../../../src/components/cat-dropdown/cat-dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import { autoUpdate, computePosition, flip, offset, Placement, size } from '@floating-ui/dom';\nimport { timeTransitionS } from '@haiilo/catalyst-tokens';\nimport { Component, Event, EventEmitter, h, Host, Listen, Method, Prop } from '@stencil/core';\nimport * as focusTrap from 'focus-trap';\nimport { FocusableElement, tabbable } from 'tabbable';\nimport firstTabbable from '../../utils/first-tabbable';\n\nlet nextUniqueId = 0;\n\n@Component({\n tag: 'cat-dropdown',\n styleUrl: 'cat-dropdown.scss',\n shadow: true\n})\nexport class CatDropdown {\n private static readonly OFFSET = 4;\n private readonly id = nextUniqueId++;\n private triggerSlot!: HTMLSlotElement;\n private trigger?: FocusableElement;\n private content!: HTMLElement;\n private trap?: focusTrap.FocusTrap;\n private keyListener?: (event: KeyboardEvent) => void;\n private isOpen: boolean | null = false;\n\n /**\n * The placement of the dropdown.\n */\n @Prop() placement: Placement = 'bottom-start';\n\n /**\n * Do not close the dropdown on outside clicks.\n */\n @Prop() noAutoClose = false;\n\n /**\n * Allow overflow when dropdown is open.\n */\n @Prop() overflow = false;\n\n /**\n * Emitted when the dropdown is opened.\n */\n @Event() catOpen!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the dropdown is closed.\n */\n @Event() catClose!: EventEmitter<FocusEvent>;\n\n @Listen('catClick')\n clickHandler(event: CustomEvent<MouseEvent>) {\n // we need to delay the initialization of the trigger until first,\n // interaction because the element might still be hidden (and thus not\n // tabbable) if contained in another Stencil web component\n if (!this.trigger) {\n this.initTrigger();\n this.toggle();\n }\n\n // hide dropdown on button clicks inside the dropdown content\n if (\n !this.noAutoClose &&\n event.composedPath().includes(this.content) &&\n event.target instanceof Element &&\n event.target.slot !== 'trigger'\n ) {\n this.close();\n }\n }\n\n /**\n * Toggles the dropdown.\n */\n async toggle(): Promise<void> {\n this.isOpen ? this.close() : this.open();\n }\n\n /**\n * Opens the dropdown.\n */\n async open(): Promise<void> {\n if (this.isOpen === null) {\n return; // busy\n }\n\n this.isOpen = null;\n this.content.style.display = 'block';\n // give CSS transition time to apply\n setTimeout(() => {\n this.isOpen = true;\n this.content.classList.add('show');\n this.trigger?.setAttribute('aria-expanded', 'true');\n this.catOpen.emit();\n this.trap = this.trap\n ? this.trap.updateContainerElements(this.content)\n : focusTrap.createFocusTrap(this.content, {\n tabbableOptions: {\n getShadowRoot: true\n },\n allowOutsideClick: true,\n clickOutsideDeactivates: event => {\n const shouldClose =\n !this.noAutoClose &&\n !event.composedPath().includes(this.content) &&\n !event\n .composedPath()\n .find(el => el instanceof HTMLElement && el.hasAttribute('data-dropdown-no-close')) &&\n (!this.trigger || !event.composedPath().includes(this.trigger));\n if (shouldClose) {\n this.close();\n }\n return shouldClose;\n },\n onPostDeactivate: () => this.close()\n });\n this.trap.activate();\n });\n }\n\n /**\n * Closes the dropdown.\n */\n @Method()\n async close(): Promise<void> {\n if (this.isOpen === null) {\n return; // busy\n }\n\n this.isOpen = null;\n this.content.classList.remove('show');\n // give CSS transition time to apply\n setTimeout(() => {\n this.isOpen = false;\n this.content.classList.remove('show');\n this.content.style.display = '';\n this.trigger?.setAttribute('aria-expanded', 'false');\n this.trap?.deactivate();\n this.catClose.emit();\n }, timeTransitionS);\n }\n\n componentDidLoad(): void {\n this.keyListener = event => {\n if (this.isOpen && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n const targetElements = tabbable(this.content, { includeContainer: false, getShadowRoot: true });\n const activeElement = firstTabbable(document.activeElement);\n const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;\n const activeOff = event.key === 'ArrowDown' ? 1 : -1;\n const targetIdx = activeIdx < 0 ? 0 : (activeIdx + activeOff + targetElements.length) % targetElements.length;\n targetElements[targetIdx].focus();\n event.preventDefault();\n }\n };\n document.addEventListener('keydown', this.keyListener);\n }\n\n disconnectedCallback(): void {\n if (this.keyListener) {\n document.removeEventListener('keydown', this.keyListener);\n }\n }\n\n render() {\n return (\n <Host>\n <slot name=\"trigger\" ref={el => (this.triggerSlot = el as HTMLSlotElement)}></slot>\n <div\n id={this.contentId}\n class={{ content: true, 'overflow-auto': !this.overflow }}\n ref={el => (this.content = el as HTMLElement)}\n >\n <slot name=\"content\"></slot>\n </div>\n </Host>\n );\n }\n\n private get contentId() {\n return `cat-dropdown-${this.id}`;\n }\n\n private initTrigger() {\n this.trigger = this.findTrigger();\n this.trigger.setAttribute('aria-haspopup', 'true');\n this.trigger.setAttribute('aria-expanded', 'false');\n this.trigger.setAttribute('aria-controls', this.contentId);\n this.trigger.addEventListener('click', () => this.toggle());\n autoUpdate(this.trigger, this.content, () => this.update());\n }\n\n private findTrigger() {\n let trigger: FocusableElement | undefined;\n const elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = elem?.hasAttribute('data-trigger')\n ? (elem as HTMLElement)\n : elem?.querySelector('[data-trigger]') ?? undefined;\n }\n if (!trigger) {\n trigger = firstTabbable(this.triggerSlot);\n }\n if (!trigger) {\n throw new Error('Cannot find tabbable element. Use [data-trigger] to set the trigger.');\n }\n return trigger;\n }\n\n private update() {\n if (this.trigger) {\n computePosition(this.trigger, this.content, {\n strategy: 'fixed',\n placement: this.placement,\n middleware: [\n offset(CatDropdown.OFFSET),\n flip(),\n size({\n padding: CatDropdown.OFFSET,\n apply({ availableWidth, availableHeight, elements }) {\n Object.assign(elements.floating.style, {\n maxWidth: `${availableWidth}px`,\n maxHeight: `${availableHeight}px`\n });\n }\n })\n ]\n }).then(({ x, y, placement }) => {\n this.content.dataset.placement = placement;\n Object.assign(this.content.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"cat-dropdown.js","sourceRoot":"","sources":["../../../src/components/cat-dropdown/cat-dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import { autoUpdate, computePosition, flip, offset, Placement, size } from '@floating-ui/dom';\nimport { timeTransitionS } from '@haiilo/catalyst-tokens';\nimport { Component, Event, EventEmitter, h, Host, Listen, Method, Prop } from '@stencil/core';\nimport * as focusTrap from 'focus-trap';\nimport { FocusableElement, tabbable } from 'tabbable';\nimport firstTabbable from '../../utils/first-tabbable';\n\nlet nextUniqueId = 0;\n\n@Component({\n tag: 'cat-dropdown',\n styleUrl: 'cat-dropdown.scss',\n shadow: true\n})\nexport class CatDropdown {\n private static readonly OFFSET = 4;\n private readonly id = nextUniqueId++;\n private triggerSlot!: HTMLSlotElement;\n private trigger?: FocusableElement;\n private content!: HTMLElement;\n private trap?: focusTrap.FocusTrap;\n private keyListener?: (event: KeyboardEvent) => void;\n private isOpen: boolean | null = false;\n\n /**\n * The placement of the dropdown.\n */\n @Prop() placement: Placement = 'bottom-start';\n\n /**\n * Do not close the dropdown on outside clicks.\n */\n @Prop() noAutoClose = false;\n\n /**\n * Allow overflow when dropdown is open.\n */\n @Prop() overflow = false;\n\n /**\n * Emitted when the dropdown is opened.\n */\n @Event() catOpen!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the dropdown is closed.\n */\n @Event() catClose!: EventEmitter<FocusEvent>;\n\n @Listen('catClick')\n clickHandler(event: CustomEvent<MouseEvent>) {\n // we need to delay the initialization of the trigger until first\n // interaction because the element might still be hidden (and thus not\n // tabbable) if contained in another Stencil web component\n if (!this.trigger) {\n this.initTrigger();\n this.toggle();\n }\n\n // hide dropdown on button clicks inside the dropdown content\n const path = event.composedPath();\n if (\n !this.noAutoClose &&\n // check if click was inside of the dropdown content\n path.includes(this.content) &&\n // check if click was not on a trigger for a sub-dropdown\n (event.target as Element)?.slot !== 'trigger' &&\n // check if click was not an element marked with data-dropdown-no-close\n !path.slice(0, path.indexOf(this.content)).find(el => this.hasAttribute(el, 'data-dropdown-no-close'))\n ) {\n this.close();\n }\n }\n\n /**\n * Toggles the dropdown.\n */\n async toggle(): Promise<void> {\n this.isOpen ? this.close() : this.open();\n }\n\n /**\n * Opens the dropdown.\n */\n async open(): Promise<void> {\n if (this.isOpen === null || this.isOpen) {\n return; // busy or open\n }\n\n this.isOpen = null;\n this.content.style.display = 'block';\n // give CSS transition time to apply\n setTimeout(() => {\n this.isOpen = true;\n this.content.classList.add('show');\n this.trigger?.setAttribute('aria-expanded', 'true');\n this.catOpen.emit();\n this.trap = this.trap\n ? this.trap.updateContainerElements(this.content)\n : focusTrap.createFocusTrap(this.content, {\n tabbableOptions: {\n getShadowRoot: true\n },\n allowOutsideClick: true,\n clickOutsideDeactivates: event =>\n !this.noAutoClose &&\n // check if click was outside of the dropdown content\n !event.composedPath().includes(this.content) &&\n // check if click was not on an element marked with data-dropdown-no-close\n !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close')),\n onPostDeactivate: () => this.close()\n });\n this.trap.activate();\n });\n }\n\n /**\n * Closes the dropdown.\n */\n @Method()\n async close(): Promise<void> {\n if (!this.isOpen) {\n return; // busy or closed\n }\n\n this.isOpen = null;\n this.content.classList.remove('show');\n // give CSS transition time to apply\n setTimeout(() => {\n this.isOpen = false;\n this.content.classList.remove('show');\n this.content.style.display = '';\n this.trigger?.setAttribute('aria-expanded', 'false');\n this.trap?.deactivate();\n this.catClose.emit();\n }, timeTransitionS);\n }\n\n componentDidLoad(): void {\n this.keyListener = event => {\n if (this.isOpen && ['ArrowDown', 'ArrowUp'].includes(event.key)) {\n const targetElements = tabbable(this.content, { includeContainer: false, getShadowRoot: true });\n const activeElement = firstTabbable(document.activeElement);\n const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;\n const activeOff = event.key === 'ArrowDown' ? 1 : -1;\n const targetIdx = activeIdx < 0 ? 0 : (activeIdx + activeOff + targetElements.length) % targetElements.length;\n targetElements[targetIdx].focus();\n event.preventDefault();\n }\n };\n document.addEventListener('keydown', this.keyListener);\n }\n\n disconnectedCallback(): void {\n if (this.keyListener) {\n document.removeEventListener('keydown', this.keyListener);\n }\n }\n\n render() {\n return (\n <Host>\n <slot name=\"trigger\" ref={el => (this.triggerSlot = el as HTMLSlotElement)}></slot>\n <div\n id={this.contentId}\n class={{ content: true, 'overflow-auto': !this.overflow }}\n ref={el => (this.content = el as HTMLElement)}\n >\n <slot name=\"content\"></slot>\n </div>\n </Host>\n );\n }\n\n private get contentId() {\n return `cat-dropdown-${this.id}`;\n }\n\n private initTrigger() {\n this.trigger = this.findTrigger();\n this.trigger.setAttribute('aria-haspopup', 'true');\n this.trigger.setAttribute('aria-expanded', 'false');\n this.trigger.setAttribute('aria-controls', this.contentId);\n this.trigger.addEventListener('click', () => this.toggle());\n autoUpdate(this.trigger, this.content, () => this.update());\n }\n\n private findTrigger() {\n let trigger: FocusableElement | undefined;\n const elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = elem?.hasAttribute('data-trigger')\n ? (elem as HTMLElement)\n : elem?.querySelector('[data-trigger]') ?? undefined;\n }\n if (!trigger) {\n trigger = firstTabbable(this.triggerSlot);\n }\n if (!trigger) {\n throw new Error('Cannot find tabbable element. Use [data-trigger] to set the trigger.');\n }\n return trigger;\n }\n\n private update() {\n if (this.trigger) {\n computePosition(this.trigger, this.content, {\n strategy: 'fixed',\n placement: this.placement,\n middleware: [\n offset(CatDropdown.OFFSET),\n flip(),\n size({\n padding: CatDropdown.OFFSET,\n apply({ availableWidth, availableHeight, elements }) {\n Object.assign(elements.floating.style, {\n maxWidth: `${availableWidth}px`,\n maxHeight: `${availableHeight}px`\n });\n }\n })\n ]\n }).then(({ x, y, placement }) => {\n this.content.dataset.placement = placement;\n Object.assign(this.content.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n }\n\n private hasAttribute(elem: EventTarget, attr: string) {\n return elem instanceof HTMLElement && elem.hasAttribute(attr);\n }\n}\n"]}
@@ -257,14 +257,9 @@
257
257
  word-break: break-word;
258
258
  }
259
259
 
260
- .label-container {
261
- flex-basis: var(--label-size, 33.33%);
262
- }
263
- .label-container .label-wrapper {
264
- display: flex;
265
- gap: 0.25rem;
266
- }
267
- .label-container .hidden {
260
+ .input-field:not(.input-horizontal) .label-container.hidden,
261
+ .textarea-field:not(.textarea-horizontal) .label-container.hidden,
262
+ .select-field:not(.select-horizontal) .label-container.hidden {
268
263
  position: absolute !important;
269
264
  width: 1px !important;
270
265
  height: 1px !important;
@@ -276,6 +271,14 @@
276
271
  border: 0 !important;
277
272
  }
278
273
 
274
+ .label-container {
275
+ flex-basis: var(--label-size, 33.33%);
276
+ }
277
+ .label-container .label-wrapper {
278
+ display: flex;
279
+ gap: 0.25rem;
280
+ }
281
+
279
282
  .label-metadata {
280
283
  display: flex;
281
284
  flex-shrink: 0;
@@ -305,6 +308,19 @@
305
308
  color: rgb(var(--cat-font-color-muted, 81, 92, 108));
306
309
  }
307
310
 
311
+ .input-horizontal .label-container.hidden label,
312
+ .textarea-horizontal .label-container.hidden label,
313
+ .select-horizontal .label-container.hidden label {
314
+ position: absolute !important;
315
+ width: 1px !important;
316
+ height: 1px !important;
317
+ padding: 0 !important;
318
+ margin: -1px !important;
319
+ overflow: hidden !important;
320
+ clip: rect(0, 0, 0, 0) !important;
321
+ white-space: nowrap !important;
322
+ border: 0 !important;
323
+ }
308
324
  .input-horizontal .label-wrapper,
309
325
  .textarea-horizontal .label-wrapper,
310
326
  .select-horizontal .label-wrapper {
@@ -101,7 +101,7 @@ export class CatInput {
101
101
  return (h("div", { class: {
102
102
  'input-field': true,
103
103
  'input-horizontal': this.horizontal
104
- } }, h("div", { class: "label-container" }, (this.hasSlottedLabel || this.label) && (h("label", { htmlFor: this.id, class: { hidden: this.labelHidden } }, h("span", { class: "label-wrapper", part: "label" }, (this.hasSlottedLabel && h("slot", { name: "label" })) || this.label, h("div", { class: "label-metadata" }, !this.required && this.requiredMarker.startsWith('optional') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.optional'), ")")), this.required && this.requiredMarker.startsWith('required') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.required'), ")")), this.maxLength && (h("div", { class: "label-character-count", "aria-hidden": "true" }, this.value?.toString().length ?? 0, "/", this.maxLength))))))), h("div", { class: "input-container" }, h("div", { class: {
104
+ } }, h("div", { class: { 'label-container': true, hidden: this.labelHidden } }, (this.hasSlottedLabel || this.label) && (h("label", { htmlFor: this.id }, h("span", { class: "label-wrapper", part: "label" }, (this.hasSlottedLabel && h("slot", { name: "label" })) || this.label, h("div", { class: "label-metadata" }, !this.required && this.requiredMarker.startsWith('optional') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.optional'), ")")), this.required && this.requiredMarker.startsWith('required') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.required'), ")")), this.maxLength && (h("div", { class: "label-character-count", "aria-hidden": "true" }, this.value?.toString().length ?? 0, "/", this.maxLength))))))), h("div", { class: "input-container" }, h("div", { class: {
105
105
  'input-wrapper': true,
106
106
  'input-round': this.round,
107
107
  'input-readonly': this.readonly,
@@ -109,7 +109,7 @@ export class CatInput {
109
109
  'input-invalid': this.invalid
110
110
  }, onClick: () => this.input.focus() }, this.textPrefix && (h("span", { class: "text-prefix", part: "prefix" }, this.textPrefix)), this.icon && !this.iconRight && h("cat-icon", { icon: this.icon, class: "icon-prefix", size: "l" }), h("div", { class: "input-inner-wrapper" }, h("input", { ...this.nativeAttributes, ref: el => (this.input = el), id: this.id, class: {
111
111
  'has-clearable': this.clearable && !this.disabled && !this.readonly
112
- }, autocomplete: this.autoComplete, disabled: this.disabled, max: this.max, maxlength: this.maxLength, min: this.min, minlength: this.minLength, name: this.name, placeholder: this.placeholder, readonly: this.readonly, required: this.required, type: this.type, value: this.value, onInput: this.onInput.bind(this), onFocus: this.onFocus.bind(this), onBlur: this.onBlur.bind(this), "aria-invalid": this.invalid ? 'true' : undefined, "aria-describedby": this.hint?.length ? this.id + '-hint' : undefined }), this.clearable && !this.disabled && !this.readonly && this.value && (h("cat-button", { class: "clearable", icon: "$cat:input-close", "icon-only": "true", size: "s", variant: "text", "a11y-label": i18n.t('input.clear'), onClick: this.clear.bind(this) }))), !this.invalid && this.icon && this.iconRight && (h("cat-icon", { icon: this.icon, class: "icon-suffix", size: "l" })), this.invalid && h("cat-icon", { icon: "$cat:input-error", class: "icon-suffix cat-text-danger", size: "l" }), this.textSuffix && (h("span", { class: "text-suffix", part: "suffix" }, this.textSuffix))), (this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (h(CatFormHint, { id: this.id, hint: this.hint, slottedHint: this.hasSlottedHint && h("slot", { name: "hint" }), errorMap: this.errorMap })))));
112
+ }, autocomplete: this.autoComplete, disabled: this.disabled, max: this.max, maxlength: this.maxLength, min: this.min, minlength: this.minLength, name: this.name, placeholder: this.placeholder, readonly: this.readonly, required: this.required, type: this.type, value: this.value, onInput: this.onInput.bind(this), onFocus: this.onFocus.bind(this), onBlur: this.onBlur.bind(this), "aria-invalid": this.invalid ? 'true' : undefined, "aria-describedby": this.hint?.length ? this.id + '-hint' : undefined }), this.clearable && !this.disabled && !this.readonly && this.value && (h("cat-button", { class: "clearable", icon: "$cat:input-close", "icon-only": "true", size: "s", variant: "text", "a11y-label": i18n.t('input.clear'), onClick: this.clear.bind(this), "data-dropdown-no-close": true }))), !this.invalid && this.icon && this.iconRight && (h("cat-icon", { icon: this.icon, class: "icon-suffix", size: "l" })), this.invalid && h("cat-icon", { icon: "$cat:input-error", class: "icon-suffix cat-text-danger", size: "l" }), this.textSuffix && (h("span", { class: "text-suffix", part: "suffix" }, this.textSuffix))), (this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (h(CatFormHint, { id: this.id, hint: this.hint, slottedHint: this.hasSlottedHint && h("slot", { name: "hint" }), errorMap: this.errorMap })))));
113
113
  }
114
114
  get invalid() {
115
115
  return !!this.errorMap;
@@ -1 +1 @@
1
- {"version":3,"file":"cat-input.js","sourceRoot":"","sources":["../../../src/components/cat-input/cat-input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAgB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAY,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAGxE,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB;;;;;;;;;;GAUG;AAMH,MAAM,OAAO,QAAQ;;IACF,QAAG,GAAG,aAAa,YAAY,EAAE,EAAE,CAAC;2BAU1B,KAAK;0BAEN,KAAK;;0BAOkE,UAAU;sBAKtF,KAAK;;qBAUN,KAAK;oBAKN,KAAK;;;qBAeJ,KAAK;;iBAUT,EAAE;uBAKI,KAAK;;;;;;;;;oBA6CR,KAAK;oBAKL,KAAK;iBAKR,KAAK;gBAKK,MAAM;;;uBAsBQ,CAAC;;;EAtJzC,IAAY,EAAE;IACZ,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,CAAC;EACrC,CAAC;EA0KD,mBAAmB;IACjB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC1E,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;IACxE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;MACxC,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE,IAAI,CAAC,CAAC;KACtD;EACH,CAAC;EAED;;;;;;KAMG;EAEH,KAAK,CAAC,OAAO,CAAC,OAAsB;IAClC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;EAC5B,CAAC;EAED;;;KAGG;EAEH,KAAK,CAAC,MAAM;IACV,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;EACpB,CAAC;EAED;;KAEG;EAEH,KAAK,CAAC,KAAK;IACT,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAClC,CAAC;EAGD,eAAe,CAAC,KAAqC;IACnD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;MACpC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;KAC3B;SAAM;MACL,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrC,CAAC,CAAE,KAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9E,CAAC,CAAC,KAAK,KAAK,IAAI;UAChB,CAAC,CAAC,EAAE;UACJ,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC;MACvB,IAAI,CAAC,mBAAmB,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;KAC1D;EACH,CAAC;EAED,MAAM;IACJ,OAAO,CACL,WACE,KAAK,EAAE;QACL,aAAa,EAAE,IAAI;QACnB,kBAAkB,EAAE,IAAI,CAAC,UAAU;OACpC;MAED,WAAK,KAAK,EAAC,iBAAiB,IACzB,CAAC,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CACvC,aAAO,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE;QAC1D,YAAM,KAAK,EAAC,eAAe,EAAC,IAAI,EAAC,OAAO;UACrC,CAAC,IAAI,CAAC,eAAe,IAAI,YAAM,IAAI,EAAC,OAAO,GAAQ,CAAC,IAAI,IAAI,CAAC,KAAK;UACnE,WAAK,KAAK,EAAC,gBAAgB;YACxB,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAC/D,YAAM,KAAK,EAAC,gBAAgB,iBAAa,MAAM;;cAC3C,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;kBACrB,CACR;YACA,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAC9D,YAAM,KAAK,EAAC,gBAAgB,iBAAa,MAAM;;cAC3C,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;kBACrB,CACR;YACA,IAAI,CAAC,SAAS,IAAI,CACjB,WAAK,KAAK,EAAC,uBAAuB,iBAAa,MAAM;cAClD,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC;;cAAG,IAAI,CAAC,SAAS,CAChD,CACP,CACG,CACD,CACD,CACT,CACG;MACN,WAAK,KAAK,EAAC,iBAAiB;QAC1B,WACE,KAAK,EAAE;YACL,eAAe,EAAE,IAAI;YACrB,aAAa,EAAE,IAAI,CAAC,KAAK;YACzB,gBAAgB,EAAE,IAAI,CAAC,QAAQ;YAC/B,gBAAgB,EAAE,IAAI,CAAC,QAAQ;YAC/B,eAAe,EAAE,IAAI,CAAC,OAAO;WAC9B,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;UAEhC,IAAI,CAAC,UAAU,IAAI,CAClB,YAAM,KAAK,EAAC,aAAa,EAAC,IAAI,EAAC,QAAQ,IACpC,IAAI,CAAC,UAAU,CACX,CACR;UACA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,gBAAU,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAC,aAAa,EAAC,IAAI,EAAC,GAAG,GAAY;UACpG,WAAK,KAAK,EAAC,qBAAqB;YAC9B,gBACM,IAAI,CAAC,gBAAgB,EACzB,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,EAAsB,CAAC,EAChD,EAAE,EAAE,IAAI,CAAC,EAAE,EACX,KAAK,EAAE;gBACL,eAAe,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ;eACpE,EACD,YAAY,EAAE,IAAI,CAAC,YAAY,EAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,GAAG,EAAE,IAAI,CAAC,GAAG,EACb,SAAS,EAAE,IAAI,CAAC,SAAS,EACzB,GAAG,EAAE,IAAI,CAAC,GAAG,EACb,SAAS,EAAE,IAAI,CAAC,SAAS,EACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,WAAW,EAAE,IAAI,CAAC,WAAW,EAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAChC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAChC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kBAChB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,sBAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,GAC5D;YACR,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CACnE,kBACE,KAAK,EAAC,WAAW,EACjB,IAAI,EAAC,kBAAkB,eACb,MAAM,EAChB,IAAI,EAAC,GAAG,EACR,OAAO,EAAC,MAAM,gBACF,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,EACjC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAClB,CACf,CACG;UACL,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,CAC/C,gBAAU,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAC,aAAa,EAAC,IAAI,EAAC,GAAG,GAAY,CACpE;UACA,IAAI,CAAC,OAAO,IAAI,gBAAU,IAAI,EAAC,kBAAkB,EAAC,KAAK,EAAC,6BAA6B,EAAC,IAAI,EAAC,GAAG,GAAY;UAC1G,IAAI,CAAC,UAAU,IAAI,CAClB,YAAM,KAAK,EAAC,aAAa,EAAC,IAAI,EAAC,QAAQ,IACpC,IAAI,CAAC,UAAU,CACX,CACR,CACG;QACL,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAClF,EAAC,WAAW,IACV,EAAE,EAAE,IAAI,CAAC,EAAE,EACX,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,WAAW,EAAE,IAAI,CAAC,cAAc,IAAI,YAAM,IAAI,EAAC,MAAM,GAAQ,EAC7D,QAAQ,EAAE,IAAI,CAAC,QAAQ,GACvB,CACH,CACG,CACF,CACP,CAAC;EACJ,CAAC;EAED,IAAY,OAAO;IACjB,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;EACzB,CAAC;EAEO,OAAO;IACb,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAC9B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;EAC7B,CAAC;EAEO,OAAO,CAAC,KAAiB;IAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC5B,CAAC;EAEO,MAAM,CAAC,KAAiB;IAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;MACnC,IAAI,CAAC,UAAU,EAAE,CAAC;KACnB;EACH,CAAC;EAEO,UAAU;IAChB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC;EACnC,CAAC;EAGO,mBAAmB;IACzB,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACzD,IAAI,WAAW,KAAK,IAAI,EAAE;MACxB,OAAO,IAAI,CAAC,oBAAoB,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;MAChG,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,WAAW,CAAC,CAAC;MACpF,OAAO,IAAI,CAAC;KACb;IACD,OAAO,KAAK,CAAC;EACf,CAAC;EAEO,mBAAmB;IACzB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,aAAa,KAAK,IAAI,CAAC,KAAK,CAAC;IACtG,IAAI,CAAC,QAAQ,EAAE;MACb,IAAI,CAAC,UAAU,EAAE,CAAC;KACnB;EACH,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACF","sourcesContent":["import { Component, Element, Event, EventEmitter, h, Method, Prop, State, Watch } from '@stencil/core';\nimport log from 'loglevel';\nimport { coerceBoolean, coerceNumber } from '../../utils/coerce';\nimport { CatFormHint, ErrorMap } from '../cat-form-hint/cat-form-hint';\nimport { catI18nRegistry as i18n } from '../cat-i18n/cat-i18n-registry';\nimport { InputType } from './input-type';\n\nlet nextUniqueId = 0;\n\n/**\n * Inputs are used to allow users to provide text input when the expected input\n * is short. As well as plain text, Input supports various types of text,\n * including passwords and numbers.\n *\n * @slot hint - Optional hint element to be displayed with the input.\n * @slot label - The slotted label. If both the label property and the label slot are present, only the label slot will be displayed.\n * @part label - The label content.\n * @part prefix - The text prefix.\n * @part suffix - The text suffix.\n */\n@Component({\n tag: 'cat-input',\n styleUrl: 'cat-input.scss',\n shadow: true\n})\nexport class CatInput {\n private readonly _id = `cat-input-${nextUniqueId++}`;\n private get id() {\n return this.identifier || this._id;\n }\n\n private input!: HTMLInputElement;\n private errorMapSrc?: ErrorMap;\n\n @Element() hostElement!: HTMLElement;\n\n @State() hasSlottedLabel = false;\n\n @State() hasSlottedHint = false;\n\n @State() errorMap?: ErrorMap;\n\n /**\n * Whether the label need a marker to shown if the input is required or optional.\n */\n @Prop() requiredMarker: 'none' | 'required' | 'optional' | 'none!' | 'optional!' | 'required!' = 'optional';\n\n /**\n * Whether the label is on top or left.\n */\n @Prop() horizontal = false;\n\n /**\n * Hint for form autofill feature.\n */\n @Prop() autoComplete?: string;\n\n /**\n * Whether the input should show a clear button.\n */\n @Prop() clearable = false;\n\n /**\n * Whether the input is disabled.\n */\n @Prop() disabled = false;\n\n /**\n * Optional hint text(s) to be displayed with the input.\n */\n @Prop() hint?: string | string[];\n\n /**\n * The name of an icon to be displayed in the input.\n */\n @Prop() icon?: string;\n\n /**\n * Display the icon on the right.\n */\n @Prop() iconRight = false;\n\n /**\n * A unique identifier for the input.\n */\n @Prop() identifier?: string;\n\n /**\n * The label for the input.\n */\n @Prop() label = '';\n\n /**\n * Visually hide the label, but still show it to assistive technologies like screen readers.\n */\n @Prop() labelHidden = false;\n\n /**\n * A maximum value for date, time and numeric values.\n */\n @Prop() max?: number | string;\n\n /**\n * A maximum length (number of characters) for textual values.\n */\n @Prop() maxLength?: number;\n\n /**\n * A minimum value for date, time and numeric values.\n */\n @Prop() min?: number | string;\n\n /**\n * A minimum length (number of characters) for textual values.\n */\n @Prop() minLength?: number;\n\n /**\n * The name of the form control. Submitted with the form as part of a name/value pair.\n */\n @Prop() name?: string;\n\n /**\n * The placeholder text to display within the input.\n */\n @Prop() placeholder?: string;\n\n /**\n * A textual prefix to be displayed in the input.\n */\n @Prop() textPrefix?: string;\n\n /**\n * A textual suffix to be displayed in the input.\n */\n @Prop() textSuffix?: string;\n\n /**\n * The value is not editable.\n */\n @Prop() readonly = false;\n\n /**\n * A value is required or must be check for the form to be submittable.\n */\n @Prop() required = false;\n\n /**\n * Use round input edges.\n */\n @Prop() round = false;\n\n /**\n * Type of form control.\n */\n @Prop() type: InputType = 'text';\n\n /**\n * The value of the control.\n */\n @Prop({ mutable: true }) value?: string;\n\n /**\n * The validation errors for this input. Will render a hint under the input\n * with the translated error message(s) `error.${key}`. If an object is\n * passed, the keys will be used as error keys and the values translation\n * parameters.\n * If the value is `true`, the input will be marked as invalid without any\n * hints under the input.\n */\n @Prop() errors?: boolean | string[] | ErrorMap;\n\n /**\n * Fine-grained control over when the errors are shown. Can be `false` to\n * never show errors, `true` to show errors on blur, or a number to show\n * errors on change with the given delay in milliseconds.\n */\n @Prop() errorUpdate: boolean | number = 0;\n\n /**\n * Attributes that will be added to the native HTML input element.\n */\n @Prop() nativeAttributes?: { [key: string]: string };\n\n /**\n * Emitted when the value is changed.\n */\n @Event() catChange!: EventEmitter<string>;\n\n /**\n * Emitted when the input received focus.\n */\n @Event() catFocus!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() catBlur!: EventEmitter<FocusEvent>;\n\n componentWillRender(): void {\n this.onErrorsChanged(this.errors);\n this.hasSlottedLabel = !!this.hostElement.querySelector('[slot=\"label\"]');\n this.hasSlottedHint = !!this.hostElement.querySelector('[slot=\"hint\"]');\n if (!this.label && !this.hasSlottedLabel) {\n log.warn('[A11y] Missing ARIA label on input', this);\n }\n }\n\n /**\n * Programmatically move focus to the input. Use this method instead of\n * `input.focus()`.\n *\n * @param options An optional object providing options to control aspects of\n * the focusing process.\n */\n @Method()\n async doFocus(options?: FocusOptions): Promise<void> {\n this.input.focus(options);\n }\n\n /**\n * Programmatically remove focus from the input. Use this method instead of\n * `input.blur()`.\n */\n @Method()\n async doBlur(): Promise<void> {\n this.input.blur();\n }\n\n /**\n * Clear the input.\n */\n @Method()\n async clear(): Promise<void> {\n this.value = '';\n this.catChange.emit(this.value);\n }\n\n @Watch('errors')\n onErrorsChanged(value?: boolean | string[] | ErrorMap) {\n if (!coerceBoolean(this.errorUpdate)) {\n this.errorMap = undefined;\n } else {\n this.errorMapSrc = Array.isArray(value)\n ? (value as string[]).reduce((acc, err) => ({ ...acc, [err]: undefined }), {})\n : value === true\n ? {}\n : value || undefined;\n this.showErrorsIfTimeout() || this.showErrorsIfNoFocus();\n }\n }\n\n render() {\n return (\n <div\n class={{\n 'input-field': true,\n 'input-horizontal': this.horizontal\n }}\n >\n <div class=\"label-container\">\n {(this.hasSlottedLabel || this.label) && (\n <label htmlFor={this.id} class={{ hidden: this.labelHidden }}>\n <span class=\"label-wrapper\" part=\"label\">\n {(this.hasSlottedLabel && <slot name=\"label\"></slot>) || this.label}\n <div class=\"label-metadata\">\n {!this.required && this.requiredMarker.startsWith('optional') && (\n <span class=\"label-optional\" aria-hidden=\"true\">\n ({i18n.t('input.optional')})\n </span>\n )}\n {this.required && this.requiredMarker.startsWith('required') && (\n <span class=\"label-optional\" aria-hidden=\"true\">\n ({i18n.t('input.required')})\n </span>\n )}\n {this.maxLength && (\n <div class=\"label-character-count\" aria-hidden=\"true\">\n {this.value?.toString().length ?? 0}/{this.maxLength}\n </div>\n )}\n </div>\n </span>\n </label>\n )}\n </div>\n <div class=\"input-container\">\n <div\n class={{\n 'input-wrapper': true,\n 'input-round': this.round,\n 'input-readonly': this.readonly,\n 'input-disabled': this.disabled,\n 'input-invalid': this.invalid\n }}\n onClick={() => this.input.focus()}\n >\n {this.textPrefix && (\n <span class=\"text-prefix\" part=\"prefix\">\n {this.textPrefix}\n </span>\n )}\n {this.icon && !this.iconRight && <cat-icon icon={this.icon} class=\"icon-prefix\" size=\"l\"></cat-icon>}\n <div class=\"input-inner-wrapper\">\n <input\n {...this.nativeAttributes}\n ref={el => (this.input = el as HTMLInputElement)}\n id={this.id}\n class={{\n 'has-clearable': this.clearable && !this.disabled && !this.readonly\n }}\n autocomplete={this.autoComplete}\n disabled={this.disabled}\n max={this.max}\n maxlength={this.maxLength}\n min={this.min}\n minlength={this.minLength}\n name={this.name}\n placeholder={this.placeholder}\n readonly={this.readonly}\n required={this.required}\n type={this.type}\n value={this.value}\n onInput={this.onInput.bind(this)}\n onFocus={this.onFocus.bind(this)}\n onBlur={this.onBlur.bind(this)}\n aria-invalid={this.invalid ? 'true' : undefined}\n aria-describedby={this.hint?.length ? this.id + '-hint' : undefined}\n ></input>\n {this.clearable && !this.disabled && !this.readonly && this.value && (\n <cat-button\n class=\"clearable\"\n icon=\"$cat:input-close\"\n icon-only=\"true\"\n size=\"s\"\n variant=\"text\"\n a11y-label={i18n.t('input.clear')}\n onClick={this.clear.bind(this)}\n ></cat-button>\n )}\n </div>\n {!this.invalid && this.icon && this.iconRight && (\n <cat-icon icon={this.icon} class=\"icon-suffix\" size=\"l\"></cat-icon>\n )}\n {this.invalid && <cat-icon icon=\"$cat:input-error\" class=\"icon-suffix cat-text-danger\" size=\"l\"></cat-icon>}\n {this.textSuffix && (\n <span class=\"text-suffix\" part=\"suffix\">\n {this.textSuffix}\n </span>\n )}\n </div>\n {(this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (\n <CatFormHint\n id={this.id}\n hint={this.hint}\n slottedHint={this.hasSlottedHint && <slot name=\"hint\"></slot>}\n errorMap={this.errorMap}\n />\n )}\n </div>\n </div>\n );\n }\n\n private get invalid() {\n return !!this.errorMap;\n }\n\n private onInput() {\n this.value = this.input.value;\n this.catChange.emit(this.value);\n this.showErrorsIfTimeout();\n }\n\n private onFocus(event: FocusEvent) {\n this.catFocus.emit(event);\n }\n\n private onBlur(event: FocusEvent) {\n this.catBlur.emit(event);\n if (coerceBoolean(this.errorUpdate)) {\n this.showErrors();\n }\n }\n\n private showErrors() {\n this.errorMap = this.errorMapSrc;\n }\n\n private errorUpdateTimeoutId?: number;\n private showErrorsIfTimeout() {\n const errorUpdate = coerceNumber(this.errorUpdate, null);\n if (errorUpdate !== null) {\n typeof this.errorUpdateTimeoutId === 'number' && window.clearTimeout(this.errorUpdateTimeoutId);\n this.errorUpdateTimeoutId = window.setTimeout(() => this.showErrors(), errorUpdate);\n return true;\n }\n return false;\n }\n\n private showErrorsIfNoFocus() {\n const hasFocus = document.activeElement === this.hostElement || document.activeElement === this.input;\n if (!hasFocus) {\n this.showErrors();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"cat-input.js","sourceRoot":"","sources":["../../../src/components/cat-input/cat-input.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Event, EventEmitter, h, Method, Prop, State, Watch } from '@stencil/core';\nimport log from 'loglevel';\nimport { coerceBoolean, coerceNumber } from '../../utils/coerce';\nimport { CatFormHint, ErrorMap } from '../cat-form-hint/cat-form-hint';\nimport { catI18nRegistry as i18n } from '../cat-i18n/cat-i18n-registry';\nimport { InputType } from './input-type';\n\nlet nextUniqueId = 0;\n\n/**\n * Inputs are used to allow users to provide text input when the expected input\n * is short. As well as plain text, Input supports various types of text,\n * including passwords and numbers.\n *\n * @slot hint - Optional hint element to be displayed with the input.\n * @slot label - The slotted label. If both the label property and the label slot are present, only the label slot will be displayed.\n * @part label - The label content.\n * @part prefix - The text prefix.\n * @part suffix - The text suffix.\n */\n@Component({\n tag: 'cat-input',\n styleUrl: 'cat-input.scss',\n shadow: true\n})\nexport class CatInput {\n private readonly _id = `cat-input-${nextUniqueId++}`;\n private get id() {\n return this.identifier || this._id;\n }\n\n private input!: HTMLInputElement;\n private errorMapSrc?: ErrorMap;\n\n @Element() hostElement!: HTMLElement;\n\n @State() hasSlottedLabel = false;\n\n @State() hasSlottedHint = false;\n\n @State() errorMap?: ErrorMap;\n\n /**\n * Whether the label need a marker to shown if the input is required or optional.\n */\n @Prop() requiredMarker: 'none' | 'required' | 'optional' | 'none!' | 'optional!' | 'required!' = 'optional';\n\n /**\n * Whether the label is on top or left.\n */\n @Prop() horizontal = false;\n\n /**\n * Hint for form autofill feature.\n */\n @Prop() autoComplete?: string;\n\n /**\n * Whether the input should show a clear button.\n */\n @Prop() clearable = false;\n\n /**\n * Whether the input is disabled.\n */\n @Prop() disabled = false;\n\n /**\n * Optional hint text(s) to be displayed with the input.\n */\n @Prop() hint?: string | string[];\n\n /**\n * The name of an icon to be displayed in the input.\n */\n @Prop() icon?: string;\n\n /**\n * Display the icon on the right.\n */\n @Prop() iconRight = false;\n\n /**\n * A unique identifier for the input.\n */\n @Prop() identifier?: string;\n\n /**\n * The label for the input.\n */\n @Prop() label = '';\n\n /**\n * Visually hide the label, but still show it to assistive technologies like screen readers.\n */\n @Prop() labelHidden = false;\n\n /**\n * A maximum value for date, time and numeric values.\n */\n @Prop() max?: number | string;\n\n /**\n * A maximum length (number of characters) for textual values.\n */\n @Prop() maxLength?: number;\n\n /**\n * A minimum value for date, time and numeric values.\n */\n @Prop() min?: number | string;\n\n /**\n * A minimum length (number of characters) for textual values.\n */\n @Prop() minLength?: number;\n\n /**\n * The name of the form control. Submitted with the form as part of a name/value pair.\n */\n @Prop() name?: string;\n\n /**\n * The placeholder text to display within the input.\n */\n @Prop() placeholder?: string;\n\n /**\n * A textual prefix to be displayed in the input.\n */\n @Prop() textPrefix?: string;\n\n /**\n * A textual suffix to be displayed in the input.\n */\n @Prop() textSuffix?: string;\n\n /**\n * The value is not editable.\n */\n @Prop() readonly = false;\n\n /**\n * A value is required or must be check for the form to be submittable.\n */\n @Prop() required = false;\n\n /**\n * Use round input edges.\n */\n @Prop() round = false;\n\n /**\n * Type of form control.\n */\n @Prop() type: InputType = 'text';\n\n /**\n * The value of the control.\n */\n @Prop({ mutable: true }) value?: string;\n\n /**\n * The validation errors for this input. Will render a hint under the input\n * with the translated error message(s) `error.${key}`. If an object is\n * passed, the keys will be used as error keys and the values translation\n * parameters.\n * If the value is `true`, the input will be marked as invalid without any\n * hints under the input.\n */\n @Prop() errors?: boolean | string[] | ErrorMap;\n\n /**\n * Fine-grained control over when the errors are shown. Can be `false` to\n * never show errors, `true` to show errors on blur, or a number to show\n * errors on change with the given delay in milliseconds.\n */\n @Prop() errorUpdate: boolean | number = 0;\n\n /**\n * Attributes that will be added to the native HTML input element.\n */\n @Prop() nativeAttributes?: { [key: string]: string };\n\n /**\n * Emitted when the value is changed.\n */\n @Event() catChange!: EventEmitter<string>;\n\n /**\n * Emitted when the input received focus.\n */\n @Event() catFocus!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the input loses focus.\n */\n @Event() catBlur!: EventEmitter<FocusEvent>;\n\n componentWillRender(): void {\n this.onErrorsChanged(this.errors);\n this.hasSlottedLabel = !!this.hostElement.querySelector('[slot=\"label\"]');\n this.hasSlottedHint = !!this.hostElement.querySelector('[slot=\"hint\"]');\n if (!this.label && !this.hasSlottedLabel) {\n log.warn('[A11y] Missing ARIA label on input', this);\n }\n }\n\n /**\n * Programmatically move focus to the input. Use this method instead of\n * `input.focus()`.\n *\n * @param options An optional object providing options to control aspects of\n * the focusing process.\n */\n @Method()\n async doFocus(options?: FocusOptions): Promise<void> {\n this.input.focus(options);\n }\n\n /**\n * Programmatically remove focus from the input. Use this method instead of\n * `input.blur()`.\n */\n @Method()\n async doBlur(): Promise<void> {\n this.input.blur();\n }\n\n /**\n * Clear the input.\n */\n @Method()\n async clear(): Promise<void> {\n this.value = '';\n this.catChange.emit(this.value);\n }\n\n @Watch('errors')\n onErrorsChanged(value?: boolean | string[] | ErrorMap) {\n if (!coerceBoolean(this.errorUpdate)) {\n this.errorMap = undefined;\n } else {\n this.errorMapSrc = Array.isArray(value)\n ? (value as string[]).reduce((acc, err) => ({ ...acc, [err]: undefined }), {})\n : value === true\n ? {}\n : value || undefined;\n this.showErrorsIfTimeout() || this.showErrorsIfNoFocus();\n }\n }\n\n render() {\n return (\n <div\n class={{\n 'input-field': true,\n 'input-horizontal': this.horizontal\n }}\n >\n <div class={{ 'label-container': true, hidden: this.labelHidden }}>\n {(this.hasSlottedLabel || this.label) && (\n <label htmlFor={this.id}>\n <span class=\"label-wrapper\" part=\"label\">\n {(this.hasSlottedLabel && <slot name=\"label\"></slot>) || this.label}\n <div class=\"label-metadata\">\n {!this.required && this.requiredMarker.startsWith('optional') && (\n <span class=\"label-optional\" aria-hidden=\"true\">\n ({i18n.t('input.optional')})\n </span>\n )}\n {this.required && this.requiredMarker.startsWith('required') && (\n <span class=\"label-optional\" aria-hidden=\"true\">\n ({i18n.t('input.required')})\n </span>\n )}\n {this.maxLength && (\n <div class=\"label-character-count\" aria-hidden=\"true\">\n {this.value?.toString().length ?? 0}/{this.maxLength}\n </div>\n )}\n </div>\n </span>\n </label>\n )}\n </div>\n <div class=\"input-container\">\n <div\n class={{\n 'input-wrapper': true,\n 'input-round': this.round,\n 'input-readonly': this.readonly,\n 'input-disabled': this.disabled,\n 'input-invalid': this.invalid\n }}\n onClick={() => this.input.focus()}\n >\n {this.textPrefix && (\n <span class=\"text-prefix\" part=\"prefix\">\n {this.textPrefix}\n </span>\n )}\n {this.icon && !this.iconRight && <cat-icon icon={this.icon} class=\"icon-prefix\" size=\"l\"></cat-icon>}\n <div class=\"input-inner-wrapper\">\n <input\n {...this.nativeAttributes}\n ref={el => (this.input = el as HTMLInputElement)}\n id={this.id}\n class={{\n 'has-clearable': this.clearable && !this.disabled && !this.readonly\n }}\n autocomplete={this.autoComplete}\n disabled={this.disabled}\n max={this.max}\n maxlength={this.maxLength}\n min={this.min}\n minlength={this.minLength}\n name={this.name}\n placeholder={this.placeholder}\n readonly={this.readonly}\n required={this.required}\n type={this.type}\n value={this.value}\n onInput={this.onInput.bind(this)}\n onFocus={this.onFocus.bind(this)}\n onBlur={this.onBlur.bind(this)}\n aria-invalid={this.invalid ? 'true' : undefined}\n aria-describedby={this.hint?.length ? this.id + '-hint' : undefined}\n ></input>\n {this.clearable && !this.disabled && !this.readonly && this.value && (\n <cat-button\n class=\"clearable\"\n icon=\"$cat:input-close\"\n icon-only=\"true\"\n size=\"s\"\n variant=\"text\"\n a11y-label={i18n.t('input.clear')}\n onClick={this.clear.bind(this)}\n data-dropdown-no-close\n ></cat-button>\n )}\n </div>\n {!this.invalid && this.icon && this.iconRight && (\n <cat-icon icon={this.icon} class=\"icon-suffix\" size=\"l\"></cat-icon>\n )}\n {this.invalid && <cat-icon icon=\"$cat:input-error\" class=\"icon-suffix cat-text-danger\" size=\"l\"></cat-icon>}\n {this.textSuffix && (\n <span class=\"text-suffix\" part=\"suffix\">\n {this.textSuffix}\n </span>\n )}\n </div>\n {(this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (\n <CatFormHint\n id={this.id}\n hint={this.hint}\n slottedHint={this.hasSlottedHint && <slot name=\"hint\"></slot>}\n errorMap={this.errorMap}\n />\n )}\n </div>\n </div>\n );\n }\n\n private get invalid() {\n return !!this.errorMap;\n }\n\n private onInput() {\n this.value = this.input.value;\n this.catChange.emit(this.value);\n this.showErrorsIfTimeout();\n }\n\n private onFocus(event: FocusEvent) {\n this.catFocus.emit(event);\n }\n\n private onBlur(event: FocusEvent) {\n this.catBlur.emit(event);\n if (coerceBoolean(this.errorUpdate)) {\n this.showErrors();\n }\n }\n\n private showErrors() {\n this.errorMap = this.errorMapSrc;\n }\n\n private errorUpdateTimeoutId?: number;\n private showErrorsIfTimeout() {\n const errorUpdate = coerceNumber(this.errorUpdate, null);\n if (errorUpdate !== null) {\n typeof this.errorUpdateTimeoutId === 'number' && window.clearTimeout(this.errorUpdateTimeoutId);\n this.errorUpdateTimeoutId = window.setTimeout(() => this.showErrors(), errorUpdate);\n return true;\n }\n return false;\n }\n\n private showErrorsIfNoFocus() {\n const hasFocus = document.activeElement === this.hostElement || document.activeElement === this.input;\n if (!hasFocus) {\n this.showErrors();\n }\n }\n}\n"]}
@@ -257,14 +257,9 @@
257
257
  word-break: break-word;
258
258
  }
259
259
 
260
- .label-container {
261
- flex-basis: var(--label-size, 33.33%);
262
- }
263
- .label-container .label-wrapper {
264
- display: flex;
265
- gap: 0.25rem;
266
- }
267
- .label-container .hidden {
260
+ .input-field:not(.input-horizontal) .label-container.hidden,
261
+ .textarea-field:not(.textarea-horizontal) .label-container.hidden,
262
+ .select-field:not(.select-horizontal) .label-container.hidden {
268
263
  position: absolute !important;
269
264
  width: 1px !important;
270
265
  height: 1px !important;
@@ -276,6 +271,14 @@
276
271
  border: 0 !important;
277
272
  }
278
273
 
274
+ .label-container {
275
+ flex-basis: var(--label-size, 33.33%);
276
+ }
277
+ .label-container .label-wrapper {
278
+ display: flex;
279
+ gap: 0.25rem;
280
+ }
281
+
279
282
  .label-metadata {
280
283
  display: flex;
281
284
  flex-shrink: 0;
@@ -305,6 +308,19 @@
305
308
  color: rgb(var(--cat-font-color-muted, 81, 92, 108));
306
309
  }
307
310
 
311
+ .input-horizontal .label-container.hidden label,
312
+ .textarea-horizontal .label-container.hidden label,
313
+ .select-horizontal .label-container.hidden label {
314
+ position: absolute !important;
315
+ width: 1px !important;
316
+ height: 1px !important;
317
+ padding: 0 !important;
318
+ margin: -1px !important;
319
+ overflow: hidden !important;
320
+ clip: rect(0, 0, 0, 0) !important;
321
+ white-space: nowrap !important;
322
+ border: 0 !important;
323
+ }
308
324
  .input-horizontal .label-wrapper,
309
325
  .textarea-horizontal .label-wrapper,
310
326
  .select-horizontal .label-wrapper {
@@ -303,17 +303,14 @@ class CatSelect {
303
303
  return (h(Host, null, h("div", { class: {
304
304
  'select-field': true,
305
305
  'select-horizontal': this.horizontal
306
- } }, h("div", { class: "label-container" }, (this.hasSlottedLabel || this.label) && (h("label", { htmlFor: this.id, class: { hidden: this.labelHidden } }, h("span", { class: "label-wrapper", part: "label" }, (this.hasSlottedLabel && h("slot", { name: "label" })) || this.label, h("div", { class: "label-metadata" }, !this.required && this.requiredMarker.startsWith('optional') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.optional'), ")")), this.required && this.requiredMarker.startsWith('required') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.required'), ")"))))))), h("div", { class: "select-container" }, h("div", { class: { 'select-wrapper': true, 'select-disabled': this.disabled, 'select-invalid': this.invalid }, ref: el => (this.trigger = el), id: this.id, role: "combobox", "aria-expanded": this.state.isOpen || this.isPillboxActive(), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-required": this.required ? 'true' : false, "aria-activedescendant": this.activeDescendant, onClick: e => this.onClick(e) }, h("div", { class: "select-wrapper-inner" }, this.multiple && this.state.selection.length ? (h("div", { id: `select-pillbox-${this.id}`, role: "listbox", "aria-orientation": "horizontal", class: "select-pills" }, this.state.selection.map((item, i) => (h("span", { class: {
306
+ } }, h("div", { class: { 'label-container': true, hidden: this.labelHidden } }, (this.hasSlottedLabel || this.label) && (h("label", { htmlFor: this.id }, h("span", { class: "label-wrapper", part: "label" }, (this.hasSlottedLabel && h("slot", { name: "label" })) || this.label, h("div", { class: "label-metadata" }, !this.required && this.requiredMarker.startsWith('optional') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.optional'), ")")), this.required && this.requiredMarker.startsWith('required') && (h("span", { class: "label-optional", "aria-hidden": "true" }, "(", i18n.t('input.required'), ")"))))))), h("div", { class: "select-container" }, h("div", { class: { 'select-wrapper': true, 'select-disabled': this.disabled, 'select-invalid': this.invalid }, ref: el => (this.trigger = el), id: this.id, role: "combobox", "aria-expanded": this.state.isOpen || this.isPillboxActive(), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-required": this.required ? 'true' : false, "aria-activedescendant": this.activeDescendant, onClick: e => this.onClick(e) }, h("div", { class: "select-wrapper-inner" }, this.multiple && this.state.selection.length ? (h("div", { id: `select-pillbox-${this.id}`, role: "listbox", "aria-orientation": "horizontal", class: "select-pills" }, this.state.selection.map((item, i) => (h("span", { class: {
307
307
  pill: true,
308
308
  'select-no-open': true,
309
309
  'select-option-active': this.state.activeSelectionIndex === i
310
- }, role: "option", "aria-selected": "true", id: `select-${this.id}-selection-${i}` }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, icon: item.render.avatar.icon, initials: item.render.avatar.initials ?? '' })) : null, h("span", null, item.render.label), !this.disabled && (h("cat-button", { size: "xs", variant: "text", icon: "$cat:select-clear", iconOnly: true, a11yLabel: i18n.t('select.deselect'), onClick: () => this.deselect(item.item.id), tabIndex: -1, onCatClick: event => event.stopPropagation() }))))))) : this.state.selection.length && this.state.selection[0].render.avatar ? (h("cat-avatar", { label: this.state.selection[0].render.label, round: this.state.selection[0].render.avatar.round, src: this.state.selection[0].render.avatar.src, icon: this.state.selection[0].render.avatar.icon, initials: this.state.selection[0].render.avatar.initials ?? '' })) : null, h("input", { ...this.nativeAttributes, class: "select-input", ref: el => (this.input = el), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-activedescendant": this.activeDescendant, "aria-invalid": this.invalid ? 'true' : undefined, "aria-describedby": this.hint?.length ? this.id + '-hint' : undefined, onInput: this.onInput.bind(this), value: !this.multiple ? this.state.term : undefined, placeholder: this.placeholder, disabled: this.disabled || this.state.isResolving })), this.state.isResolving && h("cat-spinner", null), this.invalid && (h("cat-icon", { icon: "$cat:input-error", class: "icon-suffix cat-text-danger", size: "l" })), (this.state.selection.length || this.state.term.length) &&
310
+ }, role: "option", "aria-selected": "true", id: `select-${this.id}-selection-${i}` }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, icon: item.render.avatar.icon, initials: item.render.avatar.initials ?? '' })) : null, h("span", null, item.render.label), !this.disabled && (h("cat-button", { size: "xs", variant: "text", icon: "$cat:select-clear", iconOnly: true, a11yLabel: i18n.t('select.deselect'), onClick: () => this.deselect(item.item.id), tabIndex: -1, "data-dropdown-no-close": true }))))))) : this.state.selection.length && this.state.selection[0].render.avatar ? (h("cat-avatar", { label: this.state.selection[0].render.label, round: this.state.selection[0].render.avatar.round, src: this.state.selection[0].render.avatar.src, icon: this.state.selection[0].render.avatar.icon, initials: this.state.selection[0].render.avatar.initials ?? '' })) : null, h("input", { ...this.nativeAttributes, class: "select-input", ref: el => (this.input = el), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-activedescendant": this.activeDescendant, "aria-invalid": this.invalid ? 'true' : undefined, "aria-describedby": this.hint?.length ? this.id + '-hint' : undefined, onInput: this.onInput.bind(this), value: !this.multiple ? this.state.term : undefined, placeholder: this.placeholder, disabled: this.disabled || this.state.isResolving })), this.state.isResolving && h("cat-spinner", null), this.invalid && (h("cat-icon", { icon: "$cat:input-error", class: "icon-suffix cat-text-danger", size: "l" })), (this.state.selection.length || this.state.term.length) &&
311
311
  !this.disabled &&
312
312
  !this.state.isResolving &&
313
- this.clearable ? (h("cat-button", { id: `select-clear-btn-${this.id}`, iconOnly: true, icon: "$cat:input-close", variant: "text", size: "s", a11yLabel: i18n.t('input.clear'), onCatClick: event => {
314
- event.stopPropagation();
315
- this.clear();
316
- } })) : null, !this.state.isResolving && (h("cat-button", { iconOnly: true, icon: "$cat:select-open", class: { 'select-btn': true, 'select-btn-open': this.state.isOpen }, variant: "text", size: "s", a11yLabel: this.state.isOpen ? i18n.t('select.close') : i18n.t('select.open'), "aria-controls": `select-listbox-${this.id}`, "aria-expanded": this.state.isOpen, tabIndex: -1, disabled: this.disabled || this.state.isResolving, onCatClick: event => event.stopPropagation() }))), (this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (h(CatFormHint, { id: this.id, hint: this.hint, slottedHint: this.hasSlottedHint && h("slot", { name: "hint" }), errorMap: this.errorMap })))), h("div", { class: "select-dropdown", ref: el => (this.dropdown = el), style: { display: this.state.isOpen ? 'block' : undefined } }, this.state.isOpen && (h("cat-scrollable", { class: "select-options-wrapper", scrolledBuffer: 56, noOverflowX: true, noOverscroll: true, noScrolledInit: true, onScrolledBottom: () => this.more$.next() }, h("ul", { class: "select-options", role: "listbox", "aria-multiselectable": this.multiple, "aria-setsize": this.state.totalElements, id: `select-listbox-${this.id}` }, this.optionsList, this.state.isLoading
313
+ this.clearable ? (h("cat-button", { id: `select-clear-btn-${this.id}`, iconOnly: true, icon: "$cat:input-close", variant: "text", size: "s", a11yLabel: i18n.t('input.clear'), onCatClick: () => this.clear(), "data-dropdown-no-close": true })) : null, !this.state.isResolving && (h("cat-button", { iconOnly: true, icon: "$cat:select-open", class: { 'select-btn': true, 'select-btn-open': this.state.isOpen }, variant: "text", size: "s", a11yLabel: this.state.isOpen ? i18n.t('select.close') : i18n.t('select.open'), "aria-controls": `select-listbox-${this.id}`, "aria-expanded": this.state.isOpen, tabIndex: -1, disabled: this.disabled || this.state.isResolving, "data-dropdown-no-close": true }))), (this.hint || this.hasSlottedHint || !!Object.keys(this.errorMap || {}).length) && (h(CatFormHint, { id: this.id, hint: this.hint, slottedHint: this.hasSlottedHint && h("slot", { name: "hint" }), errorMap: this.errorMap })))), h("div", { class: "select-dropdown", ref: el => (this.dropdown = el), style: { display: this.state.isOpen ? 'block' : undefined } }, this.state.isOpen && (h("cat-scrollable", { class: "select-options-wrapper", scrolledBuffer: 56, noOverflowX: true, noOverscroll: true, noScrolledInit: true, onScrolledBottom: () => this.more$.next() }, h("ul", { class: "select-options", role: "listbox", "aria-multiselectable": this.multiple, "aria-setsize": this.state.totalElements, id: `select-listbox-${this.id}` }, this.optionsList, this.state.isLoading
317
314
  ? Array.from(Array(CatSelect.SKELETON_COUNT)).map(() => (h("li", { class: "select-option-loading" }, h("cat-skeleton", { variant: "body", lines: 1 }), h("cat-skeleton", { variant: "body", lines: 1 }))))
318
315
  : !this.state.options.length &&
319
316
  !this.tags && (h("li", { class: "select-option-empty" }, this.noItems ? this.noItems : i18n.t('select.empty')))))))));