@vonage/vivid 4.5.0 → 4.6.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 (170) hide show
  1. package/custom-elements.json +1091 -187
  2. package/elevation/index.cjs +1 -1
  3. package/elevation/index.js +1 -1
  4. package/index.cjs +62 -56
  5. package/index.js +20 -19
  6. package/lib/components.d.ts +1 -0
  7. package/lib/menu/menu.d.ts +2 -1
  8. package/lib/number-field/number-field.d.ts +3 -1
  9. package/lib/searchable-select/definition.d.ts +4 -0
  10. package/lib/searchable-select/locale.d.ts +6 -0
  11. package/lib/searchable-select/option-tag.d.ts +14 -0
  12. package/lib/searchable-select/option-tag.template.d.ts +4 -0
  13. package/lib/searchable-select/searchable-select.d.ts +29 -0
  14. package/lib/searchable-select/searchable-select.form-associated.d.ts +10 -0
  15. package/lib/searchable-select/searchable-select.template.d.ts +4 -0
  16. package/lib/select/select.d.ts +3 -1
  17. package/lib/tab/locale.d.ts +3 -0
  18. package/lib/tab/tab.d.ts +5 -1
  19. package/lib/tag/definition.d.ts +1 -0
  20. package/lib/text-field/text-field.d.ts +3 -1
  21. package/locales/de-DE.cjs +12 -0
  22. package/locales/de-DE.js +12 -0
  23. package/locales/en-GB.cjs +12 -0
  24. package/locales/en-GB.js +12 -0
  25. package/locales/en-US.cjs +12 -0
  26. package/locales/en-US.js +12 -0
  27. package/locales/ja-JP.cjs +12 -0
  28. package/locales/ja-JP.js +12 -0
  29. package/locales/zh-CN.cjs +12 -0
  30. package/locales/zh-CN.js +12 -0
  31. package/package.json +1 -1
  32. package/popup/index.cjs +1 -1
  33. package/popup/index.js +1 -1
  34. package/searchable-select/index.cjs +5 -0
  35. package/searchable-select/index.js +3 -0
  36. package/select/index.cjs +1 -1
  37. package/select/index.js +1 -1
  38. package/selectable-box/index.cjs +1 -1
  39. package/selectable-box/index.js +1 -1
  40. package/shared/definition11.cjs +1 -1
  41. package/shared/definition11.js +1 -1
  42. package/shared/definition14.cjs +1 -1
  43. package/shared/definition14.js +1 -1
  44. package/shared/definition16.cjs +1 -1
  45. package/shared/definition16.js +1 -1
  46. package/shared/definition18.cjs +2 -2
  47. package/shared/definition18.js +2 -2
  48. package/shared/definition19.cjs +2 -2
  49. package/shared/definition19.js +2 -2
  50. package/shared/definition20.cjs +14 -34
  51. package/shared/definition20.js +14 -34
  52. package/shared/definition21.cjs +1 -1
  53. package/shared/definition21.js +1 -1
  54. package/shared/definition26.cjs +1 -1
  55. package/shared/definition26.js +1 -1
  56. package/shared/definition29.cjs +4 -0
  57. package/shared/definition29.js +4 -0
  58. package/shared/definition30.cjs +2 -1
  59. package/shared/definition30.js +2 -1
  60. package/shared/definition35.cjs +12 -7
  61. package/shared/definition35.js +12 -7
  62. package/shared/definition36.cjs +50 -207
  63. package/shared/definition36.js +51 -207
  64. package/shared/definition4.cjs +1 -1
  65. package/shared/definition4.js +1 -1
  66. package/shared/definition42.cjs +1 -1
  67. package/shared/definition42.js +1 -1
  68. package/shared/definition43.cjs +993 -645
  69. package/shared/definition43.js +989 -642
  70. package/shared/definition44.cjs +723 -112
  71. package/shared/definition44.js +722 -111
  72. package/shared/definition45.cjs +121 -80
  73. package/shared/definition45.js +119 -78
  74. package/shared/definition46.cjs +81 -614
  75. package/shared/definition46.js +80 -612
  76. package/shared/definition47.cjs +608 -114
  77. package/shared/definition47.js +606 -113
  78. package/shared/definition48.cjs +116 -134
  79. package/shared/definition48.js +115 -133
  80. package/shared/definition49.cjs +149 -19
  81. package/shared/definition49.js +148 -18
  82. package/shared/definition5.cjs +1 -1
  83. package/shared/definition5.js +1 -1
  84. package/shared/definition50.cjs +21 -82
  85. package/shared/definition50.js +20 -81
  86. package/shared/definition51.cjs +77 -539
  87. package/shared/definition51.js +76 -538
  88. package/shared/definition52.cjs +568 -28
  89. package/shared/definition52.js +567 -27
  90. package/shared/definition53.cjs +28 -123
  91. package/shared/definition53.js +26 -122
  92. package/shared/definition54.cjs +115 -295
  93. package/shared/definition54.js +114 -294
  94. package/shared/definition55.cjs +251 -311
  95. package/shared/definition55.js +251 -311
  96. package/shared/definition56.cjs +299 -780
  97. package/shared/definition56.js +298 -779
  98. package/shared/definition57.cjs +800 -102
  99. package/shared/definition57.js +799 -101
  100. package/shared/definition58.cjs +92 -63
  101. package/shared/definition58.js +91 -62
  102. package/shared/definition59.cjs +117 -75
  103. package/shared/definition59.js +116 -74
  104. package/shared/definition60.cjs +70 -285
  105. package/shared/definition60.js +71 -286
  106. package/shared/definition61.cjs +274 -66146
  107. package/shared/definition61.js +273 -66145
  108. package/shared/definition62.cjs +66160 -27
  109. package/shared/definition62.js +66158 -25
  110. package/shared/definition63.cjs +24 -1952
  111. package/shared/definition63.js +23 -1950
  112. package/shared/definition64.cjs +1976 -0
  113. package/shared/definition64.js +1971 -0
  114. package/shared/listbox-option.cjs +204 -0
  115. package/shared/listbox-option.js +201 -0
  116. package/shared/listbox.cjs +3 -3
  117. package/shared/listbox.js +1 -1
  118. package/shared/localization/Locale.d.ts +4 -0
  119. package/shared/presentationDate.cjs +2 -2
  120. package/shared/presentationDate.js +2 -2
  121. package/shared/scrollIntoView.cjs +51 -0
  122. package/shared/scrollIntoView.js +49 -0
  123. package/shared/slider.template.cjs +1 -1
  124. package/shared/slider.template.js +1 -1
  125. package/shared/text-field.cjs +1 -1
  126. package/shared/text-field.js +1 -1
  127. package/shared/utils/scrollIntoView.d.ts +1 -0
  128. package/side-drawer/index.cjs +1 -1
  129. package/side-drawer/index.js +1 -1
  130. package/slider/index.cjs +1 -1
  131. package/slider/index.js +1 -1
  132. package/split-button/index.cjs +1 -1
  133. package/split-button/index.js +1 -1
  134. package/styles/core/all.css +1 -1
  135. package/styles/core/theme.css +1 -1
  136. package/styles/core/typography.css +1 -1
  137. package/styles/tokens/theme-dark.css +4 -4
  138. package/styles/tokens/theme-light.css +4 -4
  139. package/styles/tokens/vivid-2-compat.css +1 -1
  140. package/switch/index.cjs +1 -1
  141. package/switch/index.js +1 -1
  142. package/tab/index.cjs +1 -1
  143. package/tab/index.js +1 -1
  144. package/tab-panel/index.cjs +1 -1
  145. package/tab-panel/index.js +1 -1
  146. package/tabs/index.cjs +1 -1
  147. package/tabs/index.js +1 -1
  148. package/tag/index.cjs +1 -1
  149. package/tag/index.js +1 -1
  150. package/tag-group/index.cjs +1 -1
  151. package/tag-group/index.js +1 -1
  152. package/text-area/index.cjs +1 -1
  153. package/text-area/index.js +1 -1
  154. package/text-field/index.cjs +1 -1
  155. package/text-field/index.js +1 -1
  156. package/time-picker/index.cjs +1 -1
  157. package/time-picker/index.js +1 -1
  158. package/toggletip/index.cjs +1 -1
  159. package/toggletip/index.js +1 -1
  160. package/tooltip/index.cjs +1 -1
  161. package/tooltip/index.js +1 -1
  162. package/tree-item/index.cjs +1 -1
  163. package/tree-item/index.js +1 -1
  164. package/tree-view/index.cjs +1 -1
  165. package/tree-view/index.js +1 -1
  166. package/video-player/index.cjs +1 -1
  167. package/video-player/index.js +1 -1
  168. package/vivid.api.json +295 -0
  169. package/api-extractor.json +0 -25
  170. package/tsdoc-metadata.json +0 -11
@@ -1,753 +1,1100 @@
1
- import { D as DOM, O as Observable, _ as __decorate, a as attr, v as volatile, o as observable, h as html, r as registerFactory } from './index.js';
2
- import { P as Popup, p as popupRegistries } from './definition63.js';
1
+ import { F as FoundationElement, O as Observable, D as DOM, a as attr, n as nullableNumberConverter, o as observable, h as html, r as registerFactory } from './index.js';
2
+ import { c as chevronTemplateFactory, a as buttonRegistries } from './definition11.js';
3
+ import { P as Popup, p as popupRegistries } from './definition64.js';
3
4
  import { a as iconRegistries } from './definition27.js';
4
- import { L as ListboxOption, a as listboxOptionRegistries } from './definition36.js';
5
- import { L as ListboxElement, b as Listbox, D as DelegatesARIAListbox, a as Listbox$1 } from './listbox.js';
6
5
  import { a as applyMixinsWithObservables } from './applyMixinsWithObservables.js';
7
- import { S as StartEnd } from './start-end.js';
8
- import { a as applyMixins } from './apply-mixins.js';
6
+ import { s as scrollIntoView } from './scrollIntoView.js';
9
7
  import { F as FormAssociated } from './form-associated.js';
10
- import { S as SelectPosition } from './select.options.js';
11
- import { u as uniqueId } from './strings.js';
12
- import { c as keyTab, b as keyEscape, k as keyEnter, d as keyEnd, g as keyHome, a as keySpace, f as keyArrowDown, e as keyArrowUp } from './key-codes.js';
13
8
  import { b as AffixIconWithTrailing, a as affixIconTemplateFactory, I as IconWrapper } from './affix.js';
14
9
  import { e as errorText, f as formElements, F as FormElementSuccessText, a as FormElementHelperText, g as getFeedbackTemplate } from './form-elements.js';
15
- import { c as chevronTemplateFactory } from './definition11.js';
16
- import { h as handleEscapeKeyAndStopPropogation } from './index2.js';
17
- import { r as ref } from './ref.js';
10
+ import { L as Localized } from './localized.js';
11
+ import { a as Listbox } from './listbox.js';
12
+ import { a as applyMixins } from './apply-mixins.js';
18
13
  import { w as when } from './when.js';
