@solid-design-system/components 3.22.17 → 3.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. package/dist/components/es/combobox.js +11 -0
  2. package/dist/components/es/map-marker.js +1 -1
  3. package/dist/components/es/optgroup.js +1 -0
  4. package/dist/components/es/option-renderer.js +1 -0
  5. package/dist/components/es/select.js +7 -3
  6. package/dist/components/es/solid-components2.js +7 -7
  7. package/dist/components/es/utils.js +1 -0
  8. package/dist/components/umd/solid-components.js +37 -23
  9. package/dist/custom-elements.json +1 -1
  10. package/dist/package/components/combobox/combobox.d.ts +129 -0
  11. package/dist/package/components/combobox/combobox.js +958 -0
  12. package/dist/package/components/combobox/option-renderer.d.ts +5 -0
  13. package/dist/package/components/combobox/option-renderer.js +4 -0
  14. package/dist/package/components/combobox/utils.d.ts +8 -0
  15. package/dist/package/components/combobox/utils.js +14 -0
  16. package/dist/package/components/optgroup/optgroup.d.ts +20 -0
  17. package/dist/package/components/optgroup/optgroup.js +68 -0
  18. package/dist/package/components/select/select.d.ts +6 -1
  19. package/dist/package/components/select/select.js +100 -30
  20. package/dist/package/solid-components.d.ts +2 -0
  21. package/dist/package/solid-components.js +74 -70
  22. package/dist/package/styles/tailwind.css.js +1 -1
  23. package/dist/package/translations/de.js +8 -4
  24. package/dist/package/translations/en.js +8 -4
  25. package/dist/package/utilities/localize.d.ts +4 -0
  26. package/dist/versioned-components/es/accordion-group.js +1 -1
  27. package/dist/versioned-components/es/accordion.js +1 -1
  28. package/dist/versioned-components/es/audio.js +1 -1
  29. package/dist/versioned-components/es/badge.js +1 -1
  30. package/dist/versioned-components/es/brandshape.js +1 -1
  31. package/dist/versioned-components/es/button.js +1 -1
  32. package/dist/versioned-components/es/carousel-item.js +1 -1
  33. package/dist/versioned-components/es/carousel.js +3 -3
  34. package/dist/versioned-components/es/checkbox-group.js +1 -1
  35. package/dist/versioned-components/es/checkbox.js +1 -1
  36. package/dist/versioned-components/es/combobox.js +11 -0
  37. package/dist/versioned-components/es/dialog.js +1 -1
  38. package/dist/versioned-components/es/divider.js +1 -1
  39. package/dist/versioned-components/es/drawer.js +1 -1
  40. package/dist/versioned-components/es/dropdown.js +1 -1
  41. package/dist/versioned-components/es/expandable.js +1 -1
  42. package/dist/versioned-components/es/flipcard.js +1 -1
  43. package/dist/versioned-components/es/form.js +1 -1
  44. package/dist/versioned-components/es/header.js +1 -1
  45. package/dist/versioned-components/es/icon.js +1 -1
  46. package/dist/versioned-components/es/include.js +1 -1
  47. package/dist/versioned-components/es/input.js +1 -1
  48. package/dist/versioned-components/es/link.js +1 -1
  49. package/dist/versioned-components/es/map-marker.js +1 -1
  50. package/dist/versioned-components/es/navigation-item.js +1 -1
  51. package/dist/versioned-components/es/notification.js +1 -1
  52. package/dist/versioned-components/es/optgroup.js +1 -0
  53. package/dist/versioned-components/es/option-renderer.js +1 -0
  54. package/dist/versioned-components/es/option.js +1 -1
  55. package/dist/versioned-components/es/quickfact.js +1 -1
  56. package/dist/versioned-components/es/radio-button.js +1 -1
  57. package/dist/versioned-components/es/radio-group.js +1 -1
  58. package/dist/versioned-components/es/radio.js +1 -1
  59. package/dist/versioned-components/es/scrollable.js +1 -1
  60. package/dist/versioned-components/es/select.js +7 -3
  61. package/dist/versioned-components/es/solid-components2.js +7 -7
  62. package/dist/versioned-components/es/spinner.js +1 -1
  63. package/dist/versioned-components/es/step-group.js +1 -1
  64. package/dist/versioned-components/es/step.js +1 -1
  65. package/dist/versioned-components/es/switch.js +1 -1
  66. package/dist/versioned-components/es/tab-group.js +1 -1
  67. package/dist/versioned-components/es/tab-panel.js +1 -1
  68. package/dist/versioned-components/es/tab.js +1 -1
  69. package/dist/versioned-components/es/tag.js +1 -1
  70. package/dist/versioned-components/es/teaser-media.js +1 -1
  71. package/dist/versioned-components/es/teaser.js +1 -1
  72. package/dist/versioned-components/es/textarea.js +1 -1
  73. package/dist/versioned-components/es/tooltip.js +2 -2
  74. package/dist/versioned-components/es/utils.js +1 -0
  75. package/dist/versioned-components/es/video.js +1 -1
  76. package/dist/versioned-package/_components/button-group/button-group.d.ts +1 -1
  77. package/dist/versioned-package/_components/button-group/button-group.js +11 -11
  78. package/dist/versioned-package/components/accordion/accordion.d.ts +1 -1
  79. package/dist/versioned-package/components/accordion/accordion.js +2 -2
  80. package/dist/versioned-package/components/accordion-group/accordion-group.d.ts +1 -1
  81. package/dist/versioned-package/components/accordion-group/accordion-group.js +3 -3
  82. package/dist/versioned-package/components/audio/audio.d.ts +1 -1
  83. package/dist/versioned-package/components/audio/audio.js +6 -6
  84. package/dist/versioned-package/components/badge/badge.d.ts +1 -1
  85. package/dist/versioned-package/components/badge/badge.js +1 -1
  86. package/dist/versioned-package/components/brandshape/brandshape.d.ts +1 -1
  87. package/dist/versioned-package/components/brandshape/brandshape.js +1 -1
  88. package/dist/versioned-package/components/button/button.d.ts +1 -1
  89. package/dist/versioned-package/components/button/button.js +4 -4
  90. package/dist/versioned-package/components/carousel/carousel.d.ts +1 -1
  91. package/dist/versioned-package/components/carousel/carousel.js +6 -6
  92. package/dist/versioned-package/components/carousel-item/carousel-item.d.ts +1 -1
  93. package/dist/versioned-package/components/carousel-item/carousel-item.js +1 -1
  94. package/dist/versioned-package/components/checkbox/checkbox.d.ts +1 -1
  95. package/dist/versioned-package/components/checkbox/checkbox.js +3 -3
  96. package/dist/versioned-package/components/checkbox-group/checkbox-group.d.ts +1 -1
  97. package/dist/versioned-package/components/checkbox-group/checkbox-group.js +5 -5
  98. package/dist/versioned-package/components/combobox/combobox.d.ts +129 -0
  99. package/dist/versioned-package/components/combobox/combobox.js +958 -0
  100. package/dist/versioned-package/components/combobox/option-renderer.d.ts +5 -0
  101. package/dist/versioned-package/components/combobox/option-renderer.js +4 -0
  102. package/dist/versioned-package/components/combobox/utils.d.ts +8 -0
  103. package/dist/versioned-package/components/combobox/utils.js +14 -0
  104. package/dist/versioned-package/components/dialog/dialog.d.ts +1 -1
  105. package/dist/versioned-package/components/dialog/dialog.js +2 -2
  106. package/dist/versioned-package/components/divider/divider.d.ts +1 -1
  107. package/dist/versioned-package/components/divider/divider.js +2 -2
  108. package/dist/versioned-package/components/drawer/drawer.d.ts +1 -1
  109. package/dist/versioned-package/components/drawer/drawer.js +2 -2
  110. package/dist/versioned-package/components/dropdown/dropdown.d.ts +1 -1
  111. package/dist/versioned-package/components/dropdown/dropdown.js +8 -8
  112. package/dist/versioned-package/components/expandable/expandable.d.ts +1 -1
  113. package/dist/versioned-package/components/expandable/expandable.js +2 -2
  114. package/dist/versioned-package/components/flipcard/flipcard.d.ts +1 -1
  115. package/dist/versioned-package/components/flipcard/flipcard.js +1 -1
  116. package/dist/versioned-package/components/header/header.d.ts +1 -1
  117. package/dist/versioned-package/components/header/header.js +4 -4
  118. package/dist/versioned-package/components/icon/icon.d.ts +1 -1
  119. package/dist/versioned-package/components/icon/icon.js +1 -1
  120. package/dist/versioned-package/components/include/include.d.ts +1 -1
  121. package/dist/versioned-package/components/include/include.js +1 -1
  122. package/dist/versioned-package/components/input/input.d.ts +1 -1
  123. package/dist/versioned-package/components/input/input.js +3 -3
  124. package/dist/versioned-package/components/link/link.d.ts +1 -1
  125. package/dist/versioned-package/components/link/link.js +2 -2
  126. package/dist/versioned-package/components/map-marker/map-marker.d.ts +1 -1
  127. package/dist/versioned-package/components/map-marker/map-marker.js +1 -1
  128. package/dist/versioned-package/components/navigation-item/navigation-item.d.ts +1 -1
  129. package/dist/versioned-package/components/navigation-item/navigation-item.js +5 -5
  130. package/dist/versioned-package/components/notification/notification.d.ts +1 -1
  131. package/dist/versioned-package/components/notification/notification.js +5 -5
  132. package/dist/versioned-package/components/optgroup/optgroup.d.ts +20 -0
  133. package/dist/versioned-package/components/optgroup/optgroup.js +68 -0
  134. package/dist/versioned-package/components/option/option.d.ts +1 -1
  135. package/dist/versioned-package/components/option/option.js +2 -2
  136. package/dist/versioned-package/components/popup/popup.d.ts +1 -1
  137. package/dist/versioned-package/components/popup/popup.js +1 -1
  138. package/dist/versioned-package/components/quickfact/quickfact.d.ts +1 -1
  139. package/dist/versioned-package/components/quickfact/quickfact.js +2 -2
  140. package/dist/versioned-package/components/radio/radio.d.ts +1 -1
  141. package/dist/versioned-package/components/radio/radio.js +2 -2
  142. package/dist/versioned-package/components/radio-button/radio-button.d.ts +1 -1
  143. package/dist/versioned-package/components/radio-button/radio-button.js +2 -2
  144. package/dist/versioned-package/components/radio-group/radio-group.d.ts +2 -2
  145. package/dist/versioned-package/components/radio-group/radio-group.js +13 -13
  146. package/dist/versioned-package/components/scrollable/scrollable.d.ts +1 -1
  147. package/dist/versioned-package/components/scrollable/scrollable.js +3 -3
  148. package/dist/versioned-package/components/select/select.d.ts +10 -5
  149. package/dist/versioned-package/components/select/select.js +121 -51
  150. package/dist/versioned-package/components/spinner/spinner.d.ts +1 -1
  151. package/dist/versioned-package/components/spinner/spinner.js +1 -1
  152. package/dist/versioned-package/components/step/step.d.ts +1 -1
  153. package/dist/versioned-package/components/step/step.js +2 -2
  154. package/dist/versioned-package/components/step-group/step-group.d.ts +1 -1
  155. package/dist/versioned-package/components/step-group/step-group.js +2 -2
  156. package/dist/versioned-package/components/switch/switch.d.ts +1 -1
  157. package/dist/versioned-package/components/switch/switch.js +1 -1
  158. package/dist/versioned-package/components/tab/tab.d.ts +1 -1
  159. package/dist/versioned-package/components/tab/tab.js +2 -2
  160. package/dist/versioned-package/components/tab-group/tab-group.d.ts +1 -1
  161. package/dist/versioned-package/components/tab-group/tab-group.js +13 -13
  162. package/dist/versioned-package/components/tab-panel/tab-panel.d.ts +1 -1
  163. package/dist/versioned-package/components/tab-panel/tab-panel.js +2 -2
  164. package/dist/versioned-package/components/tag/tag.d.ts +1 -1
  165. package/dist/versioned-package/components/tag/tag.js +2 -2
  166. package/dist/versioned-package/components/teaser/teaser.js +1 -1
  167. package/dist/versioned-package/components/teaser-media/teaser-media.js +1 -1
  168. package/dist/versioned-package/components/textarea/textarea.d.ts +1 -1
  169. package/dist/versioned-package/components/textarea/textarea.js +2 -2
  170. package/dist/versioned-package/components/tooltip/tooltip.d.ts +1 -1
  171. package/dist/versioned-package/components/tooltip/tooltip.js +5 -5
  172. package/dist/versioned-package/components/video/video.d.ts +1 -1
  173. package/dist/versioned-package/components/video/video.js +2 -2
  174. package/dist/versioned-package/internal/form.js +3 -3
  175. package/dist/versioned-package/solid-components.d.ts +2 -0
  176. package/dist/versioned-package/solid-components.js +74 -70
  177. package/dist/versioned-package/styles/headline/headline.css.js +1 -1
  178. package/dist/versioned-package/styles/tailwind.css.js +1 -1
  179. package/dist/versioned-package/translations/de.js +8 -4
  180. package/dist/versioned-package/translations/en.js +8 -4
  181. package/dist/versioned-package/utilities/autocomplete-config.js +4 -4
  182. package/dist/versioned-package/utilities/localize.d.ts +4 -0
  183. package/dist/versioned-styles/solid-styles.css +1 -1
  184. package/dist/vscode.html-custom-data.json +371 -45
  185. package/dist/web-types.json +5471 -3959
  186. package/package.json +3 -3
