@vonage/vivid 5.4.0 → 5.6.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 (351) hide show
  1. package/LICENSE.md +201 -0
  2. package/accordion/definition.cjs +5 -0
  3. package/accordion/definition.js +5 -0
  4. package/accordion/index.cjs +1 -1
  5. package/accordion/index.js +14 -3
  6. package/alert/definition.cjs +4 -12
  7. package/alert/definition.js +5 -13
  8. package/alert/index.cjs +11 -11
  9. package/alert/index.js +33 -37
  10. package/audio-player/definition.cjs +4 -0
  11. package/audio-player/definition.js +4 -0
  12. package/audio-player/index.cjs +1 -1
  13. package/audio-player/index.js +8 -2
  14. package/banner/definition.cjs +2 -4
  15. package/banner/definition.js +2 -4
  16. package/banner/index.cjs +2 -2
  17. package/banner/index.js +1 -1
  18. package/breadcrumb/definition.cjs +1 -0
  19. package/breadcrumb/definition.js +1 -0
  20. package/breadcrumb/index.cjs +1 -1
  21. package/breadcrumb/index.js +1 -0
  22. package/bundled/affix.js +1 -1
  23. package/bundled/anchored.cjs +1 -1
  24. package/bundled/anchored.js +6 -6
  25. package/bundled/attribute-binding-behaviour.cjs +1 -1
  26. package/bundled/attribute-binding-behaviour.js +3 -1
  27. package/bundled/base-color-picker.cjs +18 -13
  28. package/bundled/base-color-picker.js +107 -84
  29. package/bundled/base-progress.cjs +1 -1
  30. package/bundled/base-progress.js +3 -0
  31. package/bundled/button.cjs +1 -1
  32. package/bundled/button.js +14 -10
  33. package/bundled/calendar-picker.template.cjs +1 -1
  34. package/bundled/calendar-picker.template.js +4 -2
  35. package/bundled/char-count.cjs +1 -1
  36. package/bundled/char-count.js +1 -1
  37. package/bundled/definition10.cjs +7 -7
  38. package/bundled/definition10.js +29 -19
  39. package/bundled/definition11.cjs +12 -19
  40. package/bundled/definition11.js +73 -204
  41. package/bundled/definition12.cjs +19 -10
  42. package/bundled/definition12.js +218 -36
  43. package/bundled/definition13.cjs +10 -1
  44. package/bundled/definition13.js +38 -14
  45. package/bundled/definition14.cjs +1 -5
  46. package/bundled/definition14.js +15 -24
  47. package/bundled/definition15.cjs +5 -30
  48. package/bundled/definition15.js +22 -73
  49. package/bundled/definition16.cjs +30 -19
  50. package/bundled/definition16.js +74 -97
  51. package/bundled/definition17.cjs +19 -13
  52. package/bundled/definition17.js +86 -117
  53. package/bundled/definition18.cjs +13 -12
  54. package/bundled/definition18.js +125 -71
  55. package/bundled/definition19.cjs +16 -16
  56. package/bundled/definition19.js +132 -94
  57. package/bundled/definition2.cjs +8 -9
  58. package/bundled/definition2.js +89 -142
  59. package/bundled/definition22.cjs +1 -1
  60. package/bundled/definition22.js +1 -0
  61. package/bundled/definition3.cjs +1 -1
  62. package/bundled/definition3.js +2 -1
  63. package/bundled/definition5.cjs +1 -1
  64. package/bundled/definition5.js +9 -3
  65. package/bundled/definition6.cjs +1 -1
  66. package/bundled/definition6.js +1 -0
  67. package/bundled/definition7.cjs +1 -1
  68. package/bundled/definition7.js +7 -4
  69. package/bundled/definition8.cjs +1 -1
  70. package/bundled/definition8.js +1 -0
  71. package/bundled/definition9.cjs +6 -6
  72. package/bundled/definition9.js +545 -488
  73. package/bundled/delegates-aria.cjs +1 -1
  74. package/bundled/delegates-aria.js +3 -1
  75. package/bundled/form-associated.cjs +1 -1
  76. package/bundled/form-associated.js +11 -3
  77. package/bundled/host-semantics.js +4 -4
  78. package/bundled/listbox.cjs +1 -1
  79. package/bundled/listbox.js +22 -4
  80. package/bundled/localized.cjs +1 -1
  81. package/bundled/localized.js +149 -66
  82. package/bundled/mixins.cjs +4 -4
  83. package/bundled/mixins.js +11 -8
  84. package/bundled/picker-field.template.cjs +14 -14
  85. package/bundled/picker-field.template.js +36 -56
  86. package/bundled/scrollIntoView.cjs +1 -1
  87. package/bundled/scrollIntoView.js +4 -1
  88. package/bundled/text-field.cjs +1 -1
  89. package/bundled/text-field.js +1 -1
  90. package/bundled/time-selection-picker.template.cjs +12 -12
  91. package/bundled/time-selection-picker.template.js +16 -12
  92. package/bundled/trapped-focus.cjs +1 -0
  93. package/bundled/trapped-focus.js +26 -0
  94. package/bundled/vivid-element.cjs +4 -4
  95. package/bundled/vivid-element.js +529 -492
  96. package/calendar/definition.cjs +2 -0
  97. package/calendar/definition.js +2 -0
  98. package/calendar/index.cjs +13 -13
  99. package/calendar/index.js +174 -144
  100. package/checkbox/definition.cjs +1 -0
  101. package/checkbox/definition.js +1 -0
  102. package/color-picker/definition.cjs +213 -112
  103. package/color-picker/definition.js +213 -112
  104. package/color-picker/index.cjs +104 -75
  105. package/color-picker/index.js +417 -326
  106. package/combobox/definition.cjs +17 -6
  107. package/combobox/definition.js +17 -6
  108. package/combobox/index.cjs +14 -9
  109. package/combobox/index.js +54 -42
  110. package/contextual-help/index.cjs +1 -1
  111. package/contextual-help/index.js +1 -1
  112. package/custom-elements.json +6976 -484
  113. package/data-grid/definition.cjs +105 -7
  114. package/data-grid/definition.js +105 -7
  115. package/data-grid/index.cjs +52 -38
  116. package/data-grid/index.js +313 -242
  117. package/date-picker/index.cjs +1 -1
  118. package/date-picker/index.js +2 -2
  119. package/date-range-picker/definition.cjs +2 -0
  120. package/date-range-picker/definition.js +2 -0
  121. package/date-range-picker/index.cjs +1 -1
  122. package/date-range-picker/index.js +7 -3
  123. package/date-time-picker/index.cjs +1 -1
  124. package/date-time-picker/index.js +2 -2
  125. package/dial-pad/definition.cjs +148 -0
  126. package/dial-pad/definition.js +148 -0
  127. package/dial-pad/index.cjs +27 -20
  128. package/dial-pad/index.js +202 -101
  129. package/dialog/definition.cjs +1 -0
  130. package/dialog/definition.js +1 -0
  131. package/dialog/index.cjs +1 -1
  132. package/dialog/index.js +1 -0
  133. package/divider/index.cjs +1 -1
  134. package/divider/index.js +1 -1
  135. package/fab/definition.cjs +1 -0
  136. package/fab/definition.js +1 -0
  137. package/fab/index.cjs +1 -1
  138. package/fab/index.js +1 -0
  139. package/file-picker/definition.cjs +7 -2
  140. package/file-picker/definition.js +7 -2
  141. package/file-picker/index.cjs +6 -6
  142. package/file-picker/index.js +82 -73
  143. package/icon/definition.cjs +66 -41
  144. package/icon/definition.js +67 -42
  145. package/index.cjs +21 -0
  146. package/index.js +1 -1
  147. package/lib/color-picker/color-picker.d.ts +390 -12
  148. package/lib/color-picker/locale.d.ts +4 -0
  149. package/lib/data-grid/locale.d.ts +5 -0
  150. package/lib/date-picker/date-picker.d.ts +38 -38
  151. package/lib/date-range-picker/date-range-picker.d.ts +20 -20
  152. package/lib/date-time-picker/date-time-picker.d.ts +40 -40
  153. package/lib/dial-pad/dial-pad.d.ts +1 -0
  154. package/lib/icon/icon.d.ts +1 -1
  155. package/lib/menu/menu.d.ts +4 -4
  156. package/lib/rich-text-editor/definition.d.ts +3 -2
  157. package/lib/rich-text-editor/locale.d.ts +29 -3
  158. package/lib/rich-text-editor/popover.d.ts +19 -0
  159. package/lib/rich-text-editor/rich-text-editor.d.ts +16 -45
  160. package/lib/rich-text-editor/rich-text-editor.template.d.ts +2 -2
  161. package/lib/rich-text-editor/rte/config.d.ts +18 -0
  162. package/lib/rich-text-editor/rte/document.d.ts +28 -0
  163. package/lib/rich-text-editor/rte/exports.d.ts +23 -0
  164. package/lib/rich-text-editor/rte/feature.d.ts +46 -0
  165. package/lib/rich-text-editor/rte/features/internal/basic-text-blocks.d.ts +33 -0
  166. package/lib/rich-text-editor/rte/features/internal/foreign-html.d.ts +11 -0
  167. package/lib/rich-text-editor/rte/features/internal/history.d.ts +10 -0
  168. package/lib/rich-text-editor/rte/features/internal/text-style.d.ts +18 -0
  169. package/lib/rich-text-editor/rte/html-parser.d.ts +24 -0
  170. package/lib/rich-text-editor/rte/html-serializer.d.ts +30 -0
  171. package/lib/rich-text-editor/rte/instance.d.ts +57 -0
  172. package/lib/rich-text-editor/rte/utils/default-textblock.d.ts +2 -0
  173. package/lib/rich-text-editor/rte/utils/impl.d.ts +1 -0
  174. package/lib/rich-text-editor/rte/utils/textblock-attrs.d.ts +29 -0
  175. package/lib/rich-text-editor/rte/utils/textblock-marks.d.ts +10 -0
  176. package/lib/rich-text-editor/rte/utils/ui.d.ts +109 -0
  177. package/lib/simple-color-picker/simple-color-picker.d.ts +6 -5
  178. package/lib/text-area/text-area.d.ts +1 -1
  179. package/lib/text-field/text-field.d.ts +1 -1
  180. package/lib/time-picker/time-picker.d.ts +20 -20
  181. package/lib/toggletip/toggletip.d.ts +4 -4
  182. package/lib/tooltip/tooltip.d.ts +4 -4
  183. package/locales/de-DE.cjs +58 -7
  184. package/locales/de-DE.js +58 -7
  185. package/locales/en-GB.cjs +60 -9
  186. package/locales/en-GB.js +60 -9
  187. package/locales/en-US.cjs +60 -9
  188. package/locales/en-US.js +60 -9
  189. package/locales/ja-JP.cjs +59 -8
  190. package/locales/ja-JP.js +59 -8
  191. package/locales/zh-CN.cjs +58 -7
  192. package/locales/zh-CN.js +58 -7
  193. package/menu/definition.cjs +1 -0
  194. package/menu/definition.js +1 -0
  195. package/number-field/definition.cjs +5 -3
  196. package/number-field/definition.js +5 -3
  197. package/number-field/index.cjs +5 -3
  198. package/number-field/index.js +34 -32
  199. package/option/index.cjs +1 -1
  200. package/option/index.js +1 -1
  201. package/package.json +76 -62
  202. package/pagination/definition.cjs +2 -0
  203. package/pagination/definition.js +2 -0
  204. package/pagination/index.cjs +1 -1
  205. package/pagination/index.js +2 -0
  206. package/progress-ring/index.cjs +1 -1
  207. package/progress-ring/index.js +1 -1
  208. package/radio/definition.cjs +4 -0
  209. package/radio/definition.js +4 -0
  210. package/radio/index.cjs +1 -1
  211. package/radio/index.js +1 -1
  212. package/radio-group/index.cjs +1 -1
  213. package/radio-group/index.js +1 -1
  214. package/range-slider/definition.cjs +2 -1
  215. package/range-slider/definition.js +2 -1
  216. package/range-slider/index.cjs +1 -1
  217. package/range-slider/index.js +3 -1
  218. package/rich-text-editor/definition.cjs +17942 -1074
  219. package/rich-text-editor/definition.js +17926 -1079
  220. package/rich-text-editor/index.cjs +29 -130
  221. package/rich-text-editor/index.js +5565 -2474
  222. package/searchable-select/definition.cjs +6 -2
  223. package/searchable-select/definition.js +6 -2
  224. package/searchable-select/index.cjs +1 -1
  225. package/searchable-select/index.js +14 -10
  226. package/select/definition.cjs +22 -4
  227. package/select/definition.js +22 -4
  228. package/selectable-box/index.cjs +1 -1
  229. package/selectable-box/index.js +1 -1
  230. package/shared/color-picker/base-color-picker.d.ts +2 -1
  231. package/shared/patterns/anchored.d.ts +8 -8
  232. package/shared/patterns/char-count/char-count.d.ts +1 -1
  233. package/shared/patterns/localized.d.ts +386 -0
  234. package/shared/picker-field/mixins/calendar-picker.d.ts +10 -10
  235. package/shared/picker-field/mixins/calendar-picker.template.d.ts +10 -10
  236. package/shared/picker-field/mixins/min-max-calendar-picker.d.ts +20 -20
  237. package/shared/picker-field/mixins/single-date-picker.d.ts +28 -28
  238. package/shared/picker-field/mixins/single-value-picker.d.ts +8 -8
  239. package/shared/picker-field/mixins/time-selection-picker.d.ts +20 -20
  240. package/shared/picker-field/mixins/time-selection-picker.template.d.ts +20 -20
  241. package/shared/utils/promise.d.ts +7 -0
  242. package/simple-color-picker/definition.cjs +11 -6
  243. package/simple-color-picker/definition.js +11 -6
  244. package/simple-color-picker/index.cjs +6 -6
  245. package/simple-color-picker/index.js +44 -39
  246. package/slider/definition.cjs +7 -1
  247. package/slider/definition.js +7 -1
  248. package/styles/core/all.css +5 -1
  249. package/styles/core/theme.css +5 -1
  250. package/styles/core/typography.css +1 -1
  251. package/styles/tokens/theme-dark.css +4 -4
  252. package/styles/tokens/theme-light.css +4 -4
  253. package/styles/tokens/vivid-2-compat.css +1 -1
  254. package/switch/definition.cjs +1 -0
  255. package/switch/definition.js +1 -0
  256. package/switch/index.cjs +1 -1
  257. package/switch/index.js +1 -0
  258. package/tabs/definition.cjs +2 -0
  259. package/tabs/definition.js +2 -0
  260. package/tabs/index.cjs +1 -1
  261. package/tabs/index.js +2 -0
  262. package/tag/definition.cjs +34 -14
  263. package/tag/definition.js +34 -14
  264. package/tag/index.cjs +25 -12
  265. package/tag/index.js +64 -47
  266. package/tag-group/definition.cjs +1 -2
  267. package/tag-group/definition.js +1 -2
  268. package/tag-group/index.cjs +1 -1
  269. package/tag-group/index.js +11 -12
  270. package/text-area/definition.cjs +13 -7
  271. package/text-area/definition.js +13 -7
  272. package/text-area/index.cjs +6 -6
  273. package/text-area/index.js +20 -14
  274. package/text-field/definition.cjs +16 -6
  275. package/text-field/definition.js +16 -6
  276. package/time-picker/index.cjs +1 -1
  277. package/time-picker/index.js +1 -1
  278. package/toggletip/definition.cjs +5 -1
  279. package/toggletip/definition.js +5 -1
  280. package/toggletip/index.cjs +1 -1
  281. package/toggletip/index.js +1 -1
  282. package/tooltip/definition.cjs +6 -3
  283. package/tooltip/definition.js +6 -3
  284. package/tooltip/index.cjs +1 -1
  285. package/tooltip/index.js +1 -1
  286. package/tree-view/definition.cjs +28 -6
  287. package/tree-view/definition.js +28 -6
  288. package/tree-view/index.cjs +1 -1
  289. package/tree-view/index.js +28 -6
  290. package/unbundled/_commonjsHelpers.cjs +0 -26
  291. package/unbundled/_commonjsHelpers.js +1 -26
  292. package/unbundled/attribute-binding-behaviour.cjs +1 -0
  293. package/unbundled/attribute-binding-behaviour.js +1 -0
  294. package/unbundled/base-color-picker.cjs +45 -21
  295. package/unbundled/base-color-picker.js +45 -21
  296. package/unbundled/base-progress.cjs +3 -0
  297. package/unbundled/base-progress.js +3 -0
  298. package/unbundled/button.cjs +14 -10
  299. package/unbundled/button.js +14 -10
  300. package/unbundled/calendar-picker.template.cjs +3 -1
  301. package/unbundled/calendar-picker.template.js +3 -1
  302. package/unbundled/definition.cjs +1 -0
  303. package/unbundled/definition.js +1 -0
  304. package/unbundled/definition2.cjs +4 -1
  305. package/unbundled/definition2.js +4 -1
  306. package/unbundled/definition3.cjs +1 -0
  307. package/unbundled/definition3.js +1 -0
  308. package/unbundled/definition4.cjs +1 -0
  309. package/unbundled/definition4.js +1 -0
  310. package/unbundled/definition5.cjs +3 -2
  311. package/unbundled/definition5.js +4 -3
  312. package/unbundled/delegates-aria.cjs +1 -0
  313. package/unbundled/delegates-aria.js +1 -0
  314. package/unbundled/form-associated.cjs +4 -0
  315. package/unbundled/form-associated.js +4 -0
  316. package/unbundled/listbox.cjs +16 -1
  317. package/unbundled/listbox.js +16 -1
  318. package/unbundled/localized.cjs +36 -0
  319. package/unbundled/localized.js +37 -2
  320. package/unbundled/mixins.cjs +2 -0
  321. package/unbundled/mixins.js +2 -0
  322. package/unbundled/picker-field.template.cjs +3 -35
  323. package/unbundled/picker-field.template.js +3 -34
  324. package/unbundled/scrollIntoView.cjs +1 -0
  325. package/unbundled/scrollIntoView.js +1 -0
  326. package/unbundled/text-field.cjs +1 -1
  327. package/unbundled/text-field.js +1 -1
  328. package/unbundled/time-selection-picker.template.cjs +5 -1
  329. package/unbundled/time-selection-picker.template.js +5 -1
  330. package/unbundled/trapped-focus.cjs +37 -0
  331. package/unbundled/trapped-focus.js +34 -0
  332. package/unbundled/vivid-element.cjs +1 -1
  333. package/unbundled/vivid-element.js +1 -1
  334. package/video-player/definition.cjs +54 -44
  335. package/video-player/definition.js +50 -40
  336. package/video-player/index.cjs +28 -28
  337. package/video-player/index.js +1448 -1442
  338. package/visually-hidden/index.cjs +1 -1
  339. package/visually-hidden/index.js +1 -1
  340. package/vivid.api.json +6463 -6099
  341. package/bundled/_has.cjs +0 -1
  342. package/bundled/_has.js +0 -34
  343. package/lib/rich-text-editor/facades/prose-mirror-vivid.schema.d.ts +0 -4
  344. package/lib/rich-text-editor/facades/vivid-prose-mirror.facade.d.ts +0 -18
  345. package/lib/rich-text-editor/image-placeholder/definition.d.ts +0 -2
  346. package/lib/rich-text-editor/image-placeholder/image-placeholder.d.ts +0 -7
  347. package/lib/rich-text-editor/image-placeholder/image-placeholder.template.d.ts +0 -4
  348. package/lib/rich-text-editor/menubar/consts.d.ts +0 -18
  349. package/lib/rich-text-editor/menubar/definition.d.ts +0 -2
  350. package/lib/rich-text-editor/menubar/menubar.d.ts +0 -386
  351. package/lib/rich-text-editor/menubar/menubar.template.d.ts +0 -4
