svelte-select-5 6.0.0

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 (123) hide show
  1. package/.claude/settings.local.json +20 -0
  2. package/.prettierignore +2 -0
  3. package/.prettierrc +17 -0
  4. package/CHANGELOG.md +571 -0
  5. package/LICENSE +9 -0
  6. package/MIGRATION_GUIDE.md +98 -0
  7. package/README.md +316 -0
  8. package/docs/generate_theming_variables_md.cjs +53 -0
  9. package/docs/theming_variables.md +113 -0
  10. package/jsconfig.json +3 -0
  11. package/package.json +77 -0
  12. package/rollup.config.js +33 -0
  13. package/src/app.html +29 -0
  14. package/src/global.d.ts +1 -0
  15. package/src/lib/ChevronIcon.svelte +22 -0
  16. package/src/lib/ClearIcon.svelte +22 -0
  17. package/src/lib/LoadingIcon.svelte +33 -0
  18. package/src/lib/Select.svelte +1345 -0
  19. package/src/lib/filter.js +38 -0
  20. package/src/lib/get-items.js +25 -0
  21. package/src/lib/index.js +1 -0
  22. package/src/lib/tailwind.css +130 -0
  23. package/src/post-prepare.cjs +6 -0
  24. package/src/remove-styles.cjs +22 -0
  25. package/src/routes/+layout.js +1 -0
  26. package/src/routes/+layout.svelte +263 -0
  27. package/src/routes/+page.js +5 -0
  28. package/src/routes/+page.svelte +0 -0
  29. package/src/routes/examples/+page.svelte +84 -0
  30. package/src/routes/examples/advanced/create-item/+page.svelte +36 -0
  31. package/src/routes/examples/advanced/create-item-multiple/+page.svelte +38 -0
  32. package/src/routes/examples/advanced/floating-ui/+page.svelte +22 -0
  33. package/src/routes/examples/advanced/form-action/+page.server.js +10 -0
  34. package/src/routes/examples/advanced/form-action/+page.svelte +20 -0
  35. package/src/routes/examples/advanced/limit-multi-value/+page.svelte +31 -0
  36. package/src/routes/examples/advanced/long-item/+page.svelte +38 -0
  37. package/src/routes/examples/advanced/multi-item-checkboxes/+page.svelte +49 -0
  38. package/src/routes/examples/advanced/style-props/+page.svelte +14 -0
  39. package/src/routes/examples/advanced/virtual-list/+page.svelte +95 -0
  40. package/src/routes/examples/events/blur/+page.svelte +19 -0
  41. package/src/routes/examples/events/change/+page.svelte +16 -0
  42. package/src/routes/examples/events/clear/+page.svelte +18 -0
  43. package/src/routes/examples/events/error/+page.svelte +17 -0
  44. package/src/routes/examples/events/filter/+page.svelte +16 -0
  45. package/src/routes/examples/events/focus/+page.svelte +16 -0
  46. package/src/routes/examples/events/hoverItem/+page.svelte +16 -0
  47. package/src/routes/examples/events/input/+page.svelte +16 -0
  48. package/src/routes/examples/events/loaded/+page.svelte +23 -0
  49. package/src/routes/examples/props/class/+page.svelte +17 -0
  50. package/src/routes/examples/props/clearFilterTextOnBlur/+page.svelte +13 -0
  51. package/src/routes/examples/props/clearable/+page.svelte +13 -0
  52. package/src/routes/examples/props/closeListOnChange/+page.svelte +12 -0
  53. package/src/routes/examples/props/container-styles/+page.svelte +11 -0
  54. package/src/routes/examples/props/debounce-wait/+page.svelte +19 -0
  55. package/src/routes/examples/props/disabled/+page.svelte +15 -0
  56. package/src/routes/examples/props/filter-text/+page.svelte +14 -0
  57. package/src/routes/examples/props/floating-config/+page.svelte +42 -0
  58. package/src/routes/examples/props/focused/+page.svelte +16 -0
  59. package/src/routes/examples/props/group-header-selectable/+page.svelte +18 -0
  60. package/src/routes/examples/props/hide-empty-state/+page.svelte +8 -0
  61. package/src/routes/examples/props/id/+page.svelte +15 -0
  62. package/src/routes/examples/props/input-attributes/+page.svelte +11 -0
  63. package/src/routes/examples/props/item-id/+page.svelte +15 -0
  64. package/src/routes/examples/props/items/+page.svelte +15 -0
  65. package/src/routes/examples/props/just-value/+page.svelte +16 -0
  66. package/src/routes/examples/props/label/+page.svelte +15 -0
  67. package/src/routes/examples/props/list-auto-width/+page.svelte +21 -0
  68. package/src/routes/examples/props/list-offset/+page.svelte +21 -0
  69. package/src/routes/examples/props/list-open/+page.svelte +31 -0
  70. package/src/routes/examples/props/loadOptions/+page.svelte +16 -0
  71. package/src/routes/examples/props/loading/+page.svelte +15 -0
  72. package/src/routes/examples/props/multiFullItemClearable/+page.svelte +12 -0
  73. package/src/routes/examples/props/multiple/+page.svelte +12 -0
  74. package/src/routes/examples/props/name/+page.svelte +13 -0
  75. package/src/routes/examples/props/placeholder/+page.svelte +14 -0
  76. package/src/routes/examples/props/placeholder-always-show/+page.svelte +11 -0
  77. package/src/routes/examples/props/required/+page.svelte +14 -0
  78. package/src/routes/examples/props/searchable/+page.svelte +15 -0
  79. package/src/routes/examples/props/show-chevron/+page.svelte +15 -0
  80. package/src/routes/examples/props/value/+page.svelte +19 -0
  81. package/src/routes/examples/slots/chevron-icon/+page.svelte +16 -0
  82. package/src/routes/examples/slots/clear-icon/+page.svelte +21 -0
  83. package/src/routes/examples/slots/empty/+page.svelte +18 -0
  84. package/src/routes/examples/slots/input-hidden/+page.server.js +10 -0
  85. package/src/routes/examples/slots/input-hidden/+page.svelte +22 -0
  86. package/src/routes/examples/slots/item/+page.svelte +15 -0
  87. package/src/routes/examples/slots/list/+page.svelte +49 -0
  88. package/src/routes/examples/slots/list-append/+page.svelte +16 -0
  89. package/src/routes/examples/slots/list-prepend/+page.svelte +16 -0
  90. package/src/routes/examples/slots/loading-icon/+page.svelte +29 -0
  91. package/src/routes/examples/slots/multi-clear-icon/+page.svelte +16 -0
  92. package/src/routes/examples/slots/prepend/+page.svelte +22 -0
  93. package/src/routes/examples/slots/required/+page.svelte +31 -0
  94. package/src/routes/examples/slots/selection/+page.svelte +25 -0
  95. package/static/nav-icon.svg +2 -0
  96. package/static/svelte-select.png +0 -0
  97. package/svelte-select.png +0 -0
  98. package/svelte.config.js +10 -0
  99. package/tailwind.config.cjs +4 -0
  100. package/test/public/favicon.ico +0 -0
  101. package/test/public/index.html +15 -0
  102. package/test/src/ChevronSlotTest.svelte +19 -0
  103. package/test/src/ClearIconSlotTest.svelte +12 -0
  104. package/test/src/CustomItem.svelte +78 -0
  105. package/test/src/GroupHeaderNotSelectable.svelte +17 -0
  106. package/test/src/HoverItemIndexTest.svelte +21 -0
  107. package/test/src/InputHiddenSlotTest.svelte +12 -0
  108. package/test/src/ItemHeightTest.svelte +7 -0
  109. package/test/src/ItemSlotTest.svelte +11 -0
  110. package/test/src/ListSlotTest.svelte +14 -0
  111. package/test/src/LoadOptionsGroup.svelte +21 -0
  112. package/test/src/MultiItemColor.svelte +7 -0
  113. package/test/src/OuterListTest.svelte +16 -0
  114. package/test/src/PrependSlotTest.svelte +12 -0
  115. package/test/src/Select/ParentContainer.svelte +11 -0
  116. package/test/src/SelectionSlotMultipleTest.svelte +12 -0
  117. package/test/src/SelectionSlotTest.svelte +12 -0
  118. package/test/src/TestClearIcon.svelte +1 -0
  119. package/test/src/TestIcon.svelte +15 -0
  120. package/test/src/env.js +1 -0
  121. package/test/src/test-utils.js +124 -0
  122. package/test/src/tests.js +3745 -0
  123. package/vite.config.js +9 -0
