@vonage/vivid 4.22.0 → 4.24.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 (232) hide show
  1. package/custom-elements.json +1658 -370
  2. package/lib/accordion-item/accordion-item.d.ts +11 -5
  3. package/lib/action-group/action-group.d.ts +8 -6
  4. package/lib/alert/alert.d.ts +21 -9
  5. package/lib/audio-player/audio-player.d.ts +11 -5
  6. package/lib/badge/badge.d.ts +11 -5
  7. package/lib/banner/banner.d.ts +26 -12
  8. package/lib/breadcrumb/breadcrumb.d.ts +333 -1
  9. package/lib/breadcrumb/breadcrumb.template.d.ts +2 -3
  10. package/lib/breadcrumb-item/breadcrumb-item.d.ts +8 -6
  11. package/lib/button/button.d.ts +11 -5
  12. package/lib/calendar-event/calendar-event.d.ts +333 -1
  13. package/lib/checkbox/checkbox.d.ts +8 -6
  14. package/lib/combobox/combobox.d.ts +11 -5
  15. package/lib/date-picker/date-picker.d.ts +74 -50
  16. package/lib/date-range-picker/date-range-picker.d.ts +38 -26
  17. package/lib/date-time-picker/date-time-picker.d.ts +76 -52
  18. package/lib/dial-pad/dial-pad.d.ts +11 -5
  19. package/lib/dialog/dialog.d.ts +16 -8
  20. package/lib/divider/divider.d.ts +8 -6
  21. package/lib/fab/fab.d.ts +11 -5
  22. package/lib/file-picker/file-picker.d.ts +337 -1
  23. package/lib/file-picker/locale.d.ts +1 -0
  24. package/lib/header/header.d.ts +333 -1
  25. package/lib/menu/menu.d.ts +16 -8
  26. package/lib/menu-item/menu-item.d.ts +338 -2
  27. package/lib/nav/nav.d.ts +333 -1
  28. package/lib/nav-disclosure/nav-disclosure.d.ts +16 -8
  29. package/lib/nav-item/nav-item.d.ts +11 -5
  30. package/lib/note/note.d.ts +11 -5
  31. package/lib/number-field/number-field.d.ts +26 -12
  32. package/lib/option/option.d.ts +339 -3
  33. package/lib/progress/progress.d.ts +8 -6
  34. package/lib/progress-ring/progress-ring.d.ts +8 -6
  35. package/lib/radio-group/radio-group.d.ts +333 -1
  36. package/lib/range-slider/range-slider.d.ts +11 -5
  37. package/lib/rich-text-editor/facades/prose-mirror-vivid.schema.d.ts +1 -1
  38. package/lib/rich-text-editor/facades/vivid-prose-mirror.facade.d.ts +7 -1
  39. package/lib/rich-text-editor/locale.d.ts +9 -0
  40. package/lib/rich-text-editor/menubar/consts.d.ts +18 -0
  41. package/lib/rich-text-editor/menubar/menubar.d.ts +337 -1
  42. package/lib/rich-text-editor/rich-text-editor.d.ts +10 -0
  43. package/lib/searchable-select/locale.d.ts +1 -0
  44. package/lib/searchable-select/option-tag.d.ts +11 -5
  45. package/lib/searchable-select/searchable-select.d.ts +350 -7
  46. package/lib/select/select.d.ts +339 -3
  47. package/lib/selectable-box/selectable-box.d.ts +8 -6
  48. package/lib/slider/slider.d.ts +16 -8
  49. package/lib/split-button/split-button.d.ts +26 -12
  50. package/lib/switch/switch.d.ts +8 -6
  51. package/lib/tab/tab.d.ts +349 -7
  52. package/lib/tab-panel/tab-panel.d.ts +333 -1
  53. package/lib/tabs/tabs.d.ts +5 -21
  54. package/lib/tag/tag.d.ts +338 -2
  55. package/lib/tag-group/tag-group.d.ts +8 -6
  56. package/lib/text-anchor/text-anchor.d.ts +16 -8
  57. package/lib/text-area/text-area.d.ts +8 -6
  58. package/lib/text-field/text-field.d.ts +16 -8
  59. package/lib/time-picker/time-picker.d.ts +38 -26
  60. package/lib/toggletip/toggletip.d.ts +9 -3
  61. package/lib/tooltip/tooltip.d.ts +9 -3
  62. package/lib/tree-item/tree-item.d.ts +338 -2
  63. package/lib/tree-view/tree-view.d.ts +333 -1
  64. package/lib/video-player/video-player.d.ts +11 -5
  65. package/locales/de-DE.cjs +15 -1
  66. package/locales/de-DE.js +15 -1
  67. package/locales/en-GB.cjs +15 -1
  68. package/locales/en-GB.js +15 -1
  69. package/locales/en-US.cjs +15 -1
  70. package/locales/en-US.js +15 -1
  71. package/locales/ja-JP.cjs +15 -1
  72. package/locales/ja-JP.js +15 -1
  73. package/locales/zh-CN.cjs +15 -1
  74. package/locales/zh-CN.js +15 -1
  75. package/package.json +1 -1
  76. package/shared/affix.js +1 -1
  77. package/shared/aria/aria-change-subscription.d.ts +6 -0
  78. package/shared/aria/aria-mixin.d.ts +338 -0
  79. package/shared/aria/delegate-aria-behavior.d.ts +31 -0
  80. package/shared/aria/delegates-aria.d.ts +14 -9
  81. package/shared/aria/host-semantics-behavior.d.ts +22 -0
  82. package/shared/aria/host-semantics.d.ts +337 -0
  83. package/shared/attribute-binding-behaviour.cjs +41 -0
  84. package/shared/attribute-binding-behaviour.js +39 -0
  85. package/shared/button.cjs +6 -3
  86. package/shared/button.js +6 -3
  87. package/shared/calendar-event.cjs +2 -1
  88. package/shared/calendar-event.js +2 -1
  89. package/shared/definition.js +1 -1
  90. package/shared/definition10.cjs +8 -2
  91. package/shared/definition10.js +9 -3
  92. package/shared/definition11.cjs +4 -28
  93. package/shared/definition11.js +5 -29
  94. package/shared/definition12.cjs +5 -2
  95. package/shared/definition12.js +6 -3
  96. package/shared/definition13.js +1 -1
  97. package/shared/definition14.js +1 -1
  98. package/shared/definition15.cjs +8 -7
  99. package/shared/definition15.js +10 -9
  100. package/shared/definition16.js +1 -1
  101. package/shared/definition17.cjs +4 -1
  102. package/shared/definition17.js +5 -2
  103. package/shared/definition18.js +1 -1
  104. package/shared/definition19.js +1 -1
  105. package/shared/definition2.js +1 -1
  106. package/shared/definition20.js +1 -1
  107. package/shared/definition21.js +1 -1
  108. package/shared/definition22.cjs +11 -4
  109. package/shared/definition22.js +13 -6
  110. package/shared/definition23.cjs +4 -2
  111. package/shared/definition23.js +6 -4
  112. package/shared/definition24.js +1 -1
  113. package/shared/definition25.cjs +2 -14
  114. package/shared/definition25.js +3 -15
  115. package/shared/definition26.cjs +19 -3
  116. package/shared/definition26.js +20 -4
  117. package/shared/definition27.cjs +3 -2
  118. package/shared/definition27.js +4 -3
  119. package/shared/definition28.js +1 -1
  120. package/shared/definition29.js +1 -1
  121. package/shared/definition3.cjs +3 -2
  122. package/shared/definition3.js +5 -4
  123. package/shared/definition30.cjs +33 -34
  124. package/shared/definition30.js +35 -36
  125. package/shared/definition31.cjs +6 -4
  126. package/shared/definition31.js +8 -6
  127. package/shared/definition32.js +1 -1
  128. package/shared/definition33.cjs +7 -2
  129. package/shared/definition33.js +8 -3
  130. package/shared/definition34.js +1 -1
  131. package/shared/definition35.cjs +2 -13
  132. package/shared/definition35.js +4 -15
  133. package/shared/definition36.cjs +8 -5
  134. package/shared/definition36.js +9 -6
  135. package/shared/definition37.js +1 -1
  136. package/shared/definition38.cjs +7 -8
  137. package/shared/definition38.js +9 -10
  138. package/shared/definition39.cjs +7 -8
  139. package/shared/definition39.js +9 -10
  140. package/shared/definition4.js +1 -1
  141. package/shared/definition40.cjs +8 -5
  142. package/shared/definition40.js +9 -6
  143. package/shared/definition41.js +1 -1
  144. package/shared/definition42.js +1 -1
  145. package/shared/definition43.cjs +558 -134
  146. package/shared/definition43.js +550 -126
  147. package/shared/definition44.cjs +83 -10
  148. package/shared/definition44.js +84 -11
  149. package/shared/definition45.cjs +20 -8
  150. package/shared/definition45.js +21 -9
  151. package/shared/definition46.cjs +18 -6
  152. package/shared/definition46.js +20 -8
  153. package/shared/definition47.js +1 -1
  154. package/shared/definition48.js +1 -1
  155. package/shared/definition49.cjs +10 -3
  156. package/shared/definition49.js +12 -5
  157. package/shared/definition5.cjs +7 -2
  158. package/shared/definition5.js +8 -3
  159. package/shared/definition50.cjs +8 -7
  160. package/shared/definition50.js +10 -9
  161. package/shared/definition51.cjs +3 -2
  162. package/shared/definition51.js +4 -3
  163. package/shared/definition52.cjs +8 -4
  164. package/shared/definition52.js +9 -5
  165. package/shared/definition53.cjs +219 -297
  166. package/shared/definition53.js +221 -299
  167. package/shared/definition54.cjs +4 -3
  168. package/shared/definition54.js +6 -5
  169. package/shared/definition55.cjs +7 -4
  170. package/shared/definition55.js +8 -5
  171. package/shared/definition56.cjs +68 -14
  172. package/shared/definition56.js +69 -15
  173. package/shared/definition57.cjs +163 -112
  174. package/shared/definition57.js +165 -114
  175. package/shared/definition58.js +1 -1
  176. package/shared/definition59.js +1 -1
  177. package/shared/definition6.js +1 -1
  178. package/shared/definition60.js +1 -1
  179. package/shared/definition61.cjs +8 -5
  180. package/shared/definition61.js +9 -6
  181. package/shared/definition62.cjs +5 -2
  182. package/shared/definition62.js +6 -3
  183. package/shared/definition63.js +1 -1
  184. package/shared/definition64.js +1 -1
  185. package/shared/definition65.js +1 -1
  186. package/shared/definition7.js +1 -1
  187. package/shared/definition8.cjs +4 -2
  188. package/shared/definition8.js +6 -4
  189. package/shared/definition9.js +1 -1
  190. package/shared/delegates-aria.cjs +106 -56
  191. package/shared/delegates-aria.js +107 -58
  192. package/shared/foundation/button/button.d.ts +8 -6
  193. package/shared/foundation/vivid-element/vivid-element.d.ts +339 -1
  194. package/shared/host-semantics.cjs +65 -0
  195. package/shared/host-semantics.js +62 -0
  196. package/shared/localization/Locale.d.ts +2 -0
  197. package/shared/option.cjs +4 -1
  198. package/shared/option.js +4 -1
  199. package/shared/patterns/affix.d.ts +22 -10
  200. package/shared/patterns/anchored.d.ts +18 -6
  201. package/shared/patterns/localized.d.ts +11 -5
  202. package/shared/patterns/trapped-focus.d.ts +11 -5
  203. package/shared/picker-field/mixins/calendar-picker.d.ts +19 -13
  204. package/shared/picker-field/mixins/calendar-picker.template.d.ts +19 -13
  205. package/shared/picker-field/mixins/inline-time-picker/inline-time-picker.d.ts +11 -5
  206. package/shared/picker-field/mixins/min-max-calendar-picker.d.ts +38 -26
  207. package/shared/picker-field/mixins/single-date-picker.d.ts +55 -37
  208. package/shared/picker-field/mixins/single-value-picker.d.ts +17 -11
  209. package/shared/picker-field/mixins/time-selection-picker.d.ts +38 -26
  210. package/shared/picker-field/mixins/time-selection-picker.template.d.ts +38 -26
  211. package/shared/picker-field/picker-field.d.ts +21 -9
  212. package/shared/picker-field.template.js +1 -1
  213. package/shared/repeat.js +1 -1
  214. package/shared/slider.template.cjs +10 -9
  215. package/shared/slider.template.js +10 -9
  216. package/shared/templating/attribute-binding-behaviour.d.ts +15 -0
  217. package/shared/templating/render-in-light-dom.d.ts +22 -0
  218. package/shared/text-anchor.template.cjs +2 -13
  219. package/shared/text-anchor.template.js +2 -13
  220. package/shared/time-selection-picker.template.js +1 -1
  221. package/shared/vivid-element.cjs +96 -2
  222. package/shared/vivid-element.js +93 -3
  223. package/styles/core/all.css +1 -1
  224. package/styles/core/theme.css +1 -1
  225. package/styles/core/typography.css +1 -1
  226. package/styles/tokens/theme-dark.css +4 -4
  227. package/styles/tokens/theme-light.css +4 -4
  228. package/styles/tokens/vivid-2-compat.css +1 -1
  229. package/text-anchor/index.js +1 -1
  230. package/vivid.api.json +188 -17
  231. package/shared/Reflector.cjs +0 -71
  232. package/shared/Reflector.js +0 -69