@@ -4,15 +4,18 @@ import { VwcIconElement as Icon, iconDefinition } from '../icon/definition.js';
4
4
  import { a as WithFeedback, f as feedbackMessageDefinition } from '../unbundled/mixins.js';
5
5
  import { attr, observable, nullableNumberConverter, ref, when, html, slotted, repeat } from '@microsoft/fast-element';
6
6
  import { D as DelegatesAria, d as delegateAria } from '../unbundled/delegates-aria.js';
7
+ import { h as handleEscapeKeyAndStopPropogation } from '../unbundled/index.js';
7
8
  import { W as WithContextualHelp } from '../unbundled/with-contextual-help.js';
9
+ import { T as TrappedFocus } from '../unbundled/trapped-focus.js';
8
10
  import { B as BaseColorPicker, i as isValidHexColor } from '../unbundled/base-color-picker.js';
9
11
  import { W as WithErrorText } from '../unbundled/with-error-text.js';
10
12
  import { W as WithSuccessText } from '../unbundled/with-success-text.js';
11
13
  import { classNames } from '@microsoft/fast-web-utilities';
12
14
  import { VwcTextFieldElement as TextField, textFieldDefinition } from '../text-field/definition.js';
13
15
  import { B as Button, b as buttonDefinition } from '../unbundled/definition.js';
