@vonage/vivid 4.17.0 → 4.18.0

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