@@ -0,0 +1,958 @@
1
+ import { stopAnimations, animateTo } from "../../internal/animate.js";
2
+ import { css, html } from "lit";
3
+ import { customElement } from "../../internal/register-custom-element.js";
4
+ import { defaultOptionRenderer } from "./option-renderer.js";
5
+ import { defaultValue } from "../../internal/default-value.js";
6
+ import { normalizeString, getAllOptions, getAssignedElementsForSlot, filterOnlyOptgroups } from "./utils.js";
7
+ import { FormControlController } from "../../internal/form.js";
8
+ import { setDefaultAnimation, getAnimation } from "../../utilities/animation-registry.js";
9
+ import { HasSlotController } from "../../internal/slot.js";
10
+ import { LocalizeController } from "../../utilities/localize.js";
11
+ import { query, state, property } from "lit/decorators.js";
12
+ import { scrollIntoView } from "../../internal/scroll.js";
13
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
14
+ import { waitForEvent } from "../../internal/event.js";
15
+ import { watch } from "../../internal/watch.js";
16
+ import componentStyles from "../../styles/component.styles.js";
17
+ import cx from "classix";
18
+ import SdIcon from "../icon/icon.js";
19
+ import SdPopup from "../popup/popup.js";
20
+ import SdTag from "../tag/tag.js";
21
+ import SolidElement from "../../internal/solid-element.js";
22
+ var __defProp = Object.defineProperty;
23
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
24
+ var __decorateClass = (decorators, target, key, kind) => {
25
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
26
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
27
+ if (decorator = decorators[i])
28
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
29
+ if (kind && result) __defProp(target, key, result);
30
+ return result;
31
+ };
32
+ let SdCombobox = class extends SolidElement {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.formControlController = new FormControlController(this, {
36
+ assumeInteractionOn: ["sd-blur", "sd-input"]
37
+ });
38
+ this.hasSlotController = new HasSlotController(this, "help-text", "label");
39
+ this.localize = new LocalizeController(this);
40
+ this.hasHover = false;
41
+ this.hasFocus = false;
42
+ this.displayInputValue = "";
43
+ this.selectedTextLabel = "";
44
+ this.selectedOptions = [];
45
+ this.filteredOptions = [];
46
+ this.allOptions = [];
47
+ this.showValidStyle = false;
48
+ this.showInvalidStyle = false;
49
+ this.name = "";
50
+ this.value = "";
51
+ this.defaultValue = "";
52
+ this.size = "lg";
53
+ this.placeholder = this.localize.term("comboboxDefaultPlaceholder");
54
+ this.disabled = false;
55
+ this.clearable = false;
56
+ this.open = false;
57
+ this.hoist = false;
58
+ this.label = "";
59
+ this.placement = "bottom";
60
+ this.helpText = "";
61
+ this.form = "";
62
+ this.required = false;
63
+ this.currentPlacement = this.placement;
64
+ this.getOption = defaultOptionRenderer;
65
+ this.multiple = false;
66
+ this.useTags = true;
67
+ this.maxOptionsVisible = 3;
68
+ this.styleOnValid = false;
69
+ this.filter = (option, queryString) => {
70
+ const normalizedOption = normalizeString(option.value);
71
+ const normalizedOptionLabel = normalizeString(option.getTextLabel());
72
+ const normalizedQuery = normalizeString(queryString);
73
+ return normalizedOption.includes(normalizedQuery) || normalizedOptionLabel.includes(normalizedQuery);
74
+ };
75
+ this.getTag = (option) => {
76
+ return html`<sd-tag ?disabled="${this.disabled}" part="tag" exportparts="
77
+ base:tag__base,
78
+ content:tag__content,
79
+ removable-indicator:tag__removable-indicator,
80
+ " size="${this.size === "sm" ? "sm" : "lg"}" removable @keydown="${(event) => this.handleTagKeyDown(event, option)}" @sd-remove="${(event) => this.handleTagRemove(event, option)}">${option.getTextLabel()}</sd-tag>`;
81
+ };
82
+ this.handleDocumentFocusIn = (event) => {
83
+ const path = event.composedPath();
84
+ if (this && !path.includes(this)) {
85
+ this.hide();
86
+ }
87
+ };
88
+ this.handleDocumentKeyDown = (event) => {
89
+ const target = event.target;
90
+ const isClearButton = target.closest(".combobox__clear") !== null;
91
+ if (isClearButton) {
92
+ return;
93
+ }
94
+ if (event.key === "Escape") {
95
+ if (this.open) {
96
+ event.preventDefault();
97
+ event.stopPropagation();
98
+ this.hide();
99
+ this.displayInput.focus({ preventScroll: true });
100
+ } else {
101
+ this.displayInputValue = "";
102
+ }
103
+ }
104
+ if (event.key === "Backspace" && this.multiple && this.displayInput.value === "") {
105
+ this.handleTagRemove(new CustomEvent("sd-remove"), this.selectedOptions[this.selectedOptions.length - 1]);
106
+ this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
107
+ return;
108
+ }
109
+ if (event.key === "Enter") {
110
+ const currentOption = this.getCurrentOption();
111
+ const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
112
+ if (!this.open && !hasModifier) {
113
+ setTimeout(() => {
114
+ if (!event.defaultPrevented) {
115
+ this.formControlController.submit();
116
+ }
117
+ });
118
+ return;
119
+ }
120
+ if (!this.open || (currentOption == null ? void 0 : currentOption.disabled)) {
121
+ return;
122
+ }
123
+ if (currentOption && !currentOption.disabled) {
124
+ const oldValue = this.value;
125
+ if (this.multiple) {
126
+ this.toggleOptionSelection(currentOption);
127
+ this.lastOption = currentOption;
128
+ this.setOrderedSelectedOptions(currentOption);
129
+ this.updateComplete.then(() => {
130
+ this.selectionChanged();
131
+ });
132
+ } else {
133
+ this.setOrderedSelectedOptions(currentOption);
134
+ this.setSelectedOptions(currentOption);
135
+ }
136
+ this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
137
+ if (this.value !== oldValue) {
138
+ this.updateComplete.then(() => {
139
+ this.emit("sd-input");
140
+ this.emit("sd-change");
141
+ });
142
+ }
143
+ }
144
+ this.displayInput.focus({ preventScroll: true });
145
+ if (!this.multiple) {
146
+ this.hide();
147
+ this.displayInput.focus({ preventScroll: true });
148
+ }
149
+ return;
150
+ }
151
+ if (["ArrowUp", "ArrowDown"].includes(event.key)) {
152
+ event.preventDefault();
153
+ event.stopPropagation();
154
+ if (!this.open) {
155
+ this.show();
156
+ }
157
+ this.selectNextOption(event.key === "ArrowDown");
158
+ }
159
+ if (["Home", "End"].includes(event.key)) {
160
+ event.preventDefault();
161
+ event.stopPropagation();
162
+ if (event.key === "Home") {
163
+ this.displayInput.setSelectionRange(0, 0);
164
+ } else if (event.key === "End") {
165
+ this.displayInput.setSelectionRange(this.displayInput.value.length, this.displayInput.value.length);
166
+ }
167
+ }
168
+ };
169
+ this.handleDocumentMouseDown = (event) => {
170
+ const path = event.composedPath();
171
+ if (this && !path.includes(this)) {
172
+ this.hide();
173
+ }
174
+ };
175
+ }
176
+ connectedCallback() {
177
+ super.connectedCallback();
178
+ this.open = false;
179
+ }
180
+ firstUpdated() {
181
+ if (!this.multiple) {
182
+ const option = this.findOptionByValue(this.getSlottedOptions(), this.value);
183
+ this.selectedTextLabel = (option == null ? void 0 : option.getTextLabel()) || "";
184
+ }
185
+ this.formControlController.updateValidity();
186
+ this.applySizeToOptions();
187
+ }
188
+ /** Gets the validity state object */
189
+ get validity() {
190
+ return this.valueInput.validity;
191
+ }
192
+ /** Gets the validation message */
193
+ get validationMessage() {
194
+ return this.valueInput.validationMessage;
195
+ }
196
+ get options() {
197
+ const renderOption = (option) => {
198
+ const queryString = this.displayInput.value;
199
+ const optionHtml = this.getOption(option, queryString);
200
+ return html`${typeof optionHtml === "string" ? unsafeHTML(optionHtml) : optionHtml}`;
201
+ };
202
+ return this.filteredOptions.map((item) => {
203
+ if (item.tagName.toLowerCase() === "sd-optgroup") {
204
+ Array.from(item.children).forEach((option) => {
205
+ if (option.tagName.toLowerCase() === "sd-option") {
206
+ renderOption(option);
207
+ }
208
+ });
209
+ return item;
210
+ }
211
+ return renderOption(item);
212
+ });
213
+ }
214
+ get tags() {
215
+ if (this.selectedOptions.length <= this.maxOptionsVisible) {
216
+ return this.selectedOptions.map((option, index) => {
217
+ if (index < this.maxOptionsVisible || this.maxOptionsVisible <= 0) {
218
+ const tag = this.getTag(option, index);
219
+ return html`<div @sd-remove="${(e) => this.handleTagRemove(e, option)}">${typeof tag === "string" ? unsafeHTML(tag) : tag}</div>`;
220
+ }
221
+ return [html``];
222
+ });
223
+ } else {
224
+ return [
225
+ html`<sd-tag ?disabled="${this.disabled}" part="tag" exportparts="
226
+ base:tag__base,
227
+ content:tag__content,
228
+ removable-indicator:tag__removable-indicator,
229
+ " size="${this.size === "sm" ? "sm" : "lg"}" removable @keydown="${(event) => this.handleTagMaxOptionsKeyDown(event)}" @sd-remove="${(event) => this.handleTagRemove(event)}">${this.selectedOptions.length} ${this.localize.term("tagsSelected")}</sd-tag>`
230
+ ];
231
+ }
232
+ }
233
+ addOpenListeners() {
234
+ document.addEventListener("focusin", this.handleDocumentFocusIn);
235
+ document.addEventListener("mousedown", this.handleDocumentMouseDown);
236
+ if (this.getRootNode() !== document) {
237
+ this.getRootNode().addEventListener("focusin", this.handleDocumentFocusIn);
238
+ }
239
+ }
240
+ removeOpenListeners() {
241
+ document.removeEventListener("focusin", this.handleDocumentFocusIn);
242
+ document.removeEventListener("mousedown", this.handleDocumentMouseDown);
243
+ if (this.getRootNode() !== document) {
244
+ this.getRootNode().removeEventListener("focusin", this.handleDocumentFocusIn);
245
+ }
246
+ }
247
+ handleFocus() {
248
+ this.hasFocus = true;
249
+ this.emit("sd-focus");
250
+ }
251
+ handleBlur() {
252
+ this.hasFocus = false;
253
+ this.emit("sd-blur");
254
+ }
255
+ handleTagKeyDown(event, option) {
256
+ if (event.key === "Backspace" && this.multiple) {
257
+ event.stopPropagation();
258
+ this.handleTagRemove(new CustomEvent("sd-remove"), option);
259
+ this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
260
+ }
261
+ }
262
+ handleTagMaxOptionsKeyDown(event) {
263
+ if (event.key === "Backspace" && this.multiple) {
264
+ event.stopPropagation();
265
+ this.handleTagRemove(new CustomEvent("sd-remove"), this.selectedOptions[this.selectedOptions.length - 1]);
266
+ this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
267
+ }
268
+ }
269
+ handleLabelClick() {
270
+ this.displayInput.focus();
271
+ }
272
+ handleTagRemove(event, option) {
273
+ event.stopPropagation();
274
+ if (!option) {
275
+ this.clearCombobox();
276
+ }
277
+ if (option && !this.disabled) {
278
+ this.toggleOptionSelection(option, false);
279
+ this.setOrderedSelectedOptions(option);
280
+ this.updateComplete.then(() => {
281
+ this.selectionChanged();
282
+ this.emit("sd-input");
283
+ this.emit("sd-change");
284
+ });
285
+ }
286
+ }
287
+ handleComboboxMouseDown(event) {
288
+ const path = event.composedPath();
289
+ const isRemovableIndicator = path.some((el) => el instanceof HTMLSlotElement && el.name === "removable-indicator");
290
+ if (this.disabled || isRemovableIndicator) {
291
+ return;
292
+ }
293
+ const toggleListboxOpen = () => this.open ? this.hide() : this.show();
294
+ toggleListboxOpen().then(() => {
295
+ setTimeout(() => this.displayInput.focus({ preventScroll: true }));
296
+ });
297
+ }
298
+ handleComboboxKeyDown(event) {
299
+ if (event.key === "Tab") {
300
+ return;
301
+ }
302
+ this.handleDocumentKeyDown(event);
303
+ }
304
+ handleClearClick(event) {
305
+ event.stopPropagation();
306
+ this.clearCombobox();
307
+ }
308
+ handleNoResultsClick(event) {
309
+ event.preventDefault();
310
+ this.hide();
311
+ }
312
+ clearCombobox() {
313
+ if (this.value !== "") {
314
+ this.value = "";
315
+ this.displayInputValue = "";
316
+ this.selectedTextLabel = "";
317
+ this.lastOption = void 0;
318
+ this.selectedOptions = [];
319
+ this.getSlottedOptions().forEach((option) => {
320
+ option.selected = false;
321
+ });
322
+ this.displayInput.focus({ preventScroll: true });
323
+ this.updateComplete.then(() => {
324
+ this.emit("sd-clear");
325
+ this.emit("sd-input");
326
+ this.emit("sd-change");
327
+ });
328
+ }
329
+ }
330
+ // eslint-disable-next-line class-methods-use-this
331
+ preventLoosingFocus(event) {
332
+ event.stopPropagation();
333
+ event.preventDefault();
334
+ }
335
+ /* eslint-disable @typescript-eslint/no-floating-promises */
336
+ handleOptionClick(event) {
337
+ const target = event.target;
338
+ const option = target.closest("sd-option");
339
+ const oldValue = this.value;
340
+ if (option && !option.disabled) {
341
+ if (this.multiple) {
342
+ this.toggleOptionSelection(option);
343
+ this.lastOption = option;
344
+ this.setOrderedSelectedOptions(option);
345
+ this.updateComplete.then(() => {
346
+ this.selectionChanged();
347
+ });
348
+ } else {
349
+ this.setOrderedSelectedOptions(option);
350
+ this.setSelectedOptions(option);
351
+ }
352
+ this.updateComplete.then(() => this.displayInput.focus({ preventScroll: true }));
353
+ if (this.value !== oldValue) {
354
+ this.updateComplete.then(() => {
355
+ this.emit("sd-input");
356
+ this.emit("sd-change");
357
+ });
358
+ }
359
+ if (!this.multiple) {
360
+ this.hide();
361
+ this.displayInput.focus({ preventScroll: true });
362
+ }
363
+ }
364
+ }
365
+ /* eslint-enable @typescript-eslint/no-floating-promises */
366
+ /**
367
+ * Selects the following or previous option.
368
+ *
369
+ * @param isNext - A boolean indicating whether to select the following option (true)
370
+ * or the previous option (false).
371
+ */
372
+ selectNextOption(isNext) {
373
+ const filteredOptions = this.getAllFilteredOptions();
374
+ if (filteredOptions.length === 0) {
375
+ return;
376
+ }
377
+ const currentOption = this.getCurrentOption();
378
+ const currentIndex = filteredOptions.indexOf(currentOption);
379
+ let newIndex = Math.max(0, currentIndex);
380
+ if (isNext) {
381
+ const nextIndex = currentIndex + 1;
382
+ newIndex = nextIndex > filteredOptions.length - 1 ? 0 : nextIndex;
383
+ } else {
384
+ const previousIndex = currentIndex - 1;
385
+ newIndex = previousIndex < 0 ? filteredOptions.length - 1 : previousIndex;
386
+ }
387
+ this.setCurrentOption(filteredOptions[newIndex]);
388
+ scrollIntoView(this.getCurrentOption(), this.listbox, "vertical", "auto");
389
+ }
390
+ getAllFilteredOptions() {
391
+ return [...this.filteredWrapper.querySelectorAll("sd-option")];
392
+ }
393
+ getCurrentOption() {
394
+ return this.getAllFilteredOptions().find((option) => option.current);
395
+ }
396
+ // Sets the current option, which is the option the user is currently interacting with
397
+ // (e.g. via keyboard). Only one option may be "current" at a time.
398
+ setCurrentOption(option) {
399
+ const allFilteredOptions = this.getAllFilteredOptions();
400
+ this.displayInput.removeAttribute("aria-activedescendant");
401
+ allFilteredOptions.forEach((el) => {
402
+ el.current = false;
403
+ el.setAttribute("aria-selected", "false");
404
+ });
405
+ if (option) {
406
+ option.current = true;
407
+ option.setAttribute("aria-selected", "true");
408
+ this.displayInput.setAttribute("aria-activedescendant", option.id);
409
+ }
410
+ }
411
+ // Toggles an option's selected state
412
+ toggleOptionSelection(option, force) {
413
+ const allOptions = this.getSlottedOptions();
414
+ const optionEl = allOptions.find(
415
+ (el) => el.value && option.value ? el.value === option.value : el.getTextLabel() === option.getTextLabel()
416
+ );
417
+ if (optionEl) optionEl.selected = force ?? !optionEl.selected;
418
+ }
419
+ findOptionByValue(slottedOptions, value) {
420
+ if (!value) return void 0;
421
+ if (Array.isArray(value)) {
422
+ return slottedOptions.find((option) => value.includes(option.value));
423
+ }
424
+ return slottedOptions.find((option) => option.value === value);
425
+ }
426
+ selectedOptionsAndValueSynced() {
427
+ var _a;
428
+ if (!this.value && this.selectedOptions.length === 0) return true;
429
+ return Array.isArray(this.value) ? this.value.length === this.selectedOptions.length : this.value === ((_a = this.selectedOptions[0]) == null ? void 0 : _a.value);
430
+ }
431
+ isOptionSelected(option) {
432
+ if (option.value) {
433
+ return this.value.includes(option.value);
434
+ } else {
435
+ return this.value.includes(option.getTextLabel());
436
+ }
437
+ }
438
+ syncSelectedOptionsAndValue() {
439
+ if (this.selectedOptionsAndValueSynced()) {
440
+ return;
441
+ }
442
+ const allOptions = this.getSlottedOptions();
443
+ allOptions.forEach((option) => {
444
+ option.selected = false;
445
+ });
446
+ this.selectedOptions = this.getSlottedOptions().filter((option) => {
447
+ return this.isOptionSelected(option);
448
+ });
449
+ this.selectedOptions.forEach((option) => {
450
+ if (option) option.selected = true;
451
+ });
452
+ return Promise.resolve();
453
+ }
454
+ compareOptions(a, b) {
455
+ if (a.value && b.value) {
456
+ return a.value === b.value;
457
+ }
458
+ return a.getTextLabel() === b.getTextLabel();
459
+ }
460
+ /**
461
+ * Updates the selected options cache, the current value, and the display value
462
+ */
463
+ setSelectedOptions(option) {
464
+ const allOptions = this.getSlottedOptions();
465
+ allOptions.forEach((el) => {
466
+ el.selected = this.compareOptions(el, option);
467
+ });
468
+ this.selectionChanged();
469
+ }
470
+ setOrderedSelectedOptions(option) {
471
+ const selectedSlottedOption = this.getSlottedOptions().find((el) => this.compareOptions(el, option));
472
+ if (this.multiple) {
473
+ if (this.selectedOptions.length > 0 && selectedSlottedOption && this.selectedOptions.find((el) => this.compareOptions(el, selectedSlottedOption))) {
474
+ this.selectedOptions = this.selectedOptions.filter((el) => !this.compareOptions(el, selectedSlottedOption));
475
+ } else {
476
+ this.selectedOptions = [...this.selectedOptions, selectedSlottedOption];
477
+ }
478
+ } else {
479
+ this.selectedOptions = [selectedSlottedOption];
480
+ }
481
+ }
482
+ selectionChanged() {
483
+ var _a, _b, _c;
484
+ const hasSelectedOptions = this.selectedOptions.some((option) => {
485
+ if (!option) return false;
486
+ return this.isOptionSelected(option);
487
+ });
488
+ if (this.multiple) {
489
+ if (!hasSelectedOptions && this.selectedOptions.length > 0) {
490
+ this.value = [...this.value, ...this.selectedOptions.map((el) => el.value || el.getTextLabel())];
491
+ } else {
492
+ this.value = this.selectedOptions.map((el) => {
493
+ return (el == null ? void 0 : el.value) || (el == null ? void 0 : el.getTextLabel()) || "";
494
+ });
495
+ }
496
+ this.displayInputValue = "";
497
+ } else {
498
+ this.value = ((_a = this.selectedOptions[0]) == null ? void 0 : _a.value) || ((_b = this.selectedOptions[0]) == null ? void 0 : _b.getTextLabel()) || "";
499
+ this.selectedTextLabel = ((_c = this.selectedOptions[0]) == null ? void 0 : _c.getTextLabel()) || "";
500
+ this.displayInputValue = "";
501
+ }
502
+ this.updateComplete.then(() => {
503
+ this.formControlController.updateValidity();
504
+ });
505
+ }
506
+ createComboboxOptionsFromQuery(queryString) {
507
+ const optgroups = [];
508
+ this.filteredOptions = this.getSlottedOptions().filter((option) => {
509
+ return this.filter(option, queryString) || queryString === "";
510
+ }).map((option) => {
511
+ var _a, _b, _c;
512
+ const clonedOption = option.cloneNode(true);
513
+ clonedOption.current = clonedOption.value === ((_a = this.lastOption) == null ? void 0 : _a.value);
514
+ clonedOption.selected = option.selected;
515
+ const hasOptgroup = ((_b = option.parentElement) == null ? void 0 : _b.tagName.toLowerCase()) === "sd-optgroup";
516
+ if (!hasOptgroup) {
517
+ return clonedOption;
518
+ }
519
+ const optgroup = option.parentElement;
520
+ const optGroupLabel = (_c = optgroup.querySelector('[slot="label"]')) == null ? void 0 : _c.cloneNode(true);
521
+ const filteredOptgroup = optgroups.find((el) => el.id === optgroup.id);
522
+ if (filteredOptgroup) {
523
+ filteredOptgroup == null ? void 0 : filteredOptgroup.appendChild(clonedOption);
524
+ if (optGroupLabel) filteredOptgroup == null ? void 0 : filteredOptgroup.appendChild(optGroupLabel);
525
+ return void 0;
526
+ }
527
+ const clonedOptgroup = optgroup.cloneNode();
528
+ clonedOptgroup.appendChild(clonedOption);
529
+ if (optGroupLabel) clonedOptgroup.appendChild(optGroupLabel);
530
+ optgroups.push(clonedOptgroup);
531
+ return clonedOptgroup;
532
+ }).filter(Boolean);
533
+ }
534
+ handleInvalid(event) {
535
+ this.formControlController.setValidity(false);
536
+ this.formControlController.emitInvalidEvent(event);
537
+ this.invalidMessage.textContent = event.target.validationMessage;
538
+ }
539
+ handleMouseEnter() {
540
+ this.hasHover = true;
541
+ }
542
+ handleMouseLeave() {
543
+ this.hasHover = false;
544
+ }
545
+ /** Receives incoming event detail from sd-popup and updates local state for conditional styling. */
546
+ handleCurrentPlacement(e) {
547
+ const incomingPlacement = e.detail;
548
+ if (incomingPlacement) {
549
+ this.currentPlacement = incomingPlacement;
550
+ }
551
+ }
552
+ handleFilterChange() {
553
+ this.createComboboxOptionsFromQuery(this.displayInputValue);
554
+ }
555
+ handleUseTagsChange() {
556
+ const allOptions = this.getAllFilteredOptions();
557
+ if (customElements.get("sd-option")) {
558
+ allOptions.forEach((option) => {
559
+ option.checkbox = this.multiple;
560
+ });
561
+ }
562
+ }
563
+ applySizeToOptions() {
564
+ this.getSlottedOptions().forEach((option) => {
565
+ option.size = this.size;
566
+ });
567
+ }
568
+ handleDisabledChange() {
569
+ this.formControlController.setValidity(this.disabled);
570
+ if (this.disabled) {
571
+ this.open = false;
572
+ this.handleOpenChange();
573
+ }
574
+ }
575
+ handleValueChange() {
576
+ this.syncSelectedOptionsAndValue();
577
+ if (this.multiple) {
578
+ this.createComboboxOptionsFromQuery(this.displayInput.value);
579
+ } else {
580
+ this.createComboboxOptionsFromQuery("");
581
+ }
582
+ }
583
+ handleDisplayInputValueChange() {
584
+ this.createComboboxOptionsFromQuery(this.displayInputValue);
585
+ }
586
+ async handleOpenChange() {
587
+ if (this.open && !this.disabled) {
588
+ this.emit("sd-show");
589
+ this.addOpenListeners();
590
+ await stopAnimations(this);
591
+ this.listbox.hidden = false;
592
+ this.popup.active = true;
593
+ const { keyframes: keyframes2, options: options2 } = getAnimation(this, "combobox.show", { dir: this.localize.dir() });
594
+ await animateTo(this.popup.popup, keyframes2, options2);
595
+ this.emit("sd-after-show");
596
+ if (this.filteredOptions.length === 0) {
597
+ this.emit("sd-error");
598
+ }
599
+ return;
600
+ }
601
+ this.setCurrentOption(null);
602
+ this.displayInput.removeAttribute("aria-activedescendant");
603
+ this.emit("sd-hide");
604
+ this.removeOpenListeners();
605
+ await stopAnimations(this);
606
+ const { keyframes, options } = getAnimation(this, "combobox.hide", { dir: this.localize.dir() });
607
+ await animateTo(this.popup.popup, keyframes, options);
608
+ this.listbox.hidden = true;
609
+ this.popup.active = false;
610
+ this.emit("sd-after-hide");
611
+ }
612
+ async show() {
613
+ if (this.open || this.disabled) {
614
+ this.open = false;
615
+ return void 0;
616
+ }
617
+ this.open = true;
618
+ return Promise.race([waitForEvent(this, "sd-after-show"), waitForEvent(this, "sd-error")]);
619
+ }
620
+ /** Hides the listbox. */
621
+ async hide() {
622
+ if (!this.open || this.disabled) {
623
+ this.open = false;
624
+ return void 0;
625
+ }
626
+ this.displayInputValue = "";
627
+ this.open = false;
628
+ return waitForEvent(this, "sd-after-hide");
629
+ }
630
+ /**
631
+ * Checks for validity but does not show a validation message.
632
+ * Returns `true` when valid and `false` when invalid.
633
+ */
634
+ checkValidity() {
635
+ return this.valueInput.checkValidity();
636
+ }
637
+ /** Gets the associated form, if one exists. */
638
+ getForm() {
639
+ return this.formControlController.getForm();
640
+ }
641
+ /** Checks for validity and shows the browser's validation message if the control is invalid. */
642
+ reportValidity() {
643
+ this.formControlController.fakeUserInteraction();
644
+ return this.valueInput.reportValidity();
645
+ }
646
+ /** Sets a custom validation message. Pass an empty string to restore validity. */
647
+ setCustomValidity(message) {
648
+ this.valueInput.setCustomValidity(message);
649
+ this.formControlController.updateValidity();
650
+ }
651
+ /** Sets focus on the control. */
652
+ focus(options) {
653
+ this.displayInput.focus(options);
654
+ }
655
+ /** Removes focus from the control. */
656
+ blur() {
657
+ this.displayInput.blur();
658
+ }
659
+ async handleInput() {
660
+ const inputValue = this.displayInput.value;
661
+ this.displayInputValue = inputValue;
662
+ await this.updateComplete;
663
+ this.open = this.filteredWrapper.children.length > 0;
664
+ this.formControlController.updateValidity();
665
+ this.emit("sd-input");
666
+ }
667
+ handleChange() {
668
+ if (!this.selectedOptions || !this.multiple) {
669
+ this.selectedTextLabel = this.displayInput.value;
670
+ this.updateComplete.then(() => {
671
+ this.formControlController.updateValidity();
672
+ });
673
+ this.emit("sd-change");
674
+ }
675
+ }
676
+ getSlottedOptions() {
677
+ return getAllOptions(getAssignedElementsForSlot(this.defaultSlot)).flat();
678
+ }
679
+ getSlottedOptGroups() {
680
+ return filterOnlyOptgroups(getAssignedElementsForSlot(this.defaultSlot));
681
+ }
682
+ /* eslint-disable no-param-reassign, @typescript-eslint/no-floating-promises */
683
+ async handleDefaultSlotChange() {
684
+ if (!customElements.get("sd-option")) {
685
+ customElements.whenDefined("sd-option").then(() => this.handleDefaultSlotChange());
686
+ return;
687
+ }
688
+ const slottedOptions = this.getSlottedOptions();
689
+ const slottedOptgroups = this.getSlottedOptGroups();
690
+ slottedOptions.forEach((option, index) => {
691
+ if (this.multiple) {
692
+ option.checkbox = true;
693
+ }
694
+ option.id = option.id || `sd-combobox-option-${index}`;
695
+ });
696
+ slottedOptgroups.forEach((optgroup, index) => {
697
+ optgroup.id = optgroup.id || `sd-combobox-optgroup-${index}`;
698
+ });
699
+ await this.syncSelectedOptionsAndValue();
700
+ if (this.multiple) {
701
+ this.createComboboxOptionsFromQuery(this.displayInputValue);
702
+ } else {
703
+ this.createComboboxOptionsFromQuery("");
704
+ }
705
+ if (this.hasFocus && this.value.length > 0 && !this.open) {
706
+ await this.show();
707
+ }
708
+ }
709
+ /* eslint-enable no-param-reassign, @typescript-eslint/no-floating-promises */
710
+ /* eslint-disable @typescript-eslint/unbound-method */
711
+ // eslint-disable-next-line complexity
712
+ render() {
713
+ const slots = {
714
+ left: this.hasSlotController.test("left"),
715
+ right: this.hasSlotController.test("right")
716
+ };
717
+ const hasLabelSlot = this.hasSlotController.test("label");
718
+ const hasHelpTextSlot = this.hasSlotController.test("help-text");
719
+ const hasLabel = this.label ? true : !!hasLabelSlot;
720
+ const hasHelpText = this.helpText ? true : !!hasHelpTextSlot;
721
+ const hasClearIcon = this.clearable && !this.disabled && this.value.length > 0;
722
+ const selectState = this.disabled ? "disabled" : this.hasFocus && this.showInvalidStyle ? "activeInvalid" : this.hasFocus && this.styleOnValid && this.showValidStyle ? "activeValid" : this.hasFocus || this.open ? "active" : this.showInvalidStyle ? "invalid" : this.styleOnValid && this.showValidStyle ? "valid" : "default";
723
+ const cursorStyles = this.disabled ? "cursor-not-allowed" : "cursor-pointer";
724
+ const iconColor = this.disabled ? "text-neutral-500" : "text-primary";
725
+ const iconMarginLeft = { sm: "ml-1", md: "ml-2", lg: "ml-2" }[this.size];
726
+ const iconMarginRight = { sm: "mr-1", md: "mr-2", lg: "mr-2" }[this.size];
727
+ const iconSize = {
728
+ sm: "text-base",
729
+ md: "text-lg",
730
+ lg: "text-xl"
731
+ }[this.size];
732
+ return html`<div part="form-control" class="${cx(
733
+ "relative text-left",
734
+ cursorStyles,
735
+ this.size === "sm" ? "text-sm" : "text-base",
736
+ this.open && "z-50"
737
+ )}"><label id="label" part="form-control-label" class="${hasLabel && "inline-block mb-2"}" aria-hidden="${!hasLabel}" @click="${this.handleLabelClick}"><slot name="label">${this.label}</slot></label><div part="form-control-input" class="relative w-full bg-white text-black"><div part="border" class="${cx(
738
+ "absolute top-0 w-full h-full pointer-events-none border rounded-default",
739
+ this.hasHover && "bg-neutral-200",
740
+ {
741
+ disabled: "border-neutral-500",
742
+ readonly: "border-neutral-800",
743
+ activeInvalid: "border-error border-2",
744
+ activeValid: "border-success border-2",
745
+ active: "border-primary border-2",
746
+ invalid: "border-error",
747
+ valid: "border-success",
748
+ default: "border-neutral-800"
749
+ }[selectState],
750
+ this.open && (this.currentPlacement === "bottom" ? "rounded-bl-none rounded-br-none" : "rounded-tl-none rounded-tr-none")
751
+ )}"></div><sd-popup @sd-current-placement="${this.handleCurrentPlacement}" class="${cx(
752
+ "inline-flex relative w-full",
753
+ this.currentPlacement === "bottom" ? "origin-top" : "origin-bottom"
754
+ )}" placement="${this.placement}" strategy="${this.hoist ? "fixed" : "absolute"}" flip shift sync="width" auto-size="vertical" auto-size-padding="10" exportparts="
755
+ popup:popup__content,
756
+ "><div part="combobox" class="${cx(
757
+ "relative w-full px-4 flex flex-row items-center rounded-default",
758
+ this.open && "shadow",
759
+ {
760
+ sm: "py-1 min-h-[32px]",
761
+ md: "py-1 min-h-[40px]",
762
+ lg: "py-2 min-h-[48px]"
763
+ }[this.size]
764
+ )}" slot="anchor" @keydown="${this.handleComboboxKeyDown}" @mousedown="${this.handleComboboxMouseDown}" @mouseenter="${this.handleMouseEnter}" @mouseleave="${this.handleMouseLeave}">${slots["left"] ? html`<slot part="left" name="left" class="${cx("inline-flex", iconMarginRight, iconColor, iconSize)}"></slot>` : ""} ${this.multiple && this.useTags && this.tags.length > 0 ? html`<div part="tags" class="${cx("flex items-center gap-1", iconMarginRight)}">${this.tags}</div>` : null} <input id="display-input" name="${this.name}" form="${this.form}" part="display-input" class="${cx(
765
+ "appearance-none outline-none bg-transparent flex-auto min-w-0",
766
+ cursorStyles,
767
+ this.selectedTextLabel && !this.multiple ? "placeholder-black" : "placeholder-neutral-700"
768
+ )}" type="text" placeholder="${this.selectedTextLabel && !this.multiple ? this.selectedTextLabel : this.placeholder}" .disabled="${this.disabled}" .value="${this.displayInputValue}" autocomplete="off" spellcheck="false" autocapitalize="off" aria-controls="listbox" aria-expanded="${this.open}" aria-haspopup="listbox" aria-labelledby="label" aria-disabled="${this.disabled}" aria-describedby="help-text invalid-message" aria-invalid="${this.showInvalidStyle}" role="combobox" tabindex="0" @focus="${this.handleFocus}" @blur="${this.handleBlur}" aria-autocomplete="list" aria-owns="listbox" @input="${this.handleInput}" @change="${this.handleChange}"><div aria-live="polite" id="control-value" class="absolute top-0 left-0 opacity-0 -z-10">${this.selectedOptions.map((option) => option == null ? void 0 : option.getTextLabel()).join(", ")}</div><input class="${cx("value-input absolute top-0 left-0 w-full h-full opacity-0 -z-10", cursorStyles)}" type="text" ?disabled="${this.disabled}" ?required="${this.required}" .value="${Array.isArray(this.value) ? this.value.join(", ") : this.value}" tabindex="-1" aria-controls="control-value" aria-hidden="true" @focus="${() => this.focus()}" @invalid="${this.handleInvalid}"> ${hasClearIcon ? html`<button part="clear-button" class="${cx("flex justify-center", iconMarginLeft)}" type="button" aria-label="${this.localize.term("clearEntry")}" @mousedown="${this.preventLoosingFocus}" @click="${this.handleClearClick}" tabindex="-1"><slot name="clear-icon"><sd-icon class="${cx("text-icon-fill-neutral-800", iconSize)}" name="closing-round" library="system"></sd-icon></slot></button>` : ""} ${this.showInvalidStyle ? html`<sd-icon part="invalid-icon" class="${cx(iconMarginLeft, iconSize, "text-error")}" library="system" name="risk"></sd-icon>` : ""} ${this.styleOnValid && this.showValidStyle ? html`<sd-icon part="valid-icon" class="${cx("flex-shrink-0 text-success", iconMarginLeft, iconSize)}" library="system" name="status-check"></sd-icon>` : ""}<slot name="right" part="right" class="${cx(
769
+ "inline-flex ml-2 leading-[0]",
770
+ this.disabled ? "text-neutral-500" : "text-primary",
771
+ iconSize
772
+ )}"><sd-icon class="${cx("transition-all", this.open ? "rotate-180" : "rotate-0")}" name="chevron-down" part="chevron" library="system" color="currentColor"></sd-icon></slot></div><div id="listbox" role="listbox" aria-expanded="${this.open}" aria-multiselectable="${this.multiple}" aria-labelledby="label" part="listbox" class="${cx(
773
+ "bg-white px-2 py-3 relative border-primary overflow-y-auto",
774
+ this.open && "shadow",
775
+ this.currentPlacement === "bottom" ? "border-r-2 border-b-2 border-l-2 rounded-br-default rounded-bl-default" : "border-r-2 border-t-2 border-l-2 rounded-tr-default rounded-tl-default"
776
+ )}" tabindex="-1" @mousedown="${this.preventLoosingFocus}" @mouseup="${this.handleOptionClick}"><div part="filtered-listbox" class="overflow-y-scroll">${this.filteredOptions.length === 0 ? html`<span id="noResults" class="px-4 flex items-center w-full transition-all text-left text-base relative text-black py-3" aria-hidden="true" @click="${this.handleNoResultsClick}">${this.localize.term("noResults")}</span>` : this.options}</div><slot id="defaultOptionsSlot" class="hidden" @slotchange="${this.handleDefaultSlotChange}"></slot></div></sd-popup></div><div part="form-control-help-text" id="help-text" class="text-sm text-neutral-700" aria-hidden="${!hasHelpText}"><slot name="help-text">${this.helpText}</slot></div></div>${this.formControlController.renderInvalidMessage()}`;
777
+ }
778
+ /* eslint-enable @typescript-eslint/unbound-method */
779
+ };
780
+ SdCombobox.dependencies = {
781
+ "sd-icon": SdIcon,
782
+ "sd-popup": SdPopup,
783
+ "sd-tag": SdTag
784
+ };
785
+ SdCombobox.styles = [
786
+ componentStyles,
787
+ SolidElement.styles,
788
+ css`:host{position:relative;display:block;width:100%}:host([required]) #label::after{content:' *'}[part=listbox]{max-height:var(--auto-size-available-height,auto)}sd-popup::part(popup){z-index:var(--sd-z-index-dropdown,900)}sd-tag::part(base){border-radius:var(--sd-border-radius-default,.25rem);padding-left:var(--sd-spacing-1,.25rem);padding-right:var(--sd-spacing-1,.25rem)}sd-tag::part(content){max-width:var(--tag-max-width,15ch);overflow:hidden;white-space:nowrap;display:inline-block;text-overflow:ellipsis}sd-tag[size=lg]::part(base){padding-left:var(--sd-spacing-2,.5rem);padding-right:var(--sd-spacing-2,.5rem)}sd-tag[disabled=false]::part(base):hover{--tw-bg-opacity:1;background-color:rgb(var(--sd-color-primary-100,236 240 249) / var(--tw-bg-opacity))}[part=filtered-listbox] sd-optgroup:first-of-type{--display-divider:none}mark{background-color:transparent;font-weight:700;color:inherit}`
789
+ ];
790
+ __decorateClass([
791
+ query("sd-popup")
792
+ ], SdCombobox.prototype, "popup", 2);
793
+ __decorateClass([
794
+ query('[part="combobox"]')
795
+ ], SdCombobox.prototype, "combobox", 2);
796
+ __decorateClass([
797
+ query('[part="display-input"]')
798
+ ], SdCombobox.prototype, "displayInput", 2);
799
+ __decorateClass([
800
+ query(".value-input")
801
+ ], SdCombobox.prototype, "valueInput", 2);
802
+ __decorateClass([
803
+ query('[part="listbox"]')
804
+ ], SdCombobox.prototype, "listbox", 2);
805
+ __decorateClass([
806
+ query('[part="tags"]')
807
+ ], SdCombobox.prototype, "tagWrapper", 2);
808
+ __decorateClass([
809
+ query('[part="filtered-listbox"]')
810
+ ], SdCombobox.prototype, "filteredWrapper", 2);
811
+ __decorateClass([
812
+ query("slot:not([name])")
813
+ ], SdCombobox.prototype, "defaultSlot", 2);
814
+ __decorateClass([
815
+ query("#invalid-message")
816
+ ], SdCombobox.prototype, "invalidMessage", 2);
817
+ __decorateClass([
818
+ state()
819
+ ], SdCombobox.prototype, "hasHover", 2);
820
+ __decorateClass([
821
+ state()
822
+ ], SdCombobox.prototype, "hasFocus", 2);
823
+ __decorateClass([
824
+ state()
825
+ ], SdCombobox.prototype, "displayInputValue", 2);
826
+ __decorateClass([
827
+ state()
828
+ ], SdCombobox.prototype, "selectedTextLabel", 2);
829
+ __decorateClass([
830
+ state()
831
+ ], SdCombobox.prototype, "selectedOptions", 2);
832
+ __decorateClass([
833
+ state()
834
+ ], SdCombobox.prototype, "filteredOptions", 2);
835
+ __decorateClass([
836
+ state()
837
+ ], SdCombobox.prototype, "allOptions", 2);
838
+ __decorateClass([
839
+ state()
840
+ ], SdCombobox.prototype, "lastOption", 2);
841
+ __decorateClass([
842
+ state()
843
+ ], SdCombobox.prototype, "showValidStyle", 2);
844
+ __decorateClass([
845
+ state()
846
+ ], SdCombobox.prototype, "showInvalidStyle", 2);
847
+ __decorateClass([
848
+ property()
849
+ ], SdCombobox.prototype, "name", 2);
850
+ __decorateClass([
851
+ property({
852
+ converter: {
853
+ fromAttribute: (value) => value.split(" "),
854
+ toAttribute: (value) => value.join(" ")
855
+ }
856
+ })
857
+ ], SdCombobox.prototype, "value", 2);
858
+ __decorateClass([
859
+ defaultValue()
860
+ ], SdCombobox.prototype, "defaultValue", 2);
861
+ __decorateClass([
862
+ property({ reflect: true })
863
+ ], SdCombobox.prototype, "size", 2);
864
+ __decorateClass([
865
+ property()
866
+ ], SdCombobox.prototype, "placeholder", 2);
867
+ __decorateClass([
868
+ property({ reflect: true, type: Boolean })
869
+ ], SdCombobox.prototype, "disabled", 2);
870
+ __decorateClass([
871
+ property({ type: Boolean })
872
+ ], SdCombobox.prototype, "clearable", 2);
873
+ __decorateClass([
874
+ property({ reflect: true, type: Boolean })
875
+ ], SdCombobox.prototype, "open", 2);
876
+ __decorateClass([
877
+ property({ type: Boolean })
878
+ ], SdCombobox.prototype, "hoist", 2);
879
+ __decorateClass([
880
+ property()
881
+ ], SdCombobox.prototype, "label", 2);
882
+ __decorateClass([
883
+ property({ reflect: true })
884
+ ], SdCombobox.prototype, "placement", 2);
885
+ __decorateClass([
886
+ property({ attribute: "help-text" })
887
+ ], SdCombobox.prototype, "helpText", 2);
888
+ __decorateClass([
889
+ property({ reflect: true })
890
+ ], SdCombobox.prototype, "form", 2);
891
+ __decorateClass([
892
+ property({ reflect: true, type: Boolean })
893
+ ], SdCombobox.prototype, "required", 2);
894
+ __decorateClass([
895
+ state()
896
+ ], SdCombobox.prototype, "currentPlacement", 2);
897
+ __decorateClass([
898
+ property()
899
+ ], SdCombobox.prototype, "getOption", 2);
900
+ __decorateClass([
901
+ property({ type: Boolean, reflect: true })
902
+ ], SdCombobox.prototype, "multiple", 2);
903
+ __decorateClass([
904
+ property({ type: Boolean, reflect: true })
905
+ ], SdCombobox.prototype, "useTags", 2);
906
+ __decorateClass([
907
+ property({ attribute: "max-options-visible", type: Number })
908
+ ], SdCombobox.prototype, "maxOptionsVisible", 2);
909
+ __decorateClass([
910
+ property({ type: Boolean, reflect: true, attribute: "style-on-valid" })
911
+ ], SdCombobox.prototype, "styleOnValid", 2);
912
+ __decorateClass([
913
+ property()
914
+ ], SdCombobox.prototype, "filter", 2);
915
+ __decorateClass([
916
+ property()
917
+ ], SdCombobox.prototype, "getTag", 2);
918
+ __decorateClass([
919
+ watch("filter", { waitUntilFirstUpdate: true })
920
+ ], SdCombobox.prototype, "handleFilterChange", 1);
921
+ __decorateClass([
922
+ watch("useTags", { waitUntilFirstUpdate: true })
923
+ ], SdCombobox.prototype, "handleUseTagsChange", 1);
924
+ __decorateClass([
925
+ watch("size", { waitUntilFirstUpdate: true })
926
+ ], SdCombobox.prototype, "applySizeToOptions", 1);
927
+ __decorateClass([
928
+ watch("disabled", { waitUntilFirstUpdate: true })
929
+ ], SdCombobox.prototype, "handleDisabledChange", 1);
930
+ __decorateClass([
931
+ watch("value", { waitUntilFirstUpdate: true })
932
+ ], SdCombobox.prototype, "handleValueChange", 1);
933
+ __decorateClass([
934
+ watch("displayInputValue", { waitUntilFirstUpdate: true })
935
+ ], SdCombobox.prototype, "handleDisplayInputValueChange", 1);
936
+ __decorateClass([
937
+ watch("open", { waitUntilFirstUpdate: true })
938
+ ], SdCombobox.prototype, "handleOpenChange", 1);
939
+ SdCombobox = __decorateClass([
940
+ customElement("sd-combobox")
941
+ ], SdCombobox);
942
+ setDefaultAnimation("combobox.show", {
943
+ keyframes: [
944
+ { opacity: 0, scale: 0.9 },
945
+ { opacity: 1, scale: 1 }
946
+ ],
947
+ options: { duration: 100, easing: "ease" }
948
+ });
949
+ setDefaultAnimation("combobox.hide", {
950
+ keyframes: [
951
+ { opacity: 1, scale: 1 },
952
+ { opacity: 0, scale: 0.9 }
953
+ ],
954
+ options: { duration: 100, easing: "ease" }
955
+ });
956
+ export {
957
+ SdCombobox as default
958
+ };