@vonage/vivid 5.24.0 → 5.25.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 (331) hide show
  1. package/README.md +1 -1
  2. package/avatar/index.cjs +10 -10
  3. package/avatar/index.js +4 -3
  4. package/breadcrumb-item/index.cjs +9 -5
  5. package/breadcrumb-item/index.js +11 -6
  6. package/bundled/affix.cjs +1 -1
  7. package/bundled/affix.js +1 -1
  8. package/bundled/definition10.cjs +2 -1
  9. package/bundled/definition10.js +3 -2
  10. package/bundled/definition11.cjs +4 -4
  11. package/bundled/definition11.js +4 -3
  12. package/bundled/definition12.cjs +1 -1
  13. package/bundled/definition12.js +1 -0
  14. package/bundled/definition15.cjs +5 -5
  15. package/bundled/definition15.js +4 -3
  16. package/bundled/definition17.cjs +7 -7
  17. package/bundled/definition17.js +22 -109
  18. package/bundled/definition18.cjs +3 -3
  19. package/bundled/definition18.js +9 -31
  20. package/bundled/definition19.cjs +19 -19
  21. package/bundled/definition19.js +3 -2
  22. package/bundled/definition21.cjs +8 -8
  23. package/bundled/definition21.js +5 -4
  24. package/bundled/definition22.cjs +2 -2
  25. package/bundled/definition22.js +2 -2
  26. package/bundled/definition24.cjs +4 -4
  27. package/bundled/definition24.js +4 -3
  28. package/bundled/definition25.cjs +3 -3
  29. package/bundled/definition25.js +32 -28
  30. package/bundled/definition3.cjs +5 -5
  31. package/bundled/definition3.js +10 -40
  32. package/bundled/definition4.cjs +6 -6
  33. package/bundled/definition4.js +4 -3
  34. package/bundled/definition6.cjs +11 -11
  35. package/bundled/definition6.js +4 -3
  36. package/bundled/definition9.cjs +12 -6
  37. package/bundled/definition9.js +66 -43
  38. package/bundled/extractOptions.cjs +1 -1
  39. package/bundled/extractOptions.js +2 -2
  40. package/bundled/icon.cjs +1 -0
  41. package/bundled/icon.js +34 -0
  42. package/bundled/listbox.cjs +1 -1
  43. package/bundled/listbox.js +5 -2
  44. package/bundled/mixins.cjs +8 -8
  45. package/bundled/mixins.js +4 -3
  46. package/bundled/optgroup.cjs +1 -0
  47. package/bundled/optgroup.js +27 -0
  48. package/bundled/option.cjs +1 -0
  49. package/bundled/option.js +93 -0
  50. package/bundled/vivid-element.cjs +1 -1
  51. package/bundled/vivid-element.js +1 -1
  52. package/card/index.cjs +22 -22
  53. package/card/index.js +4 -3
  54. package/color-picker/index.cjs +18 -18
  55. package/color-picker/index.js +4 -3
  56. package/combobox/index.cjs +7 -7
  57. package/combobox/index.js +4 -2
  58. package/custom-elements.json +4159 -3847
  59. package/data-grid/index.cjs +24 -24
  60. package/data-grid/index.js +4 -3
  61. package/dial-pad/index.cjs +21 -21
  62. package/dial-pad/index.js +4 -3
  63. package/dialog/index.cjs +14 -14
  64. package/dialog/index.js +4 -3
  65. package/empty-state/index.cjs +3 -3
  66. package/empty-state/index.js +4 -3
  67. package/file-picker/index.cjs +7 -7
  68. package/file-picker/index.js +4 -3
  69. package/icon/definition.cjs +2 -1
  70. package/icon/definition.js +2 -1
  71. package/index.cjs +148 -141
  72. package/index.js +41 -37
  73. package/lib/accordion-item/accordion-item.d.ts +1 -0
  74. package/lib/combobox/combobox.d.ts +1 -1
  75. package/lib/components.d.ts +1 -0
  76. package/lib/dial-pad/dial-pad.d.ts +0 -1
  77. package/lib/listbox/definition.d.ts +3 -0
  78. package/lib/listbox/index.d.ts +1 -0
  79. package/lib/listbox/listbox.d.ts +1302 -0
  80. package/lib/listbox/listbox.template.d.ts +3 -0
  81. package/lib/listbox/variations.browser-spec.d.ts +1 -0
  82. package/lib/menu/menu.d.ts +0 -1
  83. package/lib/number-field/number-field.d.ts +0 -1
  84. package/lib/rich-text-editor/rte/features/base.d.ts +1 -0
  85. package/lib/rich-text-editor/rte/utils/default-textblock.d.ts +2 -2
  86. package/lib/tag-name-map.d.ts +2 -1
  87. package/lib/text-field/text-field.d.ts +1 -0
  88. package/lib/toggletip/toggletip.d.ts +1 -0
  89. package/lib/tooltip/tooltip.d.ts +1 -0
  90. package/listbox/definition.cjs +5 -0
  91. package/listbox/definition.js +2 -0
  92. package/listbox/index.cjs +11 -0
  93. package/listbox/index.js +540 -0
  94. package/nav/definition.cjs +1 -1
  95. package/nav/definition.js +1 -1
  96. package/nav-disclosure/definition.cjs +1 -1
  97. package/nav-disclosure/definition.js +1 -1
  98. package/nav-disclosure/index.cjs +4 -4
  99. package/nav-disclosure/index.js +4 -3
  100. package/nav-item/definition.cjs +1 -1
  101. package/nav-item/definition.js +1 -1
  102. package/note/definition.cjs +1 -1
  103. package/note/definition.js +1 -1
  104. package/number-field/definition.cjs +1 -1
  105. package/number-field/definition.js +1 -1
  106. package/optgroup/definition.cjs +2 -1
  107. package/optgroup/definition.js +2 -1
  108. package/option/definition.cjs +2 -1
  109. package/option/definition.js +2 -1
  110. package/package.json +8 -7
  111. package/pagination/definition.cjs +1 -1
  112. package/pagination/definition.js +1 -1
  113. package/platform-switch/definition.cjs +1 -1
  114. package/platform-switch/definition.js +1 -1
  115. package/popover/definition.cjs +1 -1
  116. package/popover/definition.js +1 -1
  117. package/popover/index.cjs +5 -5
  118. package/popover/index.js +4 -3
  119. package/progress/definition.cjs +1 -1
  120. package/progress/definition.js +1 -1
  121. package/radio/definition.cjs +1 -1
  122. package/radio/definition.js +1 -1
  123. package/radio-group/definition.cjs +1 -1
  124. package/radio-group/definition.js +1 -1
  125. package/range-slider/definition.cjs +1 -1
  126. package/range-slider/definition.js +1 -1
  127. package/rich-text-editor/definition.cjs +1 -1
  128. package/rich-text-editor/definition.js +1 -1
  129. package/rich-text-editor/index.cjs +13 -13
  130. package/rich-text-editor/index.js +22 -19
  131. package/rich-text-view/definition.cjs +1 -1
  132. package/rich-text-view/definition.js +1 -1
  133. package/searchable-select/definition.cjs +1 -1
  134. package/searchable-select/definition.js +1 -1
  135. package/searchable-select/index.cjs +23 -23
  136. package/searchable-select/index.js +10 -7
  137. package/select/definition.cjs +1 -1
  138. package/select/definition.js +1 -1
  139. package/selectable-box/definition.cjs +1 -1
  140. package/selectable-box/definition.js +1 -1
  141. package/shared/listbox/commands.d.ts +17 -0
  142. package/shared/listbox/move.d.ts +6 -0
  143. package/shared/listbox/options.d.ts +12 -0
  144. package/shared/listbox/selection.d.ts +28 -0
  145. package/shared/listbox/state.d.ts +26 -0
  146. package/shared/listbox/typeahead.d.ts +8 -0
  147. package/shared/listbox/with-options-filter.d.ts +440 -0
  148. package/shared/listbox/with-options.d.ts +862 -0
  149. package/side-drawer/definition.cjs +1 -1
  150. package/side-drawer/definition.js +1 -1
  151. package/simple-color-picker/definition.cjs +1 -1
  152. package/simple-color-picker/definition.js +1 -1
  153. package/simple-color-picker/index.cjs +6 -6
  154. package/simple-color-picker/index.js +4 -3
  155. package/split-button/definition.cjs +1 -1
  156. package/split-button/definition.js +1 -1
  157. package/status/definition.cjs +1 -1
  158. package/status/definition.js +1 -1
  159. package/switch/definition.cjs +1 -1
  160. package/switch/definition.js +1 -1
  161. package/tab/definition.cjs +1 -1
  162. package/tab/definition.js +1 -1
  163. package/tab-panel/definition.cjs +1 -1
  164. package/tab-panel/definition.js +1 -1
  165. package/table/definition.cjs +1 -1
  166. package/table/definition.js +1 -1
  167. package/table/index.cjs +13 -13
  168. package/table/index.js +4 -3
  169. package/tabs/definition.cjs +1 -1
  170. package/tabs/definition.js +1 -1
  171. package/tag/definition.cjs +1 -1
  172. package/tag/definition.js +1 -1
  173. package/tag/index.cjs +11 -11
  174. package/tag/index.js +4 -3
  175. package/tag-group/definition.cjs +1 -1
  176. package/tag-group/definition.js +1 -1
  177. package/text-area/definition.cjs +1 -1
  178. package/text-area/definition.js +1 -1
  179. package/time-picker/definition.cjs +1 -1
  180. package/time-picker/definition.js +1 -1
  181. package/tree-item/definition.cjs +1 -1
  182. package/tree-item/definition.js +1 -1
  183. package/tree-view/definition.cjs +1 -1
  184. package/tree-view/definition.js +1 -1
  185. package/unbundled/affix.cjs +2 -2
  186. package/unbundled/affix.js +1 -1
  187. package/unbundled/base-progress.cjs +1 -1
  188. package/unbundled/base-progress.js +1 -1
  189. package/unbundled/button.cjs +2 -2
  190. package/unbundled/button.js +2 -2
  191. package/unbundled/definition.cjs +2 -65
  192. package/unbundled/definition.js +4 -61
  193. package/unbundled/definition11.cjs +4 -3
  194. package/unbundled/definition11.js +3 -2
  195. package/unbundled/definition12.cjs +3 -2
  196. package/unbundled/definition12.js +3 -2
  197. package/unbundled/definition14.cjs +2 -1
  198. package/unbundled/definition14.js +2 -1
  199. package/unbundled/definition17.cjs +9 -4
  200. package/unbundled/definition17.js +9 -4
  201. package/unbundled/definition2.cjs +7 -2
  202. package/unbundled/definition2.js +8 -3
  203. package/unbundled/definition21.cjs +2 -1
  204. package/unbundled/definition21.js +2 -1
  205. package/unbundled/definition23.cjs +2 -1
  206. package/unbundled/definition23.js +2 -1
  207. package/unbundled/definition24.cjs +6 -4
  208. package/unbundled/definition24.js +6 -4
  209. package/unbundled/definition25.cjs +2 -1
  210. package/unbundled/definition25.js +2 -1
  211. package/unbundled/definition26.cjs +7 -4
  212. package/unbundled/definition26.js +7 -4
  213. package/unbundled/definition27.cjs +39 -5
  214. package/unbundled/definition27.js +40 -6
  215. package/unbundled/definition28.cjs +4 -3
  216. package/unbundled/definition28.js +4 -3
  217. package/unbundled/definition29.cjs +5 -168
  218. package/unbundled/definition29.js +11 -162
  219. package/unbundled/definition30.cjs +2 -63
  220. package/unbundled/definition30.js +5 -54
  221. package/unbundled/definition31.cjs +5 -3
  222. package/unbundled/definition31.js +5 -3
  223. package/unbundled/definition32.cjs +2 -1
  224. package/unbundled/definition32.js +2 -1
  225. package/unbundled/definition35.cjs +2 -1
  226. package/unbundled/definition35.js +2 -1
  227. package/unbundled/definition37.cjs +1 -1
  228. package/unbundled/definition37.js +1 -1
  229. package/unbundled/definition39.cjs +1 -1
  230. package/unbundled/definition39.js +1 -1
  231. package/unbundled/definition40.cjs +4 -2
  232. package/unbundled/definition40.js +4 -2
  233. package/unbundled/definition41.cjs +11 -6
  234. package/unbundled/definition41.js +11 -6
  235. package/unbundled/definition42.cjs +5 -4
  236. package/unbundled/definition42.js +5 -4
  237. package/unbundled/definition44.cjs +3 -2
  238. package/unbundled/definition44.js +3 -2
  239. package/unbundled/definition45.cjs +2 -2
  240. package/unbundled/definition45.js +2 -2
  241. package/unbundled/definition49.cjs +583 -79
  242. package/unbundled/definition49.js +579 -76
  243. package/unbundled/definition50.cjs +71 -33
  244. package/unbundled/definition50.js +67 -29
  245. package/unbundled/definition51.cjs +54 -23
  246. package/unbundled/definition51.js +52 -18
  247. package/unbundled/definition52.cjs +23 -39
  248. package/unbundled/definition52.js +17 -36
  249. package/unbundled/definition53.cjs +29 -314
  250. package/unbundled/definition53.js +27 -312
  251. package/unbundled/definition54.cjs +302 -195
  252. package/unbundled/definition54.js +298 -191
  253. package/unbundled/definition55.cjs +210 -40
  254. package/unbundled/definition55.js +206 -36
  255. package/unbundled/definition56.cjs +42 -266
  256. package/unbundled/definition56.js +38 -262
  257. package/unbundled/definition57.cjs +270 -50
  258. package/unbundled/definition57.js +267 -46
  259. package/unbundled/definition58.cjs +48 -146
  260. package/unbundled/definition58.js +47 -143
  261. package/unbundled/definition59.cjs +127 -225
  262. package/unbundled/definition59.js +122 -223
  263. package/unbundled/definition6.cjs +2 -1
  264. package/unbundled/definition6.js +2 -1
  265. package/unbundled/definition60.cjs +199 -418
  266. package/unbundled/definition60.js +196 -415
  267. package/unbundled/definition61.cjs +442 -3738
  268. package/unbundled/definition61.js +432 -3565
  269. package/unbundled/definition62.cjs +3717 -730
  270. package/unbundled/definition62.js +3544 -720
  271. package/unbundled/definition63.cjs +770 -97
  272. package/unbundled/definition63.js +767 -94
  273. package/unbundled/definition64.cjs +100 -999
  274. package/unbundled/definition64.js +98 -994
  275. package/unbundled/definition65.cjs +991 -93
  276. package/unbundled/definition65.js +985 -90
  277. package/unbundled/definition66.cjs +109 -73
  278. package/unbundled/definition66.js +105 -63
  279. package/unbundled/definition67.cjs +69 -155
  280. package/unbundled/definition67.js +60 -152
  281. package/unbundled/definition68.cjs +155 -119
  282. package/unbundled/definition68.js +151 -115
  283. package/unbundled/definition69.cjs +124 -49
  284. package/unbundled/definition69.js +120 -45
  285. package/unbundled/definition70.cjs +51 -85
  286. package/unbundled/definition70.js +50 -81
  287. package/unbundled/definition71.cjs +91 -19
  288. package/unbundled/definition71.js +86 -14
  289. package/unbundled/definition72.cjs +20 -87
  290. package/unbundled/definition72.js +14 -84
  291. package/unbundled/definition73.cjs +77 -294
  292. package/unbundled/definition73.js +72 -217
  293. package/unbundled/definition74.cjs +289 -311
  294. package/unbundled/definition74.js +219 -306
  295. package/unbundled/definition75.cjs +326 -26
  296. package/unbundled/definition75.js +317 -23
  297. package/unbundled/definition76.cjs +27 -122
  298. package/unbundled/definition76.js +22 -118
  299. package/unbundled/definition77.cjs +105 -232
  300. package/unbundled/definition77.js +101 -228
  301. package/unbundled/definition78.cjs +259 -26
  302. package/unbundled/definition78.js +249 -23
  303. package/unbundled/definition79.cjs +29 -148
  304. package/unbundled/definition79.js +27 -133
  305. package/unbundled/definition80.cjs +118 -173
  306. package/unbundled/definition80.js +109 -169
  307. package/unbundled/definition81.cjs +181 -477
  308. package/unbundled/definition81.js +176 -471
  309. package/unbundled/definition82.cjs +517 -0
  310. package/unbundled/definition82.js +497 -0
  311. package/unbundled/extractOptions.cjs +5 -5
  312. package/unbundled/extractOptions.js +2 -2
  313. package/unbundled/icon.cjs +67 -0
  314. package/unbundled/icon.js +61 -0
  315. package/unbundled/linkable.cjs +1 -1
  316. package/unbundled/linkable.js +1 -1
  317. package/unbundled/listbox.cjs +8 -3
  318. package/unbundled/listbox.js +7 -2
  319. package/unbundled/mixins.cjs +2 -1
  320. package/unbundled/mixins.js +2 -1
  321. package/unbundled/optgroup.cjs +66 -0
  322. package/unbundled/optgroup.js +54 -0
  323. package/unbundled/option.cjs +176 -0
  324. package/unbundled/option.js +164 -0
  325. package/unbundled/time-selection-picker.template.cjs +1 -1
  326. package/unbundled/time-selection-picker.template.js +1 -1
  327. package/unbundled/vivid-element.cjs +1 -1
  328. package/unbundled/vivid-element.js +1 -1
  329. package/video-player/definition.cjs +1 -1
  330. package/video-player/definition.js +1 -1
  331. package/vivid.api.json +336 -193