16
+ import { VwcTooltipElement as Tooltip, tooltipDefinition } from '../tooltip/definition.js';
14
17
 
15
- const styles = ".palette{display:grid;grid-template-columns:repeat(var(--swatches-per-row, 7),var(--_color-swatch-size, 24px))}.swatch{position:relative;padding:0;border:none;border-radius:4px;background-color:var(--swatch-color);block-size:var(--_color-swatch-size, 24px);color:var(--vvd-color-canvas);cursor:pointer;inline-size:var(--_color-swatch-size, 24px)}.swatch.contrast{color:var(--vvd-color-canvas-text)}.swatch:focus-visible{outline:none;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;--focus-inset: -3px}:host{display:inline-block}.base{display:inline-block;min-inline-size:var(--_color-picker-min-inline-size, 280px)}.control{inline-size:100%}.button{display:inline-flex;box-sizing:border-box;align-items:center;border:0 none;border-radius:4px;margin:0;background-color:var(--button-color, var(--vvd-color-canvas-text));block-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2)));color:var(--vvd-color-canvas);inline-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2)));padding-inline:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2))/4);text-decoration:none;vertical-align:middle}.button.contrast{color:var(--vvd-color-canvas-text)}.button:not(.disabled){cursor:pointer}.button.disabled{background-color:var(--vvd-color-neutral-300);color:var(--vvd-color-neutral-500);cursor:not-allowed}.button:focus-visible{--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))}.button [data-vvd-component=icon]{font-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2))/2);line-height:1}.dialog{display:flex;flex-direction:column;min-inline-size:var(--_color-picker-popup-min-inline-size, 264px)}.dialog .header{display:inline-flex;align-items:center;justify-content:space-between;padding-block:8px;padding-inline:16px}.dialog .header-title{font:var(--vvd-typography-base-extended-bold)}.dialog .body{display:flex;flex-direction:column;gap:16px;margin-block-end:16px;padding-inline:16px}.dialog .hex-input-wrapper{display:flex;align-items:stretch;gap:8px}.dialog .hex-input-wrapper [data-vvd-component=button]{flex:0 0 auto}.dialog .footer{padding:16px;border-top:1px solid var(--vvd-color-neutral-200)}.dialog .footer-title{display:block;margin-block-end:8px}.dialog .palette{gap:var(--_color-swatches-gap, 8px)}vvd-hex-input{min-width:0;flex:1 1 auto}vvd-hex-input::part(input){width:100%;height:100%;box-sizing:border-box;border:0 none;border-radius:8px;background-color:var(--vvd-color-canvas);box-shadow:inset 0 0 0 1px var(--vvd-color-neutral-500);font:var(--vvd-typography-base);outline:transparent;padding-inline:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2))*.4)}vvd-hex-input::part(input):focus-visible{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}vvd-hex-picker{width:auto;height:auto;gap:16px;inline-size:100%}vvd-hex-picker::part(saturation){border-radius:8px;block-size:120px}vvd-hex-picker::part(hue){flex:0 0 8px;border-radius:8px}vvd-hex-picker::part(hue-pointer){width:10px;height:10px}vvd-hex-picker::part(saturation-pointer){width:18px;height:18px}::part(popup-base){inline-size:max-content;min-block-size:var(--_color-picker-popup-min-inline-size, 264px);min-inline-size:var(--_color-picker-popup-min-inline-size, 264px)}";
18
+ const styles = ".palette{display:grid;grid-template-columns:repeat(var(--swatches-per-row, 7),var(--_color-swatch-size, 24px))}.swatch{position:relative;padding:0;border-radius:4px;background-color:var(--swatch-color);block-size:var(--_color-swatch-size, 24px);color:var(--vvd-color-canvas);cursor:pointer;inline-size:var(--_color-swatch-size, 24px)}.swatch:not(.contrast){border:none}.swatch.contrast{border:1px solid var(--vvd-color-neutral-400);color:var(--vvd-color-canvas-text)}.swatch:focus-visible{outline:none;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;--focus-inset: -3px}:host{display:inline-block;--_low-ink-color: var(--vvd-color-neutral-600)}.base{display:inline-block;min-inline-size:var(--_color-picker-min-inline-size, 280px)}.control{inline-size:100%}.button{display:inline-flex;box-sizing:border-box;align-items:center;border:0 none;border-radius:4px;margin:0;background-color:var(--button-color, var(--vvd-color-canvas-text));block-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2)));color:var(--vvd-color-canvas);inline-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2)));padding-inline:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2))/4);text-decoration:none;vertical-align:middle}.button.contrast{color:var(--vvd-color-canvas-text)}.button:not(.disabled){cursor:pointer}.button.disabled{background-color:var(--vvd-color-neutral-300);color:var(--vvd-color-neutral-500);cursor:not-allowed}.button:focus-visible{--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))}.button [data-vvd-component=icon]{font-size:calc(1px*(32 + 4*clamp(-1,var(--vvd-size-density, 0),2))/2);line-height:1}.dialog{display:flex;flex-direction:column;min-inline-size:var(--_color-picker-popup-min-inline-size, 264px)}.dialog .header{display:inline-flex;align-items:center;justify-content:space-between;padding-block:8px;padding-inline:16px}.dialog .header-title{font:var(--vvd-typography-base-extended-bold);margin-block:0}.dialog .body{display:flex;flex-direction:column;gap:16px;margin-block-end:16px;padding-inline:16px}.dialog .hex-input-wrapper{display:flex;align-items:stretch;gap:8px}.dialog .hex-input-wrapper [data-vvd-component=button]{flex:0 0 auto}.dialog .footer{padding:16px;border-top:1px solid var(--vvd-color-neutral-200)}.dialog .footer-header{margin-block-end:8px}.dialog .swatches-count{color:var(--_low-ink-color);font:var(--vvd-typography-base)}.dialog .palette{gap:var(--_color-swatches-gap, 8px)}vvd-hex-input{min-width:0;flex:1 1 auto}vvd-hex-input::part(input),vvd-hex-input>input{width:100%;height:100%;box-sizing:border-box;border:0 none;border-radius:8px;background-color:var(--vvd-color-canvas);box-shadow:inset 0 0 0 1px var(--vvd-color-neutral-500);font:var(--vvd-typography-base);outline:transparent;padding-inline:calc(1px*(40 + 4*clamp(-1,var(--vvd-size-density, 0),2))*.4)}vvd-hex-input::part(input):focus-visible,vvd-hex-input>input:focus-visible{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}vvd-hex-picker{width:auto;height:auto;gap:16px;inline-size:100%}vvd-hex-picker::part(saturation){border-radius:8px;block-size:120px}vvd-hex-picker::part(hue){flex:0 0 8px;border-radius:8px}vvd-hex-picker::part(hue-pointer){width:10px;height:10px}vvd-hex-picker::part(saturation-pointer){width:18px;height:18px}::part(popup-base){inline-size:max-content;min-block-size:var(--_color-picker-popup-min-inline-size, 264px);min-inline-size:var(--_color-picker-popup-min-inline-size, 264px)}.visually-hidden{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;border:0;margin:-1px;clip:rect(0 0 0 0)}";
16
19
 
