@vonage/vivid 5.19.0 → 5.20.1

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 (648) hide show
  1. package/accordion/definition.cjs +1 -1
  2. package/accordion/definition.js +1 -1
  3. package/accordion/index.cjs +2 -2
  4. package/accordion/index.js +2 -2
  5. package/accordion-item/definition.cjs +1 -1
  6. package/accordion-item/definition.js +1 -1
  7. package/action-group/definition.cjs +1 -1
  8. package/action-group/definition.js +1 -1
  9. package/action-group/index.cjs +2 -2
  10. package/action-group/index.js +2 -2
  11. package/alert/index.cjs +5 -5
  12. package/alert/index.js +8 -8
  13. package/audio-player/index.cjs +10 -10
  14. package/audio-player/index.js +28 -28
  15. package/avatar/index.cjs +7 -7
  16. package/avatar/index.js +14 -14
  17. package/banner/index.cjs +5 -5
  18. package/banner/index.js +9 -9
  19. package/breadcrumb/index.cjs +2 -2
  20. package/breadcrumb/index.js +3 -3
  21. package/breadcrumb-item/index.cjs +5 -5
  22. package/breadcrumb-item/index.js +1 -1
  23. package/bundled/affix.cjs +2 -2
  24. package/bundled/affix.js +11 -11
  25. package/bundled/anchored.cjs +1 -1
  26. package/bundled/anchored.js +6 -6
  27. package/bundled/aria-binding-directive.cjs +1 -1
  28. package/bundled/aria-binding-directive.js +88 -16
  29. package/bundled/base-color-picker.cjs +3 -3
  30. package/bundled/base-color-picker.js +5 -5
  31. package/bundled/base-progress.cjs +1 -1
  32. package/bundled/base-progress.js +3 -3
  33. package/bundled/breadcrumb-item.cjs +1 -1
  34. package/bundled/breadcrumb-item.js +3 -3
  35. package/bundled/button.cjs +1 -1
  36. package/bundled/button.js +3 -3
  37. package/bundled/calendar-event.cjs +1 -1
  38. package/bundled/calendar-event.js +4 -4
  39. package/bundled/calendar-picker.template.cjs +23 -24
  40. package/bundled/calendar-picker.template.js +35 -36
  41. package/bundled/char-count.cjs +2 -2
  42. package/bundled/char-count.js +8 -8
  43. package/bundled/children.cjs +1 -1
  44. package/bundled/children.js +11 -13
  45. package/bundled/definition.cjs +1 -1
  46. package/bundled/definition.js +2 -2
  47. package/bundled/definition10.cjs +3 -3
  48. package/bundled/definition10.js +5 -5
  49. package/bundled/definition11.cjs +2 -2
  50. package/bundled/definition11.js +7 -7
  51. package/bundled/definition12.cjs +15 -16
  52. package/bundled/definition12.js +22 -22
  53. package/bundled/definition13.cjs +3 -3
  54. package/bundled/definition13.js +5 -5
  55. package/bundled/definition14.cjs +2 -2
  56. package/bundled/definition14.js +2 -2
  57. package/bundled/definition15.cjs +7 -8
  58. package/bundled/definition15.js +14 -14
  59. package/bundled/definition16.cjs +3 -3
  60. package/bundled/definition16.js +8 -8
  61. package/bundled/definition17.cjs +7 -7
  62. package/bundled/definition17.js +13 -13
  63. package/bundled/definition18.cjs +18 -18
  64. package/bundled/definition18.js +36 -36
  65. package/bundled/definition19.cjs +2 -2
  66. package/bundled/definition19.js +1 -1
  67. package/bundled/definition2.cjs +10 -9
  68. package/bundled/definition2.js +24 -24
  69. package/bundled/definition20.cjs +19 -14
  70. package/bundled/definition20.js +51 -39
  71. package/bundled/definition21.cjs +6 -6
  72. package/bundled/definition21.js +18 -18
  73. package/bundled/definition22.cjs +3 -3
  74. package/bundled/definition22.js +7 -7
  75. package/bundled/definition23.cjs +4 -4
  76. package/bundled/definition23.js +8 -8
  77. package/bundled/definition24.cjs +8 -8
  78. package/bundled/definition24.js +17 -17
  79. package/bundled/definition3.cjs +1 -1
  80. package/bundled/definition3.js +5 -5
  81. package/bundled/definition4.cjs +9 -9
  82. package/bundled/definition4.js +16 -16
  83. package/bundled/definition5.cjs +4 -4
  84. package/bundled/definition5.js +5 -5
  85. package/bundled/definition6.cjs +6 -6
  86. package/bundled/definition6.js +21 -21
  87. package/bundled/definition7.cjs +2 -2
  88. package/bundled/definition7.js +4 -4
  89. package/bundled/definition8.cjs +4 -4
  90. package/bundled/definition8.js +7 -7
  91. package/bundled/definition9.cjs +10 -6
  92. package/bundled/definition9.js +48 -34
  93. package/bundled/delegates-aria.cjs +1 -1
  94. package/bundled/delegates-aria.js +20 -9
  95. package/bundled/divider.cjs +1 -1
  96. package/bundled/divider.js +3 -3
  97. package/bundled/form-associated.cjs +1 -1
  98. package/bundled/form-associated.js +6 -6
  99. package/bundled/form-element.cjs +1 -1
  100. package/bundled/form-element.js +1 -1
  101. package/bundled/host-semantics.cjs +1 -1
  102. package/bundled/host-semantics.js +2 -1
  103. package/bundled/kbd-shortcut.cjs +1 -0
  104. package/bundled/kbd-shortcut.js +14 -0
  105. package/bundled/linkable.cjs +2 -2
  106. package/bundled/linkable.js +5 -5
  107. package/bundled/listbox.cjs +1 -1
  108. package/bundled/listbox.js +4 -4
  109. package/bundled/localized.cjs +1 -1
  110. package/bundled/localized.js +3 -2
  111. package/bundled/mixins.cjs +16 -16
  112. package/bundled/mixins.js +39 -105
  113. package/bundled/picker-field.template.cjs +6 -6
  114. package/bundled/picker-field.template.js +15 -15
  115. package/bundled/platform.cjs +1 -0
  116. package/bundled/platform.js +9 -0
  117. package/bundled/ref.cjs +1 -1
  118. package/bundled/ref.js +2 -2
  119. package/bundled/render-in-light-dom.cjs +1 -0
  120. package/bundled/render-in-light-dom.js +57 -0
  121. package/bundled/repeat.cjs +1 -1
  122. package/bundled/repeat.js +117 -107
  123. package/bundled/slider.template.cjs +3 -3
  124. package/bundled/slider.template.js +1 -1
  125. package/bundled/slotted.cjs +1 -1
  126. package/bundled/slotted.js +2 -2
  127. package/bundled/time-selection-picker.template.cjs +4 -4
  128. package/bundled/time-selection-picker.template.js +18 -18
  129. package/bundled/vivid-element.cjs +3 -3
  130. package/bundled/vivid-element.js +626 -550
  131. package/bundled/when.cjs +1 -1
  132. package/bundled/when.js +2 -2
  133. package/bundled/with-contextual-help.cjs +1 -1
  134. package/bundled/with-contextual-help.js +1 -1
  135. package/bundled/with-error-text.cjs +1 -1
  136. package/bundled/with-error-text.js +1 -1
  137. package/bundled/with-success-text.cjs +1 -1
  138. package/bundled/with-success-text.js +1 -1
  139. package/calendar/index.cjs +8 -8
  140. package/calendar/index.js +9 -9
  141. package/calendar-event/index.cjs +4 -4
  142. package/calendar-event/index.js +1 -1
  143. package/card/index.cjs +24 -25
  144. package/card/index.js +29 -30
  145. package/color-picker/index.cjs +26 -26
  146. package/color-picker/index.js +90 -90
  147. package/combobox/index.cjs +13 -13
  148. package/combobox/index.js +22 -22
  149. package/country-group/index.cjs +4 -4
  150. package/country-group/index.js +3 -3
  151. package/custom-elements.json +849 -12
  152. package/data-grid/index.cjs +34 -34
  153. package/data-grid/index.js +37 -38
  154. package/date-picker/definition.cjs +1 -1
  155. package/date-picker/definition.js +1 -1
  156. package/date-picker/index.cjs +1 -1
  157. package/date-picker/index.js +2 -2
  158. package/date-range-picker/definition.cjs +1 -1
  159. package/date-range-picker/definition.js +1 -1
  160. package/date-range-picker/index.cjs +1 -1
  161. package/date-range-picker/index.js +4 -4
  162. package/date-time-picker/definition.cjs +1 -1
  163. package/date-time-picker/definition.js +1 -1
  164. package/date-time-picker/index.cjs +2 -2
  165. package/date-time-picker/index.js +6 -6
  166. package/dial-pad/definition.cjs +1 -1
  167. package/dial-pad/definition.js +1 -1
  168. package/dial-pad/index.cjs +8 -8
  169. package/dial-pad/index.js +15 -15
  170. package/dialog/definition.cjs +1 -1
  171. package/dialog/definition.js +1 -1
  172. package/dialog/index.cjs +16 -17
  173. package/dialog/index.js +29 -27
  174. package/divider/definition.cjs +1 -1
  175. package/divider/definition.js +1 -1
  176. package/empty-state/definition.cjs +1 -1
  177. package/empty-state/definition.js +1 -1
  178. package/empty-state/index.cjs +5 -5
  179. package/empty-state/index.js +9 -9
  180. package/fab/definition.cjs +1 -1
  181. package/fab/definition.js +1 -1
  182. package/fab/index.cjs +2 -2
  183. package/fab/index.js +6 -6
  184. package/file-picker/definition.cjs +1 -1
  185. package/file-picker/definition.js +1 -1
  186. package/file-picker/index.cjs +9 -10
  187. package/file-picker/index.js +21 -22
  188. package/flag/index.cjs +3 -3
  189. package/flag/index.js +7 -7
  190. package/header/definition.cjs +1 -1
  191. package/header/definition.js +1 -1
  192. package/header/index.cjs +2 -2
  193. package/header/index.js +8 -8
  194. package/icon/definition.cjs +1 -1
  195. package/icon/definition.js +1 -1
  196. package/index.cjs +184 -172
  197. package/index.js +52 -49
  198. package/kbd-key/definition.cjs +5 -0
  199. package/kbd-key/definition.js +2 -0
  200. package/kbd-key/index.cjs +5 -0
  201. package/kbd-key/index.js +65 -0
  202. package/kbd-shortcut/definition.cjs +5 -0
  203. package/kbd-shortcut/definition.js +2 -0
  204. package/kbd-shortcut/index.cjs +3 -0
  205. package/kbd-shortcut/index.js +27 -0
  206. package/layout/definition.cjs +1 -1
  207. package/layout/definition.js +1 -1
  208. package/layout/index.cjs +2 -2
  209. package/layout/index.js +2 -2
  210. package/lib/accordion-item/accordion-item.d.ts +18 -1
  211. package/lib/action-group/action-group.d.ts +18 -1
  212. package/lib/alert/alert.d.ts +36 -2
  213. package/lib/audio-player/audio-player.d.ts +18 -1
  214. package/lib/avatar/avatar.d.ts +18 -1
  215. package/lib/badge/badge.d.ts +18 -1
  216. package/lib/banner/banner.d.ts +54 -3
  217. package/lib/breadcrumb/breadcrumb.d.ts +18 -1
  218. package/lib/breadcrumb-item/breadcrumb-item.d.ts +18 -1
  219. package/lib/button/button.d.ts +54 -3
  220. package/lib/calendar-event/calendar-event.d.ts +18 -1
  221. package/lib/card/card.d.ts +18 -1
  222. package/lib/checkbox/checkbox.d.ts +107 -5
  223. package/lib/color-picker/color-picker.d.ts +126 -7
  224. package/lib/combobox/combobox.d.ts +124 -5
  225. package/lib/components.d.ts +4 -1
  226. package/lib/country-group/country-group.d.ts +36 -2
  227. package/lib/data-grid/data-grid-cell.d.ts +36 -2
  228. package/lib/data-grid/data-grid-row.d.ts +18 -1
  229. package/lib/date-picker/date-picker.d.ts +140 -4
  230. package/lib/date-range-picker/date-range-picker.d.ts +70 -2
  231. package/lib/date-time-picker/date-time-picker.d.ts +140 -4
  232. package/lib/dial-pad/dial-pad.d.ts +18 -1
  233. package/lib/dialog/dialog.d.ts +36 -2
  234. package/lib/divider/divider.d.ts +18 -1
  235. package/lib/fab/fab.d.ts +18 -1
  236. package/lib/file-picker/file-picker.d.ts +124 -5
  237. package/lib/header/header.d.ts +18 -1
  238. package/lib/icon/icon.template.d.ts +1 -2
  239. package/lib/kbd-key/definition.d.ts +4 -0
  240. package/lib/kbd-key/index.d.ts +1 -0
  241. package/lib/kbd-key/kbd-key.d.ts +18 -0
  242. package/lib/kbd-key/kbd-key.template.d.ts +4 -0
  243. package/lib/kbd-shortcut/definition.d.ts +3 -0
  244. package/lib/kbd-shortcut/index.d.ts +1 -0
  245. package/lib/kbd-shortcut/kbd-shortcut.d.ts +4 -0
  246. package/lib/kbd-shortcut/kbd-shortcut.template.d.ts +4 -0
  247. package/lib/menu/menu.d.ts +35 -1
  248. package/lib/menu-item/menu-item.d.ts +463 -2
  249. package/lib/nav/nav.d.ts +18 -1
  250. package/lib/nav-disclosure/nav-disclosure.d.ts +36 -2
  251. package/lib/nav-item/nav-item.d.ts +36 -2
  252. package/lib/note/note.d.ts +18 -1
  253. package/lib/number-field/number-field.d.ts +160 -7
  254. package/lib/option/option.d.ts +36 -2
  255. package/lib/pagination/pagination.d.ts +18 -1
  256. package/lib/platform-switch/definition.d.ts +3 -0
  257. package/lib/platform-switch/index.d.ts +1 -0
  258. package/lib/platform-switch/platform-switch.d.ts +4 -0
  259. package/lib/platform-switch/platform-switch.template.d.ts +4 -0
  260. package/lib/popover/popover.d.ts +36 -2
  261. package/lib/progress/progress.d.ts +18 -1
  262. package/lib/progress-ring/progress-ring.d.ts +18 -1
  263. package/lib/radio/radio.d.ts +53 -2
  264. package/lib/radio-group/radio-group.d.ts +18 -1
  265. package/lib/range-slider/range-slider.d.ts +52 -1
  266. package/lib/rich-text-editor/locale.d.ts +1 -0
  267. package/lib/rich-text-editor/popover.d.ts +1 -0
  268. package/lib/rich-text-editor/rich-text-editor.d.ts +17 -0
  269. package/lib/rich-text-editor/rte/utils/ui.d.ts +3 -0
  270. package/lib/searchable-select/option-tag.d.ts +18 -1
  271. package/lib/searchable-select/searchable-select.d.ts +160 -7
  272. package/lib/select/select.d.ts +160 -7
  273. package/lib/selectable-box/selectable-box.d.ts +18 -1
  274. package/lib/simple-color-picker/simple-color-picker.d.ts +35 -1
  275. package/lib/slider/slider.d.ts +53 -2
  276. package/lib/split-button/split-button.d.ts +54 -3
  277. package/lib/status/status.d.ts +18 -1
  278. package/lib/switch/switch.d.ts +36 -2
  279. package/lib/tab/tab.d.ts +54 -3
  280. package/lib/tab-panel/tab-panel.d.ts +18 -1
  281. package/lib/table/table-cell.d.ts +18 -1
  282. package/lib/table/table-header-cell.d.ts +18 -1
  283. package/lib/table/table-row.d.ts +18 -1
  284. package/lib/table/table-sorting-button.d.ts +18 -1
  285. package/lib/tag/tag.d.ts +54 -3
  286. package/lib/tag-group/tag-group.d.ts +18 -1
  287. package/lib/tag-name-map.d.ts +4 -1
  288. package/lib/text-area/text-area.d.ts +142 -6
  289. package/lib/text-field/text-field.d.ts +160 -7
  290. package/lib/time-picker/time-picker.d.ts +70 -2
  291. package/lib/toggletip/toggletip.d.ts +35 -1
  292. package/lib/tooltip/tooltip.d.ts +444 -0
  293. package/lib/tree-item/tree-item.d.ts +36 -2
  294. package/lib/tree-view/tree-view.d.ts +18 -1
  295. package/lib/video-player/video-player.d.ts +18 -1
  296. package/locales/de-DE.cjs +1 -0
  297. package/locales/de-DE.js +1 -0
  298. package/locales/en-GB.cjs +1 -0
  299. package/locales/en-GB.js +1 -0
  300. package/locales/en-US.cjs +1 -0
  301. package/locales/en-US.js +1 -0
  302. package/locales/ja-JP.cjs +1 -0
  303. package/locales/ja-JP.js +1 -0
  304. package/locales/zh-CN.cjs +1 -0
  305. package/locales/zh-CN.js +1 -0
  306. package/nav/definition.cjs +1 -1
  307. package/nav/definition.js +1 -1
  308. package/nav/index.cjs +2 -2
  309. package/nav/index.js +2 -2
  310. package/nav-disclosure/definition.cjs +1 -1
  311. package/nav-disclosure/definition.js +1 -1
  312. package/nav-disclosure/index.cjs +3 -4
  313. package/nav-disclosure/index.js +11 -11
  314. package/nav-item/definition.cjs +1 -1
  315. package/nav-item/definition.js +1 -1
  316. package/nav-item/index.cjs +2 -2
  317. package/nav-item/index.js +6 -6
  318. package/note/definition.cjs +1 -1
  319. package/note/definition.js +1 -1
  320. package/note/index.cjs +2 -2
  321. package/note/index.js +7 -7
  322. package/number-field/definition.cjs +1 -1
  323. package/number-field/definition.js +1 -1
  324. package/number-field/index.cjs +8 -9
  325. package/number-field/index.js +16 -17
  326. package/package.json +6 -6
  327. package/pagination/definition.cjs +1 -1
  328. package/pagination/definition.js +1 -1
  329. package/pagination/index.cjs +9 -9
  330. package/pagination/index.js +16 -16
  331. package/platform-switch/definition.cjs +5 -0
  332. package/platform-switch/definition.js +2 -0
  333. package/platform-switch/index.cjs +1 -0
  334. package/platform-switch/index.js +28 -0
  335. package/popover/definition.cjs +1 -1
  336. package/popover/definition.js +1 -1
  337. package/popover/index.cjs +6 -6
  338. package/popover/index.js +12 -12
  339. package/progress/definition.cjs +1 -1
  340. package/progress/definition.js +1 -1
  341. package/progress/index.cjs +4 -4
  342. package/progress/index.js +5 -5
  343. package/progress-ring/definition.cjs +1 -1
  344. package/progress-ring/definition.js +1 -1
  345. package/radio/definition.cjs +1 -1
  346. package/radio/definition.js +1 -1
  347. package/radio-group/definition.cjs +1 -1
  348. package/radio-group/definition.js +1 -1
  349. package/radio-group/index.cjs +5 -8
  350. package/radio-group/index.js +16 -16
  351. package/range-slider/definition.cjs +1 -1
  352. package/range-slider/definition.js +1 -1
  353. package/range-slider/index.cjs +5 -5
  354. package/range-slider/index.js +9 -9
  355. package/rich-text-editor/definition.cjs +1 -1
  356. package/rich-text-editor/definition.js +1 -1
  357. package/rich-text-editor/index.cjs +8 -6
  358. package/rich-text-editor/index.js +136 -94
  359. package/rich-text-view/definition.cjs +1 -1
  360. package/rich-text-view/definition.js +1 -1
  361. package/rich-text-view/index.cjs +1 -1
  362. package/rich-text-view/index.js +3 -3
  363. package/searchable-select/definition.cjs +1 -1
  364. package/searchable-select/definition.js +1 -1
  365. package/searchable-select/index.cjs +38 -40
  366. package/searchable-select/index.js +64 -64
  367. package/select/definition.cjs +1 -1
  368. package/select/definition.js +1 -1
  369. package/selectable-box/definition.cjs +1 -1
  370. package/selectable-box/definition.js +1 -1
  371. package/selectable-box/index.cjs +4 -4
  372. package/selectable-box/index.js +13 -13
  373. package/shared/aria/aria-binding-directive.d.ts +4 -4
  374. package/shared/aria/aria-mixin.d.ts +21 -3
  375. package/shared/aria/delegates-aria.d.ts +18 -1
  376. package/shared/aria/host-semantics.d.ts +18 -1
  377. package/shared/aria/idrefs-controller.d.ts +17 -0
  378. package/shared/color-picker/base-color-picker.d.ts +18 -1
  379. package/shared/feedback/feedback-message.d.ts +18 -1
  380. package/shared/feedback/mixins.d.ts +36 -2
  381. package/shared/foundation/button/button.d.ts +35 -1
  382. package/shared/foundation/form-associated/form-associated.d.ts +35 -1
  383. package/shared/foundation/vivid-element/vivid-element.d.ts +375 -0
  384. package/shared/framework/reactive-controller.d.ts +373 -0
  385. package/shared/patterns/affix.d.ts +36 -2
  386. package/shared/patterns/anchored.d.ts +34 -0
  387. package/shared/patterns/char-count/char-count.d.ts +18 -1
  388. package/shared/patterns/form-elements/form-element.d.ts +17 -0
  389. package/shared/patterns/form-elements/with-contextual-help.d.ts +18 -1
  390. package/shared/patterns/form-elements/with-error-text.d.ts +18 -1
  391. package/shared/patterns/form-elements/with-success-text.d.ts +18 -1
  392. package/shared/patterns/index.d.ts +1 -0
  393. package/shared/patterns/kbd-shortcut.d.ts +431 -0
  394. package/shared/patterns/linkable.d.ts +18 -1
  395. package/shared/patterns/localized.d.ts +35 -1
  396. package/shared/patterns/trapped-focus.d.ts +18 -1
  397. package/shared/picker-field/mixins/calendar-picker.d.ts +35 -1
  398. package/shared/picker-field/mixins/calendar-picker.template.d.ts +35 -1
  399. package/shared/picker-field/mixins/inline-time-picker/inline-time-picker.d.ts +18 -1
  400. package/shared/picker-field/mixins/min-max-calendar-picker.d.ts +35 -1
  401. package/shared/picker-field/mixins/single-date-picker.d.ts +35 -1
  402. package/shared/picker-field/mixins/single-value-picker.d.ts +35 -1
  403. package/shared/picker-field/mixins/time-selection-picker.d.ts +35 -1
  404. package/shared/picker-field/mixins/time-selection-picker.template.d.ts +70 -2
  405. package/shared/picker-field/picker-field.d.ts +124 -5
  406. package/shared/templating/render-in-light-dom.d.ts +7 -20
  407. package/shared/utils/platform.d.ts +1 -0
  408. package/side-drawer/definition.cjs +1 -1
  409. package/side-drawer/definition.js +1 -1
  410. package/side-drawer/index.cjs +3 -3
  411. package/side-drawer/index.js +3 -3
  412. package/simple-color-picker/definition.cjs +1 -1
  413. package/simple-color-picker/definition.js +1 -1
  414. package/simple-color-picker/index.cjs +2 -2
  415. package/simple-color-picker/index.js +6 -6
  416. package/split-button/definition.cjs +1 -1
  417. package/split-button/definition.js +1 -1
  418. package/split-button/index.cjs +5 -6
  419. package/split-button/index.js +8 -8
  420. package/status/definition.cjs +1 -1
  421. package/status/definition.js +1 -1
  422. package/status/index.cjs +4 -4
  423. package/status/index.js +9 -9
  424. package/styles/core/all.css +24 -2
  425. package/styles/core/typography.css +24 -2
  426. package/styles/fonts/spezia-variable.css +6 -0
  427. package/styles/tokens/theme-dark.css +2 -0
  428. package/styles/tokens/theme-light.css +2 -0
  429. package/switch/definition.cjs +1 -1
  430. package/switch/definition.js +1 -1
  431. package/switch/index.cjs +3 -3
  432. package/switch/index.js +4 -4
  433. package/tab/definition.cjs +1 -1
  434. package/tab/definition.js +1 -1
  435. package/tab-panel/definition.cjs +1 -1
  436. package/tab-panel/definition.js +1 -1
  437. package/table/definition.cjs +1 -1
  438. package/table/definition.js +1 -1
  439. package/table/index.cjs +9 -9
  440. package/table/index.js +19 -19
  441. package/tabs/definition.cjs +1 -1
  442. package/tabs/definition.js +1 -1
  443. package/tabs/index.cjs +8 -8
  444. package/tabs/index.js +14 -14
  445. package/tag/definition.cjs +1 -1
  446. package/tag/definition.js +1 -1
  447. package/tag/index.cjs +8 -8
  448. package/tag/index.js +11 -11
  449. package/tag-group/definition.cjs +1 -1
  450. package/tag-group/definition.js +1 -1
  451. package/tag-group/index.cjs +2 -2
  452. package/tag-group/index.js +2 -2
  453. package/text-area/definition.cjs +1 -1
  454. package/text-area/definition.js +1 -1
  455. package/text-area/index.cjs +8 -9
  456. package/text-area/index.js +25 -26
  457. package/time-picker/definition.cjs +1 -1
  458. package/time-picker/definition.js +1 -1
  459. package/time-picker/index.cjs +1 -1
  460. package/time-picker/index.js +1 -1
  461. package/tree-item/definition.cjs +1 -1
  462. package/tree-item/definition.js +1 -1
  463. package/tree-view/definition.cjs +1 -1
  464. package/tree-view/definition.js +1 -1
  465. package/tree-view/index.cjs +4 -4
  466. package/tree-view/index.js +7 -7
  467. package/unbundled/affix.cjs +1 -1
  468. package/unbundled/affix.js +1 -1
  469. package/unbundled/aria-binding-directive.cjs +112 -2
  470. package/unbundled/aria-binding-directive.js +108 -4
  471. package/unbundled/calendar-picker.template.cjs +8 -10
  472. package/unbundled/calendar-picker.template.js +8 -10
  473. package/unbundled/char-count.cjs +1 -1
  474. package/unbundled/char-count.js +1 -1
  475. package/unbundled/definition.cjs +91 -17
  476. package/unbundled/definition.js +88 -14
  477. package/unbundled/definition10.js +1 -1
  478. package/unbundled/definition11.js +1 -1
  479. package/unbundled/definition12.cjs +15 -2
  480. package/unbundled/definition12.js +17 -4
  481. package/unbundled/definition13.js +1 -1
  482. package/unbundled/definition14.js +1 -1
  483. package/unbundled/definition15.cjs +1 -1
  484. package/unbundled/definition15.js +2 -2
  485. package/unbundled/definition16.cjs +1 -1
  486. package/unbundled/definition16.js +2 -2
  487. package/unbundled/definition17.cjs +1 -1
  488. package/unbundled/definition17.js +2 -2
  489. package/unbundled/definition18.cjs +1 -1
  490. package/unbundled/definition18.js +2 -2
  491. package/unbundled/definition19.js +1 -1
  492. package/unbundled/definition2.cjs +96 -77
  493. package/unbundled/definition2.js +94 -75
  494. package/unbundled/definition20.js +1 -1
  495. package/unbundled/definition21.js +1 -1
  496. package/unbundled/definition22.cjs +2 -3
  497. package/unbundled/definition22.js +3 -4
  498. package/unbundled/definition23.cjs +3 -3
  499. package/unbundled/definition23.js +5 -5
  500. package/unbundled/definition24.js +1 -1
  501. package/unbundled/definition25.cjs +1 -1
  502. package/unbundled/definition25.js +2 -2
  503. package/unbundled/definition26.cjs +8 -8
  504. package/unbundled/definition26.js +6 -6
  505. package/unbundled/definition27.cjs +26 -12
  506. package/unbundled/definition27.js +28 -14
  507. package/unbundled/definition28.cjs +1 -1
  508. package/unbundled/definition28.js +3 -3
  509. package/unbundled/definition29.cjs +1 -1
  510. package/unbundled/definition29.js +2 -2
  511. package/unbundled/definition3.cjs +154 -95
  512. package/unbundled/definition3.js +146 -93
  513. package/unbundled/definition30.cjs +1 -1
  514. package/unbundled/definition30.js +3 -3
  515. package/unbundled/definition31.cjs +1 -1
  516. package/unbundled/definition31.js +2 -2
  517. package/unbundled/definition32.js +1 -1
  518. package/unbundled/definition33.cjs +1 -1
  519. package/unbundled/definition33.js +2 -2
  520. package/unbundled/definition34.cjs +103 -65
  521. package/unbundled/definition34.js +102 -64
  522. package/unbundled/definition35.cjs +26 -326
  523. package/unbundled/definition35.js +24 -247
  524. package/unbundled/definition36.cjs +131 -25
  525. package/unbundled/definition36.js +124 -23
  526. package/unbundled/definition37.cjs +326 -51
  527. package/unbundled/definition37.js +324 -49
  528. package/unbundled/definition38.cjs +137 -317
  529. package/unbundled/definition38.js +135 -315
  530. package/unbundled/definition39.cjs +337 -173
  531. package/unbundled/definition39.js +334 -170
  532. package/unbundled/definition4.cjs +34 -159
  533. package/unbundled/definition4.js +25 -151
  534. package/unbundled/definition40.cjs +234 -339
  535. package/unbundled/definition40.js +230 -335
  536. package/unbundled/definition41.cjs +48 -271
  537. package/unbundled/definition41.js +44 -267
  538. package/unbundled/definition42.cjs +68 -49
  539. package/unbundled/definition42.js +65 -46
  540. package/unbundled/definition43.cjs +424 -56
  541. package/unbundled/definition43.js +422 -54
  542. package/unbundled/definition44.cjs +45 -428
  543. package/unbundled/definition44.js +42 -425
  544. package/unbundled/definition45.cjs +45 -54
  545. package/unbundled/definition45.js +42 -51
  546. package/unbundled/definition46.cjs +178 -30
  547. package/unbundled/definition46.js +175 -26
  548. package/unbundled/definition47.cjs +29 -94
  549. package/unbundled/definition47.js +25 -91
  550. package/unbundled/definition48.cjs +76 -36
  551. package/unbundled/definition48.js +73 -33
  552. package/unbundled/definition49.cjs +56 -23
  553. package/unbundled/definition49.js +54 -18
  554. package/unbundled/definition5.cjs +56 -38
  555. package/unbundled/definition5.js +52 -28
  556. package/unbundled/definition50.cjs +23 -40
  557. package/unbundled/definition50.js +18 -38
  558. package/unbundled/definition51.cjs +30 -338
  559. package/unbundled/definition51.js +30 -338
  560. package/unbundled/definition52.cjs +317 -187
  561. package/unbundled/definition52.js +314 -184
  562. package/unbundled/definition53.cjs +194 -289
  563. package/unbundled/definition53.js +189 -284
  564. package/unbundled/definition54.cjs +47 -54
  565. package/unbundled/definition54.js +44 -50
  566. package/unbundled/definition55.cjs +279 -133
  567. package/unbundled/definition55.js +277 -130
  568. package/unbundled/definition56.cjs +50 -262
  569. package/unbundled/definition56.js +48 -261
  570. package/unbundled/definition57.cjs +128 -460
  571. package/unbundled/definition57.js +126 -459
  572. package/unbundled/definition58.cjs +235 -3604
  573. package/unbundled/definition58.js +231 -3437
  574. package/unbundled/definition59.cjs +419 -729
  575. package/unbundled/definition59.js +417 -727
  576. package/unbundled/definition6.cjs +18 -64
  577. package/unbundled/definition6.js +15 -60
  578. package/unbundled/definition60.cjs +3699 -106
  579. package/unbundled/definition60.js +3531 -101
  580. package/unbundled/definition61.cjs +625 -878
  581. package/unbundled/definition61.js +619 -872
  582. package/unbundled/definition62.cjs +106 -108
  583. package/unbundled/definition62.js +103 -105
  584. package/unbundled/definition63.cjs +1045 -71
  585. package/unbundled/definition63.js +1041 -66
  586. package/unbundled/definition64.cjs +105 -173
  587. package/unbundled/definition64.js +102 -170
  588. package/unbundled/definition65.cjs +70 -113
  589. package/unbundled/definition65.js +66 -110
  590. package/unbundled/definition66.cjs +185 -54
  591. package/unbundled/definition66.js +182 -51
  592. package/unbundled/definition67.cjs +110 -77
  593. package/unbundled/definition67.js +111 -77
  594. package/unbundled/definition68.cjs +58 -21
  595. package/unbundled/definition68.js +56 -16
  596. package/unbundled/definition69.cjs +82 -75
  597. package/unbundled/definition69.js +81 -75
  598. package/unbundled/definition7.cjs +2 -2
  599. package/unbundled/definition7.js +3 -3
  600. package/unbundled/definition70.cjs +19 -349
  601. package/unbundled/definition70.js +15 -341
  602. package/unbundled/definition71.cjs +88 -26
  603. package/unbundled/definition71.js +86 -23
  604. package/unbundled/definition72.cjs +309 -119
  605. package/unbundled/definition72.js +234 -116
  606. package/unbundled/definition73.cjs +293 -229
  607. package/unbundled/definition73.js +287 -230
  608. package/unbundled/definition74.cjs +39 -30
  609. package/unbundled/definition74.js +29 -28
  610. package/unbundled/definition75.cjs +106 -121
  611. package/unbundled/definition75.js +104 -113
  612. package/unbundled/definition76.cjs +260 -179
  613. package/unbundled/definition76.js +258 -176
  614. package/unbundled/definition77.cjs +29 -514
  615. package/unbundled/definition77.js +27 -503
  616. package/unbundled/definition78.cjs +171 -0
  617. package/unbundled/definition78.js +147 -0
  618. package/unbundled/definition79.cjs +233 -0
  619. package/unbundled/definition79.js +214 -0
  620. package/unbundled/definition8.js +1 -1
  621. package/unbundled/definition80.cjs +533 -0
  622. package/unbundled/definition80.js +513 -0
  623. package/unbundled/definition9.cjs +1 -1
  624. package/unbundled/definition9.js +2 -2
  625. package/unbundled/delegates-aria.cjs +15 -1
  626. package/unbundled/delegates-aria.js +17 -3
  627. package/unbundled/host-semantics.cjs +2 -1
  628. package/unbundled/host-semantics.js +2 -1
  629. package/unbundled/kbd-shortcut.cjs +26 -0
  630. package/unbundled/kbd-shortcut.js +20 -0
  631. package/unbundled/mixins.cjs +7 -77
  632. package/unbundled/mixins.js +6 -64
  633. package/unbundled/platform.cjs +17 -0
  634. package/unbundled/platform.js +12 -0
  635. package/unbundled/randomId.cjs +47 -0
  636. package/unbundled/randomId.js +35 -0
  637. package/unbundled/time-selection-picker.template.js +1 -1
  638. package/unbundled/vivid-element.cjs +82 -9
  639. package/unbundled/vivid-element.js +63 -8
  640. package/video-player/definition.cjs +1 -1
  641. package/video-player/definition.js +1 -1
  642. package/video-player/index.cjs +3 -3
  643. package/video-player/index.js +5 -5
  644. package/visually-hidden/definition.cjs +1 -1
  645. package/visually-hidden/definition.js +1 -1
  646. package/vivid.api.json +604 -6
  647. package/bundled/normalize.cjs +0 -1
  648. package/bundled/normalize.js +0 -7