@@ -1,123 +1,796 @@
1
- import { d as createRegisterFunction, t as VividElement, u as defineVividComponent } from "./vivid-element.js";
1
+ import { d as createRegisterFunction, u as defineVividComponent } from "./vivid-element.js";
2
+ import { t as iconDefinition } from "./definition.js";
2
3
  import { t as __decorate } from "./decorate.js";
3
- import { c as impl, n as removeSymbol, s as sortedContributions, t as dispatchSlottableRequest } from "./slottable-request.js";
4
- import { ElementStyles, html, observable, ref } from "@microsoft/fast-element";
5
- import { DOMSerializer, Mark, Node } from "prosemirror-model";
6
- //#region src/lib/rich-text-view/rich-text-view.scss?inline
7
- var rich_text_view_default = ":host{display:contents}.content{overflow-wrap:break-word;white-space:break-spaces;display:contents}";
4
+ import { a as affixIconTemplateFactory, i as IconWrapper, n as AffixIconWithTrailing } from "./affix.js";
5
+ import { n as FormAssociated } from "./form-associated.js";
6
+ import { t as Localized } from "./localized.js";
7
+ import { i as Button, r as chevronTemplateFactory, t as buttonDefinition } from "./definition6.js";
8
+ import { t as handleEscapeKeyAndStopPropogation } from "./dialog.js";
9
+ import { i as Popup, t as popupDefinition } from "./definition9.js";
10
+ import { n as applyHostSemantics, t as HostSemantics } from "./host-semantics.js";
11
+ import { n as WithLightDOMFeedback, r as feedbackMessageDefinition } from "./mixins.js";
12
+ import { t as FormElement } from "./form-element.js";
13
+ import { t as WithErrorText } from "./with-error-text.js";
14
+ import { t as WithSuccessText } from "./with-success-text.js";
15
+ import { t as WithContextualHelp } from "./with-contextual-help.js";
16
+ import { t as ListboxOption } from "./option.js";
17
+ import { t as listboxOptionDefinition } from "./definition29.js";
18
+ import { t as optgroupDefinition } from "./definition30.js";
19
+ import { t as Listbox } from "./listbox.js";
20
+ import { Observable, Updates, attr, html, observable, ref, slotted, volatile, when } from "@microsoft/fast-element";
21
+ import { classNames, inRange, keyArrowDown, keyArrowUp, keyEnd, keyEnter, keyEscape, keyHome, keySpace, keyTab, uniqueId } from "@microsoft/fast-web-utilities";
22
+ //#region src/lib/select/select.scss?inline
23
+ var select_default = ".label-wrapper{align-items:center;gap:var(--label-wrapper-gap,4px);flex-direction:row;display:flex}.label-wrapper[hidden]{display:none}.label:not(slot),.label::slotted(label){flex:0 auto}.chevron{font:var(--vvd-typography-base-extended);flex-shrink:0;display:flex;transform:rotate(0)}@media (prefers-reduced-motion:no-preference){.chevron{transition:transform .2s}}:host([data-expanded=true]) .chevron,:host([open]) .chevron{transform:rotate(180deg)}:host(:focus-visible){outline:none}:host{--_low-ink-color:var(--vvd-color-neutral-600);--focus-stroke-gap-color:transparent;flex-direction:column;gap:4px;display:inline-flex}:host([disabled]){--_low-ink-color:var(--vvd-color-neutral-600);cursor:not-allowed}.label{color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base)}.control{--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-500)}.control.appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}@media (hover:hover){.control:hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-700)}.control:hover:where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:var(--_connotation-color-faint);--_appearance-color-outline:transparent}}.control.hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-700)}.control.hover:where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:var(--_connotation-color-faint);--_appearance-color-outline:transparent}.control:disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control:disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control.disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.readonly:where(:not(.disabled,:disabled)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-neutral-200);--_appearance-color-outline:var(--vvd-color-neutral-400)}.control.readonly:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.error:where(:not(.disabled,:disabled)){--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:var(--vvd-color-alert-500)}.control.error:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:transparent}.control.success:where(:not(.disabled,:disabled)){--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-success-50);--_appearance-color-outline:var(--vvd-color-success-500)}.control.success:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-success-50);--_appearance-color-outline:transparent}.control{--_connotation-color-primary:var(--vvd-select-accent-primary,var(--vvd-color-canvas-text));--_connotation-color-primary-text:var(--vvd-select-accent-primary-text,var(--vvd-color-canvas));--_connotation-color-primary-increment:var(--vvd-select-accent-primary-increment,var(--vvd-color-neutral-800));--_connotation-color-intermediate:var(--vvd-select-accent-intermediate,var(--vvd-color-neutral-500));--_connotation-color-faint:var(--vvd-select-accent-faint,var(--vvd-color-neutral-50));--_connotation-color-soft:var(--vvd-select-accent-soft,var(--vvd-color-neutral-100));--_connotation-color-firm:var(--vvd-select-accent-firm,var(--vvd-color-canvas-text));--_connotation-color-fierce:var(--vvd-select-accent-fierce,var(--vvd-color-neutral-700));border-radius:var(--_select-control-border-radius);block-size:var(--_select-block-size);padding-inline:var(--_select-padding-inline);--_select-icon-size:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2);--_select-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2)));--_select-padding-inline:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);background-color:var(--_appearance-color-fill);box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);color:var(--_appearance-color-text);font:var(--vvd-typography-base);justify-content:space-between;align-items:center;gap:8px;transition:box-shadow .2s,background-color .2s;display:flex}.control.size-condensed{--_select-icon-size:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);--_select-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 8));--_select-padding-inline:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16)) / 2)}.control.size-condensed:not(.shape-pill){--_select-control-border-radius:4px}.control-wrapper{position:relative}.control:not(.disabled){cursor:pointer}.control.disabled{pointer-events:none}.control:not(.shape-pill){--_select-control-border-radius:8px}.control.shape-pill{--_select-control-border-radius:24px}.listbox{max-height:var(--select-height,408px);flex-direction:column;gap:2px;padding:4px;display:flex;overflow-y:auto}:host([multiple]:focus-visible) .listbox{box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));border-radius:8px}.selected-value{white-space:nowrap;flex-grow:1;align-items:center;column-gap:12px;display:flex;overflow:hidden}.selected-value .text{text-overflow:ellipsis;max-inline-size:100%;overflow:hidden}.control.shows-placeholder .selected-value .text{color:var(--vvd-color-neutral-600)}.selected-value slot[name=icon]{flex:0 0 var(--_select-icon-size);font-size:var(--_select-icon-size);line-height:1}.control.has-meta .selected-value{padding-inline-end:8px}.feedback-wrapper{display:contents}::part(popup-base){inline-size:max-content;min-inline-size:var(--_select-fixed-width,100%)}:host([multiple]) ::part(popup-base){position:static}@supports selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant,:has(.clear-button:focus)){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}@supports not selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}:host(:not(:focus-visible)){--_suppressable-focus-shadow:none;--_suppressable-focus-outline:none;--_suppressable-focus-outline-offset:0}:host([multiple]) .clear-button{margin-inline-start:auto}:host([multiple][clearable]) .label-wrapper{min-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16))}";
8
24
  //#endregion