14
+ import { r as ref } from './ref.js';
19
15
  import { s as slotted } from './slotted.js';
16
+ import { B as Button$1 } from './button.js';
17
+ import { r as repeat } from './repeat.js';
20
18
  import { c as classNames } from './class-names.js';
19
+ import { I as Icon } from './icon.js';
20
+
21
+ const styles = ".chevron{display:flex;flex-shrink:0;font:var(--vvd-typography-base-extended);transform:rotate(0);transition:transform .2s}:host([aria-expanded=true]) .chevron,:host([open]) .chevron{transform:rotate(180deg)}:host(:focus-visible){outline:none}:host{display:inline-block;inline-size:300px;--_low-ink-color: var(--vvd-color-neutral-600)}:host([disabled]){--_low-ink-color: var(--vvd-color-neutral-400);cursor:not-allowed}.control-wrapper{display:flex;flex-direction:column;gap:4px}.label{color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base)}.fieldset{--_connotation-color-primary: var(--vvd-searchable-select-accent-primary, var(--vvd-color-canvas-text));--_connotation-color-primary-text: var(--vvd-searchable-select-accent-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-searchable-select-accent-primary-increment, var(--vvd-color-neutral-800));--_connotation-color-intermediate: var(--vvd-searchable-select-accent-intermediate, var(--vvd-color-neutral-500));--_connotation-color-faint: var(--vvd-searchable-select-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-soft: var(--vvd-searchable-select-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-firm: var(--vvd-searchable-select-accent-firm, var(--vvd-color-canvas-text));--_connotation-color-fierce: var(--vvd-searchable-select-accent-fierce, var(--vvd-color-neutral-700))}.fieldset{--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--_connotation-color-intermediate)}.fieldset.appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.fieldset:where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--_connotation-color-fierce)}.fieldset:where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-faint);--_appearance-color-outline: transparent}.fieldset:where(.disabled,:disabled){--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: var(--vvd-color-neutral-100);--_appearance-color-outline: var(--vvd-color-neutral-300)}.fieldset:where(.disabled,:disabled).appearance-ghost{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.fieldset:where(.readonly):where(:not(.disabled,:disabled)){--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-neutral-200);--_appearance-color-outline: var(--vvd-color-neutral-400)}.fieldset:where(.readonly):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: var(--vvd-color-neutral-600);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.fieldset:where(.error):where(:not(.disabled,:disabled)){--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-alert-50);--_appearance-color-outline: var(--vvd-color-alert-500)}.fieldset:where(.error):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-alert-50);--_appearance-color-outline: transparent}.fieldset:where(.success):where(:not(.disabled,:disabled)){--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-success-50);--_appearance-color-outline: var(--vvd-color-success-500)}.fieldset:where(.success):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-success-50);--_appearance-color-outline: transparent}.fieldset{display:flex;align-items:center;justify-content:space-between;background-color:var(--_appearance-color-fill);box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);color:var(--_appearance-color-text);font:var(--vvd-typography-base);gap:8px;padding-block:8px;padding-inline:16px;transition:box-shadow .2s,background-color .2s}.fieldset:focus-within{box-shadow:inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:2px solid var(--focus-stroke-color, var(--vvd-color-canvas-text));outline-offset:calc(-2px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}:host(:not([shape=pill])) .fieldset{border-radius:8px}:host([shape=pill]) .fieldset{border-radius:24px}.popup-wrapper{position:relative}.content-area{display:flex;overflow:hidden;flex:1;flex-direction:column;gap:8px;min-block-size:24px}.tag-row{display:flex;gap:8px;inline-size:100%}.tag-row.contains-only-input:not(:focus-within){display:contents}.tag-wrapper{overflow:hidden}.tag{max-inline-size:100%}input{box-sizing:border-box;flex:1;border:none;background:none;block-size:24px;font:var(--vvd-typography-base);max-inline-size:100%;min-inline-size:100px;outline:none}.contains-only-input input:not(:focus){position:absolute;block-size:0;inline-size:0;min-inline-size:0;opacity:0;pointer-events:none}.listbox{display:flex;flex-direction:column;padding:4px;gap:2px;max-block-size:var(--searchable-select-height, 408px);overflow-y:auto}.empty-message{display:flex;align-items:center;justify-content:center;color:var(--vvd-color-neutral-300);min-block-size:40px;text-align:center}::part(popup-base){inline-size:max-content;min-inline-size:100%}slot[name=icon]{font-size:20px}";
22
+
23
+ const optionTagStyles = ".base{--_connotation-color-contrast: var(--vvd-option-tag-accent-contrast, var(--vvd-color-neutral-800));--_connotation-color-soft: var(--vvd-option-tag-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-pale: var(--vvd-option-tag-accent-pale, var(--vvd-color-neutral-300));--_connotation-color-fierce: var(--vvd-option-tag-accent-fierce, var(--vvd-color-neutral-700));--_connotation-color-firm-all: var(--vvd-option-tag-accent-firm-all, var(--vvd-color-neutral-600));--_connotation-color-faint: var(--vvd-option-tag-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-dim: var(--vvd-option-tag-accent-dim, var(--vvd-color-neutral-200))}.base{--_appearance-color-text: var(--_connotation-color-contrast);--_appearance-color-fill: var(--_connotation-color-soft);--_appearance-color-outline: transparent}.base:where(.disabled,:disabled){--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: var(--vvd-color-neutral-100);--_appearance-color-outline: transparent}.base{position:relative;display:inline-flex;box-sizing:border-box;align-items:center;background-color:var(--_appearance-color-fill);block-size:calc(1px*(24 + 4*clamp(-1,var(--vvd-size-density, 0),2)));box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);color:var(--_appearance-color-text);column-gap:8px;font:var(--vvd-typography-base-bold);max-inline-size:100%;padding-inline:8px;user-select:none;vertical-align:middle}.base:not(.shape-pill){border-radius:4px}.base.shape-pill{border-radius:16px}.label{overflow:hidden;max-inline-size:100%;text-overflow:ellipsis;white-space:nowrap}slot[name=icon]{font-size:calc(calc(1px*(24 + 4*clamp(-1,var(--vvd-size-density, 0),2))) / 1.5);line-height:1}.icon-placeholder{inline-size:calc(calc(1px*(24 + 4*clamp(-1,var(--vvd-size-density, 0),2))) / 1.5)}.remove-button{display:flex;align-items:center;border-radius:inherit;cursor:pointer;outline:none}.disabled .remove-button{pointer-events:none}.remove-button:focus-visible:before{--focus-stroke-gap-color: transparent;box-shadow:inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:2px solid var(--focus-stroke-color, var(--vvd-color-canvas-text));outline-offset:calc(-2px - var(--focus-inset, 0px));position:absolute;z-index:1;display:block;border-radius:inherit;content:\"\";inset:0;pointer-events:none}";
21
24
 