@@ -1,9 +1,7 @@
1
- import { c as createRegisterFunction, s as defineVividComponent, t as VividElement } from "./vivid-element.js";
2
- import { r as Icon, t as iconDefinition } from "./definition2.js";
1
+ import { d as createRegisterFunction, u as defineVividComponent } from "./vivid-element.js";
2
+ import { t as iconDefinition } from "./definition.js";
3
3
  import { t as __decorate } from "./decorate.js";
4
4
  import { a as affixIconTemplateFactory, i as IconWrapper, n as AffixIconWithTrailing } from "./affix.js";
5
- import { n as delegateAria, t as DelegatesAria } from "./delegates-aria.js";
6
- import { r as ProgressRing, t as progressRingDefinition } from "./definition6.js";
7
5
  import { n as FormAssociated } from "./form-associated.js";
8
6
  import { t as FormElement } from "./form-element.js";
9
7
  import { t as WithSuccessText } from "./with-success-text.js";
@@ -11,1062 +9,811 @@ import { t as WithErrorText } from "./with-error-text.js";
11
9
  import { t as WithContextualHelp } from "./with-contextual-help.js";
12
10
  import { t as Localized } from "./localized.js";
13
11
  import { i as Button, r as chevronTemplateFactory, t as buttonDefinition } from "./definition7.js";