9
- //#region src/lib/rich-text-view/rich-text-view.ts
25
+ //#region src/lib/select/select.ts
10
26
  /**
11
27
  * @public
12
- * @component rich-text-view
13
- * @dynamicSlot `@vonage/vivid#RteChildSlotProps` child - Used for custom rendered children.
28
+ * @component select
29
+ * @slot - Default slot.
30
+ * @slot icon - The preferred way to add an icon to the select control.
31
+ * @slot meta - Slot to add meta content to the select control.
32
+ * @slot helper-text - Describes how to use the select. Alternative to the `helper-text` attribute.
33
+ * @event {CustomEvent<undefined>} input - Fires a custom 'input' event when the value updates
34
+ * @event {CustomEvent<HTMLElement>} change - Fires a custom 'change' event when the value updates
35
+ * @vueModel modelValue value input,@lazy:change `event.currentTarget.value`
36
+ * @testAction selectOptionByValue selectOptionByValue
37
+ * @testAction selectOptionByText selectOptionByText
14
38
  */
15
- var RichTextView = class extends VividElement {
39
+ var Select = class extends WithLightDOMFeedback(WithContextualHelp(WithErrorText(WithSuccessText(Localized(FormElement(HostSemantics(AffixIconWithTrailing(FormAssociated(Listbox))))))))) {
16
40
  constructor(..._args) {
17
41
  super(..._args);
18
- this._slotCounter = 0;
19
- this._slottedChildren = /* @__PURE__ */ new Set();
20
- this._slotRequests = /* @__PURE__ */ new Set();
21
- this._contentElement = null;
42
+ this.proxy = document.createElement("select");
43
+ this.activeIndex = -1;
44
+ this.rangeStartIndex = -1;
45
+ this.open = false;
46
+ this.listboxId = uniqueId("listbox-");
47
+ this.maxHeight = 0;
48
+ this.fixedDropdown = false;
49
+ this._feedbackWrapper = null;
50
+ this._isResetting = false;
51
+ this.clearable = false;
52
+ this._isClearButtonFocused = false;
53
+ }
54
+ /**
55
+ * Returns the last checked option.
56
+ *
57
+ * @internal
58
+ */
59
+ get activeOption() {
60
+ return this.options[this.activeIndex];
61
+ }
62
+ /**
63
+ * Returns the list of checked options.
64
+ *
65
+ * @internal
66
+ */
67
+ get checkedOptions() {
68
+ return this.options.filter((o) => o.checked);
69
+ }
70
+ /**
71
+ * Returns the index of the first selected option.
72
+ *
73
+ * @internal
74
+ */
75
+ get firstSelectedOptionIndex() {
76
+ return this.options.indexOf(this.firstSelectedOption);
77
+ }
78
+ /**
79
+ * Updates the `ariaActiveDescendant` property when the active index changes.
80
+ *
81
+ * @internal
82
+ */
83
+ activeIndexChanged(_, next) {
84
+ this._activeDescendant = this.options[next]?.id ?? "";
85
+ this.focusAndScrollOptionIntoView();
86
+ }
87
+ /**
88
+ * Toggles the checked state for the currently active option.
89
+ *
90
+ * @remarks
91
+ * Multiple-selection mode only.
92
+ *
93
+ * @internal
94
+ */
95
+ checkActiveIndex() {
96
+ const activeItem = this.activeOption;
97
+ /* v8 ignore else -- @preserve */
98
+ if (activeItem) activeItem.checked = true;
99
+ }
100
+ /**
101
+ * Sets the active index to the first option and marks it as checked.
102
+ *
103
+ * @remarks
104
+ * Multi-selection mode only.
105
+ *
106
+ * @param preserveChecked - mark all options unchecked before changing the active index
107
+ *
108
+ * @internal
109
+ */
110
+ checkFirstOption(preserveChecked) {
111
+ const firstSelectableIndex = this.getNextSelectableIndex(0);
112
+ if (firstSelectableIndex === -1) return;
113
+ if (preserveChecked) {
114
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
115
+ this.options.forEach((o, i) => {
116
+ o.checked = inRange(i, firstSelectableIndex, this.rangeStartIndex + 1) && !o.disabled;
117
+ });
118
+ } else this.uncheckAllOptions();
119
+ this.activeIndex = firstSelectableIndex;
120
+ this.checkActiveIndex();
121
+ }
122
+ /**
123
+ * Decrements the active index and sets the matching option as checked.
124
+ *
125
+ * @remarks
126
+ * Multi-selection mode only.
127
+ *
128
+ * @param preserveChecked - mark all options unchecked before changing the active index
129
+ *
130
+ * @internal
131
+ */
132
+ checkLastOption(preserveChecked) {
133
+ const lastSelectableIndex = this.getPreviousSelectableIndex(this.length - 1);
134
+ if (lastSelectableIndex === -1) return;
135
+ if (preserveChecked) {
136
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
137
+ this.options.forEach((o, i) => {
138
+ o.checked = inRange(i, this.rangeStartIndex, lastSelectableIndex + 1) && !o.disabled;
139
+ });
140
+ } else this.uncheckAllOptions();
141
+ this.activeIndex = lastSelectableIndex;
142
+ this.checkActiveIndex();
143
+ }
144
+ /**
145
+ * Increments the active index and marks the matching option as checked.
146
+ *
147
+ * @remarks
148
+ * Multiple-selection mode only.
149
+ *
150
+ * @param preserveChecked - mark all options unchecked before changing the active index
151
+ *
152
+ * @internal
153
+ */
154
+ checkNextOption(preserveChecked) {
155
+ const nextIndex = this.getNextSelectableIndex(this.activeIndex + 1);
156
+ if (nextIndex === -1) return;
157
+ if (preserveChecked) {
158
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
159
+ this.options.forEach((o, i) => {
160
+ o.checked = inRange(i, this.rangeStartIndex, nextIndex + 1) && !o.disabled;
161
+ });
162
+ } else this.uncheckAllOptions();
163
+ this.activeIndex = nextIndex;
164
+ this.checkActiveIndex();
165
+ }
166
+ /**
167
+ * Decrements the active index and marks the matching option as checked.
168
+ *
169
+ * @remarks
170
+ * Multiple-selection mode only.
171
+ *
172
+ * @param preserveChecked - mark all options unchecked before changing the active index
173
+ *
174
+ * @internal
175
+ */
176
+ checkPreviousOption(preserveChecked) {
177
+ const previousIndex = this.getPreviousSelectableIndex(this.activeIndex - 1);
178
+ if (previousIndex === -1) return;
179
+ if (preserveChecked) {
180
+ if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
181
+ if (this.checkedOptions.length === 1) this.rangeStartIndex += 1;
182
+ this.options.forEach((o, i) => {
183
+ o.checked = inRange(i, previousIndex, this.rangeStartIndex + 1) && !o.disabled;
184
+ });
185
+ } else this.uncheckAllOptions();
186
+ this.activeIndex = previousIndex;
187
+ this.checkActiveIndex();
188
+ }
189
+ /** @internal */
190
+ focusAndScrollOptionIntoView() {
191
+ super.focusAndScrollOptionIntoView(this.activeOption);
192
+ }
193
+ /**
194
+ * In multiple-selection mode:
195
+ * If any options are selected, the first selected option is checked when
196
+ * the listbox receives focus. If no options are selected, the first
197
+ * selectable option is checked.
198
+ *
199
+ * @internal
200
+ */
201
+ focusinHandler(e) {
202
+ if (!this.multiple) {
203
+ super.focusinHandler(e);
204
+ return;
205
+ }
206
+ /* v8 ignore else -- @preserve */
207
+ if (!this.shouldSkipFocus && e.target === e.currentTarget) {
208
+ this.uncheckAllOptions();
209
+ if (this.activeIndex === -1) this.activeIndex = this.firstSelectedOptionIndex !== -1 ? this.firstSelectedOptionIndex : 0;
210
+ this.checkActiveIndex();
211
+ this.setSelectedOptions();
212
+ this.focusAndScrollOptionIntoView();
213
+ }
214
+ this.shouldSkipFocus = false;
215
+ }
216
+ /** Sets an option as selected and gives it focus. */
217
+ setSelectedOptions() {
218
+ if (!this.multiple) {
219
+ super.setSelectedOptions();
220
+ return;
221
+ }
222
+ /* v8 ignore else -- @preserve */
223
+ if (this.$fastController.isConnected && this.options) {
224
+ this.selectedOptions = this.options.filter((o) => o.selected);
225
+ this.focusAndScrollOptionIntoView();
226
+ }
227
+ }
228
+ /**
229
+ * Toggles the selected state of the provided options. If any provided items
230
+ * are in an unselected state, all items are set to selected. If every
231
+ * provided item is selected, they are all unselected.
232
+ *
233
+ * @internal
234
+ */
235
+ toggleSelectedForAllCheckedOptions() {
236
+ const enabledCheckedOptions = this.checkedOptions.filter((o) => !o.disabled);
237
+ const force = !enabledCheckedOptions.every((o) => o.selected);
238
+ enabledCheckedOptions.forEach((o) => o.selected = force);
239
+ this.selectedIndex = this.options.indexOf(enabledCheckedOptions[enabledCheckedOptions.length - 1]);
240
+ this.setSelectedOptions();
241
+ this.updateValue(true);
22
242
  }
23
243
  /** @internal */
24
- viewChanged(oldView, newView) {
25
- if (oldView) this._removeStyles();
26
- if (newView) this._addStyles(newView);
27
- this._updateView();
28
- }
29
- _addStyles(view) {
30
- const config = view[impl].config[impl];
31
- this._styles = new ElementStyles(sortedContributions(config.features.flatMap((f) => f.getStyles())));
32
- this._styles.addStylesTo(this.shadowRoot);
33
- }
34
- _removeStyles() {
35
- if (this._styles) {
36
- this._styles.removeStylesFrom(this.shadowRoot);
37
- this._styles = void 0;
244
+ typeaheadBufferChanged(prev, next) {
245
+ if (!this.multiple) {
246
+ super.typeaheadBufferChanged(prev, next);
247
+ return;
248
+ }
249
+ /* v8 ignore if -- @preserve */
250
+ if (this.$fastController.isConnected) {
251
+ const typeaheadMatches = this.getTypeaheadMatches();
252
+ const activeIndex = this.options.indexOf(typeaheadMatches[0]);
253
+ if (activeIndex > -1) {
254
+ this.activeIndex = activeIndex;
255
+ this.uncheckAllOptions();
256
+ this.checkActiveIndex();
257
+ }
258
+ this.typeaheadExpired = false;
38
259
  }
39
260
  }
40
- _cleanupLightDom() {
41
- for (const el of this._slottedChildren) this.removeChild(el);
42
- for (const slotName of this._slotRequests) dispatchSlottableRequest(this, "child", slotName, removeSymbol);
43
- this._slottedChildren.clear();
44
- this._slotRequests.clear();
45
- this._slotCounter = 0;
46
- }
47
- _updateView() {
48
- if (!this._contentElement) return;
49
- this._contentElement.innerHTML = "";
50
- this._cleanupLightDom();
51
- if (this.view) this._contentElement.appendChild(this._renderView(this.view));
52
- }
53
- _renderView(rteView) {
54
- const ctx = rteView[impl];
55
- if (rteView.type === "node" && rteView.node.type === "doc") rteView = rteView.children;
56
- if (rteView.type === "fragment") {
57
- const frag = document.createDocumentFragment();
58
- for (const child of rteView.content) frag.appendChild(this._renderView(child));
59
- return frag;
261
+ /**
262
+ * Unchecks all options.
263
+ *
264
+ * @remarks
265
+ * Multiple-selection mode only.
266
+ *
267
+ * @param preserveChecked - reset the rangeStartIndex
268
+ *
269
+ * @internal
270
+ */
271
+ uncheckAllOptions(preserveChecked = false) {
272
+ this.options.forEach((o) => o.checked = false);
273
+ /* v8 ignore else -- @preserve */
274
+ if (!preserveChecked) this.rangeStartIndex = -1;
275
+ }
276
+ /**
277
+ * Sets focus when the open property changes.
278
+ *
279
+ * @internal
280
+ */
281
+ openChanged(prev, next) {
282
+ if (!this.collapsible) return;
283
+ if (this.open) {
284
+ this.focusAndScrollOptionIntoView();
285
+ this.indexWhenOpened = this.selectedIndex;
286
+ Updates.enqueue(() => this.focus());
287
+ return;
60
288
  }
61
- const customRenderedView = ctx.options.renderChildView?.(rteView) ?? false;
62
- if (customRenderedView) return this._handleCustomRender(rteView, customRenderedView);
63
- else return this._renderDefault(rteView);
64
- }
65
- _handleCustomRender(rteView, customResult) {
66
- const slotName = `child-view-${this._slotCounter++}`;
67
- const slot = document.createElement("slot");
68
- slot.setAttribute("name", slotName);
69
- if (customResult === true) {
70
- this._slotRequests.add(slotName);
71
- dispatchSlottableRequest(this, "child", slotName, { view: rteView });
72
- } else {
73
- const { dom, contentDom = dom } = customResult;
74
- const nestedView = document.createElement(this.tagName);
75
- nestedView.view = rteView.children;
76
- contentDom.appendChild(nestedView);
77
- dom.setAttribute("slot", slotName);
78
- this.appendChild(dom);
79
- this._slottedChildren.add(dom);
289
+ const didClose = prev && !next;
290
+ const selectionChangedWhileOpen = this.indexWhenOpened !== this.selectedIndex;
291
+ if (didClose && selectionChangedWhileOpen) this.updateValue(true);
292
+ }
293
+ /**
294
+ * The component is collapsible when in single-selection mode.
295
+ *
296
+ * @internal
297
+ */
298
+ get collapsible() {
299
+ return !this.multiple;
300
+ }
301
+ /** @internal */
302
+ valueChanged(prev, next) {
303
+ const nextSelectedIndex = this.options.findIndex((el) => el.value === next);
304
+ const validNextSelectedIndex = this._validSelectedIndex(nextSelectedIndex);
305
+ const nextValue = this.options[validNextSelectedIndex]?.value ?? "";
306
+ if (this.selectedIndex !== validNextSelectedIndex) this.selectedIndex = validNextSelectedIndex;
307
+ if (next !== nextValue) return;
308
+ super.valueChanged(prev, next);
309
+ this.updateDisplayValue();
310
+ }
311
+ /**
312
+ * Sets the value and display value to match the first selected option.
313
+ *
314
+ * @param shouldEmit - if true, the input and change events will be emitted
315
+ *
316
+ * @internal
317
+ */
318
+ updateValue(shouldEmit) {
319
+ if (this.$fastController.isConnected) this.value = this.firstSelectedOption?.value ?? "";
320
+ if (shouldEmit) {
321
+ this.$emit("input");
322
+ this.$emit("change", this, {
323
+ bubbles: true,
324
+ composed: void 0
325
+ });
80
326
  }
81
- return slot;
82
- }
83
- _renderDefault(view) {
84
- const schema = view[impl].config[impl].schema;
85
- if (view.type === "node" && view.node.type === "text") return document.createTextNode(view.node.text);
86
- const item = view.type === "node" ? view.node : view.mark;
87
- const pmItem = view.type === "node" ? Node.fromJSON(schema, item) : Mark.fromJSON(schema, item);
88
- const spec = pmItem instanceof Node ? pmItem.type.spec.toDOM(pmItem) : pmItem.type.spec.toDOM(pmItem, true);
89
- const { dom, contentDOM = dom } = DOMSerializer.renderSpec(document, spec);
90
- const childrenRendered = this._renderView(view.children);
91
- contentDOM.appendChild(childrenRendered);
92
- return dom;
327
+ }
328
+ /**
329
+ * Updates the proxy value when the selected index changes.
330
+ *
331
+ * @param prev - the previous selected index
332
+ * @param next - the next selected index
333
+ *
334
+ * @internal
335
+ */
336
+ selectedIndexChanged(prev, next) {
337
+ super.selectedIndexChanged(prev, next);
338
+ this.updateValue();
339
+ }
340
+ /**
341
+ * Handle opening and closing the listbox when the select is clicked.
342
+ *
343
+ * @param e - the mouse event
344
+ * @internal
345
+ */
346
+ clickHandler(e) {
347
+ if (this.disabled || this._isFromContextualHelp(e)) return;
348
+ const clickedOption = e.target.closest(`option,[role=option],[data-vvd-component=option]`);
349
+ if (clickedOption && clickedOption.disabled) return;
350
+ if (this.multiple) {
351
+ this.uncheckAllOptions();
352
+ this.activeIndex = this.options.indexOf(clickedOption);
353
+ this.checkActiveIndex();
354
+ this.toggleSelectedForAllCheckedOptions();
355
+ } else super.clickHandler(e);
356
+ if (this.collapsible) this.open = !this.open;
357
+ return true;
358
+ }
359
+ /**
360
+ * Handles focus state when the element or its children lose focus.
361
+ *
362
+ * @param e - The focus event
363
+ * @internal
364
+ */
365
+ focusoutHandler(e) {
366
+ if (this.multiple) this.uncheckAllOptions();
367
+ if (!this.open) return true;
368
+ const focusTarget = e.relatedTarget;
369
+ if (this.isSameNode(focusTarget)) {
370
+ this.focus();
371
+ return;
372
+ }
373
+ /* v8 ignore else -- @preserve */
374
+ if (!this.options.includes(focusTarget)) {
375
+ this.open = false;
376
+ if (this.indexWhenOpened !== this.selectedIndex) this.updateValue(true);
377
+ }
378
+ }
379
+ /**
380
+ * Updates the value when an option's value changes.
381
+ *
382
+ * @param source - the source object
383
+ * @param propertyName - the property to evaluate
384
+ *
385
+ * @internal
386
+ */
387
+ handleChange(source, propertyName) {
388
+ super.handleChange(source, propertyName);
389
+ if (propertyName === "value") this.updateValue();
390
+ }
391
+ /**
392
+ * Prevents focus when a scrollbar is clicked.
393
+ *
394
+ * @param e - the mouse event object
395
+ *
396
+ * @internal
397
+ */
398
+ mousedownHandler(e) {
399
+ if (e.offsetX >= 0 && e.offsetX <= this.listbox.scrollWidth) return super.mousedownHandler(e);
400
+ return this.collapsible;
93
401
  }
94
402
  /** @internal */
403
+ multipleChanged(_, next) {
404
+ this.options.forEach((o) => {
405
+ o.checked = next ? false : void 0;
406
+ });
407
+ this.setSelectedOptions();
408
+ /* v8 ignore if -- @preserve */
409
+ if (this.proxy) this.proxy.multiple = next;
410
+ }
411
+ /**
412
+ * Updates the selectedness of each option when the list of selected options changes.
413
+ *
414
+ * @param prev - the previous list of selected options
415
+ * @param next - the current list of selected options
416
+ *
417
+ * @internal
418
+ */
419
+ selectedOptionsChanged(prev, next) {
420
+ super.selectedOptionsChanged(prev, next);
421
+ this.options.forEach((o, i) => {
422
+ const proxyOption = this.proxy.options.item(i);
423
+ if (proxyOption) proxyOption.selected = o.selected;
424
+ });
425
+ }
426
+ /**
427
+ * Resets and fills the proxy to match the component's options.
428
+ *
429
+ * @internal
430
+ */
431
+ setProxyOptions() {
432
+ /* v8 ignore else -- @preserve */
433
+ if (this.proxy instanceof HTMLSelectElement && this.options) {
434
+ this.proxy.length = 0;
435
+ this.options.forEach((option) => {
436
+ const proxyOption = option.proxy || (option instanceof HTMLOptionElement ? option.cloneNode() : null);
437
+ if (proxyOption) this.proxy.options.add(proxyOption);
438
+ });
439
+ }
440
+ }
441
+ /**
442
+ * Handles keydown actions when the select is in multiple selection mode.
443
+ *
444
+ * @internal
445
+ */
446
+ multipleKeydownHandler(e) {
447
+ if (this.disabled) return;
448
+ const { key, shiftKey } = e;
449
+ this.shouldSkipFocus = false;
450
+ switch (key) {
451
+ case keyHome:
452
+ this.checkFirstOption(shiftKey);
453
+ return;
454
+ case keyArrowDown:
455
+ this.checkNextOption(shiftKey);
456
+ return;
457
+ case keyArrowUp:
458
+ this.checkPreviousOption(shiftKey);
459
+ return;
460
+ case keyEnd:
461
+ this.checkLastOption(shiftKey);
462
+ return;
463
+ case keyTab:
464
+ this.focusAndScrollOptionIntoView();
465
+ return;
466
+ case keyEscape:
467
+ this.uncheckAllOptions();
468
+ this.checkActiveIndex();
469
+ return;
470
+ case keySpace:
471
+ e.preventDefault();
472
+ /* v8 ignore else -- @preserve */
473
+ if (this.typeaheadExpired) {
474
+ this.toggleSelectedForAllCheckedOptions();
475
+ return;
476
+ }
477
+ default:
478
+ /* v8 ignore else -- @preserve */
479
+ if (key.length === 1) this.handleTypeAhead(key);
480
+ return;
481
+ }
482
+ }
483
+ /**
484
+ * Handle keyboard interaction for the select.
485
+ *
486
+ * @param e - the keyboard event
487
+ * @internal
488
+ */
489
+ keydownHandler(e) {
490
+ const selectedIndexBefore = this.selectedIndex;
491
+ if (this.multiple) this.multipleKeydownHandler(e);
492
+ else super.keydownHandler(e);
493
+ switch (e.key) {
494
+ case keySpace:
495
+ e.preventDefault();
496
+ if (this.collapsible && this.typeaheadExpired) this.open = !this.open;
497
+ break;
498
+ case keyHome:
499
+ case keyEnd:
500
+ e.preventDefault();
501
+ break;
502
+ case keyEnter:
503
+ e.preventDefault();
504
+ this.open = !this.open;
505
+ break;
506
+ case keyEscape:
507
+ if (this.collapsible && this.open) {
508
+ e.preventDefault();
509
+ this.open = false;
510
+ }
511
+ break;
512
+ case keyTab:
513
+ if (this.collapsible && this.open) {
514
+ e.preventDefault();
515
+ this.open = false;
516
+ }
517
+ return true;
518
+ }
519
+ if (this.collapsible && !this.open && this.selectedIndex !== selectedIndexBefore) this.updateValue(true);
520
+ return !(e.key === keyArrowDown || e.key === keyArrowUp);
521
+ }
95
522
  connectedCallback() {
96
523
  super.connectedCallback();
97
- this._updateView();
524
+ this.addEventListener("focusout", this.focusoutHandler);
525
+ this.addEventListener("contentchange", this.updateDisplayValue);
98
526
  }
99
- /** @internal */
100
527
  disconnectedCallback() {
528
+ this.removeEventListener("focusout", this.focusoutHandler);
529
+ this.removeEventListener("contentchange", this.updateDisplayValue);
101
530
  super.disconnectedCallback();
102
- this._removeStyles();
103
- this._cleanupLightDom();
531
+ }
532
+ /** @internal */
533
+ updateDisplayValue() {
534
+ if (this.collapsible) Observable.notify(this, "displayValue");
535
+ }
536
+ get displayValue() {
537
+ Observable.track(this, "displayValue");
538
+ return this.firstSelectedOption?.getAttribute("label") ?? this.firstSelectedOption?.text ?? this.placeholder ?? "";
539
+ }
540
+ _newDefaultSelectedIndex(prev, next, currentSelectIndex) {
541
+ const defaultSelectedIndex = super._newDefaultSelectedIndex(prev, next, currentSelectIndex);
542
+ if (defaultSelectedIndex === null && currentSelectIndex === -1 && !this.placeholder) {
543
+ const firstSelectableIndex = this.getNextSelectableIndex(0);
544
+ if (firstSelectableIndex !== -1) return firstSelectableIndex;
545
+ }
546
+ return defaultSelectedIndex;
547
+ }
548
+ _isDefaultSelected(option) {
549
+ return super._isDefaultSelected(option) || option.value === this.initialValue || !this._isResetting && option.value === this.value;
550
+ }
551
+ slottedOptionsChanged(prev, next) {
552
+ this.options.forEach((o) => {
553
+ Observable.getNotifier(o).unsubscribe(this, "value");
554
+ });
555
+ super.slottedOptionsChanged(prev, next);
556
+ this.options.forEach((o) => {
557
+ Observable.getNotifier(o).subscribe(this, "value");
558
+ });
559
+ this.setProxyOptions();
560
+ this.updateValue();
561
+ const scale = this.getAttribute("scale") || this.scale;
562
+ next.forEach((element) => {
563
+ if (scale) {
564
+ element.setAttribute("scale", scale);
565
+ element.scale = scale;
566
+ }
567
+ });
568
+ this.proxy.value = this.value;
569
+ this.validate();
570
+ }
571
+ formResetCallback() {
572
+ this.setProxyOptions();
573
+ this._isResetting = true;
574
+ this.selectedIndex = this._newDefaultSelectedIndex([], this.options, -1) ?? -1;
575
+ this._isResetting = false;
576
+ }
577
+ /** @internal */
578
+ get _shouldShowClearButton() {
579
+ if (!this.clearable) return false;
580
+ if (this.multiple) return this.selectedOptions?.length > 0;
581
+ return this.value !== "";
582
+ }
583
+ /** @internal */
584
+ _onClearButtonFocus() {
585
+ this._isClearButtonFocused = true;
586
+ this.activeIndex = -1;
587
+ this.uncheckAllOptions();
588
+ }
589
+ /** @internal */
590
+ _onClearButtonBlur() {
591
+ this._isClearButtonFocused = false;
592
+ }
593
+ /** @internal */
594
+ get _shouldShowLabelWrapper() {
595
+ return Boolean(this.label || this._hasContextualHelp || this.multiple && this._shouldShowClearButton);
596
+ }
597
+ /** @internal */
598
+ _onClearButtonClick() {
599
+ if (this.multiple) this.selectedOptions.forEach((o) => {
600
+ /* v8 ignore else -- @preserve */
601
+ if (!o.disabled) o.selected = false;
602
+ });
603
+ else this.selectedIndex = -1;
604
+ this.updateValue(true);
104
605
  }
105
606
  };
106
- __decorate([observable], RichTextView.prototype, "view", void 0);
607
+ __decorate([observable], Select.prototype, "activeIndex", void 0);
608
+ __decorate([attr({ mode: "boolean" })], Select.prototype, "multiple", void 0);
609
+ __decorate([attr({
610
+ attribute: "open",
611
+ mode: "boolean"
612
+ })], Select.prototype, "open", void 0);
613
+ __decorate([volatile], Select.prototype, "collapsible", null);
614
+ __decorate([observable], Select.prototype, "control", void 0);
615
+ __decorate([observable], Select.prototype, "maxHeight", void 0);
616
+ __decorate([observable], Select.prototype, "_anchor", void 0);
617
+ __decorate([attr()], Select.prototype, "scale", void 0);
618
+ __decorate([attr], Select.prototype, "appearance", void 0);
619
+ __decorate([attr], Select.prototype, "shape", void 0);
620
+ __decorate([attr({
621
+ mode: "boolean",
622
+ attribute: "fixed-dropdown"
623
+ })], Select.prototype, "fixedDropdown", void 0);
624
+ __decorate([attr], Select.prototype, "placeholder", void 0);
625
+ __decorate([observable], Select.prototype, "_feedbackWrapper", void 0);
626
+ __decorate([observable], Select.prototype, "metaSlottedContent", void 0);
627
+ __decorate([attr({ mode: "boolean" })], Select.prototype, "clearable", void 0);
628
+ __decorate([observable], Select.prototype, "_isClearButtonFocused", void 0);
107
629
  //#endregion
108
- //#region src/lib/rich-text-view/rich-text-view.template.ts
109
- var RichTextViewTemplate = () => html`<div class="content rich-text" ${ref("_contentElement")}></div>`;
630
+ //#region src/lib/select/select.template.ts
631
+ function renderLabel() {
632
+ return html` <label
633
+ for="${(x) => x.multiple ? null : "control"}"
634
+ class="label"
635
+ id="label"
636
+ >
637
+ ${(x) => x.label}
638
+ </label>`;
639
+ }
640
+ function renderPlaceholder(context) {
641
+ const optionTag = context.tagFor(ListboxOption);
642
+ return html`
643
+ <${optionTag} text="${(x) => x.placeholder}" hidden disabled>
644
+ </${optionTag}>`;
645
+ }
646
+ function renderClearButton(context) {
647
+ const buttonTag = context.tagFor(Button);
648
+ return html`
649
+ <${buttonTag}
650
+ aria-label="${(x) => x.locale.select.clearButtonLabel}"
651
+ aria-hidden="${(x) => x._isClearButtonFocused ? "false" : "true"}"
652
+ @click="${(x, c) => {
653
+ x._onClearButtonClick();
654
+ c.event.stopPropagation();
655
+ }}"
656
+ @mousedown="${() => false}"
657
+ @keydown="${(x, c) => {
658
+ /* v8 ignore next -- @preserve */
659
+ if (c.event.key === "Tab") x._onClearButtonBlur();
660
+ c.event.stopPropagation();
661
+ return true;
662
+ }}"
663
+ @focusin="${(x, c) => {
664
+ c.event.stopPropagation();
665
+ x._onClearButtonFocus();
666
+ }}"
667
+ @focusout="${(x) => x._onClearButtonBlur()}"
668
+ ?disabled="${(x) => x.disabled}"
669
+ :shape="${(x) => x.shape}"
670
+ size="super-condensed"
671
+ icon="close-line"
672
+ appearance="ghost-light"
673
+ class="clear-button"
674
+ tabindex="0"
675
+ ></${buttonTag}>
676
+ `;
677
+ }
678
+ function selectValue(context) {
679
+ const affixIconTemplate = affixIconTemplateFactory(context);
680
+ const chevronTemplate = chevronTemplateFactory(context);
681
+ return html` <div
682
+ class="control ${(x) => classNames(["has-activedescendant", Boolean(x._activeDescendant) && x.open], ["disabled", x.disabled], [`appearance-${x.appearance}`, Boolean(x.appearance)], [`shape-${x.shape}`, Boolean(x.shape)], ["has-meta", Boolean(x.metaSlottedContent?.length)], ["error", Boolean(x.errorValidationMessage)], ["success", !!x.successText], ["shows-placeholder", Boolean(x.placeholder) && !x.value], [`size-${x.scale}`, Boolean(x.scale)])}"
683
+ ${ref("_anchor")}
684
+ id="control"
685
+ ?disabled="${(x) => x.disabled}"
686
+ >
687
+ <div class="selected-value">
688
+ ${(x) => affixIconTemplate(x.icon, IconWrapper.Slot)}
689
+ <span class="text">${(x) => x.displayValue}</span>
690
+ <slot name="meta" ${slotted("metaSlottedContent")}></slot>
691
+ </div>
692
+ ${when((x) => x._shouldShowClearButton, renderClearButton(context))}
693
+ ${chevronTemplate}
694
+ </div>`;
695
+ }
696
+ function setFixedDropdownVarWidth(x) {
697
+ return x.open && x.fixedDropdown ? `--_select-fixed-width: ${Math.round(x.getBoundingClientRect().width)}px` : null;
698
+ }
699
+ /** @param context - element definition context */
700
+ function renderControl(context) {
701
+ const popupTag = context.tagFor(Popup);
702
+ return html`
703
+ <div class="label-wrapper" ?hidden=${(x) => !x._shouldShowLabelWrapper}>
704
+ ${when((x) => x.label, renderLabel())}
705
+ ${when((x) => x.multiple && x._shouldShowClearButton, renderClearButton(context))}
706
+ <slot name="contextual-help" ${slotted("_contextualHelpSlottedContent")}></slot>
707
+ </div>
708
+ <div class="control-wrapper">
709
+ ${when((x) => !x.multiple, selectValue(context))}
710
+ <${popupTag} class="popup"
711
+ style="${setFixedDropdownVarWidth}"
712
+ ?open="${(x) => x.collapsible ? x.open : true}"
713
+ :anchor="${(x) => x._anchor}"
714
+ placement="bottom-start"
715
+ strategy="${(x) => x.fixedDropdown ? null : "absolute"}">
716
+ <div class="listbox"
717
+ id="${(x) => x.listboxId}"
718
+ role="listbox"
719
+ aria-multiselectable="${(x) => x.multiple}"
720
+ aria-label="${(x) => x.multiple && !x.label && x.ariaLabel ? x.ariaLabel : null}"
721
+ aria-labelledby="${(x) => x.multiple && x.label ? "label" : null}"
722
+ ?disabled="${(x) => x.disabled}"
723
+ ?hidden="${(x) => x.collapsible ? !x.open : false}"
724
+ ${ref("listbox")}>
725
+ ${when((x) => x.placeholder, renderPlaceholder(context))}
726
+ <slot
727
+ ${slotted({
728
+ filter: Listbox.slottedOptionFilter,
729
+ flatten: true,
730
+ property: "slottedOptions"
731
+ })}>
732
+ </slot>
733
+ </div>
734
+ </${popupTag}>
735
+ </div>
736
+ `;
737
+ }
738
+ /** Ignore events that originate from feedback, e.g. a click on link */
739
+ function ifNotFromFeedback(handler) {
740
+ return (x, c) => {
741
+ if (!c.event.composedPath().includes(x._feedbackWrapper)) {
742
+ handler(x, c.event);
743
+ return;
744
+ }
745
+ return true;
746
+ };
747
+ }
748
+ var SelectTemplate = (context) => {
749
+ return html`
750
+ <template
751
+ ${applyHostSemantics({
752
+ role: "combobox",
753
+ ariaLabel: (x) => x.ariaLabel ?? x.label,
754
+ ariaHasPopup: (x) => x.collapsible ? "listbox" : "false",
755
+ ariaExpanded: (x) => x.open,
756
+ ariaDisabled: (x) => x.disabled
757
+ })}
758
+ aria-controls="${(x) => x.listboxId}"
759
+ aria-activedescendant="${(x) => x.open ? x._activeDescendant : null}"
760
+ aria-describedby="${(x) => x._feedbackDescribedBy}"
761
+ tabindex="${(x) => !x.disabled ? "0" : null}"
762
+ @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
763
+ @focusin="${ifNotFromFeedback((x, e) => x.focusinHandler(e))}"
764
+ @focusout="${ifNotFromFeedback((x, e) => x.focusoutHandler(e))}"
765
+ @keydown="${ifNotFromFeedback((x, e) => {
766
+ if (x.open) handleEscapeKeyAndStopPropogation(e);
767
+ return x.keydownHandler(e);
768
+ })}"
769
+ @mousedown="${ifNotFromFeedback((x, e) => x.mousedownHandler(e))}"
770
+ >
771
+ ${renderControl(context)}
772
+ <div class="feedback-wrapper" ${ref("_feedbackWrapper")}>
773
+ ${(x) => x._getFeedbackTemplate(context)}
774
+ </div>
775
+ </template>
776
+ `;
777
+ };
110
778
  //#endregion
111
- //#region src/lib/rich-text-view/definition.ts
112
- var richTextViewDefinition = defineVividComponent("rich-text-view", RichTextView, RichTextViewTemplate, [], {
113
- styles: rich_text_view_default,
114
- shadowOptions: { delegatesFocus: true }
115
- });
779
+ //#region src/lib/select/definition.ts
780
+ /** @internal */
781
+ var selectDefinition = defineVividComponent("select", Select, SelectTemplate, [
782
+ popupDefinition,
783
+ iconDefinition,
784
+ listboxOptionDefinition,
785
+ optgroupDefinition,
786
+ buttonDefinition,
787
+ feedbackMessageDefinition
788
+ ], { styles: select_default });
116
789
  /**
117
- * Registers the rich-text-view element with the design system.
790
+ * Registers the select elements with the design system.
118
791
  *
119
792
  * @param prefix - the prefix to use for the component name
120
793
  */
121
- var registerRichTextView = createRegisterFunction(richTextViewDefinition);
794
+ var registerSelect = createRegisterFunction(selectDefinition);
122
795
  //#endregion
123
- export { richTextViewDefinition as n, RichTextView as r, registerRichTextView as t };
796
+ export { selectDefinition as n, Select as r, registerSelect as t };