@@ -7,6 +7,7 @@ const definition$2 = require('./definition38.cjs');
7
7
  const vividElement = require('./vivid-element.cjs');
8
8
  const applyMixinsWithObservables = require('./applyMixinsWithObservables.cjs');
9
9
  const scrollIntoView = require('./scrollIntoView.cjs');
10
+ const delegatesAria = require('./delegates-aria.cjs');
10
11
  const formAssociated = require('./form-associated.cjs');
11
12
  const affix = require('./affix.cjs');
12
13
  const localized = require('./localized.cjs');
@@ -18,7 +19,7 @@ const slotted = require('./slotted.cjs');
18
19
  const classNames = require('./class-names.cjs');
19
20
  const repeat = require('./repeat.cjs');
20
21
 
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(--vvd-color-neutral-500)}.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(--vvd-color-neutral-700)}.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:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}:host(:not([shape=pill])) .fieldset{border-radius: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);font:var(--vvd-typography-base);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
+ 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)}.selection-count{color:var(--_low-ink-color);font:var(--vvd-typography-base)}.fieldset{--_connotation-color-primary: var(--vvd-searchable-select-accent-primary, var(--vvd-color-canvas-text));--_connotation-color-primary-text: var(--vvd-searchable-select-accent-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-searchable-select-accent-primary-increment, var(--vvd-color-neutral-800));--_connotation-color-intermediate: var(--vvd-searchable-select-accent-intermediate, var(--vvd-color-neutral-500));--_connotation-color-faint: var(--vvd-searchable-select-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-soft: var(--vvd-searchable-select-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-firm: var(--vvd-searchable-select-accent-firm, var(--vvd-color-canvas-text));--_connotation-color-fierce: var(--vvd-searchable-select-accent-fierce, var(--vvd-color-neutral-700))}.fieldset{--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--vvd-color-neutral-500)}.fieldset.appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.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(--vvd-color-neutral-700)}.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:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}:host(:not([shape=pill])) .fieldset{border-radius: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);font:var(--vvd-typography-base);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
23
 