@@ -0,0 +1,1345 @@
1
+ <script>
2
+ import { onDestroy, onMount } from 'svelte';
3
+ import { offset, flip, shift } from 'svelte-floating-ui/dom';
4
+ import { createFloatingActions } from 'svelte-floating-ui';
5
+
6
+ import _filter from './filter';
7
+ import _getItems from './get-items';
8
+
9
+ import ChevronIcon from './ChevronIcon.svelte';
10
+ import ClearIcon from './ClearIcon.svelte';
11
+ import LoadingIcon from './LoadingIcon.svelte';
12
+
13
+ // Props with $props() rune
14
+ let {
15
+ // Bindable props (two-way binding)
16
+ justValue = $bindable(null),
17
+ container = $bindable(undefined),
18
+ input = $bindable(undefined),
19
+ focused = $bindable(false),
20
+ value = $bindable(null),
21
+ filterText = $bindable(''),
22
+ items = $bindable(null),
23
+ loading = $bindable(false),
24
+ listOpen = $bindable(false),
25
+ hoverItemIndex = $bindable(0),
26
+
27
+ // Function props
28
+ filter = _filter,
29
+ getItems = _getItems,
30
+
31
+ // Regular props
32
+ id = null,
33
+ name = null,
34
+ multiple = false,
35
+ multiFullItemClearable = false,
36
+ disabled = false,
37
+ placeholder = 'Please select',
38
+ placeholderAlwaysShow = false,
39
+ label = 'label',
40
+ itemFilter = (labelValue, filterTextValue, option) => `${labelValue}`.toLowerCase().includes(filterTextValue.toLowerCase()),
41
+ groupBy = undefined,
42
+ groupFilter = (groups) => groups,
43
+ groupHeaderSelectable = false,
44
+ itemId = 'value',
45
+ loadOptions = undefined,
46
+ containerStyles = '',
47
+ hasError = false,
48
+ filterSelectedItems = true,
49
+ required = false,
50
+ closeListOnChange = true,
51
+ clearFilterTextOnBlur = true,
52
+ createGroupHeaderItem = (groupValue, item) => {
53
+ return {
54
+ value: groupValue,
55
+ [label]: groupValue,
56
+ };
57
+ },
58
+ searchable = true,
59
+ inputStyles = '',
60
+ clearable = true,
61
+ debounce = (fn, wait = 1) => {
62
+ clearTimeout(timeout);
63
+ timeout = setTimeout(fn, wait);
64
+ },
65
+ debounceWait = 300,
66
+ hideEmptyState = false,
67
+ inputAttributes = {},
68
+ listAutoWidth = true,
69
+ showChevron = false,
70
+ listOffset = 5,
71
+ floatingConfig = {},
72
+ class: containerClasses = '',
73
+
74
+ // Aria props
75
+ ariaValues = (values) => {
76
+ return `Option ${values}, selected.`;
77
+ },
78
+ ariaListOpen = (labelValue, count) => {
79
+ return `You are currently focused on option ${labelValue}. There are ${count} results available.`;
80
+ },
81
+ ariaFocused = () => {
82
+ return `Select is focused, type to refine list, press down to open the menu.`;
83
+ },
84
+
85
+ // Event callback props (replacing createEventDispatcher)
86
+ onchange = undefined,
87
+ oninput = undefined,
88
+ onselect = undefined,
89
+ onclear = undefined,
90
+ onfocus = undefined,
91
+ onblur = undefined,
92
+ onfilter = undefined,
93
+ onerror = undefined,
94
+ onloaded = undefined,
95
+ onhoverItem = undefined,
96
+
97
+ // Snippet props (replacing slots) - using camelCase for Svelte 5 compatibility
98
+ item: itemSnippet = undefined,
99
+ selection: selectionSnippet = undefined,
100
+ empty: emptySnippet = undefined,
101
+ prepend: prependSnippet = undefined,
102
+ listPrepend: listPrependSnippet = undefined,
103
+ listAppend: listAppendSnippet = undefined,
104
+ list: listSnippet = undefined,
105
+ clearIcon: clearIconSnippet = undefined,
106
+ multiClearIcon: multiClearIconSnippet = undefined,
107
+ loadingIcon: loadingIconSnippet = undefined,
108
+ chevronIcon: chevronIconSnippet = undefined,
109
+ inputHidden: inputHiddenSnippet = undefined,
110
+ requiredSlot: requiredSlotSnippet = undefined,
111
+ } = $props();
112
+
113
+ // Internal state
114
+ let timeout;
115
+ let activeValue = $state(undefined);
116
+ let prev_value = $state(undefined);
117
+ let prev_filterText = $state(undefined);
118
+ let prev_multiple = $state(undefined);
119
+ let list = $state(null);
120
+ let isScrolling = $state(false);
121
+ let prefloat = $state(true);
122
+ let _inputAttributes = $state({});
123
+ let isScrollingTimer;
124
+
125
+ // Floating UI config - using closure for listOffset to capture current value
126
+ let _floatingConfig = {
127
+ strategy: 'absolute',
128
+ placement: 'bottom-start',
129
+ middleware: [offset(() => listOffset), flip(), shift()],
130
+ autoUpdate: false,
131
+ };
132
+
133
+ const [floatingRef, floatingContent, floatingUpdate] = createFloatingActions(_floatingConfig);
134
+
135
+ // Exported functions
136
+ export function getFilteredItems() {
137
+ return filteredItems;
138
+ }
139
+
140
+ export function handleClear() {
141
+ onclear?.(value);
142
+ value = undefined;
143
+ closeList();
144
+ handleFocus();
145
+ }
146
+
147
+ // Helper functions
148
+ function setValue() {
149
+ if (typeof value === 'string') {
150
+ let item = (items || []).find((item) => item[itemId] === value);
151
+ value = item || {
152
+ [itemId]: value,
153
+ label: value,
154
+ };
155
+ } else if (multiple && Array.isArray(value) && value.length > 0) {
156
+ value = value.map((item) => (typeof item === 'string' ? { value: item, label: item } : item));
157
+ }
158
+ }
159
+
160
+ function assignInputAttributes() {
161
+ _inputAttributes = Object.assign(
162
+ {
163
+ autocapitalize: 'none',
164
+ autocomplete: 'off',
165
+ autocorrect: 'off',
166
+ spellcheck: false,
167
+ tabindex: 0,
168
+ type: 'text',
169
+ 'aria-autocomplete': 'list',
170
+ },
171
+ inputAttributes
172
+ );
173
+
174
+ if (id) {
175
+ _inputAttributes['id'] = id;
176
+ }
177
+
178
+ if (!searchable) {
179
+ _inputAttributes['readonly'] = true;
180
+ }
181
+ }
182
+
183
+ function convertStringItemsToObjects(_items) {
184
+ return _items.map((item, index) => {
185
+ return {
186
+ index,
187
+ value: item,
188
+ label: `${item}`,
189
+ };
190
+ });
191
+ }
192
+
193
+ function filterGroupedItems(_items) {
194
+ const groupValues = [];
195
+ const groups = {};
196
+
197
+ _items.forEach((item) => {
198
+ const groupValue = groupBy(item);
199
+
200
+ if (!groupValues.includes(groupValue)) {
201
+ groupValues.push(groupValue);
202
+ groups[groupValue] = [];
203
+
204
+ if (groupValue) {
205
+ groups[groupValue].push(
206
+ Object.assign(createGroupHeaderItem(groupValue, item), {
207
+ id: groupValue,
208
+ groupHeader: true,
209
+ selectable: groupHeaderSelectable,
210
+ })
211
+ );
212
+ }
213
+ }
214
+
215
+ groups[groupValue].push(Object.assign({ groupItem: !!groupValue }, item));
216
+ });
217
+
218
+ const sortedGroupedItems = [];
219
+
220
+ groupFilter(groupValues).forEach((groupValue) => {
221
+ if (groups[groupValue]) sortedGroupedItems.push(...groups[groupValue]);
222
+ });
223
+
224
+ return sortedGroupedItems;
225
+ }
226
+
227
+ function dispatchSelectedItem() {
228
+ if (multiple) {
229
+ if (JSON.stringify(value) !== JSON.stringify(prev_value)) {
230
+ if (checkValueForDuplicates()) {
231
+ oninput?.(value);
232
+ }
233
+ }
234
+ return;
235
+ }
236
+
237
+ if (!prev_value || JSON.stringify(value[itemId]) !== JSON.stringify(prev_value[itemId])) {
238
+ oninput?.(value);
239
+ }
240
+ }
241
+
242
+ function setupMulti() {
243
+ if (value) {
244
+ if (Array.isArray(value)) {
245
+ value = [...value];
246
+ } else {
247
+ value = [value];
248
+ }
249
+ }
250
+ }
251
+
252
+ function setupSingle() {
253
+ if (value) value = null;
254
+ }
255
+
256
+ function setValueIndexAsHoverIndex() {
257
+ const valueIndex = filteredItems.findIndex((i) => {
258
+ return i[itemId] === value[itemId];
259
+ });
260
+
261
+ checkHoverSelectable(valueIndex, true);
262
+ }
263
+
264
+ function dispatchHover(i) {
265
+ onhoverItem?.(i);
266
+ }
267
+
268
+ function checkHoverSelectable(startingIndex = 0, ignoreGroup) {
269
+ hoverItemIndex = startingIndex < 0 ? 0 : startingIndex;
270
+ if (!ignoreGroup && groupBy && filteredItems[hoverItemIndex] && !filteredItems[hoverItemIndex].selectable) {
271
+ setHoverIndex(1);
272
+ }
273
+ }
274
+
275
+ function setupFilterText() {
276
+ if (!loadOptions && filterText.length === 0) return;
277
+
278
+ if (loadOptions) {
279
+ debounce(async function () {
280
+ loading = true;
281
+ let res = await getItems({
282
+ dispatch: (event, data) => {
283
+ if (event === 'error') onerror?.(data);
284
+ if (event === 'loaded') onloaded?.(data);
285
+ },
286
+ loadOptions,
287
+ convertStringItemsToObjects,
288
+ filterText,
289
+ });
290
+
291
+ if (res) {
292
+ loading = res.loading;
293
+ listOpen = listOpen ? res.listOpen : filterText.length > 0 ? true : false;
294
+ focused = listOpen && res.focused;
295
+ items = groupBy ? filterGroupedItems(res.filteredItems) : res.filteredItems;
296
+ } else {
297
+ loading = false;
298
+ focused = true;
299
+ listOpen = true;
300
+ }
301
+ }, debounceWait);
302
+ } else {
303
+ listOpen = true;
304
+
305
+ if (multiple) {
306
+ activeValue = undefined;
307
+ }
308
+ }
309
+ }
310
+
311
+ function computeJustValue() {
312
+ if (multiple) return value ? value.map((item) => item[itemId]) : null;
313
+ return value ? value[itemId] : value;
314
+ }
315
+
316
+ function checkValueForDuplicates() {
317
+ let noDuplicates = true;
318
+ if (value) {
319
+ const ids = [];
320
+ const uniqueValues = [];
321
+
322
+ value.forEach((val) => {
323
+ if (!ids.includes(val[itemId])) {
324
+ ids.push(val[itemId]);
325
+ uniqueValues.push(val);
326
+ } else {
327
+ noDuplicates = false;
328
+ }
329
+ });
330
+
331
+ if (!noDuplicates) value = uniqueValues;
332
+ }
333
+ return noDuplicates;
334
+ }
335
+
336
+ function findItem(selection) {
337
+ let matchTo = selection ? selection[itemId] : value[itemId];
338
+ return items.find((item) => item[itemId] === matchTo);
339
+ }
340
+
341
+ function updateValueDisplay(items) {
342
+ if (!items || items.length === 0 || items.some((item) => typeof item !== 'object')) return;
343
+ if (!value || (multiple ? value.some((selection) => !selection || !selection[itemId]) : !value[itemId])) return;
344
+
345
+ if (Array.isArray(value)) {
346
+ value = value.map((selection) => findItem(selection) || selection);
347
+ } else {
348
+ value = findItem() || value;
349
+ }
350
+ }
351
+
352
+ async function handleMultiItemClear(i) {
353
+ const itemToRemove = value[i];
354
+
355
+ if (value.length === 1) {
356
+ value = undefined;
357
+ } else {
358
+ value = value.filter((item) => {
359
+ return item !== itemToRemove;
360
+ });
361
+ }
362
+
363
+ onclear?.(itemToRemove);
364
+ }
365
+
366
+ function handleKeyDown(e) {
367
+ if (!focused) return;
368
+ e.stopPropagation();
369
+ switch (e.key) {
370
+ case 'Escape':
371
+ e.preventDefault();
372
+ closeList();
373
+ break;
374
+ case 'Enter':
375
+ e.preventDefault();
376
+
377
+ if (listOpen) {
378
+ if (filteredItems.length === 0) break;
379
+ const hoverItem = filteredItems[hoverItemIndex];
380
+
381
+ if (value && !multiple && value[itemId] === hoverItem[itemId]) {
382
+ closeList();
383
+ break;
384
+ } else {
385
+ handleSelect(filteredItems[hoverItemIndex]);
386
+ }
387
+ }
388
+
389
+ break;
390
+ case 'ArrowDown':
391
+ e.preventDefault();
392
+
393
+ if (listOpen) {
394
+ setHoverIndex(1);
395
+ } else {
396
+ listOpen = true;
397
+ activeValue = undefined;
398
+ }
399
+
400
+ break;
401
+ case 'ArrowUp':
402
+ e.preventDefault();
403
+
404
+ if (listOpen) {
405
+ setHoverIndex(-1);
406
+ } else {
407
+ listOpen = true;
408
+ activeValue = undefined;
409
+ }
410
+
411
+ break;
412
+ case 'Tab':
413
+ if (listOpen && focused) {
414
+ if (
415
+ filteredItems.length === 0 ||
416
+ (value && value[itemId] === filteredItems[hoverItemIndex][itemId])
417
+ )
418
+ return closeList();
419
+
420
+ e.preventDefault();
421
+ handleSelect(filteredItems[hoverItemIndex]);
422
+ closeList();
423
+ }
424
+
425
+ break;
426
+ case 'Backspace':
427
+ if (!multiple || filterText.length > 0) return;
428
+
429
+ if (multiple && value && value.length > 0) {
430
+ handleMultiItemClear(activeValue !== undefined ? activeValue : value.length - 1);
431
+ if (activeValue === 0 || activeValue === undefined) break;
432
+ activeValue = value.length > activeValue ? activeValue - 1 : undefined;
433
+ }
434
+
435
+ break;
436
+ case 'ArrowLeft':
437
+ if (!value || !multiple || filterText.length > 0) return;
438
+ if (activeValue === undefined) {
439
+ activeValue = value.length - 1;
440
+ } else if (value.length > activeValue && activeValue !== 0) {
441
+ activeValue -= 1;
442
+ }
443
+ break;
444
+ case 'ArrowRight':
445
+ if (!value || !multiple || filterText.length > 0 || activeValue === undefined) return;
446
+ if (activeValue === value.length - 1) {
447
+ activeValue = undefined;
448
+ } else if (activeValue < value.length - 1) {
449
+ activeValue += 1;
450
+ }
451
+ break;
452
+ }
453
+ }
454
+
455
+ function handleFocus(e) {
456
+ if (focused && input === document?.activeElement) return;
457
+ if (e) onfocus?.(e);
458
+ input?.focus();
459
+ focused = true;
460
+ }
461
+
462
+ async function handleBlur(e) {
463
+ if (isScrolling) return;
464
+ if (listOpen || focused) {
465
+ onblur?.(e);
466
+ closeList();
467
+ focused = false;
468
+ activeValue = undefined;
469
+ input?.blur();
470
+ }
471
+ }
472
+
473
+ function handleClick() {
474
+ if (disabled) return;
475
+ if (filterText.length > 0) return listOpen = true;
476
+ listOpen = !listOpen;
477
+ }
478
+
479
+ function itemSelected(selection) {
480
+ if (selection) {
481
+ filterText = '';
482
+ const item = Object.assign({}, selection);
483
+
484
+ if (item.groupHeader && !item.selectable) return;
485
+ value = multiple ? (value ? value.concat([item]) : [item]) : (value = item);
486
+
487
+ setTimeout(() => {
488
+ if (closeListOnChange) closeList();
489
+ activeValue = undefined;
490
+ onchange?.(value);
491
+ onselect?.(selection);
492
+ });
493
+ }
494
+ }
495
+
496
+ function closeList() {
497
+ if (clearFilterTextOnBlur) {
498
+ filterText = '';
499
+ }
500
+ listOpen = false;
501
+ }
502
+
503
+ function handleAriaSelection(_multiple) {
504
+ let selected = undefined;
505
+
506
+ if (_multiple && value.length > 0) {
507
+ selected = value.map((v) => v[label]).join(', ');
508
+ } else {
509
+ selected = value[label];
510
+ }
511
+
512
+ return ariaValues(selected);
513
+ }
514
+
515
+ function handleAriaContent() {
516
+ if (!filteredItems || filteredItems.length === 0) return '';
517
+ let _item = filteredItems[hoverItemIndex];
518
+ if (listOpen && _item) {
519
+ let count = filteredItems ? filteredItems.length : 0;
520
+ return ariaListOpen(_item[label], count);
521
+ } else {
522
+ return ariaFocused();
523
+ }
524
+ }
525
+
526
+ function handleListScroll() {
527
+ clearTimeout(isScrollingTimer);
528
+ isScrollingTimer = setTimeout(() => {
529
+ isScrolling = false;
530
+ }, 100);
531
+ }
532
+
533
+ function handleClickOutside(event) {
534
+ if (!listOpen && !focused && container && !container.contains(event.target) && !list?.contains(event.target)) {
535
+ handleBlur();
536
+ }
537
+ }
538
+
539
+ function handleSelect(item) {
540
+ if (!item || item.selectable === false) return;
541
+ itemSelected(item);
542
+ }
543
+
544
+ function handleHover(i) {
545
+ if (isScrolling) return;
546
+ hoverItemIndex = i;
547
+ }
548
+
549
+ function handleItemClick(args) {
550
+ const { item, i } = args;
551
+ if (item?.selectable === false) return;
552
+ if (value && !multiple && value[itemId] === item[itemId]) return closeList();
553
+ if (isItemSelectable(item)) {
554
+ hoverItemIndex = i;
555
+ handleSelect(item);
556
+ }
557
+ }
558
+
559
+ function setHoverIndex(increment) {
560
+ let selectableFilteredItems = filteredItems.filter(
561
+ (item) => !Object.hasOwn(item, 'selectable') || item.selectable === true
562
+ );
563
+
564
+ if (selectableFilteredItems.length === 0) {
565
+ return (hoverItemIndex = 0);
566
+ }
567
+
568
+ if (increment > 0 && hoverItemIndex === filteredItems.length - 1) {
569
+ hoverItemIndex = 0;
570
+ } else if (increment < 0 && hoverItemIndex === 0) {
571
+ hoverItemIndex = filteredItems.length - 1;
572
+ } else {
573
+ hoverItemIndex = hoverItemIndex + increment;
574
+ }
575
+
576
+ const hover = filteredItems[hoverItemIndex];
577
+
578
+ if (hover && hover.selectable === false) {
579
+ if (increment === 1 || increment === -1) setHoverIndex(increment);
580
+ return;
581
+ }
582
+ }
583
+
584
+ function isItemActive(item, value, itemId) {
585
+ if (multiple) return;
586
+ return value && value[itemId] === item[itemId];
587
+ }
588
+
589
+ function isItemFirst(itemIndex) {
590
+ return itemIndex === 0;
591
+ }
592
+
593
+ function isItemSelectable(item) {
594
+ return (item.groupHeader && item.selectable) || item.selectable || !item.hasOwnProperty('selectable');
595
+ }
596
+
597
+ const activeScroll = scrollAction;
598
+ const hoverScroll = scrollAction;
599
+
600
+ function scrollAction(node) {
601
+ return {
602
+ update(args) {
603
+ if (args.scroll) {
604
+ handleListScroll();
605
+ node.scrollIntoView({ behavior: 'auto', block: 'nearest' });
606
+ }
607
+ },
608
+ };
609
+ }
610
+
611
+ function setListWidth() {
612
+ const { width } = container.getBoundingClientRect();
613
+ list.style.width = listAutoWidth ? width + 'px' : 'auto';
614
+ }
615
+
616
+ function listMounted(list, listOpen) {
617
+ if (!list || !listOpen) return (prefloat = true);
618
+ setTimeout(() => {
619
+ prefloat = false;
620
+ }, 0);
621
+ }
622
+
623
+ function handleFilterEvent(items) {
624
+ if (listOpen) onfilter?.(items);
625
+ }
626
+
627
+ // Derived values - order matters! filteredItems must come before ariaContext
628
+ let filteredItems = $derived(filter({
629
+ loadOptions,
630
+ filterText,
631
+ items,
632
+ multiple,
633
+ value,
634
+ itemId,
635
+ groupBy,
636
+ label,
637
+ filterSelectedItems,
638
+ itemFilter,
639
+ convertStringItemsToObjects,
640
+ filterGroupedItems,
641
+ }));
642
+ let hasValue = $derived(multiple ? value && value.length > 0 : value);
643
+ let hideSelectedItem = $derived(hasValue && filterText.length > 0);
644
+ let showClear = $derived(hasValue && clearable && !disabled && !loading);
645
+ let placeholderText = $derived(
646
+ placeholderAlwaysShow && multiple
647
+ ? placeholder
648
+ : multiple && value?.length === 0
649
+ ? placeholder
650
+ : value
651
+ ? ''
652
+ : placeholder
653
+ );
654
+ let ariaSelection = $derived(value ? handleAriaSelection(multiple) : '');
655
+ let ariaContext = $derived(handleAriaContent());
656
+ let listDom = $derived(!!list);
657
+ let scrollToHoverItem = $derived(hoverItemIndex);
658
+
659
+ // Effects (side effects replacing reactive statements)
660
+ $effect.pre(() => {
661
+ prev_value = value;
662
+ prev_filterText = filterText;
663
+ prev_multiple = multiple;
664
+ });
665
+
666
+ $effect(() => {
667
+ if (items !== undefined || value !== undefined) setValue();
668
+ });
669
+
670
+ $effect(() => {
671
+ if (inputAttributes || !searchable) assignInputAttributes();
672
+ });
673
+
674
+ $effect(() => {
675
+ if (multiple) setupMulti();
676
+ });
677
+
678
+ $effect(() => {
679
+ if (prev_multiple && !multiple) setupSingle();
680
+ });
681
+
682
+ $effect(() => {
683
+ if (multiple && value && value.length > 1) checkValueForDuplicates();
684
+ });
685
+
686
+ $effect(() => {
687
+ if (value) dispatchSelectedItem();
688
+ });
689
+
690
+ $effect(() => {
691
+ if (!value && multiple && prev_value) {
692
+ oninput?.(value);
693
+ }
694
+ });
695
+
696
+ $effect(() => {
697
+ if (!focused && input) closeList();
698
+ });
699
+
700
+ $effect(() => {
701
+ if (filterText !== prev_filterText) setupFilterText();
702
+ });
703
+
704
+ $effect(() => {
705
+ if (!multiple && listOpen && value && filteredItems) setValueIndexAsHoverIndex();
706
+ });
707
+
708
+ $effect(() => {
709
+ dispatchHover(hoverItemIndex);
710
+ });
711
+
712
+ $effect(() => {
713
+ updateValueDisplay(items);
714
+ });
715
+
716
+ $effect(() => {
717
+ justValue = computeJustValue();
718
+ });
719
+
720
+ $effect(() => {
721
+ if (!multiple && prev_value && !value) oninput?.(value);
722
+ });
723
+
724
+ $effect(() => {
725
+ if (listOpen && filteredItems && !multiple && !value) checkHoverSelectable();
726
+ });
727
+
728
+ $effect(() => {
729
+ handleFilterEvent(filteredItems);
730
+ });
731
+
732
+ $effect(() => {
733
+ if (container && floatingConfig) floatingUpdate(Object.assign(_floatingConfig, floatingConfig));
734
+ });
735
+
736
+ $effect(() => {
737
+ listMounted(list, listOpen);
738
+ });
739
+
740
+ $effect(() => {
741
+ if (listOpen && container && list) setListWidth();
742
+ });
743
+
744
+ $effect(() => {
745
+ if (listOpen && multiple) hoverItemIndex = 0;
746
+ });
747
+
748
+ $effect(() => {
749
+ if (input && listOpen && !focused) handleFocus();
750
+ });
751
+
752
+ $effect(() => {
753
+ if (filterText) hoverItemIndex = 0;
754
+ });
755
+
756
+ $effect(() => {
757
+ if (container && floatingConfig?.autoUpdate === undefined) {
758
+ _floatingConfig.autoUpdate = true;
759
+ }
760
+ });
761
+
762
+ // Lifecycle
763
+ onMount(() => {
764
+ if (listOpen) focused = true;
765
+ if (focused && input) input.focus();
766
+ });
767
+
768
+ onDestroy(() => {
769
+ list?.remove();
770
+ });
771
+ </script>
772
+
773
+ <svelte:window onclick={handleClickOutside} onkeydown={handleKeyDown} />
774
+
775
+ <div
776
+ class="svelte-select {containerClasses}"
777
+ class:multi={multiple}
778
+ class:disabled
779
+ class:focused
780
+ class:list-open={listOpen}
781
+ class:show-chevron={showChevron}
782
+ class:error={hasError}
783
+ style={containerStyles}
784
+ onpointerup={(e) => { e.preventDefault(); handleClick(); }}
785
+ bind:this={container}
786
+ use:floatingRef
787
+ role="none">
788
+ {#if listOpen}
789
+ <div
790
+ use:floatingContent
791
+ bind:this={list}
792
+ class="svelte-select-list"
793
+ class:prefloat
794
+ onscroll={handleListScroll}
795
+ onpointerup={(e) => { e.preventDefault(); e.stopPropagation(); }}
796
+ onmousedown={(e) => { e.preventDefault(); e.stopPropagation(); }}
797
+ role="none">
798
+ {#if listPrependSnippet}{@render listPrependSnippet()}{/if}
799
+ {#if listSnippet}
800
+ {@render listSnippet({ filteredItems })}
801
+ {:else if filteredItems.length > 0}
802
+ {#each filteredItems as item, i}
803
+ <div
804
+ onmouseover={() => handleHover(i)}
805
+ onfocus={() => handleHover(i)}
806
+ onclick={(e) => { e.stopPropagation(); handleItemClick({ item, i }); }}
807
+ onkeydown={(e) => { e.preventDefault(); e.stopPropagation(); }}
808
+ class="list-item"
809
+ tabindex="-1"
810
+ role="none">
811
+ <div
812
+ use:activeScroll={{ scroll: isItemActive(item, value, itemId), listDom }}
813
+ use:hoverScroll={{ scroll: scrollToHoverItem === i, listDom }}
814
+ class="item"
815
+ class:list-group-title={item.groupHeader}
816
+ class:active={isItemActive(item, value, itemId)}
817
+ class:first={isItemFirst(i)}
818
+ class:hover={hoverItemIndex === i}
819
+ class:group-item={item.groupItem}
820
+ class:not-selectable={item?.selectable === false}>
821
+ {#if itemSnippet}
822
+ {@render itemSnippet({ item, index: i })}
823
+ {:else}
824
+ {item?.[label]}
825
+ {/if}
826
+ </div>
827
+ </div>
828
+ {/each}
829
+ {:else if !hideEmptyState}
830
+ {#if emptySnippet}
831
+ {@render emptySnippet()}
832
+ {:else}
833
+ <div class="empty">No options</div>
834
+ {/if}
835
+ {/if}
836
+ {#if listAppendSnippet}{@render listAppendSnippet()}{/if}
837
+ </div>
838
+ {/if}
839
+
840
+ <span aria-live="polite" aria-atomic="false" aria-relevant="additions text" class="a11y-text">
841
+ {#if focused}
842
+ <span id="aria-selection">{ariaSelection}</span>
843
+ <span id="aria-context">
844
+ {ariaContext}
845
+ </span>
846
+ {/if}
847
+ </span>
848
+
849
+ <div class="prepend">
850
+ {#if prependSnippet}
851
+ {@render prependSnippet()}
852
+ {/if}
853
+ </div>
854
+
855
+ <div class="value-container">
856
+ {#if hasValue}
857
+ {#if multiple}
858
+ {#each value as item, i}
859
+ <div
860
+ class="multi-item"
861
+ class:active={activeValue === i}
862
+ class:disabled
863
+ onclick={(e) => { e.preventDefault(); if (multiFullItemClearable) handleMultiItemClear(i); }}
864
+ onkeydown={(e) => { e.preventDefault(); e.stopPropagation(); }}
865
+ role="none">
866
+ <span class="multi-item-text">
867
+ {#if selectionSnippet}
868
+ {@render selectionSnippet({ selection: item, index: i })}
869
+ {:else}
870
+ {item[label]}
871
+ {/if}
872
+ </span>
873
+
874
+ {#if !disabled && !multiFullItemClearable && ClearIcon}
875
+ <div
876
+ class="multi-item-clear"
877
+ onpointerup={(e) => { e.preventDefault(); e.stopPropagation(); handleMultiItemClear(i); }}>
878
+ {#if multiClearIconSnippet}
879
+ {@render multiClearIconSnippet()}
880
+ {:else}
881
+ <ClearIcon />
882
+ {/if}
883
+ </div>
884
+ {/if}
885
+ </div>
886
+ {/each}
887
+ {:else}
888
+ <div class="selected-item" class:hide-selected-item={hideSelectedItem}>
889
+ {#if selectionSnippet}
890
+ {@render selectionSnippet({ selection: value })}
891
+ {:else}
892
+ {value[label]}
893
+ {/if}
894
+ </div>
895
+ {/if}
896
+ {/if}
897
+
898
+ <input
899
+ onkeydown={handleKeyDown}
900
+ onblur={handleBlur}
901
+ onfocus={handleFocus}
902
+ readonly={!searchable}
903
+ {..._inputAttributes}
904
+ bind:this={input}
905
+ bind:value={filterText}
906
+ placeholder={placeholderText}
907
+ style={inputStyles}
908
+ {disabled} />
909
+ </div>
910
+
911
+ <div class="indicators">
912
+ {#if loading}
913
+ <div class="icon loading" aria-hidden="true">
914
+ {#if loadingIconSnippet}
915
+ {@render loadingIconSnippet()}
916
+ {:else}
917
+ <LoadingIcon />
918
+ {/if}
919
+ </div>
920
+ {/if}
921
+
922
+ {#if showClear}
923
+ <button type="button" class="icon clear-select" onclick={handleClear}>
924
+ {#if clearIconSnippet}
925
+ {@render clearIconSnippet()}
926
+ {:else}
927
+ <ClearIcon />
928
+ {/if}
929
+ </button>
930
+ {/if}
931
+
932
+ {#if showChevron}
933
+ <div class="icon chevron" aria-hidden="true">
934
+ {#if chevronIconSnippet}
935
+ {@render chevronIconSnippet({ listOpen })}
936
+ {:else}
937
+ <ChevronIcon />
938
+ {/if}
939
+ </div>
940
+ {/if}
941
+ </div>
942
+
943
+ {#if inputHiddenSnippet}
944
+ {@render inputHiddenSnippet({ value })}
945
+ {:else}
946
+ <input {name} type="hidden" value={value ? JSON.stringify(value) : null} />
947
+ {/if}
948
+
949
+ {#if required && (!value || value.length === 0)}
950
+ {#if requiredSlotSnippet}
951
+ {@render requiredSlotSnippet({ value })}
952
+ {:else}
953
+ <select class="required" required tabindex="-1" aria-hidden="true"></select>
954
+ {/if}
955
+ {/if}
956
+ </div>
957
+
958
+ <style>
959
+ .svelte-select {
960
+ /* deprecating camelCase custom props in favour of kebab-case for v5 */
961
+ --borderRadius: var(--border-radius);
962
+ --clearSelectColor: var(--clear-select-color);
963
+ --clearSelectWidth: var(--clear-select-width);
964
+ --disabledBackground: var(--disabled-background);
965
+ --disabledBorderColor: var(--disabled-border-color);
966
+ --disabledColor: var(--disabled-color);
967
+ --disabledPlaceholderColor: var(--disabled-placeholder-color);
968
+ --disabledPlaceholderOpacity: var(--disabled-placeholder-opacity);
969
+ --errorBackground: var(--error-background);
970
+ --errorBorder: var(--error-border);
971
+ --groupItemPaddingLeft: var(--group-item-padding-left);
972
+ --groupTitleColor: var(--group-title-color);
973
+ --groupTitleFontSize: var(--group-title-font-size);
974
+ --groupTitleFontWeight: var(--group-title-font-weight);
975
+ --groupTitlePadding: var(--group-title-padding);
976
+ --groupTitleTextTransform: var(--group-title-text-transform);
977
+ --groupTitleBorderColor: var(--group-title-border-color);
978
+ --groupTitleBorderWidth: var(--group-title-border-width);
979
+ --groupTitleBorderStyle: var(--group-title-border-style);
980
+ --indicatorColor: var(--chevron-color);
981
+ --indicatorHeight: var(--chevron-height);
982
+ --indicatorWidth: var(--chevron-width);
983
+ --inputColor: var(--input-color);
984
+ --inputLeft: var(--input-left);
985
+ --inputLetterSpacing: var(--input-letter-spacing);
986
+ --inputMargin: var(--input-margin);
987
+ --inputPadding: var(--input-padding);
988
+ --itemActiveBackground: var(--item-active-background);
989
+ --itemColor: var(--item-color);
990
+ --itemFirstBorderRadius: var(--item-first-border-radius);
991
+ --itemHoverBG: var(--item-hover-bg);
992
+ --itemHoverColor: var(--item-hover-color);
993
+ --itemIsActiveBG: var(--item-is-active-bg);
994
+ --itemIsActiveColor: var(--item-is-active-color);
995
+ --itemIsNotSelectableColor: var(--item-is-not-selectable-color);
996
+ --itemPadding: var(--item-padding);
997
+ --listBackground: var(--list-background);
998
+ --listBorder: var(--list-border);
999
+ --listBorderRadius: var(--list-border-radius);
1000
+ --listEmptyColor: var(--list-empty-color);
1001
+ --listEmptyPadding: var(--list-empty-padding);
1002
+ --listEmptyTextAlign: var(--list-empty-text-align);
1003
+ --listMaxHeight: var(--list-max-height);
1004
+ --listPosition: var(--list-position);
1005
+ --listShadow: var(--list-shadow);
1006
+ --listZIndex: var(--list-z-index);
1007
+ --multiItemBG: var(--multi-item-bg);
1008
+ --multiItemBorderRadius: var(--multi-item-border-radius);
1009
+ --multiItemDisabledHoverBg: var(--multi-item-disabled-hover-bg);
1010
+ --multiItemDisabledHoverColor: var(--multi-item-disabled-hover-color);
1011
+ --multiItemHeight: var(--multi-item-height);
1012
+ --multiItemMargin: var(--multi-item-margin);
1013
+ --multiItemPadding: var(--multi-item-padding);
1014
+ --multiSelectInputMargin: var(--multi-select-input-margin);
1015
+ --multiSelectInputPadding: var(--multi-select-input-padding);
1016
+ --multiSelectPadding: var(--multi-select-padding);
1017
+ --placeholderColor: var(--placeholder-color);
1018
+ --placeholderOpacity: var(--placeholder-opacity);
1019
+ --selectedItemPadding: var(--selected-item-padding);
1020
+ --spinnerColor: var(--spinner-color);
1021
+ --spinnerHeight: var(--spinner-height);
1022
+ --spinnerWidth: var(--spinner-width);
1023
+
1024
+ --internal-padding: 0 0 0 16px;
1025
+
1026
+ border: var(--border, 1px solid #d8dbdf);
1027
+ border-radius: var(--border-radius, 6px);
1028
+ min-height: var(--height, 42px);
1029
+ position: relative;
1030
+ display: flex;
1031
+ align-items: stretch;
1032
+ padding: var(--padding, var(--internal-padding));
1033
+ background: var(--background, #fff);
1034
+ margin: var(--margin, 0);
1035
+ width: var(--width, 100%);
1036
+ font-size: var(--font-size, 16px);
1037
+ max-height: var(--max-height);
1038
+ }
1039
+
1040
+ * {
1041
+ box-sizing: var(--box-sizing, border-box);
1042
+ }
1043
+
1044
+ .svelte-select:hover {
1045
+ border: var(--border-hover, 1px solid #b2b8bf);
1046
+ }
1047
+
1048
+ .value-container {
1049
+ display: flex;
1050
+ flex: 1 1 0%;
1051
+ flex-wrap: wrap;
1052
+ align-items: center;
1053
+ gap: 5px 10px;
1054
+ padding: var(--value-container-padding, 5px 0);
1055
+ position: relative;
1056
+ overflow: var(--value-container-overflow, hidden);
1057
+ align-self: stretch;
1058
+ }
1059
+
1060
+ .prepend,
1061
+ .indicators {
1062
+ display: flex;
1063
+ flex-shrink: 0;
1064
+ align-items: center;
1065
+ }
1066
+
1067
+ .indicators {
1068
+ position: var(--indicators-position);
1069
+ top: var(--indicators-top);
1070
+ right: var(--indicators-right);
1071
+ bottom: var(--indicators-bottom);
1072
+ }
1073
+
1074
+ input {
1075
+ position: absolute;
1076
+ cursor: default;
1077
+ border: none;
1078
+ color: var(--input-color, var(--item-color));
1079
+ padding: var(--input-padding, 0);
1080
+ letter-spacing: var(--input-letter-spacing, inherit);
1081
+ margin: var(--input-margin, 0);
1082
+ min-width: 10px;
1083
+ top: 0;
1084
+ right: 0;
1085
+ bottom: 0;
1086
+ left: 0;
1087
+ background: transparent;
1088
+ font-size: var(--font-size, 16px);
1089
+ }
1090
+
1091
+ :not(.multi) > .value-container > input {
1092
+ width: 100%;
1093
+ height: 100%;
1094
+ }
1095
+
1096
+ input::placeholder {
1097
+ color: var(--placeholder-color, #78848f);
1098
+ opacity: var(--placeholder-opacity, 1);
1099
+ }
1100
+
1101
+ input:focus {
1102
+ outline: none;
1103
+ }
1104
+
1105
+ .svelte-select.focused {
1106
+ border: var(--border-focused, 1px solid #006fe8);
1107
+ border-radius: var(--border-radius-focused, var(--border-radius, 6px));
1108
+ }
1109
+
1110
+ .disabled {
1111
+ background: var(--disabled-background, #ebedef);
1112
+ border-color: var(--disabled-border-color, #ebedef);
1113
+ color: var(--disabled-color, #c1c6cc);
1114
+ }
1115
+
1116
+ .disabled input::placeholder {
1117
+ color: var(--disabled-placeholder-color, #c1c6cc);
1118
+ opacity: var(--disabled-placeholder-opacity, 1);
1119
+ }
1120
+
1121
+ .selected-item {
1122
+ position: relative;
1123
+ overflow: var(--selected-item-overflow, hidden);
1124
+ padding: var(--selected-item-padding, 0 20px 0 0);
1125
+ text-overflow: ellipsis;
1126
+ white-space: nowrap;
1127
+ color: var(--selected-item-color, inherit);
1128
+ font-size: var(--font-size, 16px);
1129
+ }
1130
+
1131
+ .multi .selected-item {
1132
+ position: absolute;
1133
+ line-height: var(--height, 42px);
1134
+ height: var(--height, 42px);
1135
+ }
1136
+
1137
+ .selected-item:focus {
1138
+ outline: none;
1139
+ }
1140
+
1141
+ .hide-selected-item {
1142
+ opacity: 0;
1143
+ }
1144
+
1145
+ .icon {
1146
+ display: flex;
1147
+ align-items: center;
1148
+ justify-content: center;
1149
+ }
1150
+
1151
+ .clear-select {
1152
+ all: unset;
1153
+ display: flex;
1154
+ align-items: center;
1155
+ justify-content: center;
1156
+ width: var(--clear-select-width, 40px);
1157
+ height: var(--clear-select-height, 100%);
1158
+ color: var(--clear-select-color, var(--icons-color));
1159
+ margin: var(--clear-select-margin, 0);
1160
+ pointer-events: all;
1161
+ flex-shrink: 0;
1162
+ }
1163
+
1164
+ .clear-select:focus {
1165
+ outline: var(--clear-select-focus-outline, 1px solid #006fe8);
1166
+ }
1167
+
1168
+ .loading {
1169
+ width: var(--loading-width, 40px);
1170
+ height: var(--loading-height);
1171
+ color: var(--loading-color, var(--icons-color));
1172
+ margin: var(--loading--margin, 0);
1173
+ flex-shrink: 0;
1174
+ }
1175
+
1176
+ .chevron {
1177
+ width: var(--chevron-width, 40px);
1178
+ height: var(--chevron-height, 40px);
1179
+ background: var(--chevron-background, transparent);
1180
+ pointer-events: var(--chevron-pointer-events, none);
1181
+ color: var(--chevron-color, var(--icons-color));
1182
+ border: var(--chevron-border, 0 0 0 1px solid #d8dbdf);
1183
+ flex-shrink: 0;
1184
+ }
1185
+
1186
+ .multi {
1187
+ padding: var(--multi-select-padding, var(--internal-padding));
1188
+ }
1189
+
1190
+ .multi input {
1191
+ padding: var(--multi-select-input-padding, 0);
1192
+ position: relative;
1193
+ margin: var(--multi-select-input-margin, 5px 0);
1194
+ flex: 1 1 40px;
1195
+ }
1196
+
1197
+ .svelte-select.error {
1198
+ border: var(--error-border, 1px solid #ff2d55);
1199
+ background: var(--error-background, #fff);
1200
+ }
1201
+
1202
+ .a11y-text {
1203
+ z-index: 9999;
1204
+ border: 0px;
1205
+ clip: rect(1px, 1px, 1px, 1px);
1206
+ height: 1px;
1207
+ width: 1px;
1208
+ position: absolute;
1209
+ overflow: hidden;
1210
+ padding: 0px;
1211
+ white-space: nowrap;
1212
+ }
1213
+
1214
+ .multi-item {
1215
+ background: var(--multi-item-bg, #ebedef);
1216
+ margin: var(--multi-item-margin, 0);
1217
+ outline: var(--multi-item-outline, 1px solid #ddd);
1218
+ border-radius: var(--multi-item-border-radius, 4px);
1219
+ height: var(--multi-item-height, 25px);
1220
+ line-height: var(--multi-item-height, 25px);
1221
+ display: flex;
1222
+ cursor: default;
1223
+ padding: var(--multi-item-padding, 0 5px);
1224
+ overflow: hidden;
1225
+ gap: var(--multi-item-gap, 4px);
1226
+ outline-offset: -1px;
1227
+ max-width: var(--multi-max-width, none);
1228
+ color: var(--multi-item-color, var(--item-color));
1229
+ }
1230
+
1231
+ .multi-item.disabled:hover {
1232
+ background: var(--multi-item-disabled-hover-bg, #ebedef);
1233
+ color: var(--multi-item-disabled-hover-color, #c1c6cc);
1234
+ }
1235
+
1236
+ .multi-item-text {
1237
+ overflow: hidden;
1238
+ text-overflow: ellipsis;
1239
+ white-space: nowrap;
1240
+ }
1241
+
1242
+ .multi-item-clear {
1243
+ display: flex;
1244
+ align-items: center;
1245
+ justify-content: center;
1246
+ --clear-icon-color: var(--multi-item-clear-icon-color, #000);
1247
+ }
1248
+
1249
+ .multi-item.active {
1250
+ outline: var(--multi-item-active-outline, 1px solid #006fe8);
1251
+ }
1252
+
1253
+ .svelte-select-list {
1254
+ box-shadow: var(--list-shadow, 0 2px 3px 0 rgba(44, 62, 80, 0.24));
1255
+ border-radius: var(--list-border-radius, 4px);
1256
+ max-height: var(--list-max-height, 252px);
1257
+ overflow-y: auto;
1258
+ background: var(--list-background, #fff);
1259
+ position: var(--list-position, absolute);
1260
+ z-index: var(--list-z-index, 2);
1261
+ border: var(--list-border);
1262
+ }
1263
+
1264
+ .prefloat {
1265
+ opacity: 0;
1266
+ pointer-events: none;
1267
+ }
1268
+
1269
+ .list-group-title {
1270
+ color: var(--group-title-color, #8f8f8f);
1271
+ cursor: default;
1272
+ font-size: var(--group-title-font-size, 16px);
1273
+ font-weight: var(--group-title-font-weight, 600);
1274
+ height: var(--height, 42px);
1275
+ line-height: var(--height, 42px);
1276
+ padding: var(--group-title-padding, 0 20px);
1277
+ text-overflow: ellipsis;
1278
+ overflow-x: hidden;
1279
+ white-space: nowrap;
1280
+ text-transform: var(--group-title-text-transform, uppercase);
1281
+ border-width: var(--group-title-border-width, medium);
1282
+ border-style: var(--group-title-border-style, none);
1283
+ border-color: var(--group-title-border-color, color);
1284
+ }
1285
+
1286
+ .empty {
1287
+ text-align: var(--list-empty-text-align, center);
1288
+ padding: var(--list-empty-padding, 20px 0);
1289
+ color: var(--list-empty-color, #78848f);
1290
+ }
1291
+
1292
+ .item {
1293
+ cursor: default;
1294
+ height: var(--item-height, var(--height, 42px));
1295
+ line-height: var(--item-line-height, var(--height, 42px));
1296
+ padding: var(--item-padding, 0 20px);
1297
+ color: var(--item-color, inherit);
1298
+ text-overflow: ellipsis;
1299
+ overflow: hidden;
1300
+ white-space: nowrap;
1301
+ transition: var(--item-transition, all 0.2s);
1302
+ align-items: center;
1303
+ width: 100%;
1304
+ }
1305
+
1306
+ .item.group-item {
1307
+ padding-left: var(--group-item-padding-left, 40px);
1308
+ }
1309
+
1310
+ .item:active {
1311
+ background: var(--item-active-background, #b9daff);
1312
+ }
1313
+
1314
+ .item.active {
1315
+ background: var(--item-is-active-bg, #007aff);
1316
+ color: var(--item-is-active-color, #fff);
1317
+ }
1318
+
1319
+ .item.first {
1320
+ border-radius: var(--item-first-border-radius, 4px 4px 0 0);
1321
+ }
1322
+
1323
+ .item.hover:not(.active) {
1324
+ background: var(--item-hover-bg, #e7f2ff);
1325
+ color: var(--item-hover-color, inherit);
1326
+ }
1327
+
1328
+ .item.not-selectable,
1329
+ .item.hover.item.not-selectable,
1330
+ .item.active.item.not-selectable,
1331
+ .item.not-selectable:active {
1332
+ color: var(--item-is-not-selectable-color, #999);
1333
+ background: transparent;
1334
+ }
1335
+
1336
+ .required {
1337
+ opacity: 0;
1338
+ z-index: -1;
1339
+ position: absolute;
1340
+ top: 0;
1341
+ left: 0;
1342
+ bottom: 0;
1343
+ right: 0;
1344
+ }
1345
+ </style>