17
20
  // Clamps a value between an upper and lower bound.
18
21
  // We use ternary operators because it makes the minified code
@@ -592,9 +595,11 @@ class VvdHexInput extends HexInput {
592
595
  this.displayName = "VvdHexInput";
593
596
  }
594
597
  }
598
+ /* v8 ignore if -- @preserve */
595
599
  if (!customElements.get(VC_HEX_PICKER_TAG)) {
596
600
  customElements.define(VC_HEX_PICKER_TAG, VvdHexPicker);
597
601
  }
602
+ /* v8 ignore if -- @preserve */
598
603
  if (!customElements.get(VC_HEX_INPUT_TAG)) {
599
604
  customElements.define(VC_HEX_INPUT_TAG, VvdHexInput);
600
605
  }
@@ -602,7 +607,11 @@ const vcPickerTag = VC_HEX_PICKER_TAG;
602
607
  const vcInputTag = VC_HEX_INPUT_TAG;
603
608
  class ColorPicker extends WithContextualHelp(
604
609
  WithFeedback(
605
- WithErrorText(WithSuccessText(DelegatesAria(BaseColorPicker(VividElement))))
610
+ WithErrorText(
611
+ WithSuccessText(
612
+ DelegatesAria(TrappedFocus(BaseColorPicker(VividElement)))
613
+ )
614
+ )
606
615
  )
607
616
  ) {
608
617
  constructor() {
@@ -610,20 +619,6 @@ class ColorPicker extends WithContextualHelp(
610
619
  this.disableSavedColors = false;
611
620
  this.savedColors = [];
612
621
  this.maxSwatches = 6;
613
- this.copyIconName = "copy-2-line";
614
- this.#iconResetTimer = null;
615
- /**
616
- * @internal
617
- */
618
- this._copyValueToClipboard = async (value) => {
619
- try {
620
- await navigator.clipboard.writeText(value);
621
- this._setTemporaryCopyIcon("check-circle-line");
622
- } catch {
623
- alert(this.locale?.colorPicker?.copyErrorText);
624
- this._setTemporaryCopyIcon("error-line");
625
- }
626
- };
627
622
  /**
628
623
  * @internal
629
624
  */
@@ -633,14 +628,23 @@ class ColorPicker extends WithContextualHelp(
633
628
  }
634
629
  this.open = false;
635
630
  };
631
+ this.copyIconName = "copy-2-line";
632
+ this.#iconResetTimer = null;
636
633
  /**
637
634
  * @internal
638
635
  */
639
- this.#closeOnEscape = (e) => {
640
- if (e.key === "Escape") {
641
- this.open = false;
636
+ this._copyValueToClipboard = async (value) => {
637
+ try {
638
+ await navigator.clipboard.writeText(value);
639
+ this._setTemporaryCopyIcon("check-circle-line");
640
+ this._ariaLiveDescription = this.locale.colorPicker.copySuccessMessage(value);
641
+ } catch {
642
+ alert(this.locale.colorPicker.copyErrorText);
643
+ this._setTemporaryCopyIcon("error-line");
644
+ this._ariaLiveDescription = this.locale.colorPicker.copyErrorText;
642
645
  }
643
646
  };
647
+ this._ariaLiveDescription = "";
644
648
  }
645
649
  static {
646
650
  /**
@@ -654,6 +658,7 @@ class ColorPicker extends WithContextualHelp(
654
658
  * @internal
655
659
  */
656
660
  placeholderChanged() {
661
+ /* v8 ignore if -- @preserve */
657
662
  if (this.proxy instanceof HTMLInputElement) {
658
663
  this.proxy.placeholder = this.placeholder;
659
664
  }
@@ -666,6 +671,16 @@ class ColorPicker extends WithContextualHelp(
666
671
  handleChange() {
667
672
  this.$emit("change");
668
673
  }
674
+ /**
675
+ * @internal
676
+ */
677
+ openChanged(_oldValue, newValue) {
678
+ if (newValue && this.isConnected) {
679
+ requestAnimationFrame(() => {
680
+ this._refreshCanvasColor();
681
+ });
682
+ }
683
+ }
669
684
  /**
670
685
  * @internal
671
686
  */
@@ -686,6 +701,71 @@ class ColorPicker extends WithContextualHelp(
686
701
  _handleColorSaving() {
687
702
  this._saveCurrentColor();
688
703
  }
704
+ /**
705
+ * @internal
706
+ */
707
+ _saveCurrentColor() {
708
+ const value = this.value;
709
+ if (typeof value !== "string" || !isValidHexColor(value)) return;
710
+ const swatches = Array.isArray(this.savedColors) ? [...this.savedColors] : [];
711
+ const idx = swatches.findIndex((s) => s?.value === value);
712
+ if (idx !== -1) swatches.splice(idx, 1);
713
+ swatches.unshift({ value });
714
+ this.savedColors = swatches.slice(0, this._maxSwatchesNormalized);
715
+ this._setSavedColors(this.savedColors);
716
+ }
717
+ /**
718
+ * @internal
719
+ */
720
+ _loadSavedColors() {
721
+ try {
722
+ const savedColors = localStorage.getItem(this._savedColorsStorageKey);
723
+ if (!savedColors) return [];
724
+ const parsed = JSON.parse(savedColors);
725
+ if (!Array.isArray(parsed)) return [];
726
+ return parsed.filter(
727
+ (x) => x && typeof x.value === "string" && isValidHexColor(x.value)
728
+ ).map((x) => ({
729
+ value: x.value,
730
+ label: typeof x.label === "string" ? x.label : void 0
731
+ }));
732
+ } catch {
733
+ return [];
734
+ }
735
+ }
736
+ /**
737
+ * @internal
738
+ */
739
+ _setSavedColors(swatches) {
740
+ try {
741
+ localStorage.setItem(
742
+ this._savedColorsStorageKey,
743
+ JSON.stringify(swatches)
744
+ );
745
+ } catch {
746
+ }
747
+ }
748
+ /**
749
+ * Get all color swatches combined, both from swatches property and saved colors
750
+ * @internal
751
+ */
752
+ get allSwatches() {
753
+ const predefinedColors = Array.isArray(this.swatches) ? this.swatches : [];
754
+ const savedColors = Array.isArray(this.savedColors) ? this.savedColors : [];
755
+ const seen = /* @__PURE__ */ new Set();
756
+ const merged = [];
757
+ const appendIfUniqueAndValid = (swatch) => {
758
+ if (!swatch || typeof swatch.value !== "string") return;
759
+ if (!isValidHexColor(swatch.value) || seen.has(swatch.value)) return;
760
+ seen.add(swatch.value);
761
+ merged.push(swatch);
762
+ };
763
+ if (!this.disableSavedColors) {
764
+ savedColors.forEach(appendIfUniqueAndValid);
765
+ }
766
+ predefinedColors.forEach(appendIfUniqueAndValid);
767
+ return merged.slice(0, this._maxSwatchesNormalized);
768
+ }
689
769
  /**
690
770
  * @internal
691
771
  */
@@ -732,6 +812,7 @@ class ColorPicker extends WithContextualHelp(
732
812
  * @internal
733
813
  */
734
814
  get _buttonColor() {
815
+ /* v8 ignore else -- @preserve */
735
816
  if (!this._canvasColor) {
736
817
  this._refreshCanvasColor();
737
818
  }
@@ -760,24 +841,11 @@ class ColorPicker extends WithContextualHelp(
760
841
  const path = e.composedPath?.();
761
842
  return !!(path && path.includes(el));
762
843
  }
763
- #iconResetTimer;
764
- /**
765
- * @internal
766
- */
767
- _setTemporaryCopyIcon(name, ms = 2e3) {
768
- this.copyIconName = name;
769
- if (this.#iconResetTimer) clearTimeout(this.#iconResetTimer);
770
- this.#iconResetTimer = setTimeout(() => {
771
- this.copyIconName = "copy-2-line";
772
- this.#iconResetTimer = null;
773
- }, ms);
774
- }
844
+ #closeOnPointerOutside;
775
845
  connectedCallback() {
776
846
  super.connectedCallback();
777
- this._refreshCanvasColor();
778
847
  this.savedColors = this._loadSavedColors();
779
848
  document.addEventListener("mousedown", this.#closeOnPointerOutside, true);
780
- document.addEventListener("keydown", this.#closeOnEscape);
781
849
  }
782
850
  disconnectedCallback() {
783
851
  super.disconnectedCallback();
@@ -786,74 +854,67 @@ class ColorPicker extends WithContextualHelp(
786
854
  this.#closeOnPointerOutside,
787
855
  true
788
856
  );
789
- document.removeEventListener("keydown", this.#closeOnEscape);
790
857
  }
791
- #closeOnPointerOutside;
792
- #closeOnEscape;
858
+ #iconResetTimer;
793
859
  /**
794
860
  * @internal
795
861
  */
796
- _saveCurrentColor() {
797
- const value = this.value;
798
- if (typeof value !== "string" || !isValidHexColor(value)) return;
799
- const swatches = Array.isArray(this.savedColors) ? [...this.savedColors] : [];
800
- const idx = swatches.findIndex((s) => s?.value === value);
801
- if (idx !== -1) swatches.splice(idx, 1);
802
- swatches.unshift({ value });
803
- this.savedColors = swatches.slice(0, this._maxSwatchesNormalized);
804
- this._setSavedColors(this.savedColors);
862
+ _setTemporaryCopyIcon(name, ms = 2e3) {
863
+ this.copyIconName = name;
864
+ if (this.#iconResetTimer) clearTimeout(this.#iconResetTimer);
865
+ this.#iconResetTimer = setTimeout(() => {
866
+ this.copyIconName = "copy-2-line";
867
+ this.#iconResetTimer = null;
868
+ }, ms);
805
869
  }
870
+ // --- Trapped focus ---
806
871
  /**
807
872
  * @internal
808
873
  */
809
- _loadSavedColors() {
810
- try {
811
- const savedColors = localStorage.getItem(this._savedColorsStorageKey);
812
- if (!savedColors) return [];
813
- const parsed = JSON.parse(savedColors);
814
- if (!Array.isArray(parsed)) return [];
815
- return parsed.filter(
816
- (x) => x && typeof x.value === "string" && isValidHexColor(x.value)
817
- ).map((x) => ({
818
- value: x.value,
819
- label: typeof x.label === "string" ? x.label : void 0
820
- }));
821
- } catch {
822
- return [];
874
+ _onBaseKeydown(event) {
875
+ if (this.open && handleEscapeKeyAndStopPropogation(event)) {
876
+ this.open = false;
877
+ return false;
823
878
  }
879
+ if (this._trappedFocus(event, () => this._focusableElsWithinDialog())) {
880
+ return false;
881
+ }
882
+ return true;
824
883
  }
825
884
  /**
826
885
  * @internal
827
886
  */
828
- _setSavedColors(swatches) {
829
- try {
830
- localStorage.setItem(
831
- this._savedColorsStorageKey,
832
- JSON.stringify(swatches)
887
+ _focusableElsWithinDialog() {
888
+ return this._popupEl.querySelectorAll(
889
+ 'button:not([role="gridcell"]), [data-vvd-component="button"], vwc-button:not([role="gridcell"])'
890
+ );
891
+ }
892
+ /**
893
+ * @internal
894
+ */
895
+ _handleCellKeydown(event, value, index, isSaveCell) {
896
+ if (event.key === "Tab") {
897
+ event.preventDefault();
898
+ const focusableEls = this._focusableElsWithinDialog();
899
+ const idx = Array.prototype.indexOf.call(
900
+ focusableEls,
901
+ event.currentTarget
833
902
  );
834
- } catch {
903
+ const nextIdx = event.shiftKey ? (idx - 1 + focusableEls.length) % focusableEls.length : (idx + 1) % focusableEls.length;
904
+ focusableEls[nextIdx]?.focus();
905
+ return false;
835
906
  }
907
+ return super._handleCellKeydown(event, value, index, isSaveCell);
836
908
  }
837
909
  /**
838
- * Get all color swatches combined, both from swatches property and saved colors
839
910
  * @internal
840
911
  */
841
- get allSwatches() {
842
- const predefinedColors = Array.isArray(this.swatches) ? this.swatches : [];
843
- const savedColors = Array.isArray(this.savedColors) ? this.savedColors : [];
844
- const seen = /* @__PURE__ */ new Set();
845
- const merged = [];
846
- const appendIfUniqueAndValid = (swatch) => {
847
- if (!swatch || typeof swatch.value !== "string") return;
848
- if (!isValidHexColor(swatch.value) || seen.has(swatch.value)) return;
849
- seen.add(swatch.value);
850
- merged.push(swatch);
851
- };
852
- if (!this.disableSavedColors) {
853
- savedColors.forEach(appendIfUniqueAndValid);
912
+ _handleSwatchSelection(value) {
913
+ /* v8 ignore else -- @preserve */
914
+ if (this.value !== value) {
915
+ this._ariaLiveDescription = this.locale.colorPicker.selectionSuccessMessage(value);
854
916
  }
855
- predefinedColors.forEach(appendIfUniqueAndValid);
856
- return merged.slice(0, this._maxSwatchesNormalized);
917
+ super._handleSwatchSelection(value);
857
918
  }
858
919
  }
859
920
  __decorateClass([
@@ -881,6 +942,9 @@ __decorateClass([
881
942
  __decorateClass([
882
943
  observable
883
944
  ], ColorPicker.prototype, "copyIconName");
945
+ __decorateClass([
946
+ observable
947
+ ], ColorPicker.prototype, "_ariaLiveDescription");
884
948
 
885
949
  function renderTextField(textFieldTag, iconTag) {
886
950
  const getClasses = (_) => classNames("control");
@@ -911,6 +975,8 @@ function renderTextField(textFieldTag, iconTag) {
911
975
  >
912
976
  <button
913
977
  aria-label="${(x) => x.locale.colorPicker.pickerButtonLabel}"
978
+ aria-expanded="${(x) => x.open}"
979
+ aria-haspopup="dialog"
914
980
  class="button ${(x) => classNames(
915
981
  x._applyContrastClass(x._buttonColor) ? "contrast" : "",
916
982
  x.disabled ? "disabled" : ""
@@ -938,9 +1004,9 @@ function renderTextField(textFieldTag, iconTag) {
938
1004
  function renderPopupHeader(buttonTag, iconTag) {
939
1005
  return html`
940
1006
  <div class="header">
941
- <span class="header-title" id="color-picker-title">
1007
+ <h2 class="header-title" id="color-picker-title">
942
1008
  <slot name="popup-text">${(x) => x.locale.colorPicker.popupLabel}</slot>
943
- </span>
1009
+ </h2>
944
1010
  <${buttonTag} size="condensed"
945
1011
  aria-label="${(x) => x.locale.colorPicker.closeButtonLabel}"
946
1012
  @click="${(x) => x._handleCloseRequest()}">
@@ -949,7 +1015,7 @@ function renderPopupHeader(buttonTag, iconTag) {
949
1015
  </div>
950
1016
  `;
951
1017
  }
952
- function renderPopupBody(buttonTag, iconTag) {
1018
+ function renderPopupBody(buttonTag, iconTag, tooltipTag) {
953
1019
  return html`
954
1020
  <div class="body">
955
1021
  <${html.partial(vcPickerTag)}
@@ -965,24 +1031,37 @@ function renderPopupBody(buttonTag, iconTag) {
965
1031
  color="${(x) => x.value}"
966
1032
  @color-changed="${(x, c) => x._onPickerColorChanged(c.event)}"
967
1033
  ${ref("_vcHexInputEl")}
968
- ></${html.partial(vcInputTag)}>
969
- <${buttonTag} size="normal"
970
- aria-label="${(x) => x.locale.colorPicker.copyButtonLabel}"
971
- @click="${(x) => x._copyValueToClipboard(x.value)}">
972
- <${iconTag} slot="icon" name="${(x) => x.copyIconName}"></${iconTag}>
973
- </${buttonTag}>
1034
+ >
1035
+ <input name="hex-code-input" aria-label="${(x) => x.locale.colorPicker.hexInputLabel}"
1036
+ placeholder="${(x) => x.placeholder}"
1037
+ @blur="${(x, c) => c.event.stopImmediatePropagation()}"
1038
+ part="input">
1039
+ </${html.partial(vcInputTag)}>
1040
+ <${tooltipTag} placement="top"
1041
+ text="${(x) => x.locale.colorPicker.copyButtonLabel}"
1042
+ exportparts="vvd-theme-alternate">
1043
+ <${buttonTag}
1044
+ slot="anchor" size="normal"
1045
+ aria-label="${(x) => x.locale.colorPicker.copyButtonLabel}"
1046
+ @click="${(x) => x._copyValueToClipboard(x.value)}">
1047
+ <${iconTag} slot="icon" name="${(x) => x.copyIconName}"></${iconTag}>
1048
+ </${buttonTag}>
1049
+ </${tooltipTag}>
974
1050
  </div>
975
1051
  </div>
976
1052
  `;
977
1053
  }
978
- function renderPopupFooter(buttonTag, iconTag) {
1054
+ function renderPopupFooter(buttonTag, iconTag, tooltipTag) {
979
1055
  return html`
980
1056
  <div class="footer">
981
- <span class="footer-title" id="color-picker-footer-title"
982
- ><slot name="swatches-text"
983
- >${(x) => x.locale.colorPicker.swatchesLabel}</slot
984
- ></span
985
- >
1057
+ <div class="footer-header">
1058
+ <span class="footer-title" id="color-picker-footer-title"
1059
+ ><slot name="swatches-text"
1060
+ >${(x) => x.locale.colorPicker.swatchesLabel}</slot
1061
+ ></span
1062
+ >
1063
+ ${when((x) => !x.disableSavedColors, renderSwatchesCount())}
1064
+ </div>
986
1065
  <div
987
1066
  class="palette"
988
1067
  role="grid"
@@ -993,41 +1072,62 @@ function renderPopupFooter(buttonTag, iconTag) {
993
1072
  >
994
1073
  ${repeat(
995
1074
  (x) => x.allSwatches,
996
- (x) => x._renderColorSwatch(iconTag),
1075
+ (x) => x._renderColorSwatch(iconTag, tooltipTag),
997
1076
  { positioning: true }
998
1077
  )}
999
1078
  ${when(
1000
1079
  (x) => !x.disableSavedColors,
1001
1080
  html`
1002
- <${buttonTag}
1003
- appearance="outlined"
1004
- size="super-condensed"
1005
- role="gridcell"
1006
- tabindex="${(x) => x.allSwatches.length ? "-1" : "0"}"
1007
- aria-label="${(x) => x.locale.colorPicker.saveButtonLabel}"
1008
- @click="${(x) => x._saveCurrentColor()}"
1009
- @keydown="${(x, c) => x._handleCellKeydown(
1081
+ <${tooltipTag} placement="top"
1082
+ text="${(x) => x.locale.colorPicker.saveButtonLabel}"
1083
+ exportparts="vvd-theme-alternate">
1084
+ <${buttonTag}
1085
+ slot="anchor"
1086
+ appearance="outlined"
1087
+ size="super-condensed"
1088
+ role="gridcell"
1089
+ tabindex="${(x) => x.allSwatches.length ? "-1" : "0"}"
1090
+ aria-label="${(x) => x.locale.colorPicker.saveButtonLabel}"
1091
+ @click="${(x) => x._saveCurrentColor()}"
1092
+ @keydown="${(x, c) => x._handleCellKeydown(
1010
1093
  c.event,
1011
1094
  x.value,
1012
1095
  x.allSwatches.length,
1013
1096
  true
1014
1097
  )}">
1015
- >
1016
- <${iconTag} slot="icon" name="plus-line"></${iconTag}>
1017
- </${buttonTag}>
1018
- `
1098
+ <${iconTag} slot="icon" name="plus-line"></${iconTag}>
1099
+ </${buttonTag}>
1100
+ </${tooltipTag}>
1101
+ `
1019
1102
  )}
1020
1103
  </div>
1021
1104
  </div>
1022
1105
  `;
1023
1106
  }
1107
+ function renderSwatchesCount() {
1108
+ return html`
1109
+ <span
1110
+ id="swatches-count"
1111
+ class="swatches-count"
1112
+ aria-label="${(x) => x.locale.colorPicker.maxSwatchesMessage(
1113
+ x.allSwatches.length,
1114
+ x.maxSwatches
1115
+ )}"
1116
+ >${(x) => `${x.allSwatches.length}/${x.maxSwatches}`}</span
1117
+ >
1118
+ `;
1119
+ }
1024
1120
  const ColorPickerTemplate = (context) => {
1025
1121
  const textFieldTag = context.tagFor(TextField);
1026
1122
  const iconTag = context.tagFor(Icon);
1027
1123
  const popupTag = context.tagFor(Popup);
1028
1124
  const buttonTag = context.tagFor(Button);
1125
+ const tooltipTag = context.tagFor(Tooltip);
1029
1126
  return html`
1030
- <div class="base">
1127
+ <div class="base" @keydown="${(x, { event }) => x._onBaseKeydown(event)}">
1128
+ <span aria-live="assertive" aria-relevant="text" class="visually-hidden">
1129
+ ${(x) => x._ariaLiveDescription}
1130
+ </span>
1031
1131
  ${renderTextField(textFieldTag, iconTag)}
1032
1132
  <${popupTag}
1033
1133
  :open="${(x) => x.open}"
@@ -1040,10 +1140,10 @@ const ColorPickerTemplate = (context) => {
1040
1140
  aria-modal="true"
1041
1141
  aria-labelledby="color-picker-title">
1042
1142
  ${renderPopupHeader(buttonTag, iconTag)}
1043
- ${renderPopupBody(buttonTag, iconTag)}
1143
+ ${renderPopupBody(buttonTag, iconTag, tooltipTag)}
1044
1144
  ${when(
1045
1145
  (x) => !x.disableSavedColors || x.allSwatches.length > 0,
1046
- renderPopupFooter(buttonTag, iconTag)
1146
+ renderPopupFooter(buttonTag, iconTag, tooltipTag)
1047
1147
  )}
1048
1148
  </div>
1049
1149
  </${popupTag}>
@@ -1060,6 +1160,7 @@ const colorPickerDefinition = defineVividComponent(
1060
1160
  iconDefinition,
1061
1161
  textFieldDefinition,
1062
1162
  buttonDefinition,
1163
+ tooltipDefinition,
1063
1164
  feedbackMessageDefinition
1064
1165
  ],
1065
1166
  {