22
- class _Select extends ListboxElement {
25
+ class _SearchableSelect extends FoundationElement {
23
26
  }
24
- /**
25
- * A form-associated base class for the {@link @microsoft/fast-foundation#(Select:class)} component.
26
- *
27
- * @internal
28
- */
29
- class FormAssociatedSelect extends FormAssociated(_Select) {
30
- constructor() {
31
- super(...arguments);
32
- this.proxy = document.createElement("select");
33
- }
27
+ class FormAssociatedSearchableSelect extends FormAssociated(
28
+ _SearchableSelect
29
+ ) {
30
+ constructor() {
31
+ super(...arguments);
32
+ this.proxy = document.createElement("input");
33
+ }
34
34
  }
35
35
 
36
- /**
37
- * A Select Custom HTML Element.
38
- * Implements the {@link https://www.w3.org/TR/wai-aria-1.1/#select | ARIA select }.
39
- *
40
- * @slot start - Content which can be provided before the button content
41
- * @slot end - Content which can be provided after the button content
42
- * @slot button-container - The element representing the select button
43
- * @slot selected-value - The selected value
44
- * @slot indicator - The visual indicator for the expand/collapse state of the button
45
- * @slot - The default slot for slotted options
46
- * @csspart control - The element representing the select invoking element
47
- * @csspart selected-value - The element wrapping the selected value
48
- * @csspart indicator - The element wrapping the visual indicator
49
- * @csspart listbox - The listbox element
50
- * @fires input - Fires a custom 'input' event when the value updates
51
- * @fires change - Fires a custom 'change' event when the value updates
52
- *
53
- * @public
54
- */
55
- let Select$1 = class Select extends FormAssociatedSelect {
56
- constructor() {
57
- super(...arguments);
58
- /**
59
- * The open attribute.
60
- *
61
- * @public
62
- * @remarks
63
- * HTML Attribute: open
64
- */
65
- this.open = false;
66
- /**
67
- * Indicates the initial state of the position attribute.
68
- *
69
- * @internal
70
- */
71
- this.forcedPosition = false;
72
- /**
73
- * The unique id for the internal listbox element.
74
- *
75
- * @internal
76
- */
77
- this.listboxId = uniqueId("listbox-");
78
- /**
79
- * The max height for the listbox when opened.
80
- *
81
- * @internal
82
- */
83
- this.maxHeight = 0;
84
- }
36
+ var __defProp$1 = Object.defineProperty;
37
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
38
+ var __typeError = (msg) => {
39
+ throw TypeError(msg);
40
+ };
41
+ var __decorateClass$1 = (decorators, target, key, kind) => {
42
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
43
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
44
+ if (decorator = decorators[i])
45
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
46
+ if (kind && result) __defProp$1(target, key, result);
47
+ return result;
48
+ };
49
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
50
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
51
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
52
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
53
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
54
+ var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, _suppressFilter, updateFilteredOptions_fn, transitionHighlightedOptionTo_fn, selectHighlightedOption_fn, highlightFirstOption_fn, highlightLastOption_fn, highlightPrevPage_fn, highlightNextPage_fn, highlightPreviousOption_fn, highlightNextOption_fn, textForValue_fn, measureTagWidth_fn, updateTagLayout_fn, moveTagFocusTo_fn, nextTagIndexLeft_fn, nextTagIndexRight_fn, nextTagIndexForRemoved_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
55
+ const TagGapPx = 8;
56
+ const InputMinWidthPx = 100;
57
+ const PageSize = 10;
58
+ const isFormAssociatedTryingToSetFormValue = (value) => typeof value === "string";
59
+ let SearchableSelect = class extends FormAssociatedSearchableSelect {
60
+ constructor() {
61
+ super(...arguments);
62
+ __privateAdd(this, _SearchableSelect_instances);
63
+ this.fixedDropdown = false;
64
+ this.open = false;
65
+ this.multiple = false;
66
+ this.externalTags = false;
67
+ this.maxLines = null;
68
+ this.values = [];
69
+ this.initialValues = [];
70
+ this._inputValue = "";
71
+ // --- Slotted options ---
85
72
  /**
86
- * Sets focus and synchronizes ARIA attributes when the open property changes.
87
- *
88
- * @param prev - the previous open value
89
- * @param next - the current open value
90
- *
91
73
  * @internal
92
74
  */
93
- openChanged(prev, next) {
94
- if (!this.collapsible) {
95
- return;
75
+ this._areOptionsInitialized = false;
76
+ __privateAdd(this, _slottedOptionsChangeHandler, {
77
+ handleChange: (source, _) => {
78
+ if (source.selected && !this.values.includes(source.value)) {
79
+ this.values = [...this.values, source.value];
80
+ } else if (!source.selected && this.values.includes(source.value)) {
81
+ this.values = this.values.filter((option) => option !== source.value);
96
82
  }
97
- if (this.open) {
98
- this.ariaControls = this.listboxId;
99
- this.ariaExpanded = "true";
100
- this.setPositioning();
101
- this.focusAndScrollOptionIntoView();
102
- this.indexWhenOpened = this.selectedIndex;
103
- // focus is directed to the element when `open` is changed programmatically
104
- DOM.queueUpdate(() => this.focus());
105
- return;
106
- }
107
- this.ariaControls = "";
108
- this.ariaExpanded = "false";
109
- }
83
+ }
84
+ });
85
+ // --- Option tag icons ---
86
+ __privateAdd(this, _clonedTagIcons, /* @__PURE__ */ new Map());
87
+ this._filteredOptions = [];
88
+ this._filteredEnabledOptions = [];
89
+ __privateAdd(this, _suppressFilter, false);
90
+ // --- Highlighted option (visual focus) ---
110
91
  /**
111
- * The component is collapsible when in single-selection mode with no size attribute.
112
- *
92
+ * Currently visually highlighted option as an index into _filteredEnabledOptions
113
93
  * @internal
114
94
  */
115
- get collapsible() {
116
- return !(this.multiple || typeof this.size === "number");
95
+ this._highlightedOptionIndex = null;
96
+ this._numEllidedTags = 0;
97
+ this._tagRows = [];
98
+ this._lastTagRow = [];
99
+ this.clearable = false;
100
+ this.setFormValue = (value, state) => {
101
+ if (isFormAssociatedTryingToSetFormValue(value)) {
102
+ return;
103
+ }
104
+ super.setFormValue(value, state);
105
+ };
106
+ // --- Core ---
107
+ __privateAdd(this, _resizeObserver, new ResizeObserver(() => {
108
+ __privateMethod(this, _SearchableSelect_instances, updateTagLayout_fn).call(this);
109
+ }));
110
+ }
111
+ /**
112
+ * @internal
113
+ */
114
+ valuesChanged() {
115
+ if (!this._areOptionsInitialized) {
116
+ return;
117
117
  }
118
- /**
119
- * The value property.
120
- *
121
- * @public
122
- */
123
- get value() {
124
- Observable.track(this, "value");
125
- return this._value;
126
- }
127
- set value(next) {
128
- var _a, _b, _c, _d, _e, _f, _g;
129
- const prev = `${this._value}`;
130
- if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.length) {
131
- const selectedIndex = this._options.findIndex(el => el.value === next);
132
- const prevSelectedValue = (_c = (_b = this._options[this.selectedIndex]) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : null;
133
- const nextSelectedValue = (_e = (_d = this._options[selectedIndex]) === null || _d === void 0 ? void 0 : _d.value) !== null && _e !== void 0 ? _e : null;
134
- if (selectedIndex === -1 || prevSelectedValue !== nextSelectedValue) {
135
- next = "";
136
- this.selectedIndex = selectedIndex;
137
- }
138
- next = (_g = (_f = this.firstSelectedOption) === null || _f === void 0 ? void 0 : _f.value) !== null && _g !== void 0 ? _g : next;
139
- }
140
- if (prev !== next) {
141
- this._value = next;
142
- super.valueChanged(prev, next);
143
- Observable.notify(this, "value");
144
- this.updateDisplayValue();
145
- }
118
+ if (!this.multiple && this.values.length > 1) {
119
+ this.values = [this.values[0]];
120
+ return;
146
121
  }
147
- /**
148
- * Sets the value and display value to match the first selected option.
149
- *
150
- * @param shouldEmit - if true, the input and change events will be emitted
151
- *
152
- * @internal
153
- */
154
- updateValue(shouldEmit) {
155
- var _a, _b;
156
- if (this.$fastController.isConnected) {
157
- this.value = (_b = (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : "";
158
- }
159
- if (shouldEmit) {
160
- this.$emit("input");
161
- this.$emit("change", this, {
162
- bubbles: true,
163
- composed: undefined,
164
- });
165
- }
122
+ if (this.values.some((value) => !__privateMethod(this, _SearchableSelect_instances, isValidValue_fn).call(this, value))) {
123
+ this.values = this.values.filter((value) => __privateMethod(this, _SearchableSelect_instances, isValidValue_fn).call(this, value));
124
+ return;
166
125
  }
167
- /**
168
- * Updates the proxy value when the selected index changes.
169
- *
170
- * @param prev - the previous selected index
171
- * @param next - the next selected index
172
- *
173
- * @internal
174
- */
175
- selectedIndexChanged(prev, next) {
176
- super.selectedIndexChanged(prev, next);
177
- this.updateValue();
126
+ if (!this.multiple) {
127
+ if (this.values.length) {
128
+ __privateSet(this, _suppressFilter, true);
129
+ this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
130
+ } else {
131
+ this._inputValue = "";
132
+ }
178
133
  }
179
- positionChanged(prev, next) {
180
- this.positionAttribute = next;
181
- this.setPositioning();
134
+ this.value = this.values.length ? this.values[0] : "";
135
+ __privateMethod(this, _SearchableSelect_instances, updateSelectedOnSlottedOptions_fn).call(this);
136
+ if (this.$fastController.isConnected) {
137
+ __privateMethod(this, _SearchableSelect_instances, updateTagLayout_fn).call(this);
182
138
  }
183
- /**
184
- * Calculate and apply listbox positioning based on available viewport space.
185
- *
186
- * @public
187
- */
188
- setPositioning() {
189
- const currentBox = this.getBoundingClientRect();
190
- const viewportHeight = window.innerHeight;
191
- const availableBottom = viewportHeight - currentBox.bottom;
192
- this.position = this.forcedPosition
193
- ? this.positionAttribute
194
- : currentBox.top > availableBottom
195
- ? SelectPosition.above
196
- : SelectPosition.below;
197
- this.positionAttribute = this.forcedPosition
198
- ? this.positionAttribute
199
- : this.position;
200
- this.maxHeight =
201
- this.position === SelectPosition.above ? ~~currentBox.top : ~~availableBottom;
139
+ __privateMethod(this, _SearchableSelect_instances, updateFormValue_fn).call(this);
140
+ }
141
+ /**
142
+ * @internal
143
+ */
144
+ initialValuesChanged() {
145
+ if (!this.dirtyValue) {
146
+ this.values = this.initialValues;
147
+ this.dirtyValue = false;
202
148
  }
203
- /**
204
- * The value displayed on the button.
205
- *
206
- * @public
207
- */
208
- get displayValue() {
209
- var _a, _b;
210
- Observable.track(this, "displayValue");
211
- return (_b = (_a = this.firstSelectedOption) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : "";
149
+ }
150
+ /**
151
+ * @internal
152
+ */
153
+ valueChanged(prev, next) {
154
+ super.valueChanged(prev, next);
155
+ if (!this._areOptionsInitialized) {
156
+ return;
212
157
  }
213
- /**
214
- * Synchronize the `aria-disabled` property when the `disabled` property changes.
215
- *
216
- * @param prev - The previous disabled value
217
- * @param next - The next disabled value
218
- *
219
- * @internal
220
- */
221
- disabledChanged(prev, next) {
222
- if (super.disabledChanged) {
223
- super.disabledChanged(prev, next);
224
- }
225
- this.ariaDisabled = this.disabled ? "true" : "false";
158
+ const isValidValue = this._slottedOptions.some(
159
+ (option) => option.value === next
160
+ );
161
+ if (this.values[0] !== next) {
162
+ this.values = isValidValue ? [next] : [];
226
163
  }
227
- /**
228
- * Reset the element to its first selectable option when its parent form is reset.
229
- *
230
- * @internal
231
- */
232
- formResetCallback() {
233
- this.setProxyOptions();
234
- // Call the base class's implementation setDefaultSelectedOption instead of the select's
235
- // override, in order to reset the selectedIndex without using the value property.
236
- super.setDefaultSelectedOption();
237
- if (this.selectedIndex === -1) {
238
- this.selectedIndex = 0;
239
- }
164
+ }
165
+ get selectedIndex() {
166
+ if (this.values.length) {
167
+ return this._slottedOptions.findIndex(
168
+ (option) => option.value === this.values[0]
169
+ );
170
+ } else {
171
+ return -1;
240
172
  }
241
- /**
242
- * Handle opening and closing the listbox when the select is clicked.
243
- *
244
- * @param e - the mouse event
245
- * @internal
246
- */
247
- clickHandler(e) {
248
- // do nothing if the select is disabled
249
- if (this.disabled) {
250
- return;
173
+ }
174
+ set selectedIndex(index) {
175
+ this.value = this._slottedOptions[index]?.value ?? "";
176
+ }
177
+ get options() {
178
+ return [...this._slottedOptions];
179
+ }
180
+ get selectedOptions() {
181
+ return this._slottedOptions.filter(
182
+ (option) => this.values.includes(option.value)
183
+ );
184
+ }
185
+ /**
186
+ * @internal
187
+ */
188
+ _inputValueChanged() {
189
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
190
+ }
191
+ /**
192
+ * @internal
193
+ */
194
+ _onInputInput(event) {
195
+ __privateSet(this, _suppressFilter, false);
196
+ this._inputValue = event.target.value;
197
+ }
198
+ /**
199
+ * @internal
200
+ */
201
+ _onInputFocus(_) {
202
+ __privateSet(this, _suppressFilter, true);
203
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
204
+ this.open = true;
205
+ }
206
+ /**
207
+ * @internal
208
+ */
209
+ _onInputBlur(_) {
210
+ this.open = false;
211
+ if (this.multiple) {
212
+ this._inputValue = "";
213
+ } else {
214
+ if (this.values.length === 0) {
215
+ this._inputValue = "";
216
+ } else {
217
+ this._inputValue = __privateMethod(this, _SearchableSelect_instances, textForValue_fn).call(this, this.values[0]);
218
+ }
219
+ }
220
+ }
221
+ /**
222
+ * @internal
223
+ */
224
+ _onInputKeydown(e) {
225
+ if (e.ctrlKey || e.shiftKey) {
226
+ return true;
227
+ }
228
+ switch (e.key) {
229
+ case "Enter":
230
+ __privateMethod(this, _SearchableSelect_instances, selectHighlightedOption_fn).call(this);
231
+ return false;
232
+ case "Escape":
233
+ this.open = false;
234
+ break;
235
+ case "Home":
236
+ if (!this.open) {
237
+ this.open = true;
238
+ break;
251
239
  }
252
- if (this.open) {
253
- const captured = e.target.closest(`option,[role=option]`);
254
- if (captured && captured.disabled) {
255
- return;
256
- }
240
+ __privateMethod(this, _SearchableSelect_instances, highlightFirstOption_fn).call(this);
241
+ return false;
242
+ case "End":
243
+ if (!this.open) {
244
+ this.open = true;
245
+ break;
257
246
  }
258
- super.clickHandler(e);
259
- this.open = this.collapsible && !this.open;
260
- if (!this.open && this.indexWhenOpened !== this.selectedIndex) {
261
- this.updateValue(true);
247
+ __privateMethod(this, _SearchableSelect_instances, highlightLastOption_fn).call(this);
248
+ return false;
249
+ case "PageUp":
250
+ if (!this.open) {
251
+ this.open = true;
252
+ break;
262
253
  }
263
- return true;
264
- }
265
- /**
266
- * Handles focus state when the element or its children lose focus.
267
- *
268
- * @param e - The focus event
269
- * @internal
270
- */
271
- focusoutHandler(e) {
272
- var _a;
273
- super.focusoutHandler(e);
254
+ __privateMethod(this, _SearchableSelect_instances, highlightPrevPage_fn).call(this);
255
+ return false;
256
+ case "PageDown":
274
257
  if (!this.open) {
275
- return true;
258
+ this.open = true;
259
+ break;
276
260
  }
277
- const focusTarget = e.relatedTarget;
278
- if (this.isSameNode(focusTarget)) {
279
- this.focus();
280
- return;
261
+ __privateMethod(this, _SearchableSelect_instances, highlightNextPage_fn).call(this);
262
+ return false;
263
+ case "ArrowUp":
264
+ if (!this.open) {
265
+ this.open = true;
266
+ break;
281
267
  }
282
- if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.includes(focusTarget))) {
283
- this.open = false;
284
- if (this.indexWhenOpened !== this.selectedIndex) {
285
- this.updateValue(true);
286
- }
268
+ __privateMethod(this, _SearchableSelect_instances, highlightPreviousOption_fn).call(this);
269
+ return false;
270
+ case "ArrowDown":
271
+ if (!this.open) {
272
+ this.open = true;
273
+ break;
287
274
  }
288
- }
289
- /**
290
- * Updates the value when an option's value changes.
291
- *
292
- * @param source - the source object
293
- * @param propertyName - the property to evaluate
294
- *
295
- * @internal
296
- * @override
297
- */
298
- handleChange(source, propertyName) {
299
- super.handleChange(source, propertyName);
300
- if (propertyName === "value") {
301
- this.updateValue();
275
+ __privateMethod(this, _SearchableSelect_instances, highlightNextOption_fn).call(this);
276
+ return false;
277
+ case "ArrowLeft":
278
+ if (this.multiple && this._inputValue === "" && this.values.length && !this.externalTags) {
279
+ __privateMethod(this, _SearchableSelect_instances, moveTagFocusTo_fn).call(this, __privateMethod(this, _SearchableSelect_instances, nextTagIndexLeft_fn).call(this, this.values.length));
280
+ return false;
281
+ }
282
+ return true;
283
+ case "Backspace":
284
+ if (this.multiple && this._inputValue === "" && this.values.length) {
285
+ this._onTagRemoved(this.values[this.values.length - 1]);
286
+ return false;
302
287
  }
288
+ return true;
289
+ default:
290
+ if (!this.open) {
291
+ this.open = true;
292
+ }
293
+ return true;
303
294
  }
304
- /**
305
- * Synchronize the form-associated proxy and updates the value property of the element.
306
- *
307
- * @param prev - the previous collection of slotted option elements
308
- * @param next - the next collection of slotted option elements
309
- *
310
- * @internal
311
- */
312
- slottedOptionsChanged(prev, next) {
313
- this.options.forEach(o => {
314
- const notifier = Observable.getNotifier(o);
315
- notifier.unsubscribe(this, "value");
316
- });
317
- super.slottedOptionsChanged(prev, next);
318
- this.options.forEach(o => {
319
- const notifier = Observable.getNotifier(o);
320
- notifier.subscribe(this, "value");
321
- });
322
- this.setProxyOptions();
323
- this.updateValue();
295
+ return true;
296
+ }
297
+ /**
298
+ * @internal
299
+ */
300
+ _slottedOptionsChanged(oldValue, newValue) {
301
+ const hasSlottedOptions = Boolean(
302
+ this.querySelectorAll(`:not([slot])`).length
303
+ );
304
+ if (!newValue.length && hasSlottedOptions) {
305
+ return;
324
306
  }
325
- /**
326
- * Prevents focus when size is set and a scrollbar is clicked.
327
- *
328
- * @param e - the mouse event object
329
- *
330
- * @override
331
- * @internal
332
- */
333
- mousedownHandler(e) {
334
- var _a;
335
- if (e.offsetX >= 0 && e.offsetX <= ((_a = this.listbox) === null || _a === void 0 ? void 0 : _a.scrollWidth)) {
336
- return super.mousedownHandler(e);
337
- }
338
- return this.collapsible;
307
+ this._areOptionsInitialized = true;
308
+ if (oldValue) {
309
+ for (const option of oldValue) {
310
+ const notifier = Observable.getNotifier(option);
311
+ notifier.unsubscribe(__privateGet(this, _slottedOptionsChangeHandler), "selected");
312
+ }
339
313
  }
340
- /**
341
- * Sets the multiple property on the proxy element.
342
- *
343
- * @param prev - the previous multiple value
344
- * @param next - the current multiple value
345
- */
346
- multipleChanged(prev, next) {
347
- super.multipleChanged(prev, next);
348
- if (this.proxy) {
349
- this.proxy.multiple = next;
350
- }
314
+ if (newValue) {
315
+ for (const option of newValue) {
316
+ option._displayCheckmark = true;
317
+ const notifier = Observable.getNotifier(option);
318
+ notifier.subscribe(__privateGet(this, _slottedOptionsChangeHandler), "selected");
319
+ }
351
320
  }
352
- /**
353
- * Updates the selectedness of each option when the list of selected options changes.
354
- *
355
- * @param prev - the previous list of selected options
356
- * @param next - the current list of selected options
357
- *
358
- * @override
359
- * @internal
360
- */
361
- selectedOptionsChanged(prev, next) {
362
- var _a;
363
- super.selectedOptionsChanged(prev, next);
364
- (_a = this.options) === null || _a === void 0 ? void 0 : _a.forEach((o, i) => {
365
- var _a;
366
- const proxyOption = (_a = this.proxy) === null || _a === void 0 ? void 0 : _a.options.item(i);
367
- if (proxyOption) {
368
- proxyOption.selected = o.selected;
369
- }
370
- });
321
+ const values = [];
322
+ for (const option of this._slottedOptions) {
323
+ if (option.selected || option.value === this.value || this.values.includes(option.value)) {
324
+ values.push(option.value);
325
+ }
371
326
  }
372
- /**
373
- * Sets the selected index to match the first option with the selected attribute, or
374
- * the first selectable option.
375
- *
376
- * @override
377
- * @internal
378
- */
379
- setDefaultSelectedOption() {
380
- var _a;
381
- const options = (_a = this.options) !== null && _a !== void 0 ? _a : Array.from(this.children).filter(Listbox.slottedOptionFilter);
382
- const selectedIndex = options === null || options === void 0 ? void 0 : options.findIndex(el => el.hasAttribute("selected") || el.selected || el.value === this.value);
383
- if (selectedIndex !== -1) {
384
- this.selectedIndex = selectedIndex;
385
- return;
386
- }
387
- this.selectedIndex = 0;
327
+ __privateMethod(this, _SearchableSelect_instances, updateValuesWhileMaintainingOrder_fn).call(this, values);
328
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
329
+ }
330
+ /**
331
+ * @internal
332
+ */
333
+ _tagIconSlotName(value) {
334
+ return `_tag-icon-${this.values.indexOf(value)}`;
335
+ }
336
+ // --- Tags ---
337
+ /**
338
+ * @internal
339
+ */
340
+ _tagLabelForValue(value) {
341
+ const option = this._slottedOptions.find(
342
+ (option2) => option2.value === value
343
+ );
344
+ return option.label;
345
+ }
346
+ /**
347
+ * @internal
348
+ */
349
+ _isTagDisabled(value) {
350
+ const option = this._slottedOptions.find(
351
+ (option2) => option2.value === value
352
+ );
353
+ return this.disabled || option.disabled;
354
+ }
355
+ /**
356
+ * @internal
357
+ */
358
+ _onTagRemoved(value) {
359
+ __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, this.values.filter((option) => option !== value));
360
+ __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
361
+ }
362
+ /**
363
+ * @internal
364
+ */
365
+ _onTagKeydown(event) {
366
+ const tagIndex = parseInt(event.target.dataset.index);
367
+ switch (event.key) {
368
+ case "Backspace":
369
+ case "Delete":
370
+ case "Enter":
371
+ case " ": {
372
+ this._onTagRemoved(this.values[tagIndex]);
373
+ DOM.processUpdates();
374
+ __privateMethod(this, _SearchableSelect_instances, moveTagFocusTo_fn).call(this, __privateMethod(this, _SearchableSelect_instances, nextTagIndexForRemoved_fn).call(this, tagIndex));
375
+ break;
376
+ }
377
+ case "ArrowLeft":
378
+ __privateMethod(this, _SearchableSelect_instances, moveTagFocusTo_fn).call(this, __privateMethod(this, _SearchableSelect_instances, nextTagIndexLeft_fn).call(this, tagIndex) ?? tagIndex);
379
+ break;
380
+ case "ArrowRight":
381
+ __privateMethod(this, _SearchableSelect_instances, moveTagFocusTo_fn).call(this, __privateMethod(this, _SearchableSelect_instances, nextTagIndexRight_fn).call(this, tagIndex));
382
+ break;
388
383
  }
389
- /**
390
- * Resets and fills the proxy to match the component's options.
391
- *
392
- * @internal
393
- */
394
- setProxyOptions() {
395
- if (this.proxy instanceof HTMLSelectElement && this.options) {
396
- this.proxy.options.length = 0;
397
- this.options.forEach(option => {
398
- const proxyOption = option.proxy ||
399
- (option instanceof HTMLOptionElement ? option.cloneNode() : null);
400
- if (proxyOption) {
401
- this.proxy.options.add(proxyOption);
402
- }
403
- });
404
- }
384
+ return true;
385
+ }
386
+ /**
387
+ * @internal
388
+ */
389
+ _onListboxClick(e) {
390
+ if (this.disabled) {
391
+ return;
405
392
  }
406
- /**
407
- * Handle keyboard interaction for the select.
408
- *
409
- * @param e - the keyboard event
410
- * @internal
411
- */
412
- keydownHandler(e) {
413
- super.keydownHandler(e);
414
- const key = e.key || e.key.charCodeAt(0);
415
- switch (key) {
416
- case keySpace: {
417
- e.preventDefault();
418
- if (this.collapsible && this.typeAheadExpired) {
419
- this.open = !this.open;
420
- }
421
- break;
422
- }
423
- case keyHome:
424
- case keyEnd: {
425
- e.preventDefault();
426
- break;
427
- }
428
- case keyEnter: {
429
- e.preventDefault();
430
- this.open = !this.open;
431
- break;
432
- }
433
- case keyEscape: {
434
- if (this.collapsible && this.open) {
435
- e.preventDefault();
436
- this.open = false;
437
- }
438
- break;
439
- }
440
- case keyTab: {
441
- if (this.collapsible && this.open) {
442
- e.preventDefault();
443
- this.open = false;
444
- }
445
- return true;
446
- }
447
- }
448
- if (!this.open && this.indexWhenOpened !== this.selectedIndex) {
449
- this.updateValue(true);
450
- this.indexWhenOpened = this.selectedIndex;
451
- }
452
- return !(key === keyArrowDown || key === keyArrowUp);
393
+ const capturedOption = e.target.closest(
394
+ `option,[role=option]`
395
+ );
396
+ if (capturedOption && !capturedOption.disabled) {
397
+ __privateMethod(this, _SearchableSelect_instances, handleOptionInteraction_fn).call(this, capturedOption);
398
+ }
399
+ }
400
+ /**
401
+ * @internal
402
+ */
403
+ get _shouldShowClearButton() {
404
+ return this.clearable && this.values.length > 0;
405
+ }
406
+ /**
407
+ * @internal
408
+ */
409
+ _onClearButtonClick() {
410
+ __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, this.selectedOptions.filter((option) => option.disabled).map((option) => option.value));
411
+ }
412
+ /**
413
+ * @internal
414
+ */
415
+ nameChanged(previous, next) {
416
+ super.nameChanged(previous, next);
417
+ __privateMethod(this, _SearchableSelect_instances, updateFormValue_fn).call(this);
418
+ }
419
+ /**
420
+ * @internal
421
+ */
422
+ formResetCallback() {
423
+ super.formResetCallback();
424
+ __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, __privateMethod(this, _SearchableSelect_instances, determineInitialValues_fn).call(this));
425
+ }
426
+ /**
427
+ * @internal
428
+ */
429
+ _onFieldsetClick(e) {
430
+ if (this.disabled) {
431
+ return;
453
432
  }
454
- connectedCallback() {
455
- super.connectedCallback();
456
- this.forcedPosition = !!this.positionAttribute;
457
- this.addEventListener("contentchange", this.updateDisplayValue);
433
+ if (!e.defaultPrevented) {
434
+ this._input.focus();
458
435
  }
459
- disconnectedCallback() {
460
- this.removeEventListener("contentchange", this.updateDisplayValue);
461
- super.disconnectedCallback();
436
+ }
437
+ connectedCallback() {
438
+ super.connectedCallback();
439
+ if (!this.values.length) {
440
+ this.values = __privateMethod(this, _SearchableSelect_instances, determineInitialValues_fn).call(this);
462
441
  }
463
- /**
464
- * Updates the proxy's size property when the size attribute changes.
465
- *
466
- * @param prev - the previous size
467
- * @param next - the current size
468
- *
469
- * @override
470
- * @internal
471
- */
472
- sizeChanged(prev, next) {
473
- super.sizeChanged(prev, next);
474
- if (this.proxy) {
475
- this.proxy.size = next;
476
- }
442
+ __privateGet(this, _resizeObserver).observe(this._contentArea);
443
+ }
444
+ disconnectedCallback() {
445
+ super.disconnectedCallback();
446
+ __privateGet(this, _resizeObserver).disconnect();
447
+ }
448
+ /**
449
+ * @internal
450
+ */
451
+ validate() {
452
+ super.validate(this._input ?? void 0);
453
+ }
454
+ };
455
+ _SearchableSelect_instances = new WeakSet();
456
+ updateValuesThroughUserInteraction_fn = function(newValues) {
457
+ this.values = newValues;
458
+ this.$emit("change", void 0, {
459
+ bubbles: false
460
+ });
461
+ this.$emit("input", void 0, {
462
+ bubbles: false
463
+ });
464
+ };
465
+ updateValuesWhileMaintainingOrder_fn = function(newValues) {
466
+ const oldSet = new Set(this.values);
467
+ const newSet = new Set(newValues);
468
+ this.values = [...this.values].filter((v) => newSet.has(v)).concat([...newValues].filter((v) => !oldSet.has(v)));
469
+ };
470
+ isValidValue_fn = function(value) {
471
+ return this._slottedOptions.some((option) => option.value === value);
472
+ };
473
+ _slottedOptionsChangeHandler = new WeakMap();
474
+ updateSelectedOnSlottedOptions_fn = function() {
475
+ for (const option of this._slottedOptions) {
476
+ option.selected = this.values.includes(option.value);
477
+ __privateMethod(this, _SearchableSelect_instances, updateClonedTagIconOfOption_fn).call(this, option);
478
+ }
479
+ };
480
+ handleOptionInteraction_fn = function(option) {
481
+ const value = option.value;
482
+ let newValues;
483
+ if (this.multiple) {
484
+ if (!this.values.includes(value)) {
485
+ newValues = [...this.values, value];
486
+ } else {
487
+ newValues = this.values.filter((option2) => option2 !== value);
477
488
  }
478
- /**
479
- *
480
- * @internal
481
- */
482
- updateDisplayValue() {
483
- if (this.collapsible) {
484
- Observable.notify(this, "displayValue");
485
- }
489
+ this._inputValue = "";
490
+ } else {
491
+ if (this.values.includes(value)) {
492
+ newValues = [];
493
+ } else {
494
+ newValues = [value];
495
+ this._inputValue = option.text;
496
+ }
497
+ this.open = false;
498
+ }
499
+ __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, newValues);
500
+ };
501
+ _clonedTagIcons = new WeakMap();
502
+ tagIconOfOption_fn = function(option) {
503
+ return option.querySelector('[slot="tag-icon"]');
504
+ };
505
+ updateClonedTagIconOfOption_fn = function(option) {
506
+ if (option.selected && __privateMethod(this, _SearchableSelect_instances, tagIconOfOption_fn).call(this, option)) {
507
+ let clone = __privateGet(this, _clonedTagIcons).get(option);
508
+ if (!clone) {
509
+ clone = __privateMethod(this, _SearchableSelect_instances, tagIconOfOption_fn).call(this, option).cloneNode(true);
510
+ __privateGet(this, _clonedTagIcons).set(option, clone);
511
+ }
512
+ clone.slot = this._tagIconSlotName(option.value);
513
+ this.appendChild(clone);
514
+ } else {
515
+ const clone = __privateGet(this, _clonedTagIcons).get(option);
516
+ if (clone) {
517
+ clone.remove();
518
+ __privateGet(this, _clonedTagIcons).delete(option);
519
+ }
520
+ }
521
+ };
522
+ _suppressFilter = new WeakMap();
523
+ updateFilteredOptions_fn = function() {
524
+ const newFilteredOptions = [];
525
+ for (const option of this._slottedOptions ?? []) {
526
+ if (__privateGet(this, _suppressFilter) || this._inputValue === "") {
527
+ option.hidden = false;
528
+ option._matchedRange = null;
529
+ } else {
530
+ const matchIndex = option.text.toLowerCase().indexOf(this._inputValue.toLowerCase());
531
+ const matchedRange = matchIndex === -1 ? null : { from: matchIndex, to: matchIndex + this._inputValue.length };
532
+ option.hidden = !matchedRange;
533
+ option._matchedRange = matchedRange;
534
+ }
535
+ if (!option.hidden) {
536
+ newFilteredOptions.push(option);
486
537
  }
538
+ }
539
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, null);
540
+ this._filteredOptions = newFilteredOptions;
541
+ this._filteredEnabledOptions = newFilteredOptions.filter(
542
+ (option) => !option.disabled
543
+ );
544
+ };
545
+ transitionHighlightedOptionTo_fn = function(index) {
546
+ if (typeof this._highlightedOptionIndex === "number") {
547
+ this._filteredEnabledOptions[this._highlightedOptionIndex]._highlighted = false;
548
+ }
549
+ if (typeof index === "number") {
550
+ if (!this._filteredEnabledOptions.length) {
551
+ index = null;
552
+ } else {
553
+ index = Math.max(
554
+ 0,
555
+ Math.min(this._filteredEnabledOptions.length - 1, index)
556
+ );
557
+ }
558
+ }
559
+ this._highlightedOptionIndex = index;
560
+ if (typeof this._highlightedOptionIndex === "number") {
561
+ const highlightedOption = this._filteredEnabledOptions[this._highlightedOptionIndex];
562
+ highlightedOption._highlighted = true;
563
+ scrollIntoView(highlightedOption, this._listbox, "nearest");
564
+ }
565
+ };
566
+ selectHighlightedOption_fn = function() {
567
+ if (this._highlightedOptionIndex === null) {
568
+ return;
569
+ }
570
+ __privateMethod(this, _SearchableSelect_instances, handleOptionInteraction_fn).call(this, this._filteredEnabledOptions[this._highlightedOptionIndex]);
571
+ };
572
+ highlightFirstOption_fn = function() {
573
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, 0);
574
+ };
575
+ highlightLastOption_fn = function() {
576
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, this._filteredEnabledOptions.length - 1);
577
+ };
578
+ highlightPrevPage_fn = function() {
579
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? this._filteredEnabledOptions.length) - PageSize);
580
+ };
581
+ highlightNextPage_fn = function() {
582
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? -1) + PageSize);
583
+ };
584
+ highlightPreviousOption_fn = function() {
585
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? this._filteredEnabledOptions.length) - 1);
586
+ };
587
+ highlightNextOption_fn = function() {
588
+ __privateMethod(this, _SearchableSelect_instances, transitionHighlightedOptionTo_fn).call(this, (this._highlightedOptionIndex ?? -1) + 1);
589
+ };
590
+ textForValue_fn = function(value) {
591
+ const option = this._slottedOptions.find(
592
+ (option2) => option2.value === value
593
+ );
594
+ return option.text;
487
595
  };
488
- __decorate([
489
- attr({ attribute: "open", mode: "boolean" })
490
- ], Select$1.prototype, "open", void 0);
491
- __decorate([
492
- volatile
493
- ], Select$1.prototype, "collapsible", null);
494
- __decorate([
495
- observable
496
- ], Select$1.prototype, "control", void 0);
497
- __decorate([
498
- attr({ attribute: "position" })
499
- ], Select$1.prototype, "positionAttribute", void 0);
500
- __decorate([
501
- observable
502
- ], Select$1.prototype, "position", void 0);
503
- __decorate([
504
- observable
505
- ], Select$1.prototype, "maxHeight", void 0);
506
596
  /**
507
- * Includes ARIA states and properties relating to the ARIA select role.
508
- *
509
- * @public
597
+ * @internal
510
598
  */
511
- class DelegatesARIASelect {
512
- }
513
- __decorate([
514
- observable
515
- ], DelegatesARIASelect.prototype, "ariaControls", void 0);
516
- applyMixins(DelegatesARIASelect, DelegatesARIAListbox);
517
- applyMixins(Select$1, StartEnd, DelegatesARIASelect);
518
-
519
- const styles = ".chevron{display:flex;flex-shrink:0;font:var(--vvd-typography-base-extended);transform:rotate(0);transition:transform .2s}:host([aria-expanded=true]) .chevron{transform:rotate(180deg)}:host(:focus-visible){outline:none}:host{display:inline-flex;flex-direction:column;gap:4px;--_low-ink-color: var(--vvd-color-neutral-600);--focus-stroke-gap-color: transparent}:host([disabled]){--_low-ink-color: var(--vvd-color-neutral-400);cursor:not-allowed}.label{color:var(--vvd-color-canvas-text);contain:inline-size;font:var(--vvd-typography-base)}.control{--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--_connotation-color-intermediate)}.control.appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.control:where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--_connotation-color-fierce)}.control:where(.hover,:hover):where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: var(--_connotation-color-faint);--_appearance-color-outline: transparent}.control:where(.disabled,:disabled){--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: var(--vvd-color-neutral-100);--_appearance-color-outline: var(--vvd-color-neutral-300)}.control:where(.disabled,:disabled).appearance-ghost{--_appearance-color-text: var(--vvd-color-neutral-300);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.control:where(.readonly):where(:not(.disabled,:disabled)){--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-neutral-200);--_appearance-color-outline: var(--vvd-color-neutral-400)}.control:where(.readonly):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: var(--vvd-color-neutral-600);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.control:where(.error):where(:not(.disabled,:disabled)){--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-alert-50);--_appearance-color-outline: var(--vvd-color-alert-500)}.control:where(.error):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-alert-50);--_appearance-color-outline: transparent}.control:where(.success):where(:not(.disabled,:disabled)){--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-success-50);--_appearance-color-outline: var(--vvd-color-success-500)}.control:where(.success):where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text: notSet;--_appearance-color-fill: var(--vvd-color-success-50);--_appearance-color-outline: transparent}.control{--_connotation-color-primary: var(--vvd-select-accent-primary, var(--vvd-color-canvas-text));--_connotation-color-primary-text: var(--vvd-select-accent-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-select-accent-primary-increment, var(--vvd-color-neutral-800));--_connotation-color-intermediate: var(--vvd-select-accent-intermediate, var(--vvd-color-neutral-500));--_connotation-color-faint: var(--vvd-select-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-soft: var(--vvd-select-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-firm: var(--vvd-select-accent-firm, var(--vvd-color-canvas-text));--_connotation-color-fierce: var(--vvd-select-accent-fierce, var(--vvd-color-neutral-700))}.control{display:flex;align-items:center;justify-content:space-between;border-radius:var(--_select-control-border-radius);background-color:var(--_appearance-color-fill);block-size:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2)));box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);color:var(--_appearance-color-text);font:var(--vvd-typography-base);gap:8px;padding-inline:16px;transition:box-shadow .2s,background-color .2s}.control-wrapper{position:relative}.control:not(.disabled){cursor:pointer}.control.disabled{pointer-events:none}.control:not(.shape-pill){--_select-control-border-radius: 8px}.control.shape-pill{--_select-control-border-radius: 24px}:host(:focus-visible) .control{box-shadow:inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:2px solid var(--focus-stroke-color, var(--vvd-color-canvas-text));outline-offset:calc(-2px - var(--focus-inset, 0px))}.listbox{display:flex;max-height:var(--select-height, 408px);flex-direction:column;padding:4px;gap:2px;overflow-y:auto}:host([multiple]:focus-visible) .listbox{box-shadow:inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:2px solid var(--focus-stroke-color, var(--vvd-color-canvas-text));outline-offset:calc(-2px - var(--focus-inset, 0px));border-radius:8px}.selected-value{display:flex;overflow:hidden;flex-grow:1;align-items:center;column-gap:12px;white-space:nowrap}.selected-value .text{overflow:hidden;max-inline-size:100%;text-overflow:ellipsis}.control.shows-placeholder .selected-value .text{color:var(--vvd-color-neutral-600)}.selected-value slot[name=icon]{flex:0 0 20px;font-size:20px;line-height:1}.control.has-meta .selected-value{padding-inline-end:8px}.feedback-wrapper{display:contents}::part(popup-base){inline-size:max-content;min-inline-size:var(--_select-fixed-width, 100%)}:host([multiple]) ::part(popup-base){position:static}";
520
-
521
- var __defProp = Object.defineProperty;
522
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
523
- var __decorateClass = (decorators, target, key, kind) => {
524
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
525
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
526
- if (decorator = decorators[i])
527
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
528
- if (kind && result) __defProp(target, key, result);
529
- return result;
599
+ measureTagWidth_fn = function(label, removable, hasIcon) {
600
+ const tag = document.createElement(this._optionTagTagName);
601
+ tag.label = label;
602
+ tag.removable = removable;
603
+ tag.style.cssText = "position: absolute; visibility: hidden;";
604
+ tag.hasIconPlaceholder = hasIcon;
605
+ this.shadowRoot.appendChild(tag);
606
+ const width = tag.getBoundingClientRect().width;
607
+ tag.remove();
608
+ return width;
530
609
  };
531
- let Select = class extends Select$1 {
532
- constructor() {
533
- super(...arguments);
534
- this.fixedDropdown = false;
535
- this.placeholderOption = null;
536
- this._feedbackWrapper = null;
610
+ updateTagLayout_fn = function() {
611
+ if (!this.multiple) {
612
+ this._numEllidedTags = 0;
613
+ this._tagRows = [];
614
+ this._lastTagRow = [];
615
+ return;
616
+ }
617
+ if (this.externalTags) {
618
+ this._numEllidedTags = this.values.length;
619
+ this._tagRows = [];
620
+ this._lastTagRow = [];
621
+ return;
537
622
  }
538
- labelChanged() {
539
- if (!this.ariaLabel) {
540
- this.ariaLabel = this.label;
623
+ const rowWidth = this._contentArea.getBoundingClientRect().width;
624
+ const rows = [[]];
625
+ let currentRowIndex = 0;
626
+ let currentRowWidth = InputMinWidthPx;
627
+ let i;
628
+ for (i = this.values.length - 1; i >= 0; i--) {
629
+ const isLastRow = this.maxLines && currentRowIndex === this.maxLines - 1;
630
+ const tagWidth = __privateMethod(this, _SearchableSelect_instances, measureTagWidth_fn).call(this, this._tagLabelForValue(this.values[i]), true, __privateMethod(this, _SearchableSelect_instances, tagIconOfOption_fn).call(this, this.selectedOptions[i]) !== null);
631
+ const entry = {
632
+ value: this.values[i],
633
+ width: tagWidth
634
+ };
635
+ let elidedTagCounterWidth = 0;
636
+ if (isLastRow) {
637
+ const numElidedTags = i;
638
+ if (numElidedTags) {
639
+ elidedTagCounterWidth = TagGapPx + __privateMethod(this, _SearchableSelect_instances, measureTagWidth_fn).call(this, numElidedTags.toString(), false, false);
640
+ }
641
+ }
642
+ const totalWidthNeeded = currentRowWidth + TagGapPx + tagWidth + elidedTagCounterWidth;
643
+ if (totalWidthNeeded > rowWidth) {
644
+ if (isLastRow) {
645
+ if (i === this.values.length - 1) {
646
+ rows[currentRowIndex].unshift(entry);
647
+ currentRowWidth += TagGapPx + tagWidth;
648
+ } else {
649
+ break;
650
+ }
651
+ } else {
652
+ rows.push([]);
653
+ currentRowIndex++;
654
+ rows[currentRowIndex].unshift(entry);
655
+ currentRowWidth = tagWidth;
656
+ }
657
+ continue;
541
658
  }
659
+ rows[currentRowIndex].unshift(entry);
660
+ currentRowWidth += TagGapPx + tagWidth;
542
661
  }
543
- connectedCallback() {
544
- super.connectedCallback();
662
+ this._numEllidedTags = i + 1;
663
+ rows.reverse();
664
+ for (let i2 = 0; i2 < rows.length - 1; i2++) {
665
+ let lineWidth = rows[i2].map((e) => e.width).reduce((a, b) => a + b, 0) + (rows[i2].length - 1) * TagGapPx;
666
+ if (i2 === 0 && this._numEllidedTags) {
667
+ lineWidth += TagGapPx + __privateMethod(this, _SearchableSelect_instances, measureTagWidth_fn).call(this, this._numEllidedTags.toString(), false, false);
668
+ }
669
+ while (rows[i2 + 1].length && lineWidth + TagGapPx + rows[i2 + 1][0].width <= rowWidth) {
670
+ const nextTag = rows[i2 + 1].shift();
671
+ rows[i2].push(nextTag);
672
+ lineWidth += TagGapPx + nextTag.width;
673
+ }
545
674
  }
546
- get displayValue() {
547
- Observable.track(this, "displayValue");
548
- return this.firstSelectedOption?.getAttribute("label") ?? this.firstSelectedOption?.text ?? this.placeholder ?? "";
675
+ const rowValues = rows.map((line) => line.map((entry) => entry.value));
676
+ this._tagRows = rowValues.slice(0, -1);
677
+ this._lastTagRow = rowValues.slice(-1)[0];
678
+ };
679
+ moveTagFocusTo_fn = function(index) {
680
+ if (index === null) {
681
+ this._input.focus();
682
+ } else {
683
+ this.shadowRoot.querySelector(`[data-index="${index}"]`).focus();
549
684
  }
550
- setDefaultSelectedOption() {
551
- const options = Array.from(this.children).filter(
552
- Listbox$1.slottedOptionFilter
553
- );
554
- const selectedIndex = options.findIndex(
555
- (el) => el.hasAttribute("selected") || el.selected || el.value === this.value
556
- );
557
- if (selectedIndex === -1 && !this.placeholderOption) {
558
- this.selectedIndex = 0;
559
- return;
560
- }
561
- if (selectedIndex !== -1 || this.placeholder !== "") {
562
- this.selectedIndex = selectedIndex;
563
- return;
685
+ };
686
+ nextTagIndexLeft_fn = function(index) {
687
+ if (!this.values.length) {
688
+ return null;
689
+ }
690
+ for (let i = index - 1; i >= 0; i--) {
691
+ if (!this._isTagDisabled(this.values[i])) {
692
+ return i;
564
693
  }
565
694
  }
566
- /*
567
- * @internal
568
- */
569
- slottedOptionsChanged(prev, next) {
570
- super.slottedOptionsChanged(prev, next);
571
- this.proxy.value = this.value;
572
- this.validate();
695
+ return null;
696
+ };
697
+ nextTagIndexRight_fn = function(index) {
698
+ if (!this.values.length) {
699
+ return null;
573
700
  }
574
- formResetCallback() {
575
- super.formResetCallback();
576
- if (this.placeholder) {
577
- this.selectedIndex = -1;
701
+ for (let i = index + 1; i < this.values.length; i++) {
702
+ if (!this._isTagDisabled(this.values[i])) {
703
+ return i;
578
704
  }
579
705
  }
706
+ return null;
580
707
  };
581
- __decorateClass([
582
- observable
583
- ], Select.prototype, "_anchor", 2);
584
- __decorateClass([
708
+ nextTagIndexForRemoved_fn = function(index) {
709
+ return __privateMethod(this, _SearchableSelect_instances, nextTagIndexRight_fn).call(this, index - 1) ?? __privateMethod(this, _SearchableSelect_instances, nextTagIndexLeft_fn).call(this, index);
710
+ };
711
+ // --- Form handling ---
712
+ determineInitialValues_fn = function() {
713
+ return this.initialValues.length ? this.initialValues : this.initialValue ? [this.initialValue] : [];
714
+ };
715
+ updateFormValue_fn = function() {
716
+ if (!this.name) {
717
+ this.setFormValue(null);
718
+ } else {
719
+ const formData = new FormData();
720
+ for (const value of this.values) {
721
+ formData.append(this.name, value);
722
+ }
723
+ this.setFormValue(formData);
724
+ }
725
+ };
726
+ _resizeObserver = new WeakMap();
727
+ __decorateClass$1([
585
728
  attr
586
- ], Select.prototype, "appearance", 2);
587
- __decorateClass([
729
+ ], SearchableSelect.prototype, "appearance", 2);
730
+ __decorateClass$1([
588
731
  attr
589
- ], Select.prototype, "shape", 2);
590
- __decorateClass([
732
+ ], SearchableSelect.prototype, "shape", 2);
733
+ __decorateClass$1([
591
734
  attr({ mode: "boolean", attribute: "fixed-dropdown" })
592
- ], Select.prototype, "fixedDropdown", 2);
593
- __decorateClass([
735
+ ], SearchableSelect.prototype, "fixedDropdown", 2);
736
+ __decorateClass$1([
594
737
  attr
595
- ], Select.prototype, "placeholder", 2);
596
- __decorateClass([
738
+ ], SearchableSelect.prototype, "placeholder", 2);
739
+ __decorateClass$1([
740
+ attr({ mode: "boolean" })
741
+ ], SearchableSelect.prototype, "open", 2);
742
+ __decorateClass$1([
743
+ attr({ mode: "boolean" })
744
+ ], SearchableSelect.prototype, "multiple", 2);
745
+ __decorateClass$1([
746
+ attr({ attribute: "external-tags", mode: "boolean" })
747
+ ], SearchableSelect.prototype, "externalTags", 2);
748
+ __decorateClass$1([
749
+ attr({ attribute: "max-lines", converter: nullableNumberConverter })
750
+ ], SearchableSelect.prototype, "maxLines", 2);
751
+ __decorateClass$1([
597
752
  observable
598
- ], Select.prototype, "placeholderOption", 2);
599
- __decorateClass([
753
+ ], SearchableSelect.prototype, "values", 2);
754
+ __decorateClass$1([
600
755
  observable
601
- ], Select.prototype, "_feedbackWrapper", 2);
602
- __decorateClass([
756
+ ], SearchableSelect.prototype, "initialValues", 2);
757
+ __decorateClass$1([
758
+ observable
759
+ ], SearchableSelect.prototype, "_input", 2);
760
+ __decorateClass$1([
761
+ observable
762
+ ], SearchableSelect.prototype, "_inputValue", 2);
763
+ __decorateClass$1([
603
764
  observable
604
- ], Select.prototype, "metaSlottedContent", 2);
605
- Select = __decorateClass([
765
+ ], SearchableSelect.prototype, "_slottedOptions", 2);
766
+ __decorateClass$1([
767
+ observable
768
+ ], SearchableSelect.prototype, "_filteredOptions", 2);
769
+ __decorateClass$1([
770
+ observable
771
+ ], SearchableSelect.prototype, "_filteredEnabledOptions", 2);
772
+ __decorateClass$1([
773
+ observable
774
+ ], SearchableSelect.prototype, "_contentArea", 2);
775
+ __decorateClass$1([
776
+ observable
777
+ ], SearchableSelect.prototype, "_numEllidedTags", 2);
778
+ __decorateClass$1([
779
+ observable
780
+ ], SearchableSelect.prototype, "_tagRows", 2);
781
+ __decorateClass$1([
782
+ observable
783
+ ], SearchableSelect.prototype, "_lastTagRow", 2);
784
+ __decorateClass$1([
785
+ observable
786
+ ], SearchableSelect.prototype, "_listbox", 2);
787
+ __decorateClass$1([
788
+ attr({ mode: "boolean" })
789
+ ], SearchableSelect.prototype, "clearable", 2);
790
+ __decorateClass$1([
791
+ observable
792
+ ], SearchableSelect.prototype, "_anchor", 2);
793
+ SearchableSelect = __decorateClass$1([
606
794
  errorText,
607
795
  formElements
608
- ], Select);
796
+ ], SearchableSelect);
609
797
  applyMixinsWithObservables(
610
- Select,
798
+ SearchableSelect,
611
799
  AffixIconWithTrailing,
612
800
  FormElementHelperText,
613
- FormElementSuccessText
801
+ FormElementSuccessText,
802
+ Localized
614
803
  );
615
804
 
616
- const getStateClasses = ({
617
- shape,
618
- disabled,
619
- appearance,
620
- metaSlottedContent,
621
- errorValidationMessage,
622
- successText,
623
- placeholder,
624
- value
625
- }) => classNames(
626
- ["disabled", disabled],
627
- [`appearance-${appearance}`, Boolean(appearance)],
628
- [`shape-${shape}`, Boolean(shape)],
629
- ["has-meta", Boolean(metaSlottedContent?.length)],
630
- ["error", Boolean(errorValidationMessage)],
631
- ["success", !!successText],
632
- ["has-meta", Boolean(metaSlottedContent?.length)],
633
- ["shows-placeholder", Boolean(placeholder) && !value]
805
+ var __defProp = Object.defineProperty;
806
+ var __decorateClass = (decorators, target, key, kind) => {
807
+ var result = void 0 ;
808
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
809
+ if (decorator = decorators[i])
810
+ result = (decorator(target, key, result) ) || result;
811
+ if (result) __defProp(target, key, result);
812
+ return result;
813
+ };
814
+ class OptionTag extends FoundationElement {
815
+ constructor() {
816
+ super(...arguments);
817
+ this.removable = false;
818
+ this.disabled = false;
819
+ this.hasIconPlaceholder = false;
820
+ }
821
+ _onClickRemove() {
822
+ this.$emit("remove", void 0, {
823
+ bubbles: false
824
+ });
825
+ }
826
+ }
827
+ __decorateClass([
828
+ attr
829
+ ], OptionTag.prototype, "shape");
830
+ __decorateClass([
831
+ attr
832
+ ], OptionTag.prototype, "label");
833
+ __decorateClass([
834
+ attr({ mode: "boolean" })
835
+ ], OptionTag.prototype, "removable");
836
+ __decorateClass([
837
+ attr({ mode: "boolean" })
838
+ ], OptionTag.prototype, "disabled");
839
+ __decorateClass([
840
+ observable
841
+ ], OptionTag.prototype, "hasIconPlaceholder");
842
+ applyMixins(OptionTag, Localized);
843
+
844
+ const getStateClasses = (x) => classNames(
845
+ ["disabled", x.disabled],
846
+ [`appearance-${x.appearance}`, Boolean(x.appearance)],
847
+ [`shape-${x.shape}`, Boolean(x.shape)],
848
+ ["error", Boolean(x.errorValidationMessage)],
849
+ ["success", !!x.successText]
634
850
  );
635
851
  function renderLabel() {
636
- return html` <label for="control" class="label" id="label">
637
- ${(x) => x.label}
638
- </label>`;
639
- }
640
- function renderPlaceholder(context) {
641
- const optionTag = context.tagFor(ListboxOption);
642
852
  return html`
643
- <${optionTag} ${ref("placeholderOption")}
644
- text="${(x) => x.placeholder}" hidden disabled>
645
- </${optionTag}>`;
853
+ <label for="control" class="label" id="label"> ${(x) => x.label} </label>
854
+ `;
646
855
  }
647
- function selectValue(context) {
856
+ const tagTemplateFactory = (context, getComponent) => {
857
+ const optionTagTag = context.tagFor(OptionTag);
858
+ return html`
859
+ <div class="tag-wrapper">
860
+ <${optionTagTag}
861
+ class="tag"
862
+ tabindex="-1"
863
+ data-index="${(x, c) => getComponent(c).values.indexOf(x)}"
864
+ removable
865
+ :label="${(x, c) => getComponent(c)._tagLabelForValue(x)}"
866
+ :shape="${(_, c) => getComponent(c).shape}"
867
+ ?disabled="${(x, c) => getComponent(c)._isTagDisabled(x)}"
868
+ @remove="${(x, c) => getComponent(c)._onTagRemoved(x)}"
869
+ @keydown="${(_, c) => getComponent(c)._onTagKeydown(c.event)}"
870
+ @mousedown="${() => false}">
871
+ <slot slot="icon" name="${(x, c) => getComponent(c)._tagIconSlotName(x)}"></slot>
872
+ </${optionTagTag}>
873
+ </div>
874
+ `;
875
+ };
876
+ const ellidedTagTemplateFactory = (context, getComponent) => {
877
+ const optionTagTag = context.tagFor(OptionTag);
878
+ return html`
879
+ <${optionTagTag}
880
+ class="tag"
881
+ tabindex="-1"
882
+ :label="${(x, c) => getComponent(x, c)._numEllidedTags.toString()}"
883
+ :shape="${(x, c) => getComponent(x, c).shape}"
884
+ ?disabled="${(x, c) => getComponent(x, c).disabled}"
885
+ @mousedown="${() => false}">
886
+ </${optionTagTag}>
887
+ `;
888
+ };
889
+ function renderFieldset(context) {
890
+ const buttonTag = context.tagFor(Button$1);
648
891
  const affixIconTemplate = affixIconTemplateFactory(context);
649
892
  const chevronTemplate = chevronTemplateFactory(context);
650
- return html` <div
651
- class="control ${getStateClasses}"
652
- ${ref("_anchor")}
653
- id="control"
654
- ?disabled="${(x) => x.disabled}"
655
- >
656
- <div class="selected-value">
893
+ const tagTemplate = tagTemplateFactory(context, (c) => c.parent);
894
+ const nestedTagTemplate = tagTemplateFactory(
895
+ context,
896
+ (c) => c.parentContext.parent
897
+ );
898
+ const ellidedTagTemplate = ellidedTagTemplateFactory(context, (x, _) => x);
899
+ const nestedEllidedTagTemplate = ellidedTagTemplateFactory(
900
+ context,
901
+ (_, c) => c.parent
902
+ );
903
+ return html`
904
+ <div
905
+ class="fieldset ${getStateClasses}"
906
+ @click="${(x, c) => x._onFieldsetClick(c.event)}"
907
+ ${ref("_anchor")}
908
+ >
657
909
  ${(x) => affixIconTemplate(x.icon, IconWrapper.Slot)}
658
- <span class="text">${(x) => x.displayValue}</span>
659
- <slot name="meta" ${slotted("metaSlottedContent")}></slot>
910
+ <div class="content-area" ${ref("_contentArea")}>
911
+ ${repeat(
912
+ (x) => x._tagRows,
913
+ html`
914
+ <div class="tag-row">
915
+ ${when(
916
+ (_, c) => c.isFirst && c.parent._numEllidedTags,
917
+ nestedEllidedTagTemplate
918
+ )}
919
+ ${repeat((x) => x, nestedTagTemplate)}
920
+ </div>
921
+ `,
922
+ { positioning: true }
923
+ )}
924
+ <div
925
+ class="tag-row ${(x) => classNames([
926
+ "contains-only-input",
927
+ x._tagRows.length > 0 && x._lastTagRow.length === 0
928
+ ])}"
929
+ >
930
+ ${when(
931
+ (x) => x._tagRows.length === 0 && x._numEllidedTags,
932
+ ellidedTagTemplate
933
+ )}
934
+ ${repeat((x) => x._lastTagRow, tagTemplate)}
935
+ <input
936
+ id="control"
937
+ class="control"
938
+ autofocus
939
+ autocomplete="off"
940
+ aria-autocomplete="${(x) => x.ariaAutoComplete}"
941
+ aria-disabled="${(x) => x.ariaDisabled}"
942
+ aria-expanded="${(x) => x.ariaExpanded}"
943
+ aria-haspopup="listbox"
944
+ placeholder="${(x) => x.multiple && x.values.length ? "" : x.placeholder}"
945
+ role="combobox"
946
+ type="text"
947
+ ?disabled="${(x) => x.disabled}"
948
+ :value="${(x) => x._inputValue}"
949
+ @input="${(x, c) => x._onInputInput(c.event)}"
950
+ @focus="${(x, c) => x._onInputFocus(c.event)}"
951
+ @blur="${(x, c) => x._onInputBlur(c.event)}"
952
+ @keydown="${(x, c) => x._onInputKeydown(c.event)}"
953
+ ${ref("_input")}
954
+ />
955
+ </div>
956
+ </div>
957
+ <slot name="meta"></slot>
958
+ ${when(
959
+ (x) => x._shouldShowClearButton,
960
+ html`<${buttonTag}
961
+ aria-label="${(x) => x.locale.searchableSelect.clearButtonLabel}"
962
+ @click="${(x) => x._onClearButtonClick()}"
963
+ @mousedown="${() => false}"
964
+ ?disabled="${(x) => x.disabled}"
965
+ :shape="${(x) => x.shape}"
966
+ size="super-condensed"
967
+ icon="close-line"
968
+ variant="ghost"
969
+ tabindex="-1"
970
+ ></${buttonTag}>`
971
+ )}
972
+ ${chevronTemplate}
660
973
  </div>
661
- ${chevronTemplate}
662
- </div>`;
663
- }
664
- function setFixedDropdownVarWidth(x) {
665
- return x.open && x.fixedDropdown ? `--_select-fixed-width: ${Math.round(x.getBoundingClientRect().width)}px` : null;
974
+ `;
666
975
  }
667
976
  function renderControl(context) {
668
977
  const popupTag = context.tagFor(Popup);
669
978
  return html`
670
- ${when((x) => x.label, renderLabel())}
671
- <div class="control-wrapper">
672
- ${when((x) => !x.multiple, selectValue(context))}
673
- <${popupTag} class="popup"
674
- style="${setFixedDropdownVarWidth}"
675
- ?open="${(x) => x.collapsible ? x.open : true}"
979
+ ${when((x) => x.label, renderLabel())}
980
+ <div>
981
+ ${renderFieldset(context)}
982
+ <div class="popup-wrapper">
983
+ <${popupTag}
676
984
  :anchor="${(x) => x._anchor}"
985
+ :open="${(x) => x.open}"
986
+ class="popup"
677
987
  placement="bottom-start"
678
- strategy="${(x) => x.fixedDropdown ? null : "absolute"}">
679
- <div class="listbox"
680
- id="${(x) => x.listboxId}"
988
+ strategy="${(x) => x.fixedDropdown ? "fixed" : "absolute"}">
989
+ <div
990
+ class="listbox"
681
991
  role="listbox"
682
- ?disabled="${(x) => x.disabled}"
683
- ?hidden="${(x) => x.collapsible ? !x.open : false}"
684
- ${ref("listbox")}>
685
- ${when((x) => x.placeholder, renderPlaceholder(context))}
992
+ ${ref("_listbox")}
993
+ @click="${(x, c) => x._onListboxClick(c.event)}"
994
+ @mousedown="${() => false}"
995
+ >
686
996
  <slot
687
997
  ${slotted({
688
- filter: Listbox$1.slottedOptionFilter,
998
+ filter: Listbox.slottedOptionFilter,
689
999
  flatten: true,
690
- property: "slottedOptions"
1000
+ property: "_slottedOptions"
691
1001
  })}>
692
1002
  </slot>
693
- </div>
1003
+ ${when(
1004
+ (x) => x._filteredOptions.length === 0,
1005
+ html`<div class="empty-message">
1006
+ ${when(
1007
+ (x) => x._inputValue === "",
1008
+ html`<slot name="no-options">
1009
+ ${(x) => x.locale.searchableSelect.noOptionsMessage}
1010
+ </slot>`
1011
+ )}
1012
+ ${when(
1013
+ (x) => x._inputValue !== "",
1014
+ html`<slot name="no-matches">
1015
+ ${(x) => x.locale.searchableSelect.noMatchesMessage}
1016
+ </slot>`
1017
+ )}
1018
+ </div>`
1019
+ )}
1020
+ </div>
694
1021
  </${popupTag}>
695
1022
  </div>
696
- `;
697
- }
698
- function ifNotFromFeedback(handler) {
699
- return (x, c) => {
700
- if (!c.event.composedPath().includes(x._feedbackWrapper)) {
701
- return handler(x, c.event);
702
- }
703
- return true;
704
- };
1023
+ </div>
1024
+ `;
705
1025
  }
706
- const SelectTemplate = (context) => {
1026
+ const SearchableSelectTemplate = (context) => {
1027
+ const optionTagTag = context.tagFor(OptionTag);
707
1028
  return html`
708
- <template
709
- class="base"
710
- aria-label="${(x) => x.ariaLabel}"
711
- aria-activedescendant="${(x) => x.ariaActiveDescendant}"
712
- aria-controls="${(x) => x.ariaControls}"
713
- aria-disabled="${(x) => x.ariaDisabled}"
714
- aria-expanded="${(x) => x.ariaExpanded}"
715
- aria-haspopup="${(x) => x.collapsible ? "listbox" : null}"
716
- aria-multiselectable="${(x) => x.ariaMultiSelectable}"
717
- role="combobox"
718
- tabindex="${(x) => !x.disabled ? "0" : null}"
719
- @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
720
- @focusin="${ifNotFromFeedback((x, e) => x.focusinHandler(e))}"
721
- @focusout="${ifNotFromFeedback(
722
- (x, e) => x.focusoutHandler(e)
723
- )}"
724
- @keydown="${ifNotFromFeedback((x, e) => {
725
- x.open && handleEscapeKeyAndStopPropogation(e);
726
- return x.keydownHandler(e);
727
- })}"
728
- @mousedown="${ifNotFromFeedback(
729
- (x, e) => x.mousedownHandler(e)
730
- )}"
731
- >
732
- ${renderControl(context)}
733
- <div class="feedback-wrapper" ${ref("_feedbackWrapper")}>
734
- ${getFeedbackTemplate(context)}
1029
+ <template :_optionTagTagName="${() => optionTagTag}">
1030
+ <div class="control-wrapper">
1031
+ ${renderControl(context)} ${getFeedbackTemplate(context)}
735
1032
  </div>
736
1033
  </template>
737
1034
  `;
738
1035
  };
739
1036
 
740
- const selectDefinition = Select.compose({
741
- baseName: "select",
742
- template: SelectTemplate,
743
- styles
1037
+ const getClasses = ({ shape, disabled, removable }) => classNames(
1038
+ "base",
1039
+ ["disabled", disabled],
1040
+ ["removable", removable],
1041
+ [`shape-${shape}`, Boolean(shape)]
1042
+ );
1043
+ function renderRemoveButton(iconTag) {
1044
+ return html`
1045
+ <span
1046
+ class="remove-button"
1047
+ aria-label="${(x) => x.locale.searchableSelect.removeTagButtonLabel(x.label)}"
1048
+ role="button"
1049
+ tabindex="${(x) => x.disabled ? null : 0}"
1050
+ @click="${(x) => x._onClickRemove()}"
1051
+ >
1052
+ <${iconTag} name="close-line"></${iconTag}>
1053
+ </span>
1054
+ `;
1055
+ }
1056
+ const optionTagTemplate = (context) => {
1057
+ const iconTag = context.tagFor(Icon);
1058
+ return html`<span class="${getClasses}" aria-disabled="${(x) => x.disabled}">
1059
+ <slot name="icon" aria-hidden="true">
1060
+ ${when(
1061
+ (x) => x.hasIconPlaceholder,
1062
+ html`<div class="icon-placeholder"></div>`
1063
+ )}
1064
+ </slot>
1065
+ ${when(
1066
+ (x) => x.label,
1067
+ (x) => html`<span class="label">${x.label}</span>`
1068
+ )}
1069
+ ${when((x) => x.removable, renderRemoveButton(iconTag))}
1070
+ </span>`;
1071
+ };
1072
+
1073
+ const optionTagDefinition = OptionTag.compose({
1074
+ baseName: "option-tag",
1075
+ template: optionTagTemplate,
1076
+ styles: [optionTagStyles],
1077
+ shadowOptions: {
1078
+ delegatesFocus: true
1079
+ }
744
1080
  });
745
- const selectRegistries = [
746
- selectDefinition(),
1081
+ const searchableSelectDefinition = SearchableSelect.compose({
1082
+ baseName: "searchable-select",
1083
+ template: SearchableSelectTemplate,
1084
+ styles: [styles],
1085
+ shadowOptions: {
1086
+ delegatesFocus: true
1087
+ }
1088
+ });
1089
+ const searchableSelectRegistries = [
1090
+ ...buttonRegistries,
747
1091
  ...popupRegistries,
748
1092
  ...iconRegistries,
749
- ...listboxOptionRegistries
1093
+ optionTagDefinition(),
1094
+ searchableSelectDefinition()
750
1095
  ];
751
- const registerSelect = registerFactory(selectRegistries);
1096
+ const registerSearchableSelect = registerFactory(
1097
+ searchableSelectRegistries
1098
+ );
752
1099
 
753
- export { selectRegistries as a, registerSelect as r, selectDefinition as s };
1100
+ export { searchableSelectRegistries as a, optionTagDefinition as o, registerSearchableSelect as r, searchableSelectDefinition as s };