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