23
24
  const optionTagStyles = ".base.connotation-cta{--_connotation-color-contrast: var(--vvd-option-tag-cta-contrast, var(--vvd-color-cta-800))}.base:not(.connotation-cta){--_connotation-color-contrast: var(--vvd-option-tag-accent-contrast, var(--vvd-color-neutral-800))}.base{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:0 0 0 4px color-mix(in srgb,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));position:absolute;z-index:1;display:block;border-radius:inherit;content:\"\";inset:0;pointer-events:none}";
24
25
 
@@ -50,13 +51,13 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
50
51
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
51
52
  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
53
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
53
- var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, 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;
54
+ var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, 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, updateSelectionLimit_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
54
55
  const TagGapPx = 8;
55
56
  const InputMinWidthPx = 100;
56
57
  const PageSize = 10;
57
58
  const isFormAssociatedTryingToSetFormValue = (value) => typeof value === "string";
58
- exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTrailing(
59
- localized.Localized(FormAssociatedSearchableSelect)
59
+ exports.SearchableSelect = class SearchableSelect extends delegatesAria.DelegatesAria(
60
+ affix.AffixIconWithTrailing(localized.Localized(FormAssociatedSearchableSelect))
60
61
  ) {
61
62
  constructor() {
62
63
  super(...arguments);
@@ -93,6 +94,8 @@ exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTra
93
94
  this._tagRows = [];
94
95
  this._lastTagRow = [];
95
96
  this.clearable = false;
97
+ this.maxSelected = null;
98
+ this._slottedDisabledOptions = [];
96
99
  this.setFormValue = (value, state) => {
97
100
  if (isFormAssociatedTryingToSetFormValue(value)) {
98
101
  return;
@@ -129,6 +132,7 @@ exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTra
129
132
  return;
130
133
  }
131
134
  this.value = this.values.length ? this.values[0] : "";
135
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
132
136
  __privateMethod(this, _SearchableSelect_instances, updateSelectedOnSlottedOptions_fn).call(this);
133
137
  if (this.$fastController.isConnected) {
134
138
  __privateMethod(this, _SearchableSelect_instances, updateTagLayout_fn).call(this);
@@ -310,6 +314,7 @@ exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTra
310
314
  }
311
315
  this._areOptionsInitialized = true;
312
316
  if (oldValue) {
317
+ this._slottedDisabledOptions = [];
313
318
  for (const option of oldValue) {
314
319
  const notifier = vividElement.Observable.getNotifier(option);
315
320
  notifier.unsubscribe(__privateGet(this, _slottedOptionsChangeHandler), "selected");
@@ -327,9 +332,13 @@ exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTra
327
332
  if (option.selected || option.value === this.value || this.values.includes(option.value)) {
328
333
  values.push(option.value);
329
334
  }
335
+ if (option.disabled) {
336
+ this._slottedDisabledOptions.push(option);
337
+ }
330
338
  }
331
339
  __privateMethod(this, _SearchableSelect_instances, updateValuesWhileMaintainingOrder_fn).call(this, values);
332
340
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
341
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
333
342
  }
334
343
  /**
335
344
  * @internal
@@ -428,6 +437,12 @@ exports.SearchableSelect = class SearchableSelect extends affix.AffixIconWithTra
428
437
  _onClearButtonClick() {
429
438
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, this.selectedOptions.filter((option) => option.disabled).map((option) => option.value));
430
439
  }
440
+ /**
441
+ * @internal
442
+ */
443
+ maxSelectedChanged() {
444
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
445
+ }
431
446
  /**
432
447
  * @internal
433
448
  */
@@ -545,8 +560,13 @@ handleOptionInteraction_fn = function(option) {
545
560
  }
546
561
  this.open = false;
547
562
  }
548
- this._changeDescription = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
549
563
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, newValues);
564
+ const optionMessage = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
565
+ const maxSelectedMessage = this.multiple && this.maxSelected && this.maxSelected >= 1 ? this.locale.searchableSelect.maxSelectedMessage(
566
+ this.values.length,
567
+ this.maxSelected
568
+ ) : "";
569
+ this._changeDescription = `${optionMessage} ${maxSelectedMessage}`;
550
570
  if (shouldClearSearchText) {
551
571
  this._currentSearchText = null;
552
572
  }
@@ -757,6 +777,26 @@ nextTagIndexRight_fn = function(index) {
757
777
  nextTagIndexForRemoved_fn = function(index) {
758
778
  return __privateMethod(this, _SearchableSelect_instances, nextTagIndexRight_fn).call(this, index - 1) ?? __privateMethod(this, _SearchableSelect_instances, nextTagIndexLeft_fn).call(this, index);
759
779
  };
780
+ updateSelectionLimit_fn = function() {
781
+ if (!this.multiple || typeof this.maxSelected !== "number" || this.maxSelected <= 0) {
782
+ return;
783
+ }
784
+ const options = this._slottedOptions.filter(
785
+ (option) => !this._slottedDisabledOptions.includes(option)
786
+ );
787
+ if (this.values.length >= this.maxSelected) {
788
+ const unselectedOptions = options.filter(
789
+ (option) => !this.selectedOptions.includes(option)
790
+ );
791
+ for (const option of unselectedOptions) {
792
+ option.disabled = true;
793
+ }
794
+ } else {
795
+ for (const option of options) {
796
+ option.disabled = false;
797
+ }
798
+ }
799
+ };
760
800
  // --- Form handling ---
761
801
  determineInitialValues_fn = function() {
762
802
  return this.initialValues.length ? this.initialValues : this.initialValue ? [this.initialValue] : [];
@@ -847,6 +887,12 @@ __decorateClass$1([
847
887
  __decorateClass$1([
848
888
  vividElement.attr({ mode: "boolean" })
849
889
  ], exports.SearchableSelect.prototype, "clearable", 2);
890
+ __decorateClass$1([
891
+ vividElement.attr({ attribute: "max-selected", converter: vividElement.nullableNumberConverter })
892
+ ], exports.SearchableSelect.prototype, "maxSelected", 2);
893
+ __decorateClass$1([
894
+ vividElement.observable
895
+ ], exports.SearchableSelect.prototype, "_slottedDisabledOptions", 2);
850
896
  __decorateClass$1([
851
897
  vividElement.observable
852
898
  ], exports.SearchableSelect.prototype, "_changeDescription", 2);
@@ -916,6 +962,19 @@ function renderLabel() {
916
962
  <label for="control" class="label" id="label"> ${(x) => x.label} </label>
917
963
  `;
918
964
  }
965
+ function renderSelectionCount() {
966
+ return vividElement.html`
967
+ <span
968
+ id="selection-count"
969
+ class="selection-count"
970
+ aria-label="${(x) => x.locale.searchableSelect.maxSelectedMessage(
971
+ x.values.length,
972
+ x.maxSelected
973
+ )}"
974
+ >(${(x) => `${x.values.length}/${x.maxSelected}`})</span
975
+ >
976
+ `;
977
+ }
919
978
  const tagTemplateFactory = (context, getComponent) => {
920
979
  const optionTagTag = context.tagFor(OptionTag);
921
980
  return vividElement.html`
@@ -1001,12 +1060,15 @@ function renderFieldset(context) {
1001
1060
  id="control"
1002
1061
  class="control"
1003
1062
  autocomplete="off"
1004
- aria-autocomplete="list"
1005
- aria-expanded="${(x) => x.open}"
1006
- aria-haspopup="listbox"
1007
1063
  aria-controls="listbox"
1064
+ aria-describedby="${(x) => x.multiple && x.maxSelected && x.maxSelected >= 1 ? "selection-count" : null}"
1065
+ ${delegatesAria.delegateAria({
1066
+ role: "combobox",
1067
+ ariaAutoComplete: "list",
1068
+ ariaHasPopup: "listbox",
1069
+ ariaExpanded: (x) => x.open
1070
+ })}
1008
1071
  placeholder="${(x) => x.multiple && x.values.length ? "" : x.placeholder}"
1009
- role="combobox"
1010
1072
  type="text"
1011
1073
  ?disabled="${(x) => x.disabled}"
1012
1074
  :value="${(x) => x._inputValue}"
@@ -1057,7 +1119,18 @@ function setFixedDropdownVarWidth(x) {
1057
1119
  function renderControl(context) {
1058
1120
  const popupTag = context.tagFor(definition.Popup);
1059
1121
  return vividElement.html`
1060
- ${when.when((x) => x.label, renderLabel())}
1122
+ ${when.when(
1123
+ (x) => x.label || x.multiple && x.maxSelected && x.maxSelected >= 1,
1124
+ vividElement.html`
1125
+ <div>
1126
+ ${when.when((x) => x.label, renderLabel())}
1127
+ ${when.when(
1128
+ (x) => x.multiple && x.maxSelected && x.maxSelected >= 1,
1129
+ renderSelectionCount()
1130
+ )}
1131
+ </div>
1132
+ `
1133
+ )}
1061
1134
  <span aria-live="assertive" aria-relevant="text" class="visually-hidden">
1062
1135
  ${(x) => x._changeDescription}
1063
1136
  </span>
@@ -2,9 +2,10 @@ import { B as Button, c as chevronTemplateFactory, b as buttonDefinition } from
2
2
  import { P as Popup, p as popupDefinition } from './definition65.js';
3
3
  import { I as Icon, i as iconDefinition } from './definition28.js';
4
4
  import { P as ProgressRing, p as progressRingDefinition } from './definition38.js';
5
- import { V as VividElement, O as Observable, D as DOM, a as attr, n as nullableNumberConverter, o as observable, h as html, d as createRegisterFunction, f as defineVividComponent } from './vivid-element.js';
5
+ import { V as VividElement, O as Observable, D as DOM, a as attr, n as nullableNumberConverter, o as observable, h as html, g as createRegisterFunction, i as defineVividComponent } from './vivid-element.js';
6
6
  import { a as applyMixinsWithObservables } from './applyMixinsWithObservables.js';
7
7
  import { s as scrollIntoView } from './scrollIntoView.js';
8
+ import { D as DelegatesAria, d as delegateAria } from './delegates-aria.js';
8
9
  import { F as FormAssociated } from './form-associated.js';
9
10
  import { A as AffixIconWithTrailing, a as affixIconTemplateFactory, I as IconWrapper } from './affix.js';
10
11
  import { L as Localized } from './localized.js';
@@ -16,7 +17,7 @@ import { s as slotted } from './slotted.js';
16
17
  import { c as classNames } from './class-names.js';
17
18
  import { r as repeat } from './repeat.js';
18
19
 
19
- 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(--vvd-color-neutral-500)}.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(--vvd-color-neutral-700)}.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:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}:host(:not([shape=pill])) .fieldset{border-radius: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);font:var(--vvd-typography-base);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}";
20
+ 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)}.selection-count{color:var(--_low-ink-color);font:var(--vvd-typography-base)}.fieldset{--_connotation-color-primary: var(--vvd-searchable-select-accent-primary, var(--vvd-color-canvas-text));--_connotation-color-primary-text: var(--vvd-searchable-select-accent-primary-text, var(--vvd-color-canvas));--_connotation-color-primary-increment: var(--vvd-searchable-select-accent-primary-increment, var(--vvd-color-neutral-800));--_connotation-color-intermediate: var(--vvd-searchable-select-accent-intermediate, var(--vvd-color-neutral-500));--_connotation-color-faint: var(--vvd-searchable-select-accent-faint, var(--vvd-color-neutral-50));--_connotation-color-soft: var(--vvd-searchable-select-accent-soft, var(--vvd-color-neutral-100));--_connotation-color-firm: var(--vvd-searchable-select-accent-firm, var(--vvd-color-canvas-text));--_connotation-color-fierce: var(--vvd-searchable-select-accent-fierce, var(--vvd-color-neutral-700))}.fieldset{--_appearance-color-text: var(--vvd-color-canvas-text);--_appearance-color-fill: var(--vvd-color-canvas);--_appearance-color-outline: var(--vvd-color-neutral-500)}.fieldset.appearance-ghost{--_appearance-color-text: var(--_connotation-color-firm);--_appearance-color-fill: transparent;--_appearance-color-outline: transparent}.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(--vvd-color-neutral-700)}.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:0 0 0 4px color-mix(in srgb,var(--vvd-color-cta-500),transparent 85%),inset 0 0 0 3px var(--focus-stroke-gap-color, currentColor);outline:1px solid var(--focus-stroke-color, var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset, 0px));--focus-stroke-gap-color: transparent}:host(:not([shape=pill])) .fieldset{border-radius: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);font:var(--vvd-typography-base);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}";
20
21
 
21
22
  const optionTagStyles = ".base.connotation-cta{--_connotation-color-contrast: var(--vvd-option-tag-cta-contrast, var(--vvd-color-cta-800))}.base:not(.connotation-cta){--_connotation-color-contrast: var(--vvd-option-tag-accent-contrast, var(--vvd-color-neutral-800))}.base{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:0 0 0 4px color-mix(in srgb,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));position:absolute;z-index:1;display:block;border-radius:inherit;content:\"\";inset:0;pointer-events:none}";
22
23
 
@@ -48,13 +49,13 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
48
49
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
49
50
  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);
50
51
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
51
- var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, 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;
52
+ var _SearchableSelect_instances, updateValuesThroughUserInteraction_fn, updateValuesWhileMaintainingOrder_fn, isValidValue_fn, _slottedOptionsChangeHandler, updateSelectedOnSlottedOptions_fn, handleOptionInteraction_fn, _clonedTagIcons, tagIconOfOption_fn, updateClonedTagIconOfOption_fn, 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, updateSelectionLimit_fn, determineInitialValues_fn, updateFormValue_fn, _resizeObserver;
52
53
  const TagGapPx = 8;
53
54
  const InputMinWidthPx = 100;
54
55
  const PageSize = 10;
55
56
  const isFormAssociatedTryingToSetFormValue = (value) => typeof value === "string";
56
- let SearchableSelect = class extends AffixIconWithTrailing(
57
- Localized(FormAssociatedSearchableSelect)
57
+ let SearchableSelect = class extends DelegatesAria(
58
+ AffixIconWithTrailing(Localized(FormAssociatedSearchableSelect))
58
59
  ) {
59
60
  constructor() {
60
61
  super(...arguments);
@@ -91,6 +92,8 @@ let SearchableSelect = class extends AffixIconWithTrailing(
91
92
  this._tagRows = [];
92
93
  this._lastTagRow = [];
93
94
  this.clearable = false;
95
+ this.maxSelected = null;
96
+ this._slottedDisabledOptions = [];
94
97
  this.setFormValue = (value, state) => {
95
98
  if (isFormAssociatedTryingToSetFormValue(value)) {
96
99
  return;
@@ -127,6 +130,7 @@ let SearchableSelect = class extends AffixIconWithTrailing(
127
130
  return;
128
131
  }
129
132
  this.value = this.values.length ? this.values[0] : "";
133
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
130
134
  __privateMethod(this, _SearchableSelect_instances, updateSelectedOnSlottedOptions_fn).call(this);
131
135
  if (this.$fastController.isConnected) {
132
136
  __privateMethod(this, _SearchableSelect_instances, updateTagLayout_fn).call(this);
@@ -308,6 +312,7 @@ let SearchableSelect = class extends AffixIconWithTrailing(
308
312
  }
309
313
  this._areOptionsInitialized = true;
310
314
  if (oldValue) {
315
+ this._slottedDisabledOptions = [];
311
316
  for (const option of oldValue) {
312
317
  const notifier = Observable.getNotifier(option);
313
318
  notifier.unsubscribe(__privateGet(this, _slottedOptionsChangeHandler), "selected");
@@ -325,9 +330,13 @@ let SearchableSelect = class extends AffixIconWithTrailing(
325
330
  if (option.selected || option.value === this.value || this.values.includes(option.value)) {
326
331
  values.push(option.value);
327
332
  }
333
+ if (option.disabled) {
334
+ this._slottedDisabledOptions.push(option);
335
+ }
328
336
  }
329
337
  __privateMethod(this, _SearchableSelect_instances, updateValuesWhileMaintainingOrder_fn).call(this, values);
330
338
  __privateMethod(this, _SearchableSelect_instances, updateFilteredOptions_fn).call(this);
339
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
331
340
  }
332
341
  /**
333
342
  * @internal
@@ -426,6 +435,12 @@ let SearchableSelect = class extends AffixIconWithTrailing(
426
435
  _onClearButtonClick() {
427
436
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, this.selectedOptions.filter((option) => option.disabled).map((option) => option.value));
428
437
  }
438
+ /**
439
+ * @internal
440
+ */
441
+ maxSelectedChanged() {
442
+ __privateMethod(this, _SearchableSelect_instances, updateSelectionLimit_fn).call(this);
443
+ }
429
444
  /**
430
445
  * @internal
431
446
  */
@@ -543,8 +558,13 @@ handleOptionInteraction_fn = function(option) {
543
558
  }
544
559
  this.open = false;
545
560
  }
546
- this._changeDescription = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
547
561
  __privateMethod(this, _SearchableSelect_instances, updateValuesThroughUserInteraction_fn).call(this, newValues);
562
+ const optionMessage = isSelection ? this.locale.searchableSelect.optionSelectedMessage(option.text) : this.locale.searchableSelect.optionDeselectedMessage(option.text);
563
+ const maxSelectedMessage = this.multiple && this.maxSelected && this.maxSelected >= 1 ? this.locale.searchableSelect.maxSelectedMessage(
564
+ this.values.length,
565
+ this.maxSelected
566
+ ) : "";
567
+ this._changeDescription = `${optionMessage} ${maxSelectedMessage}`;
548
568
  if (shouldClearSearchText) {
549
569
  this._currentSearchText = null;
550
570
  }
@@ -755,6 +775,26 @@ nextTagIndexRight_fn = function(index) {
755
775
  nextTagIndexForRemoved_fn = function(index) {
756
776
  return __privateMethod(this, _SearchableSelect_instances, nextTagIndexRight_fn).call(this, index - 1) ?? __privateMethod(this, _SearchableSelect_instances, nextTagIndexLeft_fn).call(this, index);
757
777
  };
778
+ updateSelectionLimit_fn = function() {
779
+ if (!this.multiple || typeof this.maxSelected !== "number" || this.maxSelected <= 0) {
780
+ return;
781
+ }
782
+ const options = this._slottedOptions.filter(
783
+ (option) => !this._slottedDisabledOptions.includes(option)
784
+ );
785
+ if (this.values.length >= this.maxSelected) {
786
+ const unselectedOptions = options.filter(
787
+ (option) => !this.selectedOptions.includes(option)
788
+ );
789
+ for (const option of unselectedOptions) {
790
+ option.disabled = true;
791
+ }
792
+ } else {
793
+ for (const option of options) {
794
+ option.disabled = false;
795
+ }
796
+ }
797
+ };
758
798
  // --- Form handling ---
759
799
  determineInitialValues_fn = function() {
760
800
  return this.initialValues.length ? this.initialValues : this.initialValue ? [this.initialValue] : [];
@@ -845,6 +885,12 @@ __decorateClass$1([
845
885
  __decorateClass$1([
846
886
  attr({ mode: "boolean" })
847
887
  ], SearchableSelect.prototype, "clearable", 2);
888
+ __decorateClass$1([
889
+ attr({ attribute: "max-selected", converter: nullableNumberConverter })
890
+ ], SearchableSelect.prototype, "maxSelected", 2);
891
+ __decorateClass$1([
892
+ observable
893
+ ], SearchableSelect.prototype, "_slottedDisabledOptions", 2);
848
894
  __decorateClass$1([
849
895
  observable
850
896
  ], SearchableSelect.prototype, "_changeDescription", 2);
@@ -914,6 +960,19 @@ function renderLabel() {
914
960
  <label for="control" class="label" id="label"> ${(x) => x.label} </label>
915
961
  `;
916
962
  }
963
+ function renderSelectionCount() {
964
+ return html`
965
+ <span
966
+ id="selection-count"
967
+ class="selection-count"
968
+ aria-label="${(x) => x.locale.searchableSelect.maxSelectedMessage(
969
+ x.values.length,
970
+ x.maxSelected
971
+ )}"
972
+ >(${(x) => `${x.values.length}/${x.maxSelected}`})</span
973
+ >
974
+ `;
975
+ }
917
976
  const tagTemplateFactory = (context, getComponent) => {
918
977
  const optionTagTag = context.tagFor(OptionTag);
919
978
  return html`
@@ -999,12 +1058,15 @@ function renderFieldset(context) {
999
1058
  id="control"
1000
1059
  class="control"
1001
1060
  autocomplete="off"
1002
- aria-autocomplete="list"
1003
- aria-expanded="${(x) => x.open}"
1004
- aria-haspopup="listbox"
1005
1061
  aria-controls="listbox"
1062
+ aria-describedby="${(x) => x.multiple && x.maxSelected && x.maxSelected >= 1 ? "selection-count" : null}"
1063
+ ${delegateAria({
1064
+ role: "combobox",
1065
+ ariaAutoComplete: "list",
1066
+ ariaHasPopup: "listbox",
1067
+ ariaExpanded: (x) => x.open
1068
+ })}
1006
1069
  placeholder="${(x) => x.multiple && x.values.length ? "" : x.placeholder}"
1007
- role="combobox"
1008
1070
  type="text"
1009
1071
  ?disabled="${(x) => x.disabled}"
1010
1072
  :value="${(x) => x._inputValue}"
@@ -1055,7 +1117,18 @@ function setFixedDropdownVarWidth(x) {
1055
1117
  function renderControl(context) {
1056
1118
  const popupTag = context.tagFor(Popup);
1057
1119
  return html`
1058
- ${when((x) => x.label, renderLabel())}
1120
+ ${when(
1121
+ (x) => x.label || x.multiple && x.maxSelected && x.maxSelected >= 1,
1122
+ html`
1123
+ <div>
1124
+ ${when((x) => x.label, renderLabel())}
1125
+ ${when(
1126
+ (x) => x.multiple && x.maxSelected && x.maxSelected >= 1,
1127
+ renderSelectionCount()
1128
+ )}
1129
+ </div>
1130
+ `
1131
+ )}
1059
1132
  <span aria-live="assertive" aria-relevant="text" class="visually-hidden">
1060
1133
  ${(x) => x._changeDescription}
1061
1134
  </span>
@@ -6,15 +6,16 @@ const definition$3 = require('./definition36.cjs');
6
6
  const vividElement = require('./vivid-element.cjs');
7
7
  const applyMixinsWithObservables = require('./applyMixinsWithObservables.cjs');
8
8
  const listbox = require('./listbox.cjs');
9
+ const hostSemantics = require('./host-semantics.cjs');
9
10
  const formAssociated = require('./form-associated.cjs');
10
11
  const numbers = require('./numbers.cjs');
11
12
  const affix = require('./affix.cjs');
12
13
  const strings = require('./strings.cjs');
13
14
  const keyCodes = require('./key-codes.cjs');
14
15
  const formElements = require('./form-elements.cjs');
15
- const index = require('./index.cjs');
16
- const definition$1 = require('./definition11.cjs');
17
16
  const option = require('./option.cjs');
17
+ const definition$1 = require('./definition11.cjs');
18
+ const index = require('./index.cjs');
18
19
  const ref = require('./ref.cjs');
19
20
  const when = require('./when.cjs');
20
21
  const slotted = require('./slotted.cjs');
@@ -41,7 +42,9 @@ var __decorateClass = (decorators, target, key, kind) => {
41
42
  if (kind && result) __defProp(target, key, result);
42
43
  return result;
43
44
  };
44
- exports.Select = class Select extends affix.AffixIconWithTrailing(FormAssociatedSelect) {
45
+ exports.Select = class Select extends hostSemantics.HostSemantics(
46
+ affix.AffixIconWithTrailing(FormAssociatedSelect)
47
+ ) {
45
48
  constructor() {
46
49
  super(...arguments);
47
50
  this.activeIndex = -1;
@@ -777,7 +780,11 @@ const getStateClasses = ({
777
780
  [`size-${scale}`, Boolean(scale)]
778
781
  );
779
782
  function renderLabel() {
780
- return vividElement.html` <label for="control" class="label" id="label">
783
+ return vividElement.html` <label
784
+ for="${(x) => x.multiple ? null : "control"}"
785
+ class="label"
786
+ id="label"
787
+ >
781
788
  ${(x) => x.label}
782
789
  </label>`;
783
790
  }
@@ -824,6 +831,8 @@ function renderControl(context) {
824
831
  id="${(x) => x.listboxId}"
825
832
  role="listbox"
826
833
  aria-multiselectable="${(x) => x.multiple}"
834
+ aria-label="${(x) => x.multiple && !x.label && x.ariaLabel ? x.ariaLabel : null}"
835
+ aria-labelledby="${(x) => x.multiple && x.label ? "label" : null}"
827
836
  ?disabled="${(x) => x.disabled}"
828
837
  ?hidden="${(x) => x.collapsible ? !x.open : false}"
829
838
  ${ref.ref("listbox")}>
@@ -852,11 +861,14 @@ const SelectTemplate = (context) => {
852
861
  return vividElement.html`
853
862
  <template
854
863
  class="base"
855
- role="combobox"
856
- aria-haspopup="${(x) => x.collapsible ? "listbox" : "false"}"
864
+ ${hostSemantics.applyHostSemantics({
865
+ role: "combobox",
866
+ ariaLabel: (x) => x.ariaLabel ?? x.label,
867
+ ariaHasPopup: (x) => x.collapsible ? "listbox" : "false",
868
+ ariaExpanded: (x) => x.open,
869
+ ariaDisabled: (x) => x.disabled
870
+ })}
857
871
  aria-controls="${(x) => x.listboxId}"
858
- aria-expanded="${(x) => x.open}"
859
- aria-disabled="${(x) => x.disabled}"
860
872
  aria-activedescendant="${(x) => x._activeDescendant}"
861
873
  tabindex="${(x) => !x.disabled ? "0" : null}"
862
874
  @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
@@ -1,18 +1,19 @@
1
1
  import { P as Popup, p as popupDefinition } from './definition65.js';
2
2
  import { i as iconDefinition } from './definition28.js';
3
3
  import { l as listboxOptionDefinition } from './definition36.js';
4
- import { D as DOM, O as Observable, o as observable, a as attr, v as volatile, h as html, d as createRegisterFunction, f as defineVividComponent } from './vivid-element.js';
4
+ import { D as DOM, O as Observable, o as observable, a as attr, v as volatile, h as html, g as createRegisterFunction, i as defineVividComponent } from './vivid-element.js';
5
5
  import { a as applyMixinsWithObservables } from './applyMixinsWithObservables.js';
6
6
  import { L as Listbox } from './listbox.js';
7
+ import { H as HostSemantics, a as applyHostSemantics } from './host-semantics.js';
7
8
  import { F as FormAssociated } from './form-associated.js';
8
9
  import { i as inRange } from './numbers.js';
9
10
  import { A as AffixIconWithTrailing, a as affixIconTemplateFactory, I as IconWrapper } from './affix.js';
10
11
  import { u as uniqueId } from './strings.js';
11
12
  import { a as keySpace, b as keyEscape, c as keyTab, d as keyEnd, e as keyArrowUp, f as keyArrowDown, g as keyHome, k as keyEnter } from './key-codes.js';
12
13
  import { F as FormElementSuccessText, a as FormElementHelperText, e as errorText, f as formElements, g as getFeedbackTemplate } from './form-elements.js';
13
- import { h as handleEscapeKeyAndStopPropogation } from './index.js';
14
- import { c as chevronTemplateFactory } from './definition11.js';
15
14
  import { L as ListboxOption } from './option.js';
15
+ import { c as chevronTemplateFactory } from './definition11.js';
16
+ import { h as handleEscapeKeyAndStopPropogation } from './index.js';
16
17
  import { r as ref } from './ref.js';
17
18
  import { w as when } from './when.js';
18
19
  import { s as slotted } from './slotted.js';
@@ -39,7 +40,9 @@ var __decorateClass = (decorators, target, key, kind) => {
39
40
  if (kind && result) __defProp(target, key, result);
40
41
  return result;
41
42
  };
42
- let Select = class extends AffixIconWithTrailing(FormAssociatedSelect) {
43
+ let Select = class extends HostSemantics(
44
+ AffixIconWithTrailing(FormAssociatedSelect)
45
+ ) {
43
46
  constructor() {
44
47
  super(...arguments);
45
48
  this.activeIndex = -1;
@@ -775,7 +778,11 @@ const getStateClasses = ({
775
778
  [`size-${scale}`, Boolean(scale)]
776
779
  );
777
780
  function renderLabel() {
778
- return html` <label for="control" class="label" id="label">
781
+ return html` <label
782
+ for="${(x) => x.multiple ? null : "control"}"
783
+ class="label"
784
+ id="label"
785
+ >
779
786
  ${(x) => x.label}
780
787
  </label>`;
781
788
  }
@@ -822,6 +829,8 @@ function renderControl(context) {
822
829
  id="${(x) => x.listboxId}"
823
830
  role="listbox"
824
831
  aria-multiselectable="${(x) => x.multiple}"
832
+ aria-label="${(x) => x.multiple && !x.label && x.ariaLabel ? x.ariaLabel : null}"
833
+ aria-labelledby="${(x) => x.multiple && x.label ? "label" : null}"
825
834
  ?disabled="${(x) => x.disabled}"
826
835
  ?hidden="${(x) => x.collapsible ? !x.open : false}"
827
836
  ${ref("listbox")}>
@@ -850,11 +859,14 @@ const SelectTemplate = (context) => {
850
859
  return html`
851
860
  <template
852
861
  class="base"
853
- role="combobox"
854
- aria-haspopup="${(x) => x.collapsible ? "listbox" : "false"}"
862
+ ${applyHostSemantics({
863
+ role: "combobox",
864
+ ariaLabel: (x) => x.ariaLabel ?? x.label,
865
+ ariaHasPopup: (x) => x.collapsible ? "listbox" : "false",
866
+ ariaExpanded: (x) => x.open,
867
+ ariaDisabled: (x) => x.disabled
868
+ })}
855
869
  aria-controls="${(x) => x.listboxId}"
856
- aria-expanded="${(x) => x.open}"
857
- aria-disabled="${(x) => x.disabled}"
858
870
  aria-activedescendant="${(x) => x._activeDescendant}"
859
871
  tabindex="${(x) => !x.disabled ? "0" : null}"
860
872
  @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
@@ -86,7 +86,12 @@ function checkbox(context) {
86
86
  (x) => x.controlType !== "radio",
87
87
  vividElement.html`
88
88
  <${checkboxTag}
89
- aria-label="${(x) => !x.clickableBox && !x.clickable && x.ariaLabel ? x.ariaLabel : null}"
89
+ ${delegatesAria.delegateAria(
90
+ {
91
+ ariaLabel: (x) => !x.clickableBox && !x.clickable && x.ariaLabel ? x.ariaLabel : null
92
+ },
93
+ { onlySpecified: true }
94
+ )}
90
95
  @change="${(x) => handleControlChange(x)}"
91
96
  class="control checkbox"
92
97
  connotation="${(x) => x.connotation === "cta" ? enums.Connotation.CTA : enums.Connotation.Accent}"
@@ -101,7 +106,12 @@ function radio(context) {
101
106
  (x) => x.controlType === "radio",
102
107
  vividElement.html`
103
108
  <${radioTag}
104
- aria-label="${(x) => !x.clickableBox && !x.clickable && x.ariaLabel ? x.ariaLabel : null}"
109
+ ${delegatesAria.delegateAria(
110
+ {
111
+ ariaLabel: (x) => !x.clickableBox && !x.clickable && x.ariaLabel ? x.ariaLabel : null
112
+ },
113
+ { onlySpecified: true }
114
+ )}
105
115
  @change="${(x) => handleControlChange(x)}"
106
116
  class="control radio"
107
117
  connotation="${(x) => x.connotation === "cta" ? enums.Connotation.CTA : enums.Connotation.Accent}"
@@ -111,13 +121,15 @@ function radio(context) {
111
121
  )} `;
112
122
  }
113
123
  const SelectableBoxTemplate = (context) => {
114
- return vividElement.html`<template role="presentation">
124
+ return vividElement.html`<template>
115
125
  <div
116
126
  class="${getClasses}"
117
127
  tabindex="${(x) => x.clickableBox || x.clickable ? "0" : null}"
118
- role="${(x) => x.clickableBox || x.clickable ? "button" : null}"
119
- aria-pressed="${(x) => x.clickableBox || x.clickable ? x.checked ? "true" : "false" : null}"
120
- aria-label="${(x) => x.clickableBox || x.clickable ? x.ariaLabel : null}"
128
+ ${delegatesAria.delegateAria({
129
+ role: (x) => x.clickableBox || x.clickable ? "button" : null,
130
+ ariaPressed: (x) => x.clickableBox || x.clickable ? x.checked ? "true" : "false" : null,
131
+ ariaLabel: (x) => x.clickableBox || x.clickable ? x.ariaLabel : null
132
+ })}
121
133
  @keydown="${(x, c) => x._handleKeydown(c.event)}"
122
134
  @click="${(x) => x.clickableBox || x.clickable ? x._handleCheckedChange() : null}"
123
135
  >