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