12
+ import { t as handleEscapeKeyAndStopPropogation } from "./dialog.js";
14
13
  import { i as Popup, t as popupDefinition } from "./definition10.js";
15
- import { t as Divider } from "./divider.js";
16
- import { a as feedbackMessageDefinition, t as WithFeedback } from "./mixins.js";
17
- import { i as isListboxOption, r as ListboxOption, t as listboxOptionDefinition } from "./definition29.js";
18
- import { t as dividerDefinition } from "./definition36.js";
19
- import { t as scrollIntoView } from "./scrollIntoView.js";
20
- import { Observable, Updates, attr, html, nullableNumberConverter, observable, ref, repeat, slotted, when } from "@microsoft/fast-element";
21
- import { classNames } from "@microsoft/fast-web-utilities";
22
- //#region src/lib/searchable-select/searchable-select.scss?inline
23
- var searchable_select_default = ".label-wrapper{align-items:center;gap:var(--label-wrapper-gap,4px);flex-direction:row;display:flex}.label-wrapper[hidden]{display:none}.label:not(slot),.label::slotted(label){flex:0 auto}.chevron{font:var(--vvd-typography-base-extended);flex-shrink:0;transition:transform .2s;display:flex;transform:rotate(0)}:host([data-expanded=true]) .chevron,:host([open]) .chevron{transform:rotate(180deg)}:not(.disabled) .chevron{cursor:pointer}.disabled .chevron{color:var(--_low-ink-color);cursor:not-allowed}:host(:focus-visible){outline:none}:host{--_low-ink-color:var(--vvd-color-neutral-600);inline-size:300px;display:inline-block}:host([disabled]){--_low-ink-color:var(--vvd-color-neutral-400);cursor:not-allowed}.control-wrapper{flex-direction:column;gap:4px;display:flex}.label{color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base)}.selection-count{color:var(--_low-ink-color);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));--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-500)}.fieldset.appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}@media (hover:hover){.fieldset: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(--vvd-color-neutral-700)}.fieldset: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.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(--vvd-color-neutral-700)}.fieldset.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:disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.fieldset:disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.fieldset.disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.fieldset.disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.fieldset.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.readonly:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.fieldset.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.error:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notSet;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:transparent}.fieldset.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.success:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notSet;--_appearance-color-fill:var(--vvd-color-success-50);--_appearance-color-outline:transparent}.fieldset{--_searchable-select-block-size:24px;--_searchable-select-padding-block:8px;--_searchable-select-padding-inline:16px;--_searchable-select-icon-size:20px;--_searchable-select-border-radius:8px;--_searchable-select-gap:8px;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);justify-content:space-between;align-items:center;gap:var(--_searchable-select-gap);padding-block:var(--_searchable-select-padding-block);padding-inline:var(--_searchable-select-padding-inline);transition:box-shadow .2s,background-color .2s;display:flex}.fieldset.size-condensed{--_searchable-select-block-size:20px;--_searchable-select-padding-block:6px;--_searchable-select-padding-inline:12px;--_searchable-select-gap:6px}.fieldset.size-condensed:not(.shape-pill){--_searchable-select-border-radius:4px}@supports selector(:has(*)){.fieldset:not(.has-highlighted-option):has(input:focus){box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));--focus-stroke-gap-color:transparent}}@supports not selector(:has(*)){.fieldset:not(.has-highlighted-option):focus-within{box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));--focus-stroke-gap-color:transparent}}:host(:not([shape=pill])) .fieldset{border-radius:var(--_searchable-select-border-radius)}:host([shape=pill]) .fieldset{border-radius:24px}.popup-wrapper{position:relative}.content-area{gap:var(--_searchable-select-gap);min-block-size:var(--_searchable-select-block-size);flex-direction:column;flex:1;display:flex;overflow:hidden}.tag-row{gap:var(--_searchable-select-gap);inline-size:100%;display:flex}.tag-row.contains-only-input:not(:focus-within){display:contents}.tag-wrapper{overflow:hidden}.tag{max-inline-size:100%}input{box-sizing:border-box;block-size:var(--_searchable-select-block-size);font:var(--vvd-typography-base);background:0 0;border:none;outline:none;flex:1;min-inline-size:min(100px,40%);max-inline-size:100%}.contains-only-input input:not(:focus){opacity:0;pointer-events:none;block-size:0;inline-size:0;min-inline-size:0;position:absolute}.listbox{max-block-size:var(--searchable-select-height,408px);flex-direction:column;gap:2px;padding:4px;display:flex;overflow-y:auto}.empty-message{color:var(--vvd-color-neutral-300);font:var(--vvd-typography-base);text-align:center;justify-content:center;align-items:center;min-block-size:40px;display:flex}::part(popup-base){inline-size:max-content;min-inline-size:var(--_searchable-select-fixed-width,100%)}slot[name=icon]{font-size:var(--_searchable-select-icon-size)}.visually-hidden{clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}::slotted([data-vvd-component=option][data-highlighted]),[data-select-all][data-highlighted]{box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));--focus-stroke-gap-color:transparent;border-radius:8px}.divider{margin-block:10px;margin-inline:12px}";
14
+ import { n as applyHostSemantics, t as HostSemantics } from "./host-semantics.js";
15
+ import { n as WithLightDOMFeedback, r as feedbackMessageDefinition } from "./mixins.js";
16
+ import { r as ListboxOption, t as listboxOptionDefinition } from "./definition29.js";
17
+ import { t as Listbox } from "./listbox.js";
18
+ import { Observable, Updates, attr, html, observable, ref, slotted, volatile, when } from "@microsoft/fast-element";
19
+ import { classNames, inRange, keyArrowDown, keyArrowUp, keyEnd, keyEnter, keyEscape, keyHome, keySpace, keyTab, uniqueId } from "@microsoft/fast-web-utilities";
20
+ //#region src/lib/select/select.scss?inline
21
+ var select_default = ".label-wrapper{align-items:center;gap:var(--label-wrapper-gap,4px);flex-direction:row;display:flex}.label-wrapper[hidden]{display:none}.label:not(slot),.label::slotted(label){flex:0 auto}.chevron{font:var(--vvd-typography-base-extended);flex-shrink:0;transition:transform .2s;display:flex;transform:rotate(0)}:host([data-expanded=true]) .chevron,:host([open]) .chevron{transform:rotate(180deg)}:host(:focus-visible){outline:none}:host{--_low-ink-color:var(--vvd-color-neutral-600);--focus-stroke-gap-color:transparent;flex-direction:column;gap:4px;display:inline-flex}:host([disabled]){--_low-ink-color:var(--vvd-color-neutral-600);cursor:not-allowed}.label{color:var(--vvd-color-canvas-text);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(--vvd-color-neutral-500)}.control.appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}@media (hover:hover){.control: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(--vvd-color-neutral-700)}.control: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.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(--vvd-color-neutral-700)}.control.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:disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control:disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control.disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.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.readonly:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.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.error:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notSet;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:transparent}.control.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.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));border-radius:var(--_select-control-border-radius);block-size:var(--_select-block-size);padding-inline:var(--_select-padding-inline);--_select-icon-size:calc(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(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);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);justify-content:space-between;align-items:center;gap:8px;transition:box-shadow .2s,background-color .2s;display:flex}.control.size-condensed{--_select-icon-size:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);--_select-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 8));--_select-padding-inline:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16)) / 2)}.control.size-condensed:not(.shape-pill){--_select-control-border-radius:4px}.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}.listbox{max-height:var(--select-height,408px);flex-direction:column;gap:2px;padding:4px;display:flex;overflow-y:auto}:host([multiple]:focus-visible) .listbox{box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));border-radius:8px}.selected-value{white-space:nowrap;flex-grow:1;align-items:center;column-gap:12px;display:flex;overflow:hidden}.selected-value .text{text-overflow:ellipsis;max-inline-size:100%;overflow:hidden}.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}@supports selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant,:has(.clear-button:focus)){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}@supports not selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}:host(:not([multiple]):focus-visible) ::slotted([data-vvd-component=option][current-selected]){box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));--focus-stroke-gap-color:transparent;border-radius:8px}:host([multiple]) .clear-button{margin-inline-start:auto}:host([multiple][clearable]) .label-wrapper{min-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16))}";
24
22
  //#endregion
25
- //#region src/lib/searchable-select/option-tag.scss?inline
26
- var option_tag_default = ":host{display:block}.base.connotation-cta{--_connotation-color-contrast:var(--vvd-option-tag-cta-contrast,var(--vvd-color-cta-800))}.base:not(.connotation-cta){--_connotation-color-contrast:var(--vvd-option-tag-accent-contrast,var(--vvd-color-neutral-800))}.base{--_option-tag-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16));box-sizing:border-box;background-color:var(--fill-color);block-size:var(--_option-tag-block-size);box-shadow:inset 0 0 0 1px var(--outline-color);color:var(--text-color);font:var(--vvd-typography-base-bold);user-select:none;align-items:center;column-gap:8px;max-inline-size:100%;padding-inline:8px;display:flex;position:relative}.base.size-condensed{--_option-tag-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 20));padding-inline:4px}.base:not(.disabled){--text-color:var(--_connotation-color-contrast);--fill-color:var(--_connotation-color-soft);--outline-color:transparent}@supports (background-color:color-mix(in srgb, black 50%, white)){.base:not(.disabled){--fill-color:color-mix(in srgb, var(--_connotation-color-contrast), transparent 87.5%)}}.base.disabled{--text-color:var(--vvd-color-neutral-300);--fill-color:var(--vvd-color-neutral-200);--outline-color:transparent}@supports (background-color:color-mix(in srgb, black 50%, white)){.base.disabled{--fill-color:color-mix(in srgb, var(--vvd-color-neutral-800), transparent 87.5%)}}.base:not(.shape-pill){border-radius:4px}.base.shape-pill{border-radius:16px}.label{text-overflow:ellipsis;white-space:nowrap;max-inline-size:100%;overflow:hidden}slot[name=icon]{font-size:calc(var(--_option-tag-block-size) / 1.5);line-height:1}.icon-placeholder{inline-size:calc(var(--_option-tag-block-size) / 1.5)}.remove-button{border-radius:inherit;cursor:pointer;outline:none;align-items:center;display:flex}.disabled .remove-button{pointer-events:none}.remove-button:focus-visible:before{--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in srgb, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));z-index:1;border-radius:inherit;content:\"\";pointer-events:none;display:block;position:absolute;inset:0}";
27
- //#endregion
28
- //#region src/lib/searchable-select/searchable-select.ts
29
- var TagGapPx = 8;
30
- var InputMinWidthPx = 100;
31
- var PageSize = 10;
32
- var isFormAssociatedTryingToSetFormValue = (value) => typeof value === "string";
23
+ //#region src/lib/select/select.ts
33
24
  /**
34
25
  * @public
35
- * @component searchable-select
36
- * @slot - Holds the available options.
37
- * @slot icon - The preferred way to add an icon to the control.
38
- * @slot meta - Slot to add meta content to the control.
39
- * @slot helper-text - Describes how to use the component. Alternative to the `helper-text` attribute.
40
- * @slot no-options - Message that appears when no options are available.
41
- * @slot no-matches - Message that appears when no options match the search query.
42
- * @slot loading-options - Message that appears there are no options to display and the component is in a loading state.
43
- * @event {CustomEvent<undefined>} input - Fired when the selected options change
44
- * @event {CustomEvent<undefined>} search-text-change - Fired when the search text changes
45
- * @event {CustomEvent<undefined>} change - Fired when the selected options change
26
+ * @component select
27
+ * @slot - Default slot.
28
+ * @slot icon - The preferred way to add an icon to the select control.
29
+ * @slot meta - Slot to add meta content to the select control.
30
+ * @slot helper-text - Describes how to use the select. Alternative to the `helper-text` attribute.
31
+ * @event {CustomEvent<undefined>} input - Fires a custom 'input' event when the value updates
32
+ * @event {CustomEvent<HTMLElement>} change - Fires a custom 'change' event when the value updates
46
33
  * @vueModel modelValue value input,@lazy:change `event.currentTarget.value`
47
- * @vueModel values values input,@lazy:change `event.currentTarget.values`
48
34
  * @testAction selectOptionByValue selectOptionByValue
49
35
  * @testAction selectOptionByText selectOptionByText
50
- * @testQuery values values
51
- * @testQuery selectedOptions selectedOptionsText
52
36
  */
53
- var SearchableSelect = class extends WithContextualHelp(WithFeedback(WithErrorText(WithSuccessText(FormElement(DelegatesAria(AffixIconWithTrailing(Localized(FormAssociated(VividElement))))))))) {
37
+ var Select = class extends WithLightDOMFeedback(WithContextualHelp(WithErrorText(WithSuccessText(Localized(FormElement(HostSemantics(AffixIconWithTrailing(FormAssociated(Listbox))))))))) {
54
38
  constructor(..._args) {
55
39
  super(..._args);
56
- this.fixedDropdown = false;
40
+ this.proxy = document.createElement("select");
41
+ this.activeIndex = -1;
42
+ this.rangeStartIndex = -1;
57
43
  this.open = false;
58
- this.multiple = false;
59
- this.externalTags = false;
60
- this.maxLines = null;
61
- this.values = [];
62
- this.initialValues = [];
63
- this._currentSearchText = null;
64
- this._areOptionsInitialized = false;
65
- this.#slottedOptionsChangeHandler = { handleChange: (source, _) => {
66
- if (source.selected && !this.values.includes(source.value)) this.values = [...this.values, source.value];
67
- else if (!source.selected && this.values.includes(source.value)) this.values = this.values.filter((option) => option !== source.value);
68
- } };
69
- this.#clonedTagIcons = /* @__PURE__ */ new Map();
70
- this._filteredOptions = [];
71
- this._filteredEnabledOptions = [];
72
- this.loading = false;
73
- this._highlightedOptionIndex = null;
74
- this._numElidedTags = 0;
75
- this._tagRows = [];
76
- this._lastTagRow = [];
44
+ this.listboxId = uniqueId("listbox-");
45
+ this.maxHeight = 0;
46
+ this.fixedDropdown = false;
47
+ this._feedbackWrapper = null;
48
+ this._isResetting = false;
77
49
  this.clearable = false;
78
- this.maxSelected = null;
79
- this._slottedDisabledOptions = [];
80
- this.enableSelectAll = false;
81
- this.proxy = document.createElement("input");
82
- this.setFormValue = (value, state) => {
83
- if (isFormAssociatedTryingToSetFormValue(value)) return;
84
- super.setFormValue(value, state);
85
- };
86
- this._changeDescription = "";
87
- this.#resizeObserver = new ResizeObserver(() => {
88
- this.#updateTagLayout();
89
- });
50
+ this._isClearButtonFocused = false;
90
51
  }
91
52
  /**
53
+ * Returns the last checked option.
54
+ *
92
55
  * @internal
93
56
  */
94
- openChanged() {
95
- if (!this.open) this.#transitionHighlightedOptionTo(null);
57
+ get activeOption() {
58
+ return this.options[this.activeIndex];
96
59
  }
97
60
  /**
61
+ * Returns the list of checked options.
62
+ *
98
63
  * @internal
99
64
  */
100
- valuesChanged() {
101
- if (!this._areOptionsInitialized) return;
102
- if (!this.multiple && this.values.length > 1) {
103
- this.values = [this.values[0]];
104
- return;
105
- }
106
- if (this.values.some((value) => !this.#isValidValue(value))) {
107
- this.values = this.values.filter((value) => this.#isValidValue(value));
108
- return;
109
- }
110
- this.value = this.values.length ? this.values[0] : "";
111
- this.#updateSelectionLimit();
112
- this.#updateSelectedOnSlottedOptions();
113
- if (this.$fastController.isConnected) this.#updateTagLayout();
114
- this.#updateFormValue();
115
- }
116
- #updateValuesThroughUserInteraction(newValues) {
117
- this.values = newValues;
118
- this.$emit("change", void 0, { bubbles: false });
119
- this.$emit("input", void 0, { bubbles: false });
120
- }
121
- #updateValuesWhileMaintainingOrder(newValues) {
122
- const oldSet = new Set(this.values);
123
- const newSet = new Set(newValues);
124
- this.values = [...this.values].filter((v) => newSet.has(v)).concat([...newValues].filter((v) => !oldSet.has(v)));
65
+ get checkedOptions() {
66
+ return this.options.filter((o) => o.checked);
125
67
  }
126
68
  /**
69
+ * Returns the index of the first selected option.
70
+ *
127
71
  * @internal
128
72
  */
129
- initialValuesChanged() {
130
- if (!this.dirtyValue) {
131
- this.values = this.initialValues;
132
- this.dirtyValue = false;
133
- }
134
- }
135
- #isValidValue(value) {
136
- return this._slottedOptions.some((option) => option.value === value);
73
+ get firstSelectedOptionIndex() {
74
+ return this.options.indexOf(this.firstSelectedOption);
137
75
  }
138
76
  /**
77
+ * Updates the `ariaActiveDescendant` property when the active index changes.
78
+ *
139
79
  * @internal
140
80
  */
141
- valueChanged(prev, next) {
142
- super.valueChanged(prev, next);
143
- if (!this._areOptionsInitialized) return;
144
- const isValidValue = this._slottedOptions.some((option) => option.value === next);
145
- if (this.values[0] !== next) this.values = isValidValue ? [next] : [];
146
- }
147
- get selectedIndex() {
148
- if (this.values.length) return this._slottedOptions.findIndex((option) => option.value === this.values[0]);
149
- else return -1;
150
- }
151
- set selectedIndex(index) {
152
- this.value = this._slottedOptions[index]?.value ?? "";
153
- }
154
- get options() {
155
- return [...this._slottedOptions];
156
- }
157
- get selectedOptions() {
158
- return this._slottedOptions.filter((option) => this.values.includes(option.value));
159
- }
160
- /**
161
- * @internal
162
- */
163
- _currentSearchTextChanged() {
164
- this.#updateFilteredOptions();
165
- this.$emit("search-text-change", void 0, {
166
- bubbles: false,
167
- composed: false
168
- });
169
- }
170
- /**
171
- * Read-only property containing the current search text.
172
- */
173
- get searchText() {
174
- return this._currentSearchText ?? "";
175
- }
176
- /**
177
- * @internal
178
- */
179
- get _inputValue() {
180
- return this._currentSearchText ?? (!this.multiple && this.value !== "" ? this.#textForValue(this.value) ?? "" : "");
81
+ activeIndexChanged(_, next) {
82
+ this._activeDescendant = this.options[next]?.id ?? "";
83
+ this.focusAndScrollOptionIntoView();
181
84
  }
182
85
  /**
86
+ * Toggles the checked state for the currently active option.
87
+ *
88
+ * @remarks
89
+ * Multiple-selection mode only.
90
+ *
183
91
  * @internal
184
92
  */
185
- _onInputInput(event) {
186
- this._currentSearchText = event.target.value;
187
- }
188
- /**
189
- * @internal
190
- */
191
- _onInputFocus(_) {
192
- this.#updateFilteredOptions();
193
- }
194
- /**
195
- * @internal
196
- */
197
- _onInputBlur(_) {
198
- this.open = false;
199
- this._currentSearchText = null;
200
- this._changeDescription = "";
201
- }
202
- /**
203
- * @internal
204
- */
205
- _onInputKeydown(e) {
206
- if (e.ctrlKey || e.shiftKey) return true;
207
- switch (e.key) {
208
- case "Enter":
209
- this.#selectHighlightedOption();
210
- if (this._inputValue === "") this.open = !this.open;
211
- return false;
212
- case "Escape":
213
- this.open = false;
214
- break;
215
- case "Home":
216
- if (!this.open) {
217
- this.open = true;
218
- break;
219
- }
220
- this.#highlightFirstOption();
221
- return false;
222
- case "End":
223
- if (!this.open) {
224
- this.open = true;
225
- break;
226
- }
227
- this.#highlightLastOption();
228
- return false;
229
- case "PageUp":
230
- if (!this.open) {
231
- this.open = true;
232
- break;
233
- }
234
- this.#highlightPrevPage();
235
- return false;
236
- case "PageDown":
237
- if (!this.open) {
238
- this.open = true;
239
- break;
240
- }
241
- this.#highlightNextPage();
242
- return false;
243
- case "ArrowUp":
244
- if (!this.open) {
245
- this.open = true;
246
- break;
247
- }
248
- this.#highlightPreviousOption();
249
- return false;
250
- case "ArrowDown":
251
- if (!this.open) {
252
- this.open = true;
253
- break;
254
- }
255
- this.#highlightNextOption();
256
- return false;
257
- case "ArrowLeft":
258
- if (this.multiple && this._inputValue === "" && this.values.length && !this.externalTags) {
259
- this.#moveTagFocusTo(this.#nextTagIndexLeft(this.values.length));
260
- return false;
261
- }
262
- return true;
263
- case "Backspace":
264
- if (this.multiple && this._inputValue === "" && this.values.length) {
265
- this._onTagRemoved(this.values[this.values.length - 1]);
266
- return false;
267
- }
268
- return true;
269
- default:
270
- /* v8 ignore next -- @preserve */
271
- if (!this.open) this.open = true;
272
- return true;
93
+ checkActiveIndex() {
94
+ const activeItem = this.activeOption;
95
+ /* v8 ignore else -- @preserve */
96
+ if (activeItem) activeItem.checked = true;
97
+ }
98
+ /**
99
+ * Sets the active index to the first option and marks it as checked.
100
+ *
101
+ * @remarks
102
+ * Multi-selection mode only.
103
+ *
104
+ * @param preserveChecked - mark all options unchecked before changing the active index
105
+ *
106
+ * @internal
107
+ */
108
+ checkFirstOption(preserveChecked) {
109
+ const firstSelectableIndex = this.getNextSelectableIndex(0);
110
+ if (firstSelectableIndex === -1) return;
111
+ if (preserveChecked) {
112
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
113
+ this.options.forEach((o, i) => {
114
+ o.checked = inRange(i, firstSelectableIndex, this.rangeStartIndex + 1) && !o.disabled;
115
+ });
116
+ } else this.uncheckAllOptions();
117
+ this.activeIndex = firstSelectableIndex;
118
+ this.checkActiveIndex();
119
+ }
120
+ /**
121
+ * Decrements the active index and sets the matching option as checked.
122
+ *
123
+ * @remarks
124
+ * Multi-selection mode only.
125
+ *
126
+ * @param preserveChecked - mark all options unchecked before changing the active index
127
+ *
128
+ * @internal
129
+ */
130
+ checkLastOption(preserveChecked) {
131
+ const lastSelectableIndex = this.getPreviousSelectableIndex(this.length - 1);
132
+ if (lastSelectableIndex === -1) return;
133
+ if (preserveChecked) {
134
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
135
+ this.options.forEach((o, i) => {
136
+ o.checked = inRange(i, this.rangeStartIndex, lastSelectableIndex + 1) && !o.disabled;
137
+ });
138
+ } else this.uncheckAllOptions();
139
+ this.activeIndex = lastSelectableIndex;
140
+ this.checkActiveIndex();
141
+ }
142
+ /**
143
+ * Increments the active index and marks the matching option as checked.
144
+ *
145
+ * @remarks
146
+ * Multiple-selection mode only.
147
+ *
148
+ * @param preserveChecked - mark all options unchecked before changing the active index
149
+ *
150
+ * @internal
151
+ */
152
+ checkNextOption(preserveChecked) {
153
+ const nextIndex = this.getNextSelectableIndex(this.activeIndex + 1);
154
+ if (nextIndex === -1) return;
155
+ if (preserveChecked) {
156
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
157
+ this.options.forEach((o, i) => {
158
+ o.checked = inRange(i, this.rangeStartIndex, nextIndex + 1) && !o.disabled;
159
+ });
160
+ } else this.uncheckAllOptions();
161
+ this.activeIndex = nextIndex;
162
+ this.checkActiveIndex();
163
+ }
164
+ /**
165
+ * Decrements the active index and marks the matching option as checked.
166
+ *
167
+ * @remarks
168
+ * Multiple-selection mode only.
169
+ *
170
+ * @param preserveChecked - mark all options unchecked before changing the active index
171
+ *
172
+ * @internal
173
+ */
174
+ checkPreviousOption(preserveChecked) {
175
+ const previousIndex = this.getPreviousSelectableIndex(this.activeIndex - 1);
176
+ if (previousIndex === -1) return;
177
+ if (preserveChecked) {
178
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
179
+ if (this.checkedOptions.length === 1) this.rangeStartIndex += 1;
180
+ this.options.forEach((o, i) => {
181
+ o.checked = inRange(i, previousIndex, this.rangeStartIndex + 1) && !o.disabled;
182
+ });
183
+ } else this.uncheckAllOptions();
184
+ this.activeIndex = previousIndex;
185
+ this.checkActiveIndex();
186
+ }
187
+ /**
188
+ * @internal
189
+ */
190
+ focusAndScrollOptionIntoView() {
191
+ super.focusAndScrollOptionIntoView(this.activeOption);
192
+ }
193
+ /**
194
+ * In multiple-selection mode:
195
+ * If any options are selected, the first selected option is checked when
196
+ * the listbox receives focus. If no options are selected, the first
197
+ * selectable option is checked.
198
+ *
199
+ * @internal
200
+ */
201
+ focusinHandler(e) {
202
+ if (!this.multiple) return super.focusinHandler(e);
203
+ /* v8 ignore else -- @preserve */
204
+ if (!this.shouldSkipFocus && e.target === e.currentTarget) {
205
+ this.uncheckAllOptions();
206
+ if (this.activeIndex === -1) this.activeIndex = this.firstSelectedOptionIndex !== -1 ? this.firstSelectedOptionIndex : 0;
207
+ this.checkActiveIndex();
208
+ this.setSelectedOptions();
209
+ this.focusAndScrollOptionIntoView();
273
210
  }
274
- return true;
211
+ this.shouldSkipFocus = false;
275
212
  }
276
213
  /**
277
- * @internal
214
+ * Sets an option as selected and gives it focus.
215
+ *
216
+ * @public
278
217
  */
279
- _slottedOptionsChanged(oldValue, newValue) {
280
- const hasSlottedOptions = Boolean(this.querySelectorAll(`:not([slot])`).length);
281
- if (!newValue.length && hasSlottedOptions) return;
282
- this._areOptionsInitialized = true;
283
- if (oldValue) {
284
- this._slottedDisabledOptions = [];
285
- for (const option of oldValue) Observable.getNotifier(option).unsubscribe(this.#slottedOptionsChangeHandler, "selected");
218
+ setSelectedOptions() {
219
+ if (!this.multiple) {
220
+ super.setSelectedOptions();
221
+ return;
286
222
  }
287
223
  /* v8 ignore else -- @preserve */
288
- if (newValue) for (const option of newValue) {
289
- option._displayCheckmark = true;
290
- Observable.getNotifier(option).subscribe(this.#slottedOptionsChangeHandler, "selected");
224
+ if (this.$fastController.isConnected && this.options) {
225
+ this.selectedOptions = this.options.filter((o) => o.selected);
226
+ this.focusAndScrollOptionIntoView();
291
227
  }
292
- const values = [];
293
- for (const option of this._slottedOptions) {
294
- if (option.selected || option.value === this.value || this.values.includes(option.value)) values.push(option.value);
295
- if (option.disabled) this._slottedDisabledOptions.push(option);
296
- }
297
- this.#updateValuesWhileMaintainingOrder(values);
298
- this.#updateFilteredOptions();
299
- this.#updateSelectionLimit();
300
- }
301
- #slottedOptionsChangeHandler;
302
- #updateSelectedOnSlottedOptions() {
303
- for (const option of this._slottedOptions) {
304
- option.selected = this.values.includes(option.value);
305
- this.#updateClonedTagIconOfOption(option);
306
- }
307
- }
308
- #handleOptionInteraction(option) {
309
- const value = option.value;
310
- let newValues;
311
- let shouldClearSearchText = false;
312
- const isSelection = !this.values.includes(value);
313
- if (this.multiple) {
314
- if (isSelection) newValues = [...this.values, value];
315
- else newValues = this.values.filter((option) => option !== value);
316
- shouldClearSearchText = true;
317
- } else {
318
- if (isSelection) {
319
- newValues = [value];
320
- shouldClearSearchText = true;
321
- } else newValues = [];
322
- this.open = false;
323
- }
324
- this.#updateValuesThroughUserInteraction(newValues);
325
- const optionMessage = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option._getAccessibleName()) : this.locale.searchableSelect.optionDeselectedMessage(option._getAccessibleName());
326
- const maxSelectedMessage = this.multiple && this.maxSelected && this.maxSelected >= 1 ? this.locale.searchableSelect.maxSelectedMessage(this.values.length, this.maxSelected) : "";
327
- this._changeDescription = `${optionMessage} ${maxSelectedMessage}`;
328
- if (shouldClearSearchText) this._currentSearchText = null;
329
- }
330
- #clonedTagIcons;
331
- #tagIconOfOption(option) {
332
- return option.querySelector("[slot=\"tag-icon\"]");
333
228
  }
334
229
  /**
230
+ * Toggles the selected state of the provided options. If any provided items
231
+ * are in an unselected state, all items are set to selected. If every
232
+ * provided item is selected, they are all unselected.
233
+ *
335
234
  * @internal
336
235
  */
337
- _tagIconSlotName(value) {
338
- return `_tag-icon-${this.values.indexOf(value)}`;
236
+ toggleSelectedForAllCheckedOptions() {
237
+ const enabledCheckedOptions = this.checkedOptions.filter((o) => !o.disabled);
238
+ const force = !enabledCheckedOptions.every((o) => o.selected);
239
+ enabledCheckedOptions.forEach((o) => o.selected = force);
240
+ this.selectedIndex = this.options.indexOf(enabledCheckedOptions[enabledCheckedOptions.length - 1]);
241
+ this.setSelectedOptions();
242
+ this.updateValue(true);
339
243
  }
340
- #updateClonedTagIconOfOption(option) {
341
- if (option.selected && this.#tagIconOfOption(option)) {
342
- let clone = this.#clonedTagIcons.get(option);
343
- /* v8 ignore else -- @preserve */
344
- if (!clone) {
345
- clone = this.#tagIconOfOption(option).cloneNode(true);
346
- this.#clonedTagIcons.set(option, clone);
347
- }
348
- clone.slot = this._tagIconSlotName(option.value);
349
- this.appendChild(clone);
350
- } else {
351
- const clone = this.#clonedTagIcons.get(option);
352
- if (clone) {
353
- clone.remove();
354
- this.#clonedTagIcons.delete(option);
244
+ /**
245
+ * @internal
246
+ */
247
+ typeaheadBufferChanged(prev, next) {
248
+ if (!this.multiple) {
249
+ super.typeaheadBufferChanged(prev, next);
250
+ return;
251
+ }
252
+ /* v8 ignore if -- @preserve */
253
+ if (this.$fastController.isConnected) {
254
+ const typeaheadMatches = this.getTypeaheadMatches();
255
+ const activeIndex = this.options.indexOf(typeaheadMatches[0]);
256
+ if (activeIndex > -1) {
257
+ this.activeIndex = activeIndex;
258
+ this.uncheckAllOptions();
259
+ this.checkActiveIndex();
355
260
  }
261
+ this.typeaheadExpired = false;
356
262
  }
357
263
  }
358
264
  /**
265
+ * Unchecks all options.
266
+ *
267
+ * @remarks
268
+ * Multiple-selection mode only.
269
+ *
270
+ * @param preserveChecked - reset the rangeStartIndex
271
+ *
359
272
  * @internal
360
273
  */
361
- optionFilterChanged() {
362
- this.#updateFilteredOptions();
274
+ uncheckAllOptions(preserveChecked = false) {
275
+ this.options.forEach((o) => o.checked = false);
276
+ /* v8 ignore else -- @preserve */
277
+ if (!preserveChecked) this.rangeStartIndex = -1;
363
278
  }
364
279
  /**
280
+ * Sets focus when the open property changes.
281
+ *
365
282
  * @internal
366
283
  */
367
- loadingChanged(_oldValue, newValue) {
368
- this._changeDescription = this.locale.searchableSelect.loadingOptionsMessage;
369
- if (_oldValue && !newValue) this._changeDescription = "";
370
- }
371
- #updateFilteredOptions() {
372
- const newFilteredOptions = [];
373
- const optionFilter = this.optionFilter ?? ((option, searchText) => option.text.toLowerCase().includes(searchText.toLowerCase()));
374
- for (const option of this._slottedOptions ?? []) {
375
- option._vvdSearchText = this.searchText;
376
- const matches = !this.searchText || optionFilter(option, this.searchText);
377
- option._isNotMatching = !matches;
378
- if (!option.hidden && matches) newFilteredOptions.push(option);
379
- }
380
- this.#transitionHighlightedOptionTo(null);
381
- this._filteredOptions = newFilteredOptions;
382
- const enabled = newFilteredOptions.filter((o) => !o.disabled);
383
- if (this._selectAllOption) this._filteredEnabledOptions = [this._selectAllOption, ...enabled];
384
- else this._filteredEnabledOptions = enabled;
385
- }
386
- #transitionHighlightedOptionTo(index) {
387
- if (typeof this._highlightedOptionIndex === "number") {
388
- const prevOption = this._filteredEnabledOptions[this._highlightedOptionIndex];
389
- prevOption._highlighted = false;
390
- prevOption.removeAttribute("data-highlighted");
391
- }
392
- if (typeof index === "number") if (!this._filteredEnabledOptions.length) index = null;
393
- else index = Math.max(0, Math.min(this._filteredEnabledOptions.length - 1, index));
394
- this._highlightedOptionIndex = index;
395
- if (typeof this._highlightedOptionIndex === "number") {
396
- const highlightedOption = this._filteredEnabledOptions[this._highlightedOptionIndex];
397
- highlightedOption._highlighted = true;
398
- highlightedOption.setAttribute("data-highlighted", "");
399
- scrollIntoView(highlightedOption, this._listbox, "nearest");
400
- this._changeDescription = this.locale.searchableSelect.optionFocusedMessage(highlightedOption._getAccessibleName(), this._highlightedOptionIndex + 1, this._filteredEnabledOptions.length, highlightedOption.selected);
401
- }
402
- }
403
- #selectHighlightedOption() {
404
- if (this._highlightedOptionIndex === null) return;
405
- const highlightedOption = this._filteredEnabledOptions[this._highlightedOptionIndex];
406
- if (highlightedOption.getAttribute("data-select-all") !== null) {
407
- this._toggleSelectAll();
284
+ openChanged(prev, next) {
285
+ if (!this.collapsible) return;
286
+ if (this.open) {
287
+ this.focusAndScrollOptionIntoView();
288
+ this.indexWhenOpened = this.selectedIndex;
289
+ Updates.enqueue(() => this.focus());
408
290
  return;
409
291
  }
410
- this.#handleOptionInteraction(highlightedOption);
411
- }
412
- #highlightFirstOption() {
413
- this.#transitionHighlightedOptionTo(0);
414
- }
415
- #highlightLastOption() {
416
- this.#transitionHighlightedOptionTo(this._filteredEnabledOptions.length - 1);
417
- }
418
- #highlightPrevPage() {
419
- this.#transitionHighlightedOptionTo((this._highlightedOptionIndex ?? this._filteredEnabledOptions.length) - PageSize);
420
- }
421
- #highlightNextPage() {
422
- this.#transitionHighlightedOptionTo((this._highlightedOptionIndex ?? -1) + PageSize);
423
- }
424
- #highlightPreviousOption() {
425
- this.#transitionHighlightedOptionTo((this._highlightedOptionIndex ?? this._filteredEnabledOptions.length) - 1);
426
- }
427
- #highlightNextOption() {
428
- this.#transitionHighlightedOptionTo((this._highlightedOptionIndex ?? -1) + 1);
429
- }
430
- /**
431
- * @internal
432
- */
433
- _tagLabelForValue(value) {
434
- return this._slottedOptions.find((option) => option.value === value).label;
292
+ const didClose = prev === true && next === false;
293
+ const selectionChangedWhileOpen = this.indexWhenOpened !== this.selectedIndex;
294
+ if (didClose && selectionChangedWhileOpen) this.updateValue(true);
435
295
  }
436
296
  /**
297
+ * The component is collapsible when in single-selection mode.
298
+ *
437
299
  * @internal
438
300
  */
439
- _tagConnotationForValue(value) {
440
- return this._slottedOptions.find((option) => option.value === value).tagConnotation;
301
+ get collapsible() {
302
+ return !this.multiple;
441
303
  }
442
304
  /**
443
305
  * @internal
444
306
  */
445
- _isTagDisabled(value) {
446
- const option = this._slottedOptions.find((option) => option.value === value);
447
- return this.disabled || option.disabled;
448
- }
449
- #textForValue(value) {
450
- return (this._slottedOptions?.find((option) => option.value === value))?.label;
307
+ valueChanged(prev, next) {
308
+ const nextSelectedIndex = this.options.findIndex((el) => el.value === next);
309
+ const validNextSelectedIndex = this._validSelectedIndex(nextSelectedIndex);
310
+ const nextValue = this.options[validNextSelectedIndex]?.value ?? "";
311
+ if (this.selectedIndex !== validNextSelectedIndex) this.selectedIndex = validNextSelectedIndex;
312
+ if (next !== nextValue) return;
313
+ super.valueChanged(prev, next);
314
+ this.updateDisplayValue();
451
315
  }
452
316
  /**
317
+ * Sets the value and display value to match the first selected option.
318
+ *
319
+ * @param shouldEmit - if true, the input and change events will be emitted
320
+ *
453
321
  * @internal
454
322
  */
455
- #measureTagWidth(label, removable, hasIcon) {
456
- const tag = document.createElement(this._optionTagTagName);
457
- tag.label = label;
458
- tag.removable = removable;
459
- tag.style.cssText = "position: absolute; visibility: hidden;";
460
- tag.hasIconPlaceholder = hasIcon;
461
- this.shadowRoot.appendChild(tag);
462
- const width = tag.getBoundingClientRect().width;
463
- tag.remove();
464
- return width;
465
- }
466
- #updateTagLayout() {
467
- if (!this.multiple) {
468
- this._numElidedTags = 0;
469
- this._tagRows = [];
470
- this._lastTagRow = [];
471
- return;
472
- }
473
- if (this.externalTags) {
474
- this._numElidedTags = this.values.length;
475
- this._tagRows = [];
476
- this._lastTagRow = [];
477
- return;
323
+ updateValue(shouldEmit) {
324
+ if (this.$fastController.isConnected) this.value = this.firstSelectedOption?.value ?? "";
325
+ if (shouldEmit) {
326
+ this.$emit("input");
327
+ this.$emit("change", this, {
328
+ bubbles: true,
329
+ composed: void 0
330
+ });
478
331
  }
479
- const rowWidth = this._contentArea.getBoundingClientRect().width;
480
- const rows = [[]];
481
- let currentRowIndex = 0;
482
- let currentRowWidth = InputMinWidthPx;
483
- let i;
484
- for (i = this.values.length - 1; i >= 0; i--) {
485
- const isLastRow = this.maxLines && currentRowIndex === this.maxLines - 1;
486
- const tagWidth = this.#measureTagWidth(this._tagLabelForValue(this.values[i]), true, this.#tagIconOfOption(this.selectedOptions[i]) !== null);
487
- const entry = {
488
- value: this.values[i],
489
- width: tagWidth
490
- };
491
- let elidedTagCounterWidth = 0;
492
- if (isLastRow) {
493
- const numElidedTags = i;
494
- if (numElidedTags) elidedTagCounterWidth = TagGapPx + this.#measureTagWidth(numElidedTags.toString(), false, false);
495
- }
496
- if (currentRowWidth + TagGapPx + tagWidth + elidedTagCounterWidth > rowWidth) {
497
- if (isLastRow) if (i === this.values.length - 1) {
498
- rows[currentRowIndex].unshift(entry);
499
- currentRowWidth += TagGapPx + tagWidth;
500
- } else break;
501
- else {
502
- rows.push([]);
503
- currentRowIndex++;
504
- rows[currentRowIndex].unshift(entry);
505
- currentRowWidth = tagWidth;
506
- }
507
- continue;
508
- }
509
- rows[currentRowIndex].unshift(entry);
510
- currentRowWidth += TagGapPx + tagWidth;
511
- }
512
- this._numElidedTags = i + 1;
513
- rows.reverse();
514
- for (let i = 0; i < rows.length - 1; i++) {
515
- let lineWidth = rows[i].map((e) => e.width).reduce((a, b) => a + b, 0) + (rows[i].length - 1) * TagGapPx;
516
- if (i === 0 && this._numElidedTags) lineWidth += TagGapPx + this.#measureTagWidth(this._numElidedTags.toString(), false, false);
517
- while (rows[i + 1].length && lineWidth + TagGapPx + rows[i + 1][0].width <= rowWidth) {
518
- const nextTag = rows[i + 1].shift();
519
- rows[i].push(nextTag);
520
- lineWidth += TagGapPx + nextTag.width;
521
- }
522
- }
523
- const rowValues = rows.map((line) => line.map((entry) => entry.value));
524
- this._tagRows = rowValues.slice(0, -1);
525
- this._lastTagRow = rowValues.slice(-1)[0];
526
332
  }
527
333
  /**
334
+ * Updates the proxy value when the selected index changes.
335
+ *
336
+ * @param prev - the previous selected index
337
+ * @param next - the next selected index
338
+ *
528
339
  * @internal
529
340
  */
530
- _onTagRemoved(value) {
531
- this.#updateValuesThroughUserInteraction(this.values.filter((option) => option !== value));
532
- this.#updateFilteredOptions();
341
+ selectedIndexChanged(prev, next) {
342
+ super.selectedIndexChanged(prev, next);
343
+ this.updateValue();
533
344
  }
534
345
  /**
346
+ * Handle opening and closing the listbox when the select is clicked.
347
+ *
348
+ * @param e - the mouse event
535
349
  * @internal
536
350
  */
537
- _onTagKeydown(event) {
538
- const tagIndex = parseInt(event.target.dataset.index);
539
- switch (event.key) {
540
- case "Backspace":
541
- case "Delete":
542
- case "Enter":
543
- case " ":
544
- this._onTagRemoved(this.values[tagIndex]);
545
- Updates.process();
546
- this.#moveTagFocusTo(this.#nextTagIndexForRemoved(tagIndex));
547
- break;
548
- case "ArrowLeft":
549
- this.#moveTagFocusTo(this.#nextTagIndexLeft(tagIndex) ?? tagIndex);
550
- break;
551
- case "ArrowRight":
552
- this.#moveTagFocusTo(this.#nextTagIndexRight(tagIndex));
553
- break;
554
- }
351
+ clickHandler(e) {
352
+ if (this.disabled || this._isFromContextualHelp(e)) return;
353
+ const clickedOption = e.target.closest(`option,[role=option],[data-vvd-component=option]`);
354
+ if (clickedOption && clickedOption.disabled) return;
355
+ if (this.multiple) {
356
+ this.uncheckAllOptions();
357
+ this.activeIndex = this.options.indexOf(clickedOption);
358
+ this.checkActiveIndex();
359
+ this.toggleSelectedForAllCheckedOptions();
360
+ } else super.clickHandler(e);
361
+ if (this.collapsible) this.open = !this.open;
555
362
  return true;
556
363
  }
557
- #moveTagFocusTo(index) {
558
- if (index === null) this._input.focus();
559
- else this.shadowRoot.querySelector(`[data-index="${index}"]`)?.focus();
560
- }
561
- #nextTagIndexLeft(index) {
562
- if (!this.values.length) return null;
563
- for (let i = index - 1; i >= 0; i--) if (!this._isTagDisabled(this.values[i])) return i;
564
- return null;
565
- }
566
- #nextTagIndexRight(index) {
567
- if (!this.values.length) return null;
568
- for (let i = index + 1; i < this.values.length; i++) if (!this._isTagDisabled(this.values[i])) return i;
569
- return null;
570
- }
571
- #nextTagIndexForRemoved(index) {
572
- return this.#nextTagIndexRight(index - 1) ?? this.#nextTagIndexLeft(index);
573
- }
574
364
  /**
365
+ * Handles focus state when the element or its children lose focus.
366
+ *
367
+ * @param e - The focus event
575
368
  * @internal
576
369
  */
577
- _onListboxClick(e) {
578
- if (this.disabled) return;
579
- const capturedOption = e.target.closest(`option,[role=option],[data-vvd-component=option]`);
580
- if (capturedOption?.getAttribute("data-select-all") !== null) {
581
- this._toggleSelectAll();
370
+ focusoutHandler(e) {
371
+ if (this.multiple) this.uncheckAllOptions();
372
+ if (!this.open) return true;
373
+ const focusTarget = e.relatedTarget;
374
+ if (this.isSameNode(focusTarget)) {
375
+ this.focus();
582
376
  return;
583
377
  }
584
- if (capturedOption && !capturedOption.disabled) this.#handleOptionInteraction(capturedOption);
585
- }
586
- /**
587
- * @internal
588
- */
589
- get _shouldShowClearButton() {
590
- return this.clearable && this.values.length > 0;
378
+ /* v8 ignore else -- @preserve */
379
+ if (!this.options.includes(focusTarget)) {
380
+ this.open = false;
381
+ if (this.indexWhenOpened !== this.selectedIndex) this.updateValue(true);
382
+ }
591
383
  }
592
384
  /**
385
+ * Updates the value when an option's value changes.
386
+ *
387
+ * @param source - the source object
388
+ * @param propertyName - the property to evaluate
389
+ *
593
390
  * @internal
594
391
  */
595
- _onClearButtonClick() {
596
- this.#updateValuesThroughUserInteraction(this.selectedOptions.filter((option) => option.disabled).map((option) => option.value));
392
+ handleChange(source, propertyName) {
393
+ super.handleChange(source, propertyName);
394
+ if (propertyName === "value") this.updateValue();
597
395
  }
598
396
  /**
397
+ * Prevents focus when a scrollbar is clicked.
398
+ *
399
+ * @param e - the mouse event object
400
+ *
599
401
  * @internal
600
402
  */
601
- maxSelectedChanged() {
602
- this.#updateSelectionLimit();
603
- }
604
- #updateSelectionLimit() {
605
- if (!this.multiple || !this._slottedOptions || typeof this.maxSelected !== "number" || this.maxSelected <= 0) return;
606
- const options = this._slottedOptions.filter((option) => !this._slottedDisabledOptions.includes(option));
607
- if (this.values.length >= this.maxSelected) {
608
- const unselectedOptions = options.filter((option) => !this.selectedOptions.includes(option));
609
- for (const option of unselectedOptions) option.disabled = true;
610
- } else for (const option of options) option.disabled = false;
403
+ mousedownHandler(e) {
404
+ if (e.offsetX >= 0 && e.offsetX <= this.listbox.scrollWidth) return super.mousedownHandler(e);
405
+ return this.collapsible;
611
406
  }
612
407
  /**
613
408
  * @internal
614
409
  */
615
- get _hasSelectionCount() {
616
- return this.multiple && this.maxSelected && this.maxSelected >= 1;
410
+ multipleChanged(_, next) {
411
+ this.options.forEach((o) => {
412
+ o.checked = next ? false : void 0;
413
+ });
414
+ this.setSelectedOptions();
415
+ /* v8 ignore if -- @preserve */
416
+ if (this.proxy) this.proxy.multiple = next;
617
417
  }
618
418
  /**
419
+ * Updates the selectedness of each option when the list of selected options changes.
420
+ *
421
+ * @param prev - the previous list of selected options
422
+ * @param next - the current list of selected options
423
+ *
619
424
  * @internal
620
425
  */
621
- get _selectableOptions() {
622
- return this._slottedOptions?.filter((o) => !this._slottedDisabledOptions.includes(o) && !o.disabled) ?? [];
426
+ selectedOptionsChanged(prev, next) {
427
+ super.selectedOptionsChanged(prev, next);
428
+ this.options.forEach((o, i) => {
429
+ const proxyOption = this.proxy.options.item(i);
430
+ if (proxyOption) proxyOption.selected = o.selected;
431
+ });
623
432
  }
624
433
  /**
434
+ * Resets and fills the proxy to match the component's options.
435
+ *
625
436
  * @internal
626
437
  */
627
- get _selectAllLabel() {
628
- return this._isAllSelected ? this.deselectAllText ?? this.locale.searchableSelect.deselectAllLabel : this.selectAllText ?? this.locale.searchableSelect.selectAllLabel;
438
+ setProxyOptions() {
439
+ /* v8 ignore else -- @preserve */
440
+ if (this.proxy instanceof HTMLSelectElement && this.options) {
441
+ this.proxy.length = 0;
442
+ this.options.forEach((option) => {
443
+ const proxyOption = option.proxy || (option instanceof HTMLOptionElement ? option.cloneNode() : null);
444
+ if (proxyOption) this.proxy.options.add(proxyOption);
445
+ });
446
+ }
629
447
  }
630
448
  /**
449
+ * Handles keydown actions when the select is in multiple selection mode.
450
+ *
631
451
  * @internal
632
452
  */
633
- get _isAllSelected() {
634
- const selectedValues = this.values;
635
- if (!this.multiple || !this._slottedOptions) return false;
636
- const selectable = this._selectableOptions;
637
- if (selectable.length === 0) return false;
638
- const selected = new Set(selectedValues);
639
- return selectable.every((o) => selected.has(o.value));
453
+ multipleKeydownHandler(e) {
454
+ if (this.disabled) return;
455
+ const { key, shiftKey } = e;
456
+ this.shouldSkipFocus = false;
457
+ switch (key) {
458
+ case keyHome:
459
+ this.checkFirstOption(shiftKey);
460
+ return;
461
+ case keyArrowDown:
462
+ this.checkNextOption(shiftKey);
463
+ return;
464
+ case keyArrowUp:
465
+ this.checkPreviousOption(shiftKey);
466
+ return;
467
+ case keyEnd:
468
+ this.checkLastOption(shiftKey);
469
+ return;
470
+ case keyTab:
471
+ this.focusAndScrollOptionIntoView();
472
+ return;
473
+ case keyEscape:
474
+ this.uncheckAllOptions();
475
+ this.checkActiveIndex();
476
+ return;
477
+ case keySpace:
478
+ e.preventDefault();
479
+ /* v8 ignore else -- @preserve */
480
+ if (this.typeaheadExpired) {
481
+ this.toggleSelectedForAllCheckedOptions();
482
+ return;
483
+ }
484
+ default:
485
+ /* v8 ignore else -- @preserve */
486
+ if (key.length === 1) this.handleTypeAhead(`${key}`);
487
+ return;
488
+ }
640
489
  }
641
490
  /**
491
+ * Handle keyboard interaction for the select.
492
+ *
493
+ * @param e - the keyboard event
642
494
  * @internal
643
495
  */
644
- _toggleSelectAll() {
645
- const selectableValues = this._selectableOptions.map((o) => o.value);
646
- if (this._isAllSelected) {
647
- const updatedValues = this.values.filter((v) => !selectableValues.includes(v));
648
- this.#updateValuesThroughUserInteraction(updatedValues);
649
- this._changeDescription = this.locale.searchableSelect.deselectedAllMessage;
650
- return;
496
+ keydownHandler(e) {
497
+ const selectedIndexBefore = this.selectedIndex;
498
+ if (this.multiple) this.multipleKeydownHandler(e);
499
+ else super.keydownHandler(e);
500
+ switch (e.key) {
501
+ case keySpace:
502
+ e.preventDefault();
503
+ if (this.collapsible && this.typeaheadExpired) this.open = !this.open;
504
+ break;
505
+ case keyHome:
506
+ case keyEnd:
507
+ e.preventDefault();
508
+ break;
509
+ case keyEnter:
510
+ e.preventDefault();
511
+ this.open = !this.open;
512
+ break;
513
+ case keyEscape:
514
+ if (this.collapsible && this.open) {
515
+ e.preventDefault();
516
+ this.open = false;
517
+ }
518
+ break;
519
+ case keyTab:
520
+ if (this.collapsible && this.open) {
521
+ e.preventDefault();
522
+ this.open = false;
523
+ }
524
+ return true;
651
525
  }
652
- const missingValues = selectableValues.filter((v) => !this.values.includes(v));
653
- const updatedValues = [...this.values, ...missingValues];
654
- this.#updateValuesThroughUserInteraction(updatedValues);
655
- this._changeDescription = this.locale.searchableSelect.selectedAllMessage;
526
+ if (this.collapsible && !this.open && this.selectedIndex !== selectedIndexBefore) this.updateValue(true);
527
+ return !(e.key === keyArrowDown || e.key === keyArrowUp);
528
+ }
529
+ connectedCallback() {
530
+ super.connectedCallback();
531
+ this.addEventListener("focusout", this.focusoutHandler);
532
+ this.addEventListener("contentchange", this.updateDisplayValue);
656
533
  }
657
- #determineInitialValues() {
658
- return this.initialValues.length ? this.initialValues : this.initialValue ? [this.initialValue] : [];
534
+ disconnectedCallback() {
535
+ this.removeEventListener("focusout", this.focusoutHandler);
536
+ this.removeEventListener("contentchange", this.updateDisplayValue);
537
+ super.disconnectedCallback();
659
538
  }
660
539
  /**
540
+ *
661
541
  * @internal
662
542
  */
663
- nameChanged(previous, next) {
664
- super.nameChanged(previous, next);
665
- this.#updateFormValue();
543
+ updateDisplayValue() {
544
+ if (this.collapsible) Observable.notify(this, "displayValue");
545
+ }
546
+ get displayValue() {
547
+ Observable.track(this, "displayValue");
548
+ return this.firstSelectedOption?.getAttribute("label") ?? this.firstSelectedOption?.text ?? this.placeholder ?? "";
666
549
  }
667
- #updateFormValue() {
668
- if (!this.name) this.setFormValue(null);
669
- else {
670
- const formData = new FormData();
671
- for (const value of this.values) formData.append(this.name, value);
672
- this.setFormValue(formData);
550
+ _newDefaultSelectedIndex(prev, next, currentSelectIndex) {
551
+ const defaultSelectedIndex = super._newDefaultSelectedIndex(prev, next, currentSelectIndex);
552
+ if (defaultSelectedIndex === null && currentSelectIndex === -1 && !this.placeholder) {
553
+ const firstSelectableIndex = this.getNextSelectableIndex(0);
554
+ if (firstSelectableIndex !== -1) return firstSelectableIndex;
673
555
  }
556
+ return defaultSelectedIndex;
557
+ }
558
+ _isDefaultSelected(option) {
559
+ return super._isDefaultSelected(option) || option.value === this.initialValue || !this._isResetting && option.value === this.value;
560
+ }
561
+ slottedOptionsChanged(prev, next) {
562
+ this.options.forEach((o) => {
563
+ Observable.getNotifier(o).unsubscribe(this, "value");
564
+ });
565
+ super.slottedOptionsChanged(prev, next);
566
+ this.options.forEach((o) => {
567
+ Observable.getNotifier(o).subscribe(this, "value");
568
+ });
569
+ this.setProxyOptions();
570
+ this.updateValue();
571
+ const scale = this.getAttribute("scale") || this.scale;
572
+ next.forEach((element) => {
573
+ if (scale) {
574
+ element.setAttribute("scale", scale);
575
+ element.scale = scale;
576
+ }
577
+ });
578
+ this.proxy.value = this.value;
579
+ this.validate();
674
580
  }
675
- /**
676
- * @internal
677
- */
678
581
  formResetCallback() {
679
- super.formResetCallback();
680
- this.#updateValuesThroughUserInteraction(this.#determineInitialValues());
582
+ this.setProxyOptions();
583
+ this._isResetting = true;
584
+ this.selectedIndex = this._newDefaultSelectedIndex([], this.options, -1) ?? -1;
585
+ this._isResetting = false;
681
586
  }
682
- #resizeObserver;
683
587
  /**
684
588
  * @internal
685
589
  */
686
- _onFieldsetClick(e) {
687
- if (this.disabled) return;
688
- if (!e.defaultPrevented) {
689
- this._input.focus();
690
- this.open = true;
691
- }
590
+ get _shouldShowClearButton() {
591
+ if (!this.clearable) return false;
592
+ if (this.multiple) return this.selectedOptions?.length > 0;
593
+ return this.value !== "";
692
594
  }
693
595
  /**
694
596
  * @internal
695
597
  */
696
- _onChevronClick() {
697
- if (this.open) {
698
- this.open = false;
699
- return false;
700
- }
701
- return true;
702
- }
703
- connectedCallback() {
704
- super.connectedCallback();
705
- if (!this.values.length) this.values = this.#determineInitialValues();
706
- this.#resizeObserver.observe(this._contentArea);
707
- }
708
- disconnectedCallback() {
709
- super.disconnectedCallback();
710
- this.#resizeObserver.disconnect();
598
+ _onClearButtonFocus() {
599
+ this._isClearButtonFocused = true;
600
+ this.activeIndex = -1;
601
+ this.uncheckAllOptions();
711
602
  }
712
603
  /**
713
604
  * @internal
714
605
  */
715
- validate() {
716
- super.validate(this._input ?? void 0);
606
+ _onClearButtonBlur() {
607
+ this._isClearButtonFocused = false;
717
608
  }
718
609
  /**
719
610
  * @internal
720
611
  */
721
- focus(options) {
722
- this._input?.focus(options);
612
+ get _shouldShowLabelWrapper() {
613
+ return Boolean(this.label || this._hasContextualHelp || this.multiple && this._shouldShowClearButton);
723
614
  }
724
615
  /**
725
616
  * @internal
726
617
  */
727
- _onMouseDown(event) {
728
- const originalTarget = event.composedPath()[0];
729
- if (!event.defaultPrevented && originalTarget !== this._input && !this._isFromContextualHelp(event)) {
730
- this._input.focus();
731
- return false;
732
- }
733
- return true;
618
+ _onClearButtonClick() {
619
+ if (this.multiple) this.selectedOptions?.forEach((o) => {
620
+ /* v8 ignore else -- @preserve */
621
+ if (!o.disabled) o.selected = false;
622
+ });
623
+ else this.selectedIndex = -1;
624
+ this.updateValue(true);
734
625
  }
735
626
  };
736
- __decorate([attr], SearchableSelect.prototype, "appearance", void 0);
737
- __decorate([attr], SearchableSelect.prototype, "shape", void 0);
738
- __decorate([attr()], SearchableSelect.prototype, "scale", void 0);
739
- __decorate([attr({
740
- mode: "boolean",
741
- attribute: "fixed-dropdown"
742
- })], SearchableSelect.prototype, "fixedDropdown", void 0);
743
- __decorate([attr], SearchableSelect.prototype, "placeholder", void 0);
744
- __decorate([attr({ mode: "boolean" })], SearchableSelect.prototype, "open", void 0);
745
- __decorate([attr({ mode: "boolean" })], SearchableSelect.prototype, "multiple", void 0);
627
+ __decorate([observable], Select.prototype, "activeIndex", void 0);
628
+ __decorate([attr({ mode: "boolean" })], Select.prototype, "multiple", void 0);
746
629
  __decorate([attr({
747
- attribute: "external-tags",
630
+ attribute: "open",
748
631
  mode: "boolean"
749
- })], SearchableSelect.prototype, "externalTags", void 0);
750
- __decorate([attr({
751
- attribute: "max-lines",
752
- converter: nullableNumberConverter
753
- })], SearchableSelect.prototype, "maxLines", void 0);
754
- __decorate([observable], SearchableSelect.prototype, "values", void 0);
755
- __decorate([observable], SearchableSelect.prototype, "initialValues", void 0);
756
- __decorate([observable], SearchableSelect.prototype, "_input", void 0);
757
- __decorate([observable], SearchableSelect.prototype, "_currentSearchText", void 0);
758
- __decorate([observable], SearchableSelect.prototype, "_slottedOptions", void 0);
759
- __decorate([observable], SearchableSelect.prototype, "optionFilter", void 0);
760
- __decorate([observable], SearchableSelect.prototype, "_filteredOptions", void 0);
761
- __decorate([observable], SearchableSelect.prototype, "_filteredEnabledOptions", void 0);
762
- __decorate([attr({ mode: "boolean" })], SearchableSelect.prototype, "loading", void 0);
763
- __decorate([observable], SearchableSelect.prototype, "_highlightedOptionIndex", void 0);
764
- __decorate([observable], SearchableSelect.prototype, "_contentArea", void 0);
765
- __decorate([observable], SearchableSelect.prototype, "_numElidedTags", void 0);
766
- __decorate([observable], SearchableSelect.prototype, "_tagRows", void 0);
767
- __decorate([observable], SearchableSelect.prototype, "_lastTagRow", void 0);
768
- __decorate([observable], SearchableSelect.prototype, "_listbox", void 0);
769
- __decorate([attr({ mode: "boolean" })], SearchableSelect.prototype, "clearable", void 0);
770
- __decorate([attr({
771
- attribute: "max-selected",
772
- converter: nullableNumberConverter
773
- })], SearchableSelect.prototype, "maxSelected", void 0);
774
- __decorate([observable], SearchableSelect.prototype, "_slottedDisabledOptions", void 0);
632
+ })], Select.prototype, "open", void 0);
633
+ __decorate([volatile], Select.prototype, "collapsible", null);
634
+ __decorate([observable], Select.prototype, "control", void 0);
635
+ __decorate([observable], Select.prototype, "maxHeight", void 0);
636
+ __decorate([observable], Select.prototype, "_anchor", void 0);
637
+ __decorate([attr()], Select.prototype, "scale", void 0);
638
+ __decorate([attr], Select.prototype, "appearance", void 0);
639
+ __decorate([attr], Select.prototype, "shape", void 0);
775
640
  __decorate([attr({
776
- attribute: "enable-select-all",
777
- mode: "boolean"
778
- })], SearchableSelect.prototype, "enableSelectAll", void 0);
779
- __decorate([attr({ attribute: "select-all-text" })], SearchableSelect.prototype, "selectAllText", void 0);
780
- __decorate([attr({ attribute: "deselect-all-text" })], SearchableSelect.prototype, "deselectAllText", void 0);
781
- __decorate([observable], SearchableSelect.prototype, "_selectAllOption", void 0);
782
- __decorate([observable], SearchableSelect.prototype, "_changeDescription", void 0);
783
- __decorate([observable], SearchableSelect.prototype, "_anchor", void 0);
784
- //#endregion
785
- //#region src/lib/searchable-select/option-tag.ts
786
- var OptionTag = class extends Localized(VividElement) {
787
- constructor(..._args) {
788
- super(..._args);
789
- this.removable = false;
790
- this.disabled = false;
791
- this.hasIconPlaceholder = false;
792
- }
793
- /** @internal */
794
- _onClickRemove() {
795
- this.$emit("remove", void 0, { bubbles: false });
796
- }
797
- };
798
- __decorate([attr], OptionTag.prototype, "shape", void 0);
799
- __decorate([observable], OptionTag.prototype, "connotation", void 0);
800
- __decorate([attr], OptionTag.prototype, "label", void 0);
801
- __decorate([attr({ mode: "boolean" })], OptionTag.prototype, "removable", void 0);
802
- __decorate([attr({ mode: "boolean" })], OptionTag.prototype, "disabled", void 0);
803
- __decorate([observable], OptionTag.prototype, "hasIconPlaceholder", void 0);
804
- __decorate([attr()], OptionTag.prototype, "scale", void 0);
641
+ mode: "boolean",
642
+ attribute: "fixed-dropdown"
643
+ })], Select.prototype, "fixedDropdown", void 0);
644
+ __decorate([attr], Select.prototype, "placeholder", void 0);
645
+ __decorate([observable], Select.prototype, "_feedbackWrapper", void 0);
646
+ __decorate([observable], Select.prototype, "metaSlottedContent", void 0);
647
+ __decorate([attr({ mode: "boolean" })], Select.prototype, "clearable", void 0);
648
+ __decorate([observable], Select.prototype, "_isClearButtonFocused", void 0);
805
649
  //#endregion
806
- //#region src/lib/searchable-select/searchable-select.template.ts
807
- var getStateClasses = (x) => classNames(["disabled", x.disabled], [`appearance-${x.appearance}`, Boolean(x.appearance)], [`shape-${x.shape}`, Boolean(x.shape)], [`size-${x.scale}`, Boolean(x.scale)], ["error", Boolean(x.errorValidationMessage)], ["success", !!x.successText], ["has-highlighted-option", x._highlightedOptionIndex !== null]);
650
+ //#region src/lib/select/select.template.ts
651
+ var getStateClasses = ({ shape, disabled, appearance, metaSlottedContent, errorValidationMessage, successText, placeholder, value, scale, _activeDescendant, open }) => classNames(["has-activedescendant", Boolean(_activeDescendant) && open], ["disabled", disabled], [`appearance-${appearance}`, Boolean(appearance)], [`shape-${shape}`, Boolean(shape)], ["has-meta", Boolean(metaSlottedContent?.length)], ["error", Boolean(errorValidationMessage)], ["success", !!successText], ["shows-placeholder", Boolean(placeholder) && !value], [`size-${scale}`, Boolean(scale)]);
808
652
  function renderLabel() {
809
- return html`
810
- <label for="control" class="label" id="label"> ${(x) => x.label} </label>
811
- `;
653
+ return html` <label
654
+ for="${(x) => x.multiple ? null : "control"}"
655
+ class="label"
656
+ id="label"
657
+ >
658
+ ${(x) => x.label}
659
+ </label>`;
812
660
  }
813
- function renderSelectionCount() {
661
+ function renderPlaceholder(context) {
662
+ const optionTag = context.tagFor(ListboxOption);
814
663
  return html`
815
- <span
816
- id="selection-count"
817
- class="selection-count"
818
- aria-label="${(x) => x.locale.searchableSelect.maxSelectedMessage(x.values.length, x.maxSelected)}"
819
- >(${(x) => `${x.values.length}/${x.maxSelected}`})</span
820
- >
821
- `;
664
+ <${optionTag} text="${(x) => x.placeholder}" hidden disabled>
665
+ </${optionTag}>`;
822
666
  }
823
- var tagTemplateFactory = (context, getComponent) => {
824
- const optionTagTag = context.tagFor(OptionTag);
825
- return html`
826
- <div class="tag-wrapper">
827
- <${optionTagTag}
828
- class="tag"
829
- tabindex="-1"
830
- data-index="${(x, c) => getComponent(c).values.indexOf(x)}"
831
- removable
832
- :label="${(x, c) => getComponent(c)._tagLabelForValue(x)}"
833
- :shape="${(_, c) => getComponent(c).shape}"
834
- :connotation="${(x, c) => getComponent(c)._tagConnotationForValue(x)}"
835
- :scale="${(_, c) => getComponent(c).scale}"
836
- ?disabled="${(x, c) => getComponent(c)._isTagDisabled(x)}"
837
- @remove="${(x, c) => getComponent(c)._onTagRemoved(x)}"
838
- @keydown="${(_, c) => getComponent(c)._onTagKeydown(c.event)}"
839
- @mousedown="${() => false}">
840
- <slot slot="icon" name="${(x, c) => getComponent(c)._tagIconSlotName(x)}"></slot>
841
- </${optionTagTag}>
842
- </div>
843
- `;
844
- };
845
- var elidedTagTemplateFactory = (context, getComponent) => {
846
- const optionTagTag = context.tagFor(OptionTag);
847
- return html`
848
- <${optionTagTag}
849
- class="tag"
850
- tabindex="-1"
851
- :label="${(x, c) => getComponent(x, c)._numElidedTags.toString()}"
852
- :shape="${(x, c) => getComponent(x, c).shape}"
853
- :scale="${(x, c) => getComponent(x, c).scale}"
854
- ?disabled="${(x, c) => getComponent(x, c).disabled}"
855
- @mousedown="${() => false}">
856
- </${optionTagTag}>
857
- `;
858
- };
859
- function renderFieldset(context) {
667
+ function renderClearButton(context) {
860
668
  const buttonTag = context.tagFor(Button);
861
- const progressRingTag = context.tagFor(ProgressRing);
862
- const affixIconTemplate = affixIconTemplateFactory(context);
863
- const chevronTemplate = chevronTemplateFactory(context);
864
- const tagTemplate = tagTemplateFactory(context, (c) => c.parent);
865
- const nestedTagTemplate = tagTemplateFactory(context, (c) => c.parentContext.parent);
866
- const elidedTagTemplate = elidedTagTemplateFactory(context, (x, _) => x);
867
- const nestedElidedTagTemplate = elidedTagTemplateFactory(context, (_, c) => c.parent);
868
669
  return html`
869
- <div
870
- class="fieldset ${getStateClasses}"
871
- @click="${(x, c) => x._onFieldsetClick(c.event)}"
872
- ${ref("_anchor")}
873
- >
874
- ${(x) => affixIconTemplate(x.icon, IconWrapper.Slot)}
875
- <div class="content-area" ${ref("_contentArea")}>
876
- ${repeat((x) => x._tagRows, html`
877
- <div class="tag-row">
878
- ${when((_, c) => c.isFirst && c.parent._numElidedTags, nestedElidedTagTemplate)}
879
- ${repeat((x) => x, nestedTagTemplate)}
880
- </div>
881
- `, { positioning: true })}
882
- <div
883
- class="tag-row ${(x) => classNames(["contains-only-input", x._tagRows.length > 0 && x._lastTagRow.length === 0])}"
884
- >
885
- ${when((x) => x._tagRows.length === 0 && x._numElidedTags, elidedTagTemplate)}
886
- ${repeat((x) => x._lastTagRow, tagTemplate)}
887
- <input
888
- id="control"
889
- class="control"
890
- autocomplete="off"
891
- aria-controls="listbox"
892
- aria-describedby="${(x) => x._feedbackDescribedBy} ${(x) => x.multiple && x.maxSelected && x.maxSelected >= 1 ? "selection-count" : null}"
893
- ${delegateAria({
894
- role: "combobox",
895
- ariaAutoComplete: "list",
896
- ariaHasPopup: "listbox",
897
- ariaExpanded: (x) => x.open
898
- })}
899
- placeholder="${(x) => x.multiple && x.values.length ? "" : x.placeholder}"
900
- type="text"
901
- ?disabled="${(x) => x.disabled}"
902
- :value="${(x) => x._inputValue}"
903
- @input="${(x, c) => {
904
- x._onInputInput(c.event);
670
+ <${buttonTag}
671
+ aria-label="${(x) => x.locale.select.clearButtonLabel}"
672
+ aria-hidden="${(x) => x._isClearButtonFocused ? "false" : "true"}"
673
+ @click="${(x, c) => {
674
+ x._onClearButtonClick();
905
675
  c.event.stopPropagation();
906
676
  }}"
907
- @change="${(_, c) => {
677
+ @mousedown="${() => false}"
678
+ @keydown="${(x, c) => {
679
+ /* v8 ignore next -- @preserve */
680
+ if (c.event.key === "Tab") x._onClearButtonBlur();
908
681
  c.event.stopPropagation();
682
+ return true;
909
683
  }}"
910
- @focus="${(x, c) => x._onInputFocus(c.event)}"
911
- @blur="${(x, c) => x._onInputBlur(c.event)}"
912
- @keydown="${(x, c) => x._onInputKeydown(c.event)}"
913
- ${ref("_input")}
914
- />
915
- </div>
916
- </div>
917
- <slot name="meta"></slot>
918
- ${when((x) => x._shouldShowClearButton, html`<${buttonTag}
919
- aria-label="${(x) => x.locale.searchableSelect.clearButtonLabel}"
920
- @click="${(x) => x._onClearButtonClick()}"
921
- @mousedown="${() => false}"
922
- ?disabled="${(x) => x.disabled}"
923
- :shape="${(x) => x.shape}"
924
- size="super-condensed"
925
- icon="close-line"
926
- appearance="ghost-light"
927
- tabindex="0"
928
- ></${buttonTag}>`)}
929
- <div @mousedown="${() => false}" @click="${(x) => x._onChevronClick()}">
930
- ${when((x) => x.loading, html`<${progressRingTag} indeterminate size="-6" aria-hidden="true"></${progressRingTag}>`)}
931
- ${when((x) => !x.loading, chevronTemplate)}
932
- </div>
933
- </div>
684
+ @focusin="${(x, c) => {
685
+ c.event.stopPropagation();
686
+ x._onClearButtonFocus();
687
+ }}"
688
+ @focusout="${(x) => x._onClearButtonBlur()}"
689
+ ?disabled="${(x) => x.disabled}"
690
+ :shape="${(x) => x.shape}"
691
+ size="super-condensed"
692
+ icon="close-line"
693
+ appearance="ghost-light"
694
+ class="clear-button"
695
+ tabindex="0"
696
+ ></${buttonTag}>
934
697
  `;
935
698
  }
936
- function setFixedDropdownVarWidth(x) {
937
- return x.open && x.fixedDropdown ? `--_searchable-select-fixed-width: ${Math.round(x.getBoundingClientRect().width)}px` : null;
699
+ function selectValue(context) {
700
+ const affixIconTemplate = affixIconTemplateFactory(context);
701
+ const chevronTemplate = chevronTemplateFactory(context);
702
+ return html` <div
703
+ class="control ${getStateClasses}"
704
+ ${ref("_anchor")}
705
+ id="control"
706
+ ?disabled="${(x) => x.disabled}"
707
+ >
708
+ <div class="selected-value">
709
+ ${(x) => affixIconTemplate(x.icon, IconWrapper.Slot)}
710
+ <span class="text">${(x) => x.displayValue}</span>
711
+ <slot name="meta" ${slotted("metaSlottedContent")}></slot>
712
+ </div>
713
+ ${when((x) => x._shouldShowClearButton, renderClearButton(context))}
714
+ ${chevronTemplate}
715
+ </div>`;
938
716
  }
939
- function renderSelectAll(context) {
940
- const optionTag = context.tagFor(ListboxOption);
941
- const dividerTag = context.tagFor(Divider);
942
- return html`
943
- <${optionTag}
944
- data-select-all
945
- tabindex="-1"
946
- :text="${(x) => x._selectAllLabel}"
947
- :selected="${(x) => x._isAllSelected}"
948
- :_displayCheckmark="${() => true}"
949
- ?disabled="${(x) => x._selectableOptions.length === 0}"
950
- ${ref("_selectAllOption")}>
951
- </${optionTag}>
952
- <${dividerTag} class="divider"></${dividerTag}>
953
- `;
717
+ function setFixedDropdownVarWidth(x) {
718
+ return x.open && x.fixedDropdown ? `--_select-fixed-width: ${Math.round(x.getBoundingClientRect().width)}px` : null;
954
719
  }
720
+ /**
721
+ * @param context - element definition context
722
+ */
955
723
  function renderControl(context) {
956
724
  const popupTag = context.tagFor(Popup);
957
725
  return html`
958
- <div class="label-wrapper" ?hidden=${(x) => !x.label && !x._hasContextualHelp && !x._hasSelectionCount}>
959
- ${when((x) => x.label || x._hasSelectionCount, html`
960
- <div>
961
- ${when((x) => x.label, renderLabel())}
962
- ${when((x) => x._hasSelectionCount, renderSelectionCount())}
963
- </div>
964
- `)}
965
- <slot name="contextual-help" ${slotted("_contextualHelpSlottedContent")}></slot>
966
- </div>
967
- <span aria-live="assertive" aria-relevant="text" class="visually-hidden">
968
- ${(x) => x._changeDescription}
969
- </span>
970
- <div>
971
- ${renderFieldset(context)}
972
- <div class="popup-wrapper">
973
- <${popupTag}
726
+ <div class="label-wrapper" ?hidden=${(x) => !x._shouldShowLabelWrapper}>
727
+ ${when((x) => x.label, renderLabel())}
728
+ ${when((x) => x.multiple && x._shouldShowClearButton, renderClearButton(context))}
729
+ <slot name="contextual-help" ${slotted("_contextualHelpSlottedContent")}></slot>
730
+ </div>
731
+ <div class="control-wrapper">
732
+ ${when((x) => !x.multiple, selectValue(context))}
733
+ <${popupTag} class="popup"
734
+ style="${setFixedDropdownVarWidth}"
735
+ ?open="${(x) => x.collapsible ? x.open : true}"
974
736
  :anchor="${(x) => x._anchor}"
975
- :open="${(x) => x.open}"
976
- class="popup"
977
737
  placement="bottom-start"
978
- style="${setFixedDropdownVarWidth}"
979
- strategy="${(x) => x.fixedDropdown ? "fixed" : "absolute"}">
980
- <div
981
- class="listbox"
738
+ strategy="${(x) => x.fixedDropdown ? null : "absolute"}">
739
+ <div class="listbox"
740
+ id="${(x) => x.listboxId}"
982
741
  role="listbox"
983
742
  aria-multiselectable="${(x) => x.multiple}"
984
- aria-required="${(x) => x.required}"
985
- ${ref("_listbox")}
986
- @click="${(x, c) => x._onListboxClick(c.event)}"
987
- @mousedown="${() => false}"
988
- >
989
- ${when((x) => x.enableSelectAll && x.multiple && !x.maxSelected, renderSelectAll(context))}
743
+ aria-label="${(x) => x.multiple && !x.label && x.ariaLabel ? x.ariaLabel : null}"
744
+ aria-labelledby="${(x) => x.multiple && x.label ? "label" : null}"
745
+ ?disabled="${(x) => x.disabled}"
746
+ ?hidden="${(x) => x.collapsible ? !x.open : false}"
747
+ ${ref("listbox")}>
748
+ ${when((x) => x.placeholder, renderPlaceholder(context))}
990
749
  <slot
991
750
  ${slotted({
992
- filter: isListboxOption,
751
+ filter: Listbox.slottedOptionFilter,
993
752
  flatten: true,
994
- property: "_slottedOptions"
753
+ property: "slottedOptions"
995
754
  })}>
996
755
  </slot>
997
- ${when((x) => x._filteredOptions.length === 0, html`<div class="empty-message">
998
- ${when((x) => x.loading, html`<slot name="loading-options">
999
- ${(x) => x.locale.searchableSelect.loadingOptionsMessage}
1000
- </slot>`)}
1001
- ${when((x) => !x.loading && x.searchText === "", html`<slot name="no-options">
1002
- ${(x) => x.locale.searchableSelect.noOptionsMessage}
1003
- </slot>`)}
1004
- ${when((x) => !x.loading && x.searchText !== "", html`<slot name="no-matches">
1005
- ${(x) => x.locale.searchableSelect.noMatchesMessage}
1006
- </slot>`)}
1007
- </div>`)}
1008
- </div>
756
+ </div>
1009
757
  </${popupTag}>
1010
758
  </div>
1011
- </div>
1012
- `;
759
+ `;
760
+ }
761
+ /**
762
+ * Ignore events that originate from feedback, e.g. a click on link
763
+ */
764
+ function ifNotFromFeedback(handler) {
765
+ return (x, c) => {
766
+ if (!c.event.composedPath().includes(x._feedbackWrapper)) return handler(x, c.event);
767
+ return true;
768
+ };
1013
769
  }
1014
- var SearchableSelectTemplate = (context) => {
1015
- const optionTagName = context.tagFor(OptionTag, true);
770
+ var SelectTemplate = (context) => {
1016
771
  return html`
1017
772
  <template
1018
- :_optionTagTagName="${() => optionTagName}"
1019
- @mousedown="${(x, c) => x._onMouseDown(c.event)}"
773
+ ${applyHostSemantics({
774
+ role: "combobox",
775
+ ariaLabel: (x) => x.ariaLabel ?? x.label,
776
+ ariaHasPopup: (x) => x.collapsible ? "listbox" : "false",
777
+ ariaExpanded: (x) => x.open,
778
+ ariaDisabled: (x) => x.disabled
779
+ })}
780
+ aria-controls="${(x) => x.listboxId}"
781
+ aria-activedescendant="${(x) => x.open ? x._activeDescendant : null}"
782
+ aria-describedby="${(x) => x._feedbackDescribedBy}"
783
+ tabindex="${(x) => !x.disabled ? "0" : null}"
784
+ @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
785
+ @focusin="${ifNotFromFeedback((x, e) => x.focusinHandler(e))}"
786
+ @focusout="${ifNotFromFeedback((x, e) => x.focusoutHandler(e))}"
787
+ @keydown="${ifNotFromFeedback((x, e) => {
788
+ x.open && handleEscapeKeyAndStopPropogation(e);
789
+ return x.keydownHandler(e);
790
+ })}"
791
+ @mousedown="${ifNotFromFeedback((x, e) => x.mousedownHandler(e))}"
1020
792
  >
1021
- <div class="control-wrapper">
1022
- ${renderControl(context)} ${(x) => x._getFeedbackTemplate(context)}
793
+ ${renderControl(context)}
794
+ <div class="feedback-wrapper" ${ref("_feedbackWrapper")}>
795
+ ${(x) => x._getFeedbackTemplate(context)}
1023
796
  </div>
1024
797
  </template>
1025
798
  `;
1026
799
  };
1027
800
  //#endregion
1028
- //#region src/lib/searchable-select/option-tag.template.ts
1029
- var getClasses = ({ shape, connotation, disabled, removable, scale }) => classNames("base", ["disabled", disabled], ["removable", removable], [`shape-${shape}`, Boolean(shape)], [`connotation-${connotation}`, Boolean(connotation)], [`size-${scale}`, Boolean(scale)]);
1030
- function renderRemoveButton(iconTag) {
1031
- return html`
1032
- <span
1033
- class="remove-button"
1034
- aria-label="${(x) => x.locale.searchableSelect.removeTagButtonLabel(x.label)}"
1035
- role="button"
1036
- tabindex="${(x) => x.disabled ? null : 0}"
1037
- @click="${(x) => x._onClickRemove()}"
1038
- >
1039
- <${iconTag} name="close-line"></${iconTag}>
1040
- </span>
1041
- `;
1042
- }
1043
- var optionTagTemplate = (context) => {
1044
- const iconTag = context.tagFor(Icon);
1045
- return html`<span class="${getClasses}" aria-disabled="${(x) => x.disabled}">
1046
- <slot name="icon" aria-hidden="true">
1047
- ${when((x) => x.hasIconPlaceholder, html`<div class="icon-placeholder"></div>`)}
1048
- </slot>
1049
- ${when((x) => x.label, (x) => html`<span class="label">${x.label}</span>`)}
1050
- ${when((x) => x.removable, renderRemoveButton(iconTag))}
1051
- </span>`;
1052
- };
801
+ //#region src/lib/select/definition.ts
1053
802
  /**
1054
- * Registers the searchable-select element with the design system.
1055
- *
1056
- * @param prefix - the prefix to use for the component name
803
+ * @internal
1057
804
  */
1058
- var registerSearchableSelect = createRegisterFunction(defineVividComponent("searchable-select", SearchableSelect, SearchableSelectTemplate, [
1059
- buttonDefinition,
805
+ var selectDefinition = defineVividComponent("select", Select, SelectTemplate, [
1060
806
  popupDefinition,
1061
807
  iconDefinition,
1062
- defineVividComponent("option-tag", OptionTag, optionTagTemplate, [iconDefinition], {
1063
- styles: [option_tag_default],
1064
- shadowOptions: { delegatesFocus: true }
1065
- }),
1066
- progressRingDefinition,
1067
- feedbackMessageDefinition,
1068
808
  listboxOptionDefinition,
1069
- dividerDefinition
1070
- ], { styles: searchable_select_default }));
809
+ buttonDefinition,
810
+ feedbackMessageDefinition
811
+ ], { styles: select_default });
812
+ /**
813
+ * Registers the select elements with the design system.
814
+ *
815
+ * @param prefix - the prefix to use for the component name
816
+ */
817
+ var registerSelect = createRegisterFunction(selectDefinition);
1071
818
  //#endregion
1072
- export { SearchableSelect as n, registerSearchableSelect as t };
819
+ export { selectDefinition as n, Select as r, registerSelect as t };