@prolibu-suite/cobalt-core 0.9.6 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (635) hide show
  1. package/custom-elements.json +1125 -89
  2. package/dist/cjs/co-accordion.cjs.entry.js +5 -5
  3. package/dist/cjs/co-action-bar.cjs.entry.js +2 -2
  4. package/dist/cjs/co-app-shell.cjs.entry.js +4 -4
  5. package/dist/cjs/co-audio-player.cjs.entry.js +83 -13
  6. package/dist/cjs/co-autocomplete.cjs.entry.js +2 -2
  7. package/dist/cjs/co-avatar-group.cjs.entry.js +1 -1
  8. package/dist/cjs/co-avatar.cjs.entry.js +72 -0
  9. package/dist/cjs/co-badge.cjs.entry.js +11 -3
  10. package/dist/cjs/co-bottom-sheet.cjs.entry.js +1 -1
  11. package/dist/cjs/co-breadcrumb-item.cjs.entry.js +1 -1
  12. package/dist/cjs/co-breadcrumb.cjs.entry.js +1 -1
  13. package/dist/cjs/co-button-group.cjs.entry.js +1 -1
  14. package/dist/cjs/co-button.cjs.entry.js +2 -2
  15. package/dist/cjs/co-calendar-month_2.cjs.entry.js +55 -20
  16. package/dist/cjs/co-calendar_3.cjs.entry.js +27 -15
  17. package/dist/cjs/co-card.cjs.entry.js +1 -1
  18. package/dist/cjs/co-carousel-item.cjs.entry.js +1 -1
  19. package/dist/cjs/co-carousel.cjs.entry.js +2 -2
  20. package/dist/cjs/co-checkbox-group.cjs.entry.js +2 -2
  21. package/dist/cjs/co-checkbox.cjs.entry.js +6 -6
  22. package/dist/cjs/co-chip_2.cjs.entry.js +68 -13
  23. package/dist/cjs/co-color-picker.cjs.entry.js +1078 -27
  24. package/dist/cjs/co-column-picker.cjs.entry.js +3 -3
  25. package/dist/cjs/co-combobox.cjs.entry.js +2 -2
  26. package/dist/cjs/co-command-search.cjs.entry.js +1 -1
  27. package/dist/cjs/co-data-table-pagination.cjs.entry.js +5 -5
  28. package/dist/cjs/co-data-table.cjs.entry.js +83 -5
  29. package/dist/cjs/co-date-picker.cjs.entry.js +3 -3
  30. package/dist/cjs/co-date-range-picker.cjs.entry.js +3 -3
  31. package/dist/cjs/co-date-range.cjs.entry.js +2 -2
  32. package/dist/cjs/co-date-time-picker.cjs.entry.js +101 -130
  33. package/dist/cjs/co-drive-card.cjs.entry.js +2 -2
  34. package/dist/cjs/co-drop-zone.cjs.entry.js +2 -2
  35. package/dist/cjs/co-emoji-picker.cjs.entry.js +4 -4
  36. package/dist/cjs/co-empty-state.cjs.entry.js +4 -4
  37. package/dist/cjs/co-event-calendar.cjs.entry.js +4 -4
  38. package/dist/cjs/co-event-popover.cjs.entry.js +3 -3
  39. package/dist/cjs/co-fab.cjs.entry.js +3 -3
  40. package/dist/cjs/co-file-field.cjs.entry.js +102 -106
  41. package/dist/cjs/co-file-type-tile.cjs.entry.js +3 -3
  42. package/dist/cjs/co-helper-text.cjs.entry.js +3 -3
  43. package/dist/cjs/co-icon-button.cjs.entry.js +6 -6
  44. package/dist/cjs/co-icon.cjs.entry.js +3 -3
  45. package/dist/cjs/co-input.cjs.entry.js +32 -6
  46. package/dist/cjs/co-json-field.cjs.entry.js +5 -5
  47. package/dist/cjs/co-lightbox.cjs.entry.js +204 -21
  48. package/dist/cjs/co-list-footer.cjs.entry.js +2 -2
  49. package/dist/cjs/co-list-item.cjs.entry.js +5 -5
  50. package/dist/cjs/co-loader.cjs.entry.js +1 -1
  51. package/dist/cjs/co-media-thumb.cjs.entry.js +3 -3
  52. package/dist/cjs/co-menu-divider.cjs.entry.js +2 -2
  53. package/dist/cjs/co-menu-item.cjs.entry.js +85 -4
  54. package/dist/cjs/co-menu.cjs.entry.js +2 -2
  55. package/dist/cjs/co-modal.cjs.entry.js +10 -4
  56. package/dist/cjs/co-navbar.cjs.entry.js +4 -4
  57. package/dist/cjs/co-number-field.cjs.entry.js +272 -9
  58. package/dist/cjs/co-overlay.cjs.entry.js +6 -4
  59. package/dist/cjs/co-page-header.cjs.entry.js +2 -2
  60. package/dist/cjs/co-phone-field.cjs.entry.js +3 -3
  61. package/dist/cjs/co-popover.cjs.entry.js +58 -21
  62. package/dist/cjs/co-progress-bar.cjs.entry.js +3 -3
  63. package/dist/cjs/co-progress-circle.cjs.entry.js +3 -3
  64. package/dist/cjs/co-provider-logo_2.cjs.entry.js +47 -3
  65. package/dist/cjs/co-radio-group.cjs.entry.js +1 -1
  66. package/dist/cjs/co-radio.cjs.entry.js +4 -4
  67. package/dist/cjs/co-rating.cjs.entry.js +4 -4
  68. package/dist/cjs/co-ref-field.cjs.entry.js +104 -13
  69. package/dist/cjs/co-rich-text-editor.cjs.entry.js +11 -8
  70. package/dist/cjs/co-rich-text-toolbar.cjs.entry.js +7 -3
  71. package/dist/cjs/co-rich-text-viewer.cjs.entry.js +4 -3
  72. package/dist/cjs/co-row.cjs.entry.js +3 -3
  73. package/dist/cjs/co-segmented-bar.cjs.entry.js +1 -1
  74. package/dist/cjs/co-select.cjs.entry.js +6 -6
  75. package/dist/cjs/co-separator.cjs.entry.js +2 -2
  76. package/dist/cjs/co-sidebar-nav.cjs.entry.js +2 -2
  77. package/dist/cjs/co-sidebar.cjs.entry.js +3 -3
  78. package/dist/cjs/co-slider.cjs.entry.js +3 -3
  79. package/dist/cjs/co-switch.cjs.entry.js +6 -6
  80. package/dist/cjs/co-tab-group.cjs.entry.js +3 -3
  81. package/dist/cjs/co-tab.cjs.entry.js +3 -3
  82. package/dist/cjs/co-tags-field.cjs.entry.js +8 -8
  83. package/dist/cjs/co-textarea.cjs.entry.js +6 -6
  84. package/dist/cjs/co-time-field.cjs.entry.js +325 -0
  85. package/dist/cjs/co-toast.cjs.entry.js +2 -2
  86. package/dist/cjs/co-toggle-button-group.cjs.entry.js +4 -4
  87. package/dist/cjs/co-toggle-button.cjs.entry.js +4 -4
  88. package/dist/cjs/{co-avatar_2.cjs.entry.js → co-tooltip.cjs.entry.js} +48 -84
  89. package/dist/cjs/co-transfer-list.cjs.entry.js +1 -1
  90. package/dist/cjs/co-video.cjs.entry.js +32 -7
  91. package/dist/cjs/cobalt.cjs.js +2 -2
  92. package/dist/cjs/color-CML2Cfdh.js +142 -0
  93. package/dist/cjs/{dateI18n-wblvKRq_.js → dateI18n-BK2qHqoC.js} +36 -0
  94. package/dist/cjs/{fieldChip-BLzo9MEV.js → fieldChip-B6YIGU1V.js} +1 -1
  95. package/dist/cjs/fileI18n-6sdbKvo6.js +88 -0
  96. package/dist/cjs/{index-DFZ5YhIT.js → index-BYwrR87Z.js} +28 -10
  97. package/dist/cjs/{index-DK-2Lzmf.js → index-MDAnKsze.js} +35 -27
  98. package/dist/cjs/loader.cjs.js +2 -2
  99. package/dist/cjs/{positioning-DCj_AJ2T.js → positioning-CyatXeT_.js} +32 -13
  100. package/dist/cjs/{requiredMark-C1xcrzSZ.js → requiredMark-D-t-IPN0.js} +1 -1
  101. package/dist/cjs/{toolbar-config-BQfWTW6P.js → toolbar-config-BSGas-Wl.js} +10 -0
  102. package/dist/cobalt/cobalt.css +1 -1
  103. package/dist/cobalt/cobalt.esm.js +1 -1
  104. package/dist/cobalt/{p-bfc2a849.entry.js → p-000a15b8.entry.js} +1 -1
  105. package/dist/cobalt/{p-f83b48fd.entry.js → p-011dc80b.entry.js} +1 -1
  106. package/dist/cobalt/{p-316c62c0.entry.js → p-0678c797.entry.js} +1 -1
  107. package/dist/cobalt/{p-43bd298d.entry.js → p-08e42e00.entry.js} +1 -1
  108. package/dist/cobalt/{p-0e91e5c4.entry.js → p-148d4aa6.entry.js} +1 -1
  109. package/dist/cobalt/{p-07d570a6.entry.js → p-16954cea.entry.js} +1 -1
  110. package/dist/cobalt/{p-d40a465f.entry.js → p-16f8cee6.entry.js} +1 -1
  111. package/dist/cobalt/{p-85a61e28.entry.js → p-17244412.entry.js} +1 -1
  112. package/dist/cobalt/{p-da546d08.entry.js → p-1dc55e43.entry.js} +1 -1
  113. package/dist/cobalt/p-239c5c5f.entry.js +1 -0
  114. package/dist/cobalt/{p-4c7e3984.entry.js → p-23ab0cc5.entry.js} +1 -1
  115. package/dist/cobalt/{p-fabe5fb2.entry.js → p-2636b7eb.entry.js} +1 -1
  116. package/dist/cobalt/{p-88a0659f.entry.js → p-27a7e549.entry.js} +1 -1
  117. package/dist/cobalt/{p-dca4cd5f.entry.js → p-28764b8e.entry.js} +1 -1
  118. package/dist/cobalt/{p-18d34b01.entry.js → p-290066ef.entry.js} +1 -1
  119. package/dist/cobalt/p-2a30c143.entry.js +1 -0
  120. package/dist/cobalt/p-2f0f3bb1.entry.js +1 -0
  121. package/dist/cobalt/{p-89e38c5e.entry.js → p-2f9cbbd5.entry.js} +1 -1
  122. package/dist/cobalt/p-2fba312b.entry.js +1 -0
  123. package/dist/cobalt/p-354d5089.entry.js +1 -0
  124. package/dist/cobalt/{p-60cb66f5.entry.js → p-37f5036b.entry.js} +1 -1
  125. package/dist/cobalt/{p-ac91259e.entry.js → p-383a998e.entry.js} +1 -1
  126. package/dist/cobalt/{p-ef5e1167.entry.js → p-3c4f7026.entry.js} +1 -1
  127. package/dist/cobalt/p-410bee4d.entry.js +1 -0
  128. package/dist/cobalt/p-416795f5.entry.js +1 -0
  129. package/dist/cobalt/{p-6795a258.entry.js → p-44c4e4a3.entry.js} +1 -1
  130. package/dist/cobalt/{p-4b083da4.entry.js → p-44ea675f.entry.js} +1 -1
  131. package/dist/cobalt/{p-2828ecf6.entry.js → p-4592ca00.entry.js} +1 -1
  132. package/dist/cobalt/{p-342e1da4.entry.js → p-4d65e713.entry.js} +1 -1
  133. package/dist/cobalt/p-56551580.entry.js +1 -0
  134. package/dist/cobalt/p-58137c9e.entry.js +1 -0
  135. package/dist/cobalt/{p-4f754c9a.entry.js → p-58d9b650.entry.js} +1 -1
  136. package/dist/cobalt/p-59963937.entry.js +1 -0
  137. package/dist/cobalt/p-5a3e4c81.entry.js +1 -0
  138. package/dist/cobalt/p-5adf117c.entry.js +1 -0
  139. package/dist/cobalt/{p-23b3ff3f.entry.js → p-5ca394b1.entry.js} +1 -1
  140. package/dist/cobalt/p-5e4973a6.entry.js +1 -0
  141. package/dist/cobalt/{p-2d329ac8.entry.js → p-623cc195.entry.js} +1 -1
  142. package/dist/cobalt/{p-8e667eb6.entry.js → p-66b11b38.entry.js} +1 -1
  143. package/dist/cobalt/{p-7e53e9c8.entry.js → p-6c82a892.entry.js} +1 -1
  144. package/dist/cobalt/{p-a6357340.entry.js → p-76249983.entry.js} +1 -1
  145. package/dist/cobalt/{p-568cfe8d.entry.js → p-789c4b3e.entry.js} +1 -1
  146. package/dist/cobalt/p-7e8e6907.entry.js +1 -0
  147. package/dist/cobalt/{p-a9b29cc2.entry.js → p-826ee074.entry.js} +1 -1
  148. package/dist/cobalt/{p-1c68bc41.entry.js → p-8471abe2.entry.js} +1 -1
  149. package/dist/cobalt/p-8f2199ff.entry.js +1 -0
  150. package/dist/cobalt/{p-c8dba82f.entry.js → p-91e73a92.entry.js} +1 -1
  151. package/dist/cobalt/p-9246e09c.entry.js +1 -0
  152. package/dist/cobalt/{p-c1e7fb32.entry.js → p-93fe45fd.entry.js} +1 -1
  153. package/dist/cobalt/{p-8f38e24d.entry.js → p-95cfcb34.entry.js} +1 -1
  154. package/dist/cobalt/{p-36197363.entry.js → p-996f4e38.entry.js} +1 -1
  155. package/dist/cobalt/{p-c5684c79.entry.js → p-9cf738ed.entry.js} +1 -1
  156. package/dist/cobalt/p-BRbgGqLw.js +1 -0
  157. package/dist/cobalt/{p-BL0sCfMH.js → p-Bryf3-Js.js} +1 -1
  158. package/dist/cobalt/p-DFHRS9cJ.js +1 -0
  159. package/dist/cobalt/{p-CrtiywTB.js → p-DH5lfRNj.js} +1 -1
  160. package/dist/{components/p-WeuPA9Rw.js → cobalt/p-DOL2zACE.js} +1 -1
  161. package/dist/cobalt/p-D_zA1Pv4.js +1 -0
  162. package/dist/cobalt/p-a2462d7a.entry.js +1 -0
  163. package/dist/cobalt/p-a325ea0c.entry.js +1 -0
  164. package/dist/cobalt/{p-fef5db54.entry.js → p-a32b20eb.entry.js} +1 -1
  165. package/dist/cobalt/p-aa9400bf.entry.js +1 -0
  166. package/dist/cobalt/{p-8eb485c8.entry.js → p-aaca6dab.entry.js} +1 -1
  167. package/dist/cobalt/p-b0c4fc71.entry.js +1 -0
  168. package/dist/cobalt/p-b5bba7fe.entry.js +1 -0
  169. package/dist/cobalt/{p-fb3a095b.entry.js → p-b821d9de.entry.js} +1 -1
  170. package/dist/cobalt/{p-b0319a2d.entry.js → p-b90d41e4.entry.js} +1 -1
  171. package/dist/cobalt/{p-ac466658.entry.js → p-be34e447.entry.js} +1 -1
  172. package/dist/cobalt/{p-1ddbc48b.entry.js → p-c124e82b.entry.js} +1 -1
  173. package/dist/cobalt/{p-95efe661.entry.js → p-c2ebf0ec.entry.js} +1 -1
  174. package/dist/cobalt/{p-54ae807d.entry.js → p-c465d619.entry.js} +1 -1
  175. package/dist/cobalt/p-c7d7d7f7.entry.js +1 -0
  176. package/dist/cobalt/{p-ab45d9bd.entry.js → p-c91d4fc6.entry.js} +1 -1
  177. package/dist/cobalt/{p-e5495539.entry.js → p-d0b2c418.entry.js} +1 -1
  178. package/dist/cobalt/{p-ce35c898.entry.js → p-d29bb0fa.entry.js} +1 -1
  179. package/dist/cobalt/{p-33ea4a90.entry.js → p-d3344187.entry.js} +1 -1
  180. package/dist/cobalt/p-d375014b.entry.js +1 -0
  181. package/dist/cobalt/p-d9d9e8ae.entry.js +1 -0
  182. package/dist/cobalt/{p-7c5e846a.entry.js → p-db805569.entry.js} +1 -1
  183. package/dist/cobalt/p-e371ec7a.entry.js +1 -0
  184. package/dist/cobalt/p-e3aae282.entry.js +1 -0
  185. package/dist/cobalt/{p-d15d3a97.entry.js → p-e4264532.entry.js} +1 -1
  186. package/dist/cobalt/{p-3f0eed59.entry.js → p-e49a564c.entry.js} +1 -1
  187. package/dist/cobalt/p-e8a2f993.entry.js +1 -0
  188. package/dist/cobalt/p-eadfd661.entry.js +1 -0
  189. package/dist/cobalt/p-eb82358d.entry.js +1 -0
  190. package/dist/cobalt/{p-2114c036.entry.js → p-eb8691f2.entry.js} +1 -1
  191. package/dist/cobalt/{p-e8878cf9.entry.js → p-ee2023da.entry.js} +1 -1
  192. package/dist/cobalt/p-ee9a623d.entry.js +1 -0
  193. package/dist/cobalt/p-ef301976.entry.js +1 -0
  194. package/dist/cobalt/p-f4e1c3c3.entry.js +1 -0
  195. package/dist/cobalt/{p-e364b8a5.entry.js → p-f57dffca.entry.js} +1 -1
  196. package/dist/cobalt/p-f6691108.entry.js +1 -0
  197. package/dist/cobalt/p-fMqVDypp.js +1 -0
  198. package/dist/cobalt/p-fb2d1144.entry.js +1 -0
  199. package/dist/cobalt/{p-0c463d9a.entry.js → p-fd150cc6.entry.js} +1 -1
  200. package/dist/cobalt/p-gKnOhsd2.js +1 -0
  201. package/dist/cobalt/p-jYd9gu_c.js +1 -0
  202. package/dist/collection/collection-manifest.json +1 -0
  203. package/dist/collection/components/co-accordion/co-accordion.css +2 -2
  204. package/dist/collection/components/co-accordion/co-accordion.js +4 -4
  205. package/dist/collection/components/co-action-bar/co-action-bar.css +9 -2
  206. package/dist/collection/components/co-app-shell/co-app-shell.css +107 -41
  207. package/dist/collection/components/co-app-shell/co-app-shell.js +2 -2
  208. package/dist/collection/components/co-audio-player/co-audio-player.js +138 -12
  209. package/dist/collection/components/co-autocomplete/co-autocomplete.js +1 -1
  210. package/dist/collection/components/co-avatar-group/co-avatar-group.js +1 -1
  211. package/dist/collection/components/co-badge/co-badge.css +18 -0
  212. package/dist/collection/components/co-badge/co-badge.js +29 -1
  213. package/dist/collection/components/co-button/co-button.css +10 -7
  214. package/dist/collection/components/co-checkbox/co-checkbox.css +12 -3
  215. package/dist/collection/components/co-checkbox/co-checkbox.js +25 -6
  216. package/dist/collection/components/co-checkbox-group/co-checkbox-group.css +1 -3
  217. package/dist/collection/components/co-checkbox-group/co-checkbox-group.js +1 -1
  218. package/dist/collection/components/co-color-picker/co-color-picker.css +252 -5
  219. package/dist/collection/components/co-color-picker/co-color-picker.js +962 -15
  220. package/dist/collection/components/co-color-picker/presets.js +113 -15
  221. package/dist/collection/components/co-column-picker/co-column-picker.js +2 -2
  222. package/dist/collection/components/co-combobox/co-combobox.js +1 -1
  223. package/dist/collection/components/co-command-search/co-command-search.js +1 -1
  224. package/dist/collection/components/co-data-table/co-data-table.css +63 -2
  225. package/dist/collection/components/co-data-table/co-data-table.js +59 -4
  226. package/dist/collection/components/co-data-table/headerTruncationLogic.js +34 -0
  227. package/dist/collection/components/co-data-table-pagination/co-data-table-pagination.js +4 -4
  228. package/dist/collection/components/co-date-field/co-date-field.js +4 -4
  229. package/dist/collection/components/co-date-range/co-date-range.js +1 -1
  230. package/dist/collection/components/co-date-range-picker/co-date-range-picker.js +2 -2
  231. package/dist/collection/components/co-date-time-picker/co-date-time-picker.css +128 -32
  232. package/dist/collection/components/co-date-time-picker/co-date-time-picker.js +142 -138
  233. package/dist/collection/components/co-drawer/co-drawer.css +99 -36
  234. package/dist/collection/components/co-drawer/co-drawer.js +19 -7
  235. package/dist/collection/components/co-drive-card/co-drive-card.js +1 -1
  236. package/dist/collection/components/co-drop-zone/co-drop-zone.js +1 -1
  237. package/dist/collection/components/co-emoji-picker/co-emoji-picker.js +2 -2
  238. package/dist/collection/components/co-empty-state/co-empty-state.css +28 -0
  239. package/dist/collection/components/co-empty-state/co-empty-state.js +2 -2
  240. package/dist/collection/components/co-event-calendar/co-event-calendar.js +2 -2
  241. package/dist/collection/components/co-event-popover/co-event-popover.js +1 -1
  242. package/dist/collection/components/co-fab/co-fab.js +2 -2
  243. package/dist/collection/components/co-file-field/co-file-field.css +55 -2
  244. package/dist/collection/components/co-file-field/co-file-field.js +41 -13
  245. package/dist/collection/components/co-file-field/co-file-field.utils.js +51 -4
  246. package/dist/collection/components/co-file-type-tile/co-file-type-tile.js +2 -2
  247. package/dist/collection/components/co-helper-text/co-helper-text.js +2 -2
  248. package/dist/collection/components/co-icon/co-icon.js +2 -2
  249. package/dist/collection/components/co-icon-button/co-icon-button.css +40 -2
  250. package/dist/collection/components/co-icon-button/co-icon-button.js +43 -4
  251. package/dist/collection/components/co-input/co-input.css +33 -0
  252. package/dist/collection/components/co-input/co-input.js +42 -7
  253. package/dist/collection/components/co-json-field/co-json-field.js +3 -3
  254. package/dist/collection/components/co-lightbox/co-lightbox.css +23 -0
  255. package/dist/collection/components/co-lightbox/co-lightbox.js +209 -20
  256. package/dist/collection/components/co-list-footer/co-list-footer.js +1 -1
  257. package/dist/collection/components/co-list-item/co-list-item.js +4 -4
  258. package/dist/collection/components/co-media-thumb/co-media-thumb.js +2 -2
  259. package/dist/collection/components/co-menu/co-menu.js +1 -1
  260. package/dist/collection/components/co-menu-divider/co-menu-divider.js +1 -1
  261. package/dist/collection/components/co-menu-item/co-menu-item.css +9 -0
  262. package/dist/collection/components/co-menu-item/co-menu-item.js +67 -3
  263. package/dist/collection/components/co-modal/co-modal.css +112 -37
  264. package/dist/collection/components/co-modal/co-modal.js +35 -2
  265. package/dist/collection/components/co-navbar/co-navbar.css +4 -2
  266. package/dist/collection/components/co-navbar/co-navbar.js +2 -2
  267. package/dist/collection/components/co-number-field/co-number-field.css +22 -0
  268. package/dist/collection/components/co-number-field/co-number-field.js +216 -9
  269. package/dist/collection/components/co-option-list/co-option-list.css +25 -4
  270. package/dist/collection/components/co-option-list/co-option-list.js +56 -4
  271. package/dist/collection/components/co-option-list/optionListLogic.js +31 -8
  272. package/dist/collection/components/co-overlay/co-overlay.js +5 -3
  273. package/dist/collection/components/co-page-header/co-page-header.js +1 -1
  274. package/dist/collection/components/co-phone-field/co-phone-field.js +1 -1
  275. package/dist/collection/components/co-popover/co-popover.css +18 -3
  276. package/dist/collection/components/co-popover/co-popover.js +83 -20
  277. package/dist/collection/components/co-progress-bar/co-progress-bar.js +2 -2
  278. package/dist/collection/components/co-progress-circle/co-progress-circle.js +2 -2
  279. package/dist/collection/components/co-radio/co-radio.js +3 -3
  280. package/dist/collection/components/co-radio-group/co-radio-group.js +1 -1
  281. package/dist/collection/components/co-rating/co-rating.js +3 -3
  282. package/dist/collection/components/co-ref-field/co-ref-field.css +40 -0
  283. package/dist/collection/components/co-ref-field/co-ref-field.js +207 -11
  284. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.css +14 -1
  285. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.js +9 -6
  286. package/dist/collection/components/co-rich-text-toolbar/co-rich-text-toolbar.js +7 -3
  287. package/dist/collection/components/co-rich-text-viewer/co-rich-text-viewer.js +3 -2
  288. package/dist/collection/components/co-row/co-row.js +2 -2
  289. package/dist/collection/components/co-segmented-bar/co-segmented-bar.js +1 -1
  290. package/dist/collection/components/co-select/co-select.js +24 -5
  291. package/dist/collection/components/co-separator/co-separator.js +1 -1
  292. package/dist/collection/components/co-sidebar/co-sidebar.js +2 -2
  293. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.css +2 -2
  294. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.js +1 -1
  295. package/dist/collection/components/co-skeleton/co-skeleton.css +18 -0
  296. package/dist/collection/components/co-skeleton/co-skeleton.js +83 -1
  297. package/dist/collection/components/co-slider/co-slider.js +2 -2
  298. package/dist/collection/components/co-switch/co-switch.css +3 -3
  299. package/dist/collection/components/co-switch/co-switch.js +3 -3
  300. package/dist/collection/components/co-tab/co-tab.js +2 -2
  301. package/dist/collection/components/co-tab-group/co-tab-group.js +2 -2
  302. package/dist/collection/components/co-tags-field/co-tags-field.js +5 -5
  303. package/dist/collection/components/co-textarea/co-textarea.js +4 -4
  304. package/dist/collection/components/co-time-field/co-time-field.css +111 -0
  305. package/dist/collection/components/co-time-field/co-time-field.js +536 -0
  306. package/dist/collection/components/co-toast/co-toast.css +13 -7
  307. package/dist/collection/components/co-toast/co-toast.js +2 -2
  308. package/dist/collection/components/co-toggle-button/co-toggle-button.css +20 -14
  309. package/dist/collection/components/co-toggle-button/co-toggle-button.js +2 -2
  310. package/dist/collection/components/co-toggle-button-group/co-toggle-button-group.css +14 -4
  311. package/dist/collection/components/co-toggle-button-group/co-toggle-button-group.js +2 -2
  312. package/dist/collection/components/co-tooltip/co-tooltip.css +12 -1
  313. package/dist/collection/components/co-tooltip/co-tooltip.js +49 -16
  314. package/dist/collection/components/co-transfer-list/co-transfer-list.js +1 -1
  315. package/dist/collection/components/co-video/co-video.js +34 -9
  316. package/dist/collection/utils/amountText.js +95 -0
  317. package/dist/collection/utils/color.js +109 -3
  318. package/dist/collection/utils/colorPickerI18n.js +55 -0
  319. package/dist/collection/utils/dateI18n.js +36 -0
  320. package/dist/collection/utils/fileI18n.js +3 -0
  321. package/dist/collection/utils/positioning.js +37 -4
  322. package/dist/collection/utils/submenu.js +35 -0
  323. package/dist/components/co-accordion.js +1 -1
  324. package/dist/components/co-action-bar.js +1 -1
  325. package/dist/components/co-app-shell.js +1 -1
  326. package/dist/components/co-audio-player.js +1 -1
  327. package/dist/components/co-autocomplete.js +1 -1
  328. package/dist/components/co-avatar-group.js +1 -1
  329. package/dist/components/co-avatar.js +1 -1
  330. package/dist/components/co-badge.js +1 -1
  331. package/dist/components/co-breadcrumb-item.js +1 -1
  332. package/dist/components/co-breadcrumb.js +1 -1
  333. package/dist/components/co-button.js +1 -1
  334. package/dist/components/co-calendar-month.js +1 -1
  335. package/dist/components/co-calendar-timegrid.js +1 -1
  336. package/dist/components/co-calendar.js +1 -1
  337. package/dist/components/co-carousel.js +1 -1
  338. package/dist/components/co-checkbox-group.js +1 -1
  339. package/dist/components/co-checkbox.js +1 -1
  340. package/dist/components/co-chip.js +1 -1
  341. package/dist/components/co-color-picker.js +1 -1
  342. package/dist/components/co-column-picker.js +1 -1
  343. package/dist/components/co-combobox.js +1 -1
  344. package/dist/components/co-command-search.js +1 -1
  345. package/dist/components/co-data-table-pagination.js +1 -1
  346. package/dist/components/co-data-table.js +1 -1
  347. package/dist/components/co-date-field.js +1 -1
  348. package/dist/components/co-date-picker.js +1 -1
  349. package/dist/components/co-date-range-picker.js +1 -1
  350. package/dist/components/co-date-range.js +1 -1
  351. package/dist/components/co-date-time-picker.js +1 -1
  352. package/dist/components/co-drawer.js +1 -1
  353. package/dist/components/co-drive-card.js +1 -1
  354. package/dist/components/co-drop-zone.js +1 -1
  355. package/dist/components/co-emoji-picker.js +1 -1
  356. package/dist/components/co-empty-state.js +1 -1
  357. package/dist/components/co-event-calendar.js +1 -1
  358. package/dist/components/co-event-popover.js +1 -1
  359. package/dist/components/co-fab.js +1 -1
  360. package/dist/components/co-file-field.js +1 -1
  361. package/dist/components/co-file-type-tile.js +1 -1
  362. package/dist/components/co-helper-text.js +1 -1
  363. package/dist/components/co-icon-button.js +1 -1
  364. package/dist/components/co-icon.js +1 -1
  365. package/dist/components/co-input.js +1 -1
  366. package/dist/components/co-json-field.js +1 -1
  367. package/dist/components/co-lightbox.js +1 -1
  368. package/dist/components/co-list-footer.js +1 -1
  369. package/dist/components/co-list-item.js +1 -1
  370. package/dist/components/co-media-thumb.js +1 -1
  371. package/dist/components/co-menu-divider.js +1 -1
  372. package/dist/components/co-menu-item.js +1 -1
  373. package/dist/components/co-menu.js +1 -1
  374. package/dist/components/co-modal.js +1 -1
  375. package/dist/components/co-navbar.js +1 -1
  376. package/dist/components/co-number-field.js +1 -1
  377. package/dist/components/co-option-list.js +1 -1
  378. package/dist/components/co-overlay.js +1 -1
  379. package/dist/components/co-page-header.js +1 -1
  380. package/dist/components/co-phone-field.js +1 -1
  381. package/dist/components/co-popover.js +1 -1
  382. package/dist/components/co-progress-bar.js +1 -1
  383. package/dist/components/co-progress-circle.js +1 -1
  384. package/dist/components/co-radio-group.js +1 -1
  385. package/dist/components/co-radio.js +1 -1
  386. package/dist/components/co-rating.js +1 -1
  387. package/dist/components/co-ref-field.js +1 -1
  388. package/dist/components/co-rich-text-editor.js +1 -1
  389. package/dist/components/co-rich-text-toolbar.js +1 -1
  390. package/dist/components/co-rich-text-viewer.js +1 -1
  391. package/dist/components/co-row.js +1 -1
  392. package/dist/components/co-select.js +1 -1
  393. package/dist/components/co-separator.js +1 -1
  394. package/dist/components/co-sidebar-nav.js +1 -1
  395. package/dist/components/co-sidebar.js +1 -1
  396. package/dist/components/co-skeleton.js +1 -1
  397. package/dist/components/co-slider.js +1 -1
  398. package/dist/components/co-switch.js +1 -1
  399. package/dist/components/co-tab-group.js +1 -1
  400. package/dist/components/co-tab.js +1 -1
  401. package/dist/components/co-tags-field.js +1 -1
  402. package/dist/components/co-textarea.js +1 -1
  403. package/dist/components/co-time-field.d.ts +11 -0
  404. package/dist/components/co-time-field.js +1 -0
  405. package/dist/components/co-toast.js +1 -1
  406. package/dist/components/co-toggle-button-group.js +1 -1
  407. package/dist/components/co-toggle-button.js +1 -1
  408. package/dist/components/co-tooltip.js +1 -1
  409. package/dist/components/co-transfer-list.js +1 -1
  410. package/dist/components/co-video.js +1 -1
  411. package/dist/components/index.js +1 -1
  412. package/dist/components/p-7TncUlLN.js +1 -0
  413. package/dist/components/p-B4NCaKrR.js +1 -0
  414. package/dist/components/p-B9xitpGU.js +1 -0
  415. package/dist/components/{p-Dabi98BI.js → p-BGDqldEg.js} +1 -1
  416. package/dist/components/p-BRbgGqLw.js +1 -0
  417. package/dist/components/{p-BL0sCfMH.js → p-Bryf3-Js.js} +1 -1
  418. package/dist/components/{p-D6OUW6oW.js → p-CBTGN490.js} +1 -1
  419. package/dist/components/{p-P8wvwhM2.js → p-CFFDmGPS.js} +1 -1
  420. package/dist/components/p-CLsAo0-A.js +1 -0
  421. package/dist/components/{p-CA_JAK9s.js → p-CT2enQ6h.js} +1 -1
  422. package/dist/components/p-D2ldYZo1.js +1 -0
  423. package/dist/components/{p-CuZXTvDM.js → p-D3mVYO-G.js} +1 -1
  424. package/dist/components/p-DDV_bRcU.js +1 -0
  425. package/dist/components/p-DFHRS9cJ.js +1 -0
  426. package/dist/components/{p-Dj1EZ5qD.js → p-DNJAIVfI.js} +1 -1
  427. package/dist/{cobalt/p-WeuPA9Rw.js → components/p-DOL2zACE.js} +1 -1
  428. package/dist/components/p-DRP8D9ro.js +1 -0
  429. package/dist/components/p-DSnJWzQw.js +1 -0
  430. package/dist/components/p-DTi2O4O8.js +1 -0
  431. package/dist/components/p-De7w9k6_.js +1 -0
  432. package/dist/components/{p-D5EdMieb.js → p-DoHLTC0n.js} +1 -1
  433. package/dist/components/{p-Bxk96Zgc.js → p-Du_CgT5E.js} +1 -1
  434. package/dist/components/p-DxtNejr2.js +1 -0
  435. package/dist/components/{p-BHYtxTzM.js → p-HxVRXXXC.js} +1 -1
  436. package/dist/components/{p-B0Dc-I_C.js → p-NNxjElcX.js} +1 -1
  437. package/dist/components/p-gKnOhsd2.js +1 -0
  438. package/dist/components/p-jYd9gu_c.js +1 -0
  439. package/dist/components/{p-D4qzGifz.js → p-vby0ITbe.js} +1 -1
  440. package/dist/components/p-wjt4IAGZ.js +1 -0
  441. package/dist/components/p-zuhal3IZ.js +1 -0
  442. package/dist/esm/co-accordion.entry.js +5 -5
  443. package/dist/esm/co-action-bar.entry.js +2 -2
  444. package/dist/esm/co-app-shell.entry.js +4 -4
  445. package/dist/esm/co-audio-player.entry.js +83 -13
  446. package/dist/esm/co-autocomplete.entry.js +2 -2
  447. package/dist/esm/co-avatar-group.entry.js +1 -1
  448. package/dist/esm/co-avatar.entry.js +70 -0
  449. package/dist/esm/co-badge.entry.js +11 -3
  450. package/dist/esm/co-bottom-sheet.entry.js +1 -1
  451. package/dist/esm/co-breadcrumb-item.entry.js +1 -1
  452. package/dist/esm/co-breadcrumb.entry.js +1 -1
  453. package/dist/esm/co-button-group.entry.js +1 -1
  454. package/dist/esm/co-button.entry.js +2 -2
  455. package/dist/esm/co-calendar-month_2.entry.js +37 -2
  456. package/dist/esm/co-calendar_3.entry.js +27 -15
  457. package/dist/esm/co-card.entry.js +1 -1
  458. package/dist/esm/co-carousel-item.entry.js +1 -1
  459. package/dist/esm/co-carousel.entry.js +2 -2
  460. package/dist/esm/co-checkbox-group.entry.js +2 -2
  461. package/dist/esm/co-checkbox.entry.js +6 -6
  462. package/dist/esm/co-chip_2.entry.js +68 -13
  463. package/dist/esm/co-color-picker.entry.js +1078 -27
  464. package/dist/esm/co-column-picker.entry.js +3 -3
  465. package/dist/esm/co-combobox.entry.js +2 -2
  466. package/dist/esm/co-command-search.entry.js +1 -1
  467. package/dist/esm/co-data-table-pagination.entry.js +5 -5
  468. package/dist/esm/co-data-table.entry.js +83 -5
  469. package/dist/esm/co-date-picker.entry.js +3 -3
  470. package/dist/esm/co-date-range-picker.entry.js +3 -3
  471. package/dist/esm/co-date-range.entry.js +2 -2
  472. package/dist/esm/co-date-time-picker.entry.js +101 -130
  473. package/dist/esm/co-drive-card.entry.js +2 -2
  474. package/dist/esm/co-drop-zone.entry.js +2 -2
  475. package/dist/esm/co-emoji-picker.entry.js +4 -4
  476. package/dist/esm/co-empty-state.entry.js +4 -4
  477. package/dist/esm/co-event-calendar.entry.js +4 -4
  478. package/dist/esm/co-event-popover.entry.js +3 -3
  479. package/dist/esm/co-fab.entry.js +3 -3
  480. package/dist/esm/co-file-field.entry.js +95 -99
  481. package/dist/esm/co-file-type-tile.entry.js +3 -3
  482. package/dist/esm/co-helper-text.entry.js +3 -3
  483. package/dist/esm/co-icon-button.entry.js +6 -6
  484. package/dist/esm/co-icon.entry.js +3 -3
  485. package/dist/esm/co-input.entry.js +32 -6
  486. package/dist/esm/co-json-field.entry.js +5 -5
  487. package/dist/esm/co-lightbox.entry.js +204 -21
  488. package/dist/esm/co-list-footer.entry.js +2 -2
  489. package/dist/esm/co-list-item.entry.js +5 -5
  490. package/dist/esm/co-loader.entry.js +1 -1
  491. package/dist/esm/co-media-thumb.entry.js +3 -3
  492. package/dist/esm/co-menu-divider.entry.js +2 -2
  493. package/dist/esm/co-menu-item.entry.js +85 -4
  494. package/dist/esm/co-menu.entry.js +2 -2
  495. package/dist/esm/co-modal.entry.js +10 -4
  496. package/dist/esm/co-navbar.entry.js +4 -4
  497. package/dist/esm/co-number-field.entry.js +272 -9
  498. package/dist/esm/co-overlay.entry.js +6 -4
  499. package/dist/esm/co-page-header.entry.js +2 -2
  500. package/dist/esm/co-phone-field.entry.js +3 -3
  501. package/dist/esm/co-popover.entry.js +58 -21
  502. package/dist/esm/co-progress-bar.entry.js +3 -3
  503. package/dist/esm/co-progress-circle.entry.js +3 -3
  504. package/dist/esm/co-provider-logo_2.entry.js +47 -3
  505. package/dist/esm/co-radio-group.entry.js +1 -1
  506. package/dist/esm/co-radio.entry.js +4 -4
  507. package/dist/esm/co-rating.entry.js +4 -4
  508. package/dist/esm/co-ref-field.entry.js +104 -13
  509. package/dist/esm/co-rich-text-editor.entry.js +11 -8
  510. package/dist/esm/co-rich-text-toolbar.entry.js +7 -3
  511. package/dist/esm/co-rich-text-viewer.entry.js +4 -3
  512. package/dist/esm/co-row.entry.js +3 -3
  513. package/dist/esm/co-segmented-bar.entry.js +1 -1
  514. package/dist/esm/co-select.entry.js +6 -6
  515. package/dist/esm/co-separator.entry.js +2 -2
  516. package/dist/esm/co-sidebar-nav.entry.js +2 -2
  517. package/dist/esm/co-sidebar.entry.js +3 -3
  518. package/dist/esm/co-slider.entry.js +3 -3
  519. package/dist/esm/co-switch.entry.js +6 -6
  520. package/dist/esm/co-tab-group.entry.js +3 -3
  521. package/dist/esm/co-tab.entry.js +3 -3
  522. package/dist/esm/co-tags-field.entry.js +8 -8
  523. package/dist/esm/co-textarea.entry.js +6 -6
  524. package/dist/esm/co-time-field.entry.js +323 -0
  525. package/dist/esm/co-toast.entry.js +2 -2
  526. package/dist/esm/co-toggle-button-group.entry.js +4 -4
  527. package/dist/esm/co-toggle-button.entry.js +4 -4
  528. package/dist/esm/{co-avatar_2.entry.js → co-tooltip.entry.js} +49 -84
  529. package/dist/esm/co-transfer-list.entry.js +1 -1
  530. package/dist/esm/co-video.entry.js +32 -7
  531. package/dist/esm/cobalt.js +3 -3
  532. package/dist/esm/color-BRbgGqLw.js +136 -0
  533. package/dist/esm/{dateI18n-CnNpoKwg.js → dateI18n-jYd9gu_c.js} +36 -0
  534. package/dist/esm/{fieldChip-DsAfq1e0.js → fieldChip-uyggU8VV.js} +1 -1
  535. package/dist/esm/fileI18n-gKnOhsd2.js +84 -0
  536. package/dist/esm/{index-RuXxdKzC.js → index-68iUQp5j.js} +28 -10
  537. package/dist/esm/{index-CrtiywTB.js → index-DH5lfRNj.js} +35 -27
  538. package/dist/esm/loader.js +3 -3
  539. package/dist/esm/{positioning-BMdapAL8.js → positioning-DFHRS9cJ.js} +32 -13
  540. package/dist/esm/{requiredMark-DCD-ZA51.js → requiredMark-BCJUuZvC.js} +1 -1
  541. package/dist/esm/{toolbar-config-WeuPA9Rw.js → toolbar-config-DOL2zACE.js} +10 -0
  542. package/dist/types/components/co-accordion/co-accordion.d.ts +6 -0
  543. package/dist/types/components/co-audio-player/co-audio-player.d.ts +25 -0
  544. package/dist/types/components/co-badge/co-badge.d.ts +7 -0
  545. package/dist/types/components/co-checkbox/co-checkbox.d.ts +5 -1
  546. package/dist/types/components/co-color-picker/co-color-picker.d.ts +360 -4
  547. package/dist/types/components/co-color-picker/presets.d.ts +107 -4
  548. package/dist/types/components/co-data-table/co-data-table.d.ts +15 -0
  549. package/dist/types/components/co-data-table/headerTruncationLogic.d.ts +24 -0
  550. package/dist/types/components/co-date-time-picker/co-date-time-picker.d.ts +43 -21
  551. package/dist/types/components/co-drawer/co-drawer.d.ts +4 -3
  552. package/dist/types/components/co-file-field/co-file-field.d.ts +14 -0
  553. package/dist/types/components/co-file-field/co-file-field.utils.d.ts +18 -1
  554. package/dist/types/components/co-icon-button/co-icon-button.d.ts +9 -0
  555. package/dist/types/components/co-input/co-input.d.ts +9 -1
  556. package/dist/types/components/co-lightbox/co-lightbox.d.ts +60 -4
  557. package/dist/types/components/co-menu-item/co-menu-item.d.ts +16 -0
  558. package/dist/types/components/co-modal/co-modal.d.ts +10 -0
  559. package/dist/types/components/co-number-field/co-number-field.d.ts +42 -1
  560. package/dist/types/components/co-option-list/co-option-list.d.ts +16 -0
  561. package/dist/types/components/co-option-list/optionListLogic.d.ts +23 -6
  562. package/dist/types/components/co-overlay/co-overlay.d.ts +4 -2
  563. package/dist/types/components/co-popover/co-popover.d.ts +16 -0
  564. package/dist/types/components/co-ref-field/co-ref-field.d.ts +38 -0
  565. package/dist/types/components/co-rich-text-toolbar/co-rich-text-toolbar.d.ts +1 -1
  566. package/dist/types/components/co-select/co-select.d.ts +6 -0
  567. package/dist/types/components/co-skeleton/co-skeleton.d.ts +13 -0
  568. package/dist/types/components/co-time-field/co-time-field.d.ts +60 -0
  569. package/dist/types/components/co-tooltip/co-tooltip.d.ts +5 -0
  570. package/dist/types/components/co-video/co-video.d.ts +4 -0
  571. package/dist/types/components.d.ts +530 -90
  572. package/dist/types/utils/amountText.d.ts +34 -0
  573. package/dist/types/utils/color.d.ts +44 -1
  574. package/dist/types/utils/colorPickerI18n.d.ts +26 -0
  575. package/dist/types/utils/dateI18n.d.ts +12 -0
  576. package/dist/types/utils/fileI18n.d.ts +1 -0
  577. package/dist/types/utils/positioning.d.ts +10 -0
  578. package/dist/types/utils/submenu.d.ts +44 -0
  579. package/package.json +3 -3
  580. package/dist/cjs/color-YhUkm10t.js +0 -32
  581. package/dist/cjs/time-LBHtzLHe.js +0 -42
  582. package/dist/cobalt/p-07904986.entry.js +0 -1
  583. package/dist/cobalt/p-09799193.entry.js +0 -1
  584. package/dist/cobalt/p-17ae943c.entry.js +0 -1
  585. package/dist/cobalt/p-23a103a0.entry.js +0 -1
  586. package/dist/cobalt/p-2f88d151.entry.js +0 -1
  587. package/dist/cobalt/p-3495fda1.entry.js +0 -1
  588. package/dist/cobalt/p-409f28bb.entry.js +0 -1
  589. package/dist/cobalt/p-682b3313.entry.js +0 -1
  590. package/dist/cobalt/p-6bf814f9.entry.js +0 -1
  591. package/dist/cobalt/p-7532c739.entry.js +0 -1
  592. package/dist/cobalt/p-76420ac1.entry.js +0 -1
  593. package/dist/cobalt/p-7c88163e.entry.js +0 -1
  594. package/dist/cobalt/p-7cf4b4ae.entry.js +0 -1
  595. package/dist/cobalt/p-7ea87b75.entry.js +0 -1
  596. package/dist/cobalt/p-8183f56f.entry.js +0 -1
  597. package/dist/cobalt/p-8345b25f.entry.js +0 -1
  598. package/dist/cobalt/p-93c68029.entry.js +0 -1
  599. package/dist/cobalt/p-983af614.entry.js +0 -1
  600. package/dist/cobalt/p-BG4WRR22.js +0 -1
  601. package/dist/cobalt/p-BMdapAL8.js +0 -1
  602. package/dist/cobalt/p-CF8OB_TM.js +0 -1
  603. package/dist/cobalt/p-CnNpoKwg.js +0 -1
  604. package/dist/cobalt/p-T4la7ly_.js +0 -1
  605. package/dist/cobalt/p-a2d31248.entry.js +0 -1
  606. package/dist/cobalt/p-a6b5cadd.entry.js +0 -1
  607. package/dist/cobalt/p-a8c64cc3.entry.js +0 -1
  608. package/dist/cobalt/p-b8581787.entry.js +0 -1
  609. package/dist/cobalt/p-bcedbd73.entry.js +0 -1
  610. package/dist/cobalt/p-da18b5f4.entry.js +0 -1
  611. package/dist/cobalt/p-dea43204.entry.js +0 -1
  612. package/dist/cobalt/p-dfcf667d.entry.js +0 -1
  613. package/dist/cobalt/p-dfd25f1d.entry.js +0 -1
  614. package/dist/cobalt/p-e6882ddd.entry.js +0 -1
  615. package/dist/cobalt/p-e84eda2e.entry.js +0 -1
  616. package/dist/cobalt/p-f25967fb.entry.js +0 -1
  617. package/dist/cobalt/p-f5f1b463.entry.js +0 -1
  618. package/dist/cobalt/p-fd39f410.entry.js +0 -1
  619. package/dist/cobalt/p-mAGnZXRn.js +0 -1
  620. package/dist/components/p-BMdapAL8.js +0 -1
  621. package/dist/components/p-BTQEg3UO.js +0 -1
  622. package/dist/components/p-Bbny3WUc.js +0 -1
  623. package/dist/components/p-Bz0QZqnB.js +0 -1
  624. package/dist/components/p-CF8OB_TM.js +0 -1
  625. package/dist/components/p-CR0izsJC.js +0 -1
  626. package/dist/components/p-CnNpoKwg.js +0 -1
  627. package/dist/components/p-DI1ek0EB.js +0 -1
  628. package/dist/components/p-DP0bbhfN.js +0 -1
  629. package/dist/components/p-D_9BRkj6.js +0 -1
  630. package/dist/components/p-DbipMAyT.js +0 -1
  631. package/dist/components/p-DgUBcJIS.js +0 -1
  632. package/dist/components/p-DolCkNsL.js +0 -1
  633. package/dist/components/p-hfGFsvaD.js +0 -1
  634. package/dist/esm/color-BG4WRR22.js +0 -30
  635. package/dist/esm/time-CF8OB_TM.js +0 -37
@@ -1,32 +1,226 @@
1
- import { r as registerInstance, c as createEvent, h, a as getElement } from './index-CrtiywTB.js';
2
- import { R as RequiredMark } from './requiredMark-DCD-ZA51.js';
1
+ import { r as registerInstance, c as createEvent, h, a as getElement } from './index-DH5lfRNj.js';
2
+ import { R as RequiredMark } from './requiredMark-BCJUuZvC.js';
3
+ import { h as hsvToHex, a as isValidHex, p as parseCssColor, b as hexToHsv, i as isLightColor } from './color-BRbgGqLw.js';
4
+ import { l as langFromLocale, f as fillTemplate } from './fileI18n-gKnOhsd2.js';
3
5
 
4
6
  /**
5
- * Default color presets derived from Cobalt design tokens (base.json).
6
- * Uses primary colors + secondary-100 (full saturation, best contrast).
7
- * Names are English by default — consumers can override with translated presets.
7
+ * Textos de co-color-picker. Mismo patrón que fileI18n/dateI18n: el componente
8
+ * shipea es/en/pt keyado por la prop `locale`. Defaults en INGLÉS — un literal
9
+ * en español dentro de un co-* deja al host sin forma de traducirlo.
10
+ * Las plantillas usan `{n}` y se resuelven con `fillTemplate` de fileI18n
11
+ * (que ya existe exportado ahí: se reutiliza, no se duplica).
12
+ */
13
+ const DICT = {
14
+ en: {
15
+ swatches: 'Color presets',
16
+ groupNeutrals: 'Neutrals', groupBrand: 'Brand colors',
17
+ area: 'Saturation and brightness',
18
+ hue: 'Hue', hueValue: '{n} degrees',
19
+ saturation: 'Saturation', satValue: 'Saturation {n}%',
20
+ brightness: 'Brightness', briValue: 'Brightness {n}%',
21
+ area2D: '2D slider',
22
+ hexField: 'Hex code',
23
+ eyedropper: 'Pick a color from the screen',
24
+ copy: 'Copy',
25
+ },
26
+ es: {
27
+ swatches: 'Colores predefinidos',
28
+ groupNeutrals: 'Neutros', groupBrand: 'Colores de marca',
29
+ area: 'Saturación y brillo',
30
+ hue: 'Matiz', hueValue: '{n} grados',
31
+ saturation: 'Saturación', satValue: 'Saturación {n} %',
32
+ brightness: 'Brillo', briValue: 'Brillo {n} %',
33
+ area2D: 'Control 2D',
34
+ hexField: 'Código hexadecimal',
35
+ eyedropper: 'Elegir un color de la pantalla',
36
+ copy: 'Copiar',
37
+ },
38
+ pt: {
39
+ swatches: 'Cores predefinidas',
40
+ groupNeutrals: 'Neutros', groupBrand: 'Cores da marca',
41
+ area: 'Saturação e brilho',
42
+ hue: 'Matiz', hueValue: '{n} graus',
43
+ saturation: 'Saturação', satValue: 'Saturação {n} %',
44
+ brightness: 'Brilho', briValue: 'Brilho {n} %',
45
+ area2D: 'Controle 2D',
46
+ hexField: 'Código hexadecimal',
47
+ eyedropper: 'Escolher uma cor da tela',
48
+ copy: 'Copiar',
49
+ },
50
+ };
51
+ /**
52
+ * Resuelve los textos para un locale BCP-47. La resolución del idioma se
53
+ * reutiliza de `fileI18n` (mismo fallback a 'en'): tener dos implementaciones
54
+ * del mismo mapeo es exactamente la duplicación que el Step 0 vino a evitar
55
+ * cuando exigió reutilizar `fillTemplate` de ese archivo.
56
+ */
57
+ function getColorPickerStrings(locale) {
58
+ return DICT[langFromLocale(locale)];
59
+ }
60
+
61
+ /**
62
+ * Normaliza lo que llega por la prop `presets` a la forma interna, dejando
63
+ * anotado si la `key` vino declarada o se sintetizó.
64
+ *
65
+ * `ColorPreset.key` es OPCIONAL porque el tipo es superficie pública (lo
66
+ * re-exporta `components.d.ts`): exigirla rompería a todo host que hoy pasa
67
+ * `[{ name, value }]`. Puertas adentro la damos por garantizada, así que se
68
+ * rellena acá. Un hex suelto no tiene identidad traducible: su propio hex
69
+ * ES su identidad.
70
+ *
71
+ * Vive acá y no en el componente porque es el ÚNICO lugar que sintetiza keys, y
72
+ * `splitPaletteGroups` —su consumidor— depende de esa marca: separarlos deja el
73
+ * invariante a un import de distancia de romperse en silencio.
74
+ */
75
+ const resolvePreset = (p) => {
76
+ var _a;
77
+ if (typeof p === 'string')
78
+ return { key: p, name: p, value: p, synthesizedKey: true };
79
+ // La key declarada se conserva tal cual; si no vino, la cadena de siempre.
80
+ if (p.key != null)
81
+ return { key: p.key, name: p.name, value: p.value };
82
+ return { key: (_a = p.name) !== null && _a !== void 0 ? _a : p.value, name: p.name, value: p.value, synthesizedKey: true };
83
+ };
84
+ /**
85
+ * Paleta por default: 5 neutros + los 12 de marca (base.json).
86
+ * Los nombres vienen en inglés; el consumidor los traduce POR `key` — nunca
87
+ * duplicando la lista de valores, que fue lo que hizo derivar a FieldColor.vue.
88
+ *
89
+ * Sin blanco puro a propósito (spec §2): una etiqueta blanca desaparece sobre
90
+ * el fondo blanco. Los encabezados de documento lo pasan por la prop `presets`.
91
+ *
92
+ * Los hex son literales porque son DATA del picker, no estilo.
8
93
  */
9
94
  const DEFAULT_PRESETS = [
10
- { name: 'Green', value: '#02A270' },
11
- { name: 'Yellow', value: '#FDBF00' },
12
- { name: 'Blue', value: '#2563EB' },
13
- { name: 'Pink', value: '#F32A73' },
14
- { name: 'Red', value: '#EB1E1E' },
15
- { name: 'Orange', value: '#F0821E' },
16
- { name: 'Teal', value: '#00AFAF' },
17
- { name: 'Light blue', value: '#00BEE6' },
18
- { name: 'Electric blue', value: '#000AFF' },
19
- { name: 'Violet', value: '#5F4BD7' },
20
- { name: 'Burgundy', value: '#811137' },
21
- { name: 'Olive', value: '#AAB43C' },
95
+ { key: 'black', name: 'Black', value: '#1F1C1B' },
96
+ { key: 'gray', name: 'Gray', value: '#585858' },
97
+ { key: 'silver', name: 'Silver', value: '#C4C4C4' },
98
+ { key: 'smoke', name: 'Smoke', value: '#E3E3E3' },
99
+ { key: 'bone', name: 'Bone', value: '#F7F6F0' },
100
+ { key: 'green', name: 'Green', value: '#02A270' },
101
+ { key: 'olive', name: 'Olive', value: '#AAB43C' },
102
+ { key: 'yellow', name: 'Yellow', value: '#FDBF00' },
103
+ { key: 'orange', name: 'Orange', value: '#F0821E' },
104
+ { key: 'red', name: 'Red', value: '#EB1E1E' },
105
+ { key: 'pink', name: 'Pink', value: '#F32A73' },
106
+ { key: 'burgundy', name: 'Burgundy', value: '#811137' },
107
+ { key: 'violet', name: 'Violet', value: '#5F4BD7' },
108
+ { key: 'electricBlue', name: 'Electric blue', value: '#000AFF' },
109
+ { key: 'blue', name: 'Blue', value: '#2563EB' },
110
+ { key: 'lightBlue', name: 'Light blue', value: '#00BEE6' },
111
+ { key: 'teal', name: 'Teal', value: '#00AFAF' },
22
112
  ];
113
+ /**
114
+ * Los 5 primeros son neutros. Frontera ÚNICA: la grilla agrupa por acá y el
115
+ * seed sortea del resto. No repetir el `5` a mano en ningún otro lado.
116
+ */
117
+ const NEUTRAL_PRESET_KEYS = ['black', 'gray', 'silver', 'smoke', 'bone'];
118
+ /**
119
+ * Sólo las de marca, derivadas de la frontera. El seed aleatorio al CREAR un
120
+ * registro sortea de acá: nacer con una etiqueta gris es peor que el estado
121
+ * anterior.
122
+ */
123
+ const BRAND_PRESET_KEYS = DEFAULT_PRESETS
124
+ .filter((p) => !NEUTRAL_PRESET_KEYS.includes(p.key))
125
+ .map((p) => p.key);
126
+ // Índices de membresía, armados UNA vez a nivel de módulo: `splitPaletteGroups`
127
+ // corre en un getter que el render lee en cada pasada.
128
+ const NEUTRAL_KEYS = new Set(NEUTRAL_PRESET_KEYS);
129
+ const BRAND_KEYS = new Set(BRAND_PRESET_KEYS);
130
+ /**
131
+ * Parte una lista de presets en [neutros, marca], o devuelve `null` si no hay
132
+ * una partición que signifique algo.
133
+ *
134
+ * Se decide por MEMBRESÍA de `key`, nunca por identidad de referencia contra
135
+ * `DEFAULT_PRESETS`. La identidad es frágil por definición —dos arrays con el
136
+ * mismo contenido se comportan distinto— y ya costó un bug real: `FieldColor.vue`
137
+ * re-serializa la paleta para colgarle los nombres traducidos, así que llegaba
138
+ * como un array nuevo, caía en la rama "custom" y los `role="group"` +
139
+ * `aria-label` del spec §4 no se renderizaban NUNCA en la aplicación. La a11y
140
+ * existía sólo en los tests, que sí pasaban la paleta por identidad.
141
+ *
142
+ * Devuelve `null` en tres casos, y los tres terminan en un grupo único SIN
143
+ * rótulo:
144
+ * - alguna `key` la sintetizamos nosotros (`synthesizedKey`): el host no declaró
145
+ * nuestra paleta, y como doce de las keys son nombres de color CSS, mirar sólo
146
+ * el texto haría pasar por paleta nuestra a unos strings sueltos;
147
+ * - alguna `key` declarada es desconocida (paleta custom del host): no hay nada
148
+ * semántico que declarar;
149
+ * - falta alguno de los dos lados: un grupo solo no particiona nada, así que
150
+ * rotularlo anunciaría al lector de pantalla una frontera que no existe.
151
+ *
152
+ * ORDEN (decisión explícita): cuando la paleta se reconoce, se re-emite en orden
153
+ * canónico —neutros primero, marca después—, conservando el orden relativo del
154
+ * host DENTRO de cada lado. No es evitable: dos grupos contiguos no se pueden
155
+ * renderizar respetando un orden intercalado. Entre perder la agrupación
156
+ * semántica (spec §4) y perder un orden que el host no pudo curar sin adoptar
157
+ * antes nuestro vocabulario de keys, gana la agrupación. `flatPresets` y
158
+ * `focusedIndex` derivan de `presetGroups`, así que las flechas recorren el
159
+ * orden RENDERIZADO y no se desincronizan.
160
+ */
161
+ function splitPaletteGroups(presets) {
162
+ const neutrals = [];
163
+ const brand = [];
164
+ for (const p of presets) {
165
+ if (p.synthesizedKey)
166
+ return null;
167
+ if (NEUTRAL_KEYS.has(p.key))
168
+ neutrals.push(p);
169
+ else if (BRAND_KEYS.has(p.key))
170
+ brand.push(p);
171
+ else
172
+ return null;
173
+ }
174
+ if (!neutrals.length || !brand.length)
175
+ return null;
176
+ return { neutrals, brand };
177
+ }
23
178
 
24
- const coColorPickerCss = () => `:host{display:block;font-family:var(--co-font-family-primary);font-size:var(--co-font-size-14);letter-spacing:var(--co-font-letter-spacing-body);line-height:1}.co-color-picker{display:flex;flex-direction:column;gap:var(--co-spacing-sm2)}.co-color-picker--disabled{opacity:0.5;pointer-events:none}.co-color-picker__label{font-size:var(--co-font-size-14);font-weight:400;color:var(--co-semantic-text-secondary);padding:0 var(--co-spacing-xs)}.co-field-required{margin-left:2px;color:var(--co-color-status-error)}.co-field-required__caption{margin-left:4px;color:var(--co-semantic-text-muted);font-size:var(--co-font-size-12);font-weight:400}.co-field-required__caption::before{content:var(--co-field-required-text, ' (required)')}.co-color-picker co-popover{display:block;width:100%}.co-color-picker__trigger{display:flex;align-items:center;gap:var(--co-spacing-sm2);padding:var(--co-spacing-sm2) var(--co-spacing-md);background:var(--co-semantic-surface-page);border:1px solid var(--co-semantic-border-field);border-radius:var(--co-border-radius-xs);min-height:40px;box-sizing:border-box;cursor:pointer;transition:border-color var(--co-motion-duration-fast) var(--co-motion-ease-out), box-shadow var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker--s .co-color-picker__trigger{min-height:28px;padding:var(--co-spacing-xxs) var(--co-spacing-sm);font-size:var(--co-font-size-12)}.co-color-picker--sm .co-color-picker__trigger{min-height:32px;padding:var(--co-spacing-xs) var(--co-spacing-sm);font-size:var(--co-font-size-14)}.co-color-picker--lg .co-color-picker__trigger{min-height:48px;padding:var(--co-spacing-sm) var(--co-spacing-lg);font-size:var(--co-font-size-16)}.co-color-picker--s .co-color-picker__swatch,.co-color-picker--sm .co-color-picker__swatch{width:18px;height:18px}.co-color-picker__trigger:hover{border-color:var(--co-semantic-border-default)}.co-color-picker--open .co-color-picker__trigger{border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 15%, transparent)}.co-color-picker__trigger:focus-visible{outline:none;border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 15%, transparent)}.co-color-picker--error .co-color-picker__trigger{border-color:var(--co-color-status-error)}.co-color-picker__swatch{width:22px;height:22px;box-sizing:border-box;border-radius:var(--co-border-radius-full);border:1px solid var(--co-semantic-border-subtle);flex-shrink:0}.co-color-picker__value{flex:1;font-size:inherit;font-family:inherit;color:var(--co-semantic-text-default);font-weight:500;text-transform:uppercase}.co-color-picker__value--empty{color:var(--co-semantic-text-muted);font-weight:400}.co-color-picker__panel{padding:var(--co-spacing-md);display:flex;flex-direction:column;gap:var(--co-spacing-md)}.co-color-picker__grid{display:grid;grid-template-columns:repeat(8, 1fr);gap:var(--co-spacing-sm2)}.co-color-picker__grid-item{width:32px;height:32px;border-radius:var(--co-border-radius-xxs);border:2px solid transparent;cursor:pointer;transition:transform var(--co-motion-duration-fast) var(--co-motion-ease-out), border-color var(--co-motion-duration-fast) var(--co-motion-ease-out);box-sizing:border-box}.co-color-picker__grid-item:hover{transform:scale(1.1)}.co-color-picker__grid-item--selected{border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 25%, transparent)}.co-color-picker__hex-row{display:flex;align-items:center;gap:var(--co-spacing-sm2);padding:var(--co-spacing-xs) var(--co-spacing-sm);background:var(--co-semantic-surface-secondary);border:1px solid var(--co-semantic-border-subtle);border-radius:var(--co-border-radius-xxs)}.co-color-picker__hex-prefix{color:var(--co-semantic-text-muted);font-size:var(--co-font-size-14);font-weight:500}.co-color-picker__hex-value{flex:1;font-size:var(--co-font-size-14);font-family:var(--co-font-family-mono, monospace);color:var(--co-semantic-text-default);text-transform:uppercase;user-select:all}.co-color-picker__copy-btn{display:flex;align-items:center;justify-content:center;padding:var(--co-spacing-xs);border:none;background:transparent;cursor:pointer;color:var(--co-semantic-text-muted);border-radius:var(--co-border-radius-xxs);transition:color var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker__copy-btn:hover{color:var(--co-semantic-text-default);background:var(--co-semantic-surface-hover)}.co-color-picker__copy-btn--copied{color:var(--co-color-status-success)}.co-color-picker__helper{display:flex;align-items:center;gap:var(--co-spacing-xs);font-size:var(--co-font-size-14);color:var(--co-semantic-text-muted);padding:0 var(--co-spacing-xs)}.co-color-picker__helper-icon{flex-shrink:0;display:flex;align-items:center}.co-color-picker--error .co-color-picker__helper{color:var(--co-semantic-status-error)}:host([layout='horizontal']) .co-color-picker{display:grid;grid-template-columns:var(--co-field-label-width, max-content) 1fr;align-items:start;column-gap:var(--co-spacing-md);row-gap:var(--co-spacing-sm2)}:host([layout='horizontal']) .co-color-picker__label{grid-column:1;grid-row:1;padding-top:var(--co-spacing-sm2);min-width:0}:host([layout='horizontal']) .co-color-picker__label{white-space:normal}:host([layout='horizontal']) .co-color-picker>:not(.co-color-picker__label){grid-column:2;min-width:0}`;
179
+ const coColorPickerCss = () => `:host{display:block;font-family:var(--co-font-family-primary);font-size:var(--co-font-size-14);letter-spacing:var(--co-font-letter-spacing-body);line-height:1}.co-color-picker{display:flex;flex-direction:column;gap:var(--co-spacing-sm2)}.co-color-picker--disabled{opacity:0.5;pointer-events:none}.co-color-picker__label{font-size:var(--co-font-size-14);font-weight:400;color:var(--co-semantic-text-secondary);padding:0 var(--co-spacing-xs)}.co-field-required{margin-left:2px;color:var(--co-color-status-error)}.co-field-required__caption{margin-left:4px;color:var(--co-semantic-text-muted);font-size:var(--co-font-size-12);font-weight:400}.co-field-required__caption::before{content:var(--co-field-required-text, ' (required)')}.co-color-picker co-popover{display:block;width:100%}.co-color-picker__trigger{display:flex;align-items:center;gap:var(--co-spacing-sm2);padding:var(--co-spacing-sm2) var(--co-spacing-md);background:var(--co-semantic-surface-page);border:1px solid var(--co-semantic-border-field);border-radius:var(--co-border-radius-xs);min-height:40px;box-sizing:border-box;cursor:pointer;transition:border-color var(--co-motion-duration-fast) var(--co-motion-ease-out), box-shadow var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker--s .co-color-picker__trigger{min-height:28px;padding:var(--co-spacing-xxs) var(--co-spacing-sm);font-size:var(--co-font-size-12)}.co-color-picker--sm .co-color-picker__trigger{min-height:32px;padding:var(--co-spacing-xs) var(--co-spacing-sm);font-size:var(--co-font-size-14)}.co-color-picker--lg .co-color-picker__trigger{min-height:48px;padding:var(--co-spacing-sm) var(--co-spacing-lg);font-size:var(--co-font-size-16)}.co-color-picker--s .co-color-picker__swatch,.co-color-picker--sm .co-color-picker__swatch{width:18px;height:18px}.co-color-picker__trigger:hover{border-color:var(--co-semantic-border-default)}.co-color-picker--open .co-color-picker__trigger{border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 15%, transparent)}.co-color-picker__trigger:focus-visible{outline:none;border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 15%, transparent)}.co-color-picker--error .co-color-picker__trigger{border-color:var(--co-color-status-error)}.co-color-picker__swatch{width:22px;height:22px;box-sizing:border-box;border-radius:var(--co-border-radius-full);border:1px solid var(--co-semantic-border-subtle);flex-shrink:0}.co-color-picker__value{flex:1;font-size:inherit;font-family:inherit;color:var(--co-semantic-text-default);font-weight:500;text-transform:uppercase}.co-color-picker__value--empty{color:var(--co-semantic-text-muted);font-weight:400}.co-color-picker__panel{padding:var(--co-spacing-md);display:flex;flex-direction:column;gap:var(--co-spacing-md)}.co-color-picker__area{position:relative;height:132px;border-radius:var(--co-border-radius-xxs);cursor:crosshair;touch-action:none;background:linear-gradient(to top, black, transparent), linear-gradient(to right, white, transparent), hsl(var(--co-color-picker-hue, 0) 100% 50%)}.co-color-picker__area-thumb{position:absolute;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:var(--co-border-radius-full);border:2px solid var(--co-semantic-surface-page);box-shadow:0 0 0 1px var(--co-semantic-border-default);box-sizing:border-box;pointer-events:none}.co-color-picker__channel{position:absolute;inset:0;opacity:0;pointer-events:none;margin:0}.co-color-picker__area:focus-within{outline:2px solid var(--co-semantic-border-focus);outline-offset:2px}.co-color-picker__hue-input{width:100%;height:12px;margin:0;appearance:none;-webkit-appearance:none;border-radius:var(--co-border-radius-full);background:linear-gradient(to right, hsl(0 100% 50%), hsl(60 100% 50%), hsl(120 100% 50%), hsl(180 100% 50%), hsl(240 100% 50%), hsl(300 100% 50%), hsl(360 100% 50%));cursor:pointer}.co-color-picker__hue-input::-webkit-slider-thumb{appearance:none;-webkit-appearance:none;width:16px;height:16px;border-radius:var(--co-border-radius-full);background:var(--co-semantic-surface-page);box-shadow:0 0 0 1px var(--co-semantic-border-default);cursor:grab}.co-color-picker__hue-input::-moz-range-thumb{width:16px;height:16px;border:none;border-radius:var(--co-border-radius-full);background:var(--co-semantic-surface-page);box-shadow:0 0 0 1px var(--co-semantic-border-default)}.co-color-picker__hue-input:focus-visible{outline:2px solid var(--co-semantic-border-focus);outline-offset:2px}.co-color-picker__grid{display:flex;flex-direction:column;gap:var(--co-spacing-md)}.co-color-picker__grid-group{display:grid;grid-template-columns:repeat(6, 32px);gap:var(--co-spacing-sm2)}.co-color-picker__grid-item{width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:var(--co-border-radius-xxs);border:2px solid transparent;cursor:pointer;box-sizing:border-box;transition:transform var(--co-motion-duration-fast) var(--co-motion-ease-out), border-color var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker__grid-item:hover{transform:scale(1.1)}.co-color-picker__grid-item--selected{border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 25%, transparent)}.co-color-picker__grid-item--light{box-shadow:inset 0 0 0 1px var(--co-semantic-border-default)}.co-color-picker__grid-item--light.co-color-picker__grid-item--selected{box-shadow:inset 0 0 0 1px var(--co-semantic-border-default), 0 0 0 2px color-mix(in srgb, var(--co-semantic-border-focus) 25%, transparent)}.co-color-picker__grid-item:focus-visible{outline:none;box-shadow:0 0 0 2px var(--co-semantic-surface-page), 0 0 0 4px var(--co-semantic-border-focus)}.co-color-picker__grid-item--light:focus-visible{box-shadow:inset 0 0 0 1px var(--co-semantic-border-default), 0 0 0 2px var(--co-semantic-surface-page), 0 0 0 4px var(--co-semantic-border-focus)}.co-color-picker__grid-check{color:var(--co-semantic-surface-page)}.co-color-picker__grid-item--light .co-color-picker__grid-check{color:var(--co-semantic-text-default)}.co-color-picker__hex-row{display:flex;align-items:center;gap:var(--co-spacing-sm2);padding:var(--co-spacing-xs) var(--co-spacing-sm);background:var(--co-semantic-surface-secondary);border:1px solid var(--co-semantic-border-subtle);border-radius:var(--co-border-radius-xxs)}.co-color-picker__hex-prefix{color:var(--co-semantic-text-muted);font-size:var(--co-font-size-14);font-weight:500}.co-color-picker__hex-row:has(>.co-color-picker__hex-input:focus){border-color:var(--co-semantic-border-focus);box-shadow:0 0 0 2px var(--co-semantic-border-focus-ring)}.co-color-picker__hex-input{flex:1;min-width:0;box-sizing:border-box;border:none;background:transparent;padding:0;font-size:var(--co-font-size-14);font-family:var(--co-font-family-mono, monospace);color:var(--co-semantic-text-default);text-transform:uppercase}.co-color-picker__hex-input:focus,.co-color-picker__hex-input:focus-visible{outline:none}.co-color-picker__hex-input:disabled{color:var(--co-semantic-text-muted);cursor:not-allowed;opacity:1;-webkit-text-fill-color:var(--co-semantic-text-muted)}.co-color-picker__eyedropper{display:flex;align-items:center;justify-content:center;padding:var(--co-spacing-xs);border:none;background:transparent;cursor:pointer;color:var(--co-semantic-text-muted);border-radius:var(--co-border-radius-xxs);transition:color var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker__eyedropper:hover:not(:disabled){color:var(--co-semantic-text-default);background:var(--co-semantic-surface-hover)}.co-color-picker__eyedropper:focus-visible{outline:none;box-shadow:0 0 0 2px var(--co-semantic-border-focus-ring)}.co-color-picker__eyedropper:disabled{cursor:not-allowed;opacity:0.5}.co-color-picker__copy-btn{display:flex;align-items:center;justify-content:center;padding:var(--co-spacing-xs);border:none;background:transparent;cursor:pointer;color:var(--co-semantic-text-muted);border-radius:var(--co-border-radius-xxs);transition:color var(--co-motion-duration-fast) var(--co-motion-ease-out), background var(--co-motion-duration-fast) var(--co-motion-ease-out)}.co-color-picker__copy-btn:hover:not(:disabled){color:var(--co-semantic-text-default);background:var(--co-semantic-surface-hover)}.co-color-picker__copy-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--co-semantic-border-focus-ring)}.co-color-picker__copy-btn:disabled{cursor:not-allowed;opacity:0.5}.co-color-picker__copy-btn--copied{color:var(--co-color-status-success)}.co-color-picker__helper{display:flex;align-items:center;gap:var(--co-spacing-xs);font-size:var(--co-font-size-14);color:var(--co-semantic-text-muted);padding:0 var(--co-spacing-xs)}.co-color-picker__helper-icon{flex-shrink:0;display:flex;align-items:center}.co-color-picker--error .co-color-picker__helper{color:var(--co-semantic-status-error)}:host([layout='horizontal']) .co-color-picker{display:grid;grid-template-columns:var(--co-field-label-width, max-content) 1fr;align-items:start;column-gap:var(--co-spacing-md);row-gap:var(--co-spacing-sm2)}:host([layout='horizontal']) .co-color-picker__label{grid-column:1;grid-row:1;padding-top:var(--co-spacing-sm2);min-width:0}:host([layout='horizontal']) .co-color-picker__label{white-space:normal}:host([layout='horizontal']) .co-color-picker>:not(.co-color-picker__label){grid-column:2;min-width:0}`;
25
180
 
181
+ /** Columnas de la grilla. 6×32 + 5×8 de gap + 24 de padding = 256px. */
182
+ const GRID_COLS = 6;
183
+ /** Paso grueso de Shift+flecha (SLDS). La flecha sola usa el paso nativo del range: 1. */
184
+ const SHIFT_STEP = 10;
185
+ /**
186
+ * Un pegado que YA es hex, o el principio de uno (`02`, `#0263`). Es lo único
187
+ * que se deja caer al escape cuando `parseCssColor` no reconoce el texto: así
188
+ * se puede pegar un fragmento y seguir tipeando, sin que un pegado que no es un
189
+ * color (un nombre CSS, una frase) se convierta en un hex inventado.
190
+ */
191
+ const HEX_FRAGMENT = /^#?[0-9a-f]*$/i;
192
+ /**
193
+ * De dónde parte el área cuando el campo está VACÍO: rojo puro, con el thumb en
194
+ * la esquina viva.
195
+ *
196
+ * No es cosmético. El vértice negro (`{0,0,0}`) deja DOS de los tres controles
197
+ * sin poder producir color: con `v=0`, mover el matiz o la saturación da
198
+ * `#000000` haga lo que haga el usuario. Y en suite-v2 `coChange` significa
199
+ * commit, así que un gesto exploratorio sobre un campo vacío lo dejaba en negro
200
+ * Y con "cambios sin guardar", sin que nadie haya elegido nada.
201
+ *
202
+ * El seed es de DISPLAY: no toca `value` ni emite. Hasta que el usuario actúa,
203
+ * el trigger sigue mostrando su placeholder.
204
+ *
205
+ * Congelado: es un objeto de MÓDULO, compartido por el initializer, el caché y
206
+ * el fallback de `componentWillLoad`. Hoy nadie lo muta —`previewHsv` hace
207
+ * spread y `commit` reasigna—, pero un `this.hsv.h = …` futuro envenenaría a
208
+ * todas las instancias de la página a la vez, y ése es un bug que no se
209
+ * encuentra mirando el componente que lo sufre.
210
+ *
211
+ * El tipo es `Readonly<Hsv>` y no `Hsv`: anotarlo como `Hsv` BORRA el
212
+ * `Readonly` que devuelve `Object.freeze`, y la protección queda sólo en
213
+ * runtime — TS no marcaría `EMPTY_HSV.h = 1` en compilación. Sigue siendo
214
+ * asignable a `this.hsv: Hsv`.
215
+ */
216
+ const EMPTY_HSV = Object.freeze({ h: 0, s: 100, v: 100 });
217
+ /** Los swatches de todos los grupos, en orden de render. */
218
+ const flattenGroups = (groups) => groups.reduce((acc, g) => acc.concat(g.items), []);
26
219
  const CoColorPicker = class {
27
220
  constructor(hostRef) {
28
221
  registerInstance(this, hostRef);
29
222
  this.coChange = createEvent(this, "coChange", 7);
223
+ this.coInput = createEvent(this, "coInput", 7);
30
224
  /** Current color value as hex string (e.g. "#0066FF"). */
31
225
  this.value = '';
32
226
  /** Placeholder text when no color is selected. */
@@ -46,13 +240,108 @@ const CoColorPicker = class {
46
240
  * or plain hex strings. When set programmatically, accepts an actual array.
47
241
  */
48
242
  this.presets = '';
243
+ /** Idioma de los textos accesibles. Misma prop que co-file-field/co-date-picker. */
244
+ this.locale = 'en';
49
245
  this.isOpen = false;
50
246
  this.copied = false;
247
+ /**
248
+ * El estado AUTORITATIVO del color mientras el picker está vivo: HSV en punto
249
+ * flotante. El hex es una derivación de presentación, no la fuente.
250
+ *
251
+ * ⛔ No redondear: el redondeo a entero rompe el round-trip (#02A270 vuelve
252
+ * como #02A370) y ése es el temblor del cursor al arrastrar. El redondeo va
253
+ * sólo en el borde (el `value` de los range y los aria-valuetext).
254
+ */
255
+ this.hsv = EMPTY_HSV;
256
+ /**
257
+ * El TEXTO del campo hex (sin `#`), que mientras se tipea puede no ser un
258
+ * color: `12` es un hex a medio escribir, no un error. El valor real sigue
259
+ * siendo `value`; esto es sólo lo que se ve en el campo.
260
+ */
261
+ this.hexDraft = '';
262
+ /**
263
+ * Si el usuario está tipeando en el campo hex. Mientras lo esté, el campo NO
264
+ * se re-espeja desde `value`: como el commit es en vivo, tipear `F00` emite
265
+ * `#FF0000` y espejarlo le reescribiría el texto bajo el cursor (react-colorful
266
+ * hace lo mismo, pero mirándole el foco al input; acá es un flag explícito
267
+ * porque el foco dentro de un shadow root no sale por `document.activeElement`
268
+ * y porque un flag es observable desde los tests).
269
+ *
270
+ * Se apaga en el blur y al reabrir el panel: un texto a medias abandonado por
271
+ * una vía que no entrega blur (Escape desmonta el panel entero) no puede
272
+ * dejar el espejo roto para siempre.
273
+ */
274
+ this.hexEditing = false;
275
+ /**
276
+ * Cuál de los dos ejes del área tiene el tab stop. El otro sale del tab order
277
+ * (`tabindex=-1`) y del árbol de accesibilidad (`aria-hidden`), así que el
278
+ * formulario lista UN control por campo y el lector anuncia uno solo — pero
279
+ * los dos siguen operables, porque la flecha del eje oculto le mueve el foco
280
+ * por código. Es @State porque de él dependen atributos pintados.
281
+ */
282
+ this.areaAxis = 's';
283
+ /**
284
+ * Último hex que escribimos en `value`. Es el anti-drift de la capa de estado:
285
+ * si el host nos devuelve el mismo hex que acabamos de emitir, NO se
286
+ * re-convierte a HSV — un redondeo distinto movería el cursor solo.
287
+ * (El otro anti-drift está en color.ts: Hsv es float, nunca entero.)
288
+ *
289
+ * Guardaba también el HSV que produjo ese hex, y nadie lo leía nunca: los
290
+ * cuatro puntos que sellan el caché lo hacen inmediatamente después de
291
+ * asignar `this.hsv`, así que la copia era `this.hsv` por otro nombre —
292
+ * imposible de desincronizar y, por lo mismo, imposible de aprovechar. Un
293
+ * campo muerto dentro de un anti-drift es una invitación a "usarlo" y
294
+ * reintroducir justo el drift que esto evita.
295
+ */
296
+ this.emitted = '';
297
+ /**
298
+ * El último hex realmente COMMITEADO (`coChange`), que es cosa distinta de
299
+ * `emitted`: ése lo sella también cada frame de preview, así que no puede
300
+ * decir a qué color volver cuando un gesto termina sin commitear.
301
+ *
302
+ * Es la línea de base del deshacer: a él vuelve un texto que quedó a medias
303
+ * y —el agujero que esto además tapa— un arrastre abortado, que hoy dejaba
304
+ * `value` en el color previsualizado sin que el host se hubiera enterado
305
+ * nunca por `coChange`.
306
+ */
307
+ this.committed = '';
308
+ /**
309
+ * Índice del swatch enfocado, para la navegación por flechas (roving tabindex).
310
+ * Es @State y no un campo suelto porque el `tabIndex` de cada opción se pinta
311
+ * a partir de él: sin reactividad, las flechas moverían el foco pero el DOM
312
+ * quedaría con el tabbable original y salir/volver con Tab caería en el
313
+ * swatch equivocado.
314
+ */
315
+ this.focusedIndex = 0;
316
+ /**
317
+ * Si hay un arrastre ABIERTO sobre el área (hubo `pointerdown` acá que sí
318
+ * pudo traducir el punto). Sin esto, cualquier `pointerup` que aterrice sobre
319
+ * el área commitea: un arrastre iniciado en otra parte del panel y soltado
320
+ * encima emitía un `coChange` que el usuario nunca pidió — y en suite-v2
321
+ * commit significa formulario sucio.
322
+ */
323
+ this.areaDragging = false;
51
324
  this.handlePopoverOpen = () => {
52
325
  this.isOpen = true;
326
+ // Toda reapertura arranca sin gesto abierto: si el anterior se abortó por
327
+ // una vía que no entrega ningún evento al área (Escape con el botón
328
+ // apretado desmonta el panel), este es el punto por el que sí se pasa.
329
+ this.areaDragging = false;
330
+ // Y sin edición de texto abierta: el panel se desmonta al cerrar, así que un
331
+ // texto a medias que se fue sin blur (Escape) no puede dejar el campo
332
+ // congelado en un draft ya divorciado del color.
333
+ this.resetHexDraft();
334
+ // Al abrir, el foco arranca en el color ya elegido (0 si no hay ninguno).
335
+ const i = this.flatPresets.findIndex((p) => p.value.toUpperCase() === (this.value || '').toUpperCase());
336
+ this.focusedIndex = i >= 0 ? i : 0;
53
337
  };
54
338
  this.handlePopoverClose = () => {
55
339
  this.isOpen = false;
340
+ // El cierre del panel TAMBIÉN cierra el gesto del campo, y no es un detalle:
341
+ // el navegador NO emite `blur` al remover un elemento enfocado, así que
342
+ // tipear un color y salir con Escape (o clickeando afuera) se perdería en
343
+ // silencio. Cubre además el arrastre abortado, que deja un preview colgado.
344
+ this.finishHexEdit();
56
345
  this.restoreTriggerFocus();
57
346
  };
58
347
  this.handleTriggerKeyDown = (e) => {
@@ -67,22 +356,500 @@ const CoColorPicker = class {
67
356
  this.isOpen = true;
68
357
  }
69
358
  };
359
+ /**
360
+ * Coordenadas del puntero → saturación/brillo.
361
+ *
362
+ * ⚠️ Un `rect` degenerado NO se convierte en un color: con `rect.width === 0`
363
+ * (área todavía sin layout, o con `display:none`) la división da **Infinity**
364
+ * —no NaN: NaN sólo sale si el numerador es exactamente 0— y el clamp lo
365
+ * lleva a 1, así que un pointerdown escribiría `s=100, v=0`, o sea NEGRO, y
366
+ * lo emitiría como si el usuario lo hubiera elegido. Guard: area.spec.
367
+ */
368
+ this.pointerToHsv = (e) => {
369
+ var _a;
370
+ const rect = (_a = this.areaEl) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
371
+ if (!rect || !(rect.width > 0) || !(rect.height > 0))
372
+ return false;
373
+ const x = Math.min(Math.max((e.clientX - rect.left) / rect.width, 0), 1);
374
+ const y = Math.min(Math.max((e.clientY - rect.top) / rect.height, 0), 1);
375
+ this.previewHsv({ s: x * 100, v: (1 - y) * 100 });
376
+ return true;
377
+ };
378
+ this.handleAreaPointerDown = (e) => {
379
+ var _a, _b;
380
+ // Sólo el botón PRIMARIO pinta: con el secundario, el click derecho abría
381
+ // el menú contextual y de paso cambiaba y commiteaba el color.
382
+ if (this.disabled || e.button !== 0)
383
+ return;
384
+ // Captura sobre el ÁREA (el thumb es pointer-events:none, así que el target
385
+ // ya es ella) para no perder el arrastre al salirse del panel. Llamada
386
+ // opcional: no todo entorno la implementa (jsdom no la tiene) y el arrastre
387
+ // dentro del área funciona igual sin captura.
388
+ (_b = (_a = this.areaEl) === null || _a === void 0 ? void 0 : _a.setPointerCapture) === null || _b === void 0 ? void 0 : _b.call(_a, e.pointerId);
389
+ // El gesto queda abierto SÓLO si el área pudo traducir el punto: con un
390
+ // rect degenerado no hay nada que arrastrar, y por lo tanto nada que
391
+ // commitear al soltar.
392
+ this.areaDragging = this.pointerToHsv(e);
393
+ };
394
+ this.handleAreaPointerMove = (e) => {
395
+ // Sólo dentro de un arrastre abierto en el área y con el botón principal
396
+ // apretado: sin lo primero, un arrastre que empezó en otro lado repinta al
397
+ // pasar por encima; sin lo segundo, lo hace el hover a secas.
398
+ if (this.disabled || !this.areaDragging || e.buttons !== 1)
399
+ return;
400
+ this.pointerToHsv(e);
401
+ };
402
+ /**
403
+ * Un arrastre ABORTADO cierra el gesto sin commitear. Sin esto, el flag queda
404
+ * en `true` para siempre en esa instancia y el próximo `pointerup` suelto
405
+ * commitea — el mismo bug del gesto sin `pointerdown`, por otra puerta.
406
+ */
407
+ this.handleAreaPointerCancel = () => {
408
+ this.areaDragging = false;
409
+ };
410
+ this.handleAreaPointerUp = (e) => {
411
+ // Sólo cierra un gesto ABIERTO en esta área. Un `pointerup` suelto no
412
+ // commitea nada.
413
+ if (!this.areaDragging || e.button !== 0)
414
+ return;
415
+ this.areaDragging = false;
416
+ if (this.disabled)
417
+ return;
418
+ this.commit(hsvToHex(this.hsv));
419
+ };
420
+ /**
421
+ * Teclado del área: la flecha decide el eje, y ese eje pasa a ser el
422
+ * enfocado. El foco programático entra igual en el input con `tabindex=-1`
423
+ * —por eso el par tabindex-1 + aria-hidden no deja ningún eje inalcanzable—.
424
+ * SLDS: flecha = 1, Shift+flecha = 10.
425
+ */
426
+ this.handleAreaKeyDown = (e) => {
427
+ if (this.disabled)
428
+ return;
429
+ const move = CoColorPicker.AREA_KEYS[e.key];
430
+ // Home/End/PageUp/PageDown quedan DELEGADOS al range nativo, sobre su propio
431
+ // eje. ⚠️ Es el único resquicio de redondeo que queda en el camino del
432
+ // estado: el nativo opera sobre el `value` del DOM, que ya viene redondeado
433
+ // por el borde de presentación, así que PageUp/PageDown pierden la fracción
434
+ // al re-entrar por `onInput`. Es preexistente y deliberado —el salto de esas
435
+ // teclas es de 10 o al extremo, donde la fracción no significa nada—, pero
436
+ // queda anotado para que nadie lo lea como un descuido.
437
+ if (!move)
438
+ return;
439
+ e.preventDefault();
440
+ const step = e.shiftKey ? SHIFT_STEP : 1;
441
+ const next = Math.min(100, Math.max(0, this.hsv[move.axis] + move.dir * step));
442
+ this.focusAxis(move.axis);
443
+ this.previewHsv({ [move.axis]: next });
444
+ // Un teclazo es un gesto completo: preview + commit, no un arrastre abierto.
445
+ // Son DOS eventos por tecla (coInput y coChange), no uno.
446
+ this.commit(hsvToHex(this.hsv));
447
+ };
448
+ /**
449
+ * El matiz es un slider 1D suelto: las cuatro flechas son SU eje, así que el
450
+ * range nativo ya resuelve el paso de 1 y acá sólo se intercepta Shift.
451
+ */
452
+ this.handleHueKeyDown = (e) => {
453
+ if (this.disabled || !e.shiftKey)
454
+ return;
455
+ const dir = e.key === 'ArrowRight' || e.key === 'ArrowUp' ? 1
456
+ : e.key === 'ArrowLeft' || e.key === 'ArrowDown' ? -1
457
+ : 0;
458
+ if (!dir)
459
+ return;
460
+ // El range nativo aplicaría ADEMÁS su paso de 1 sobre el mismo evento.
461
+ e.preventDefault();
462
+ const next = Math.min(360, Math.max(0, this.hsv.h + dir * SHIFT_STEP));
463
+ this.previewHsv({ h: next });
464
+ this.commit(hsvToHex(this.hsv));
465
+ };
466
+ this.handleGridKeyDown = (e) => {
467
+ var _a;
468
+ // La grilla es el único control del panel que es un `<div>`: no hereda
469
+ // `disabled` del DOM como el range o el input, así que el guard tiene que
470
+ // ser explícito. Sin él, deshabilitar con el panel abierto dejaba la
471
+ // navegación por flechas viva y Enter commiteando sobre un campo apagado.
472
+ if (this.disabled)
473
+ return;
474
+ // `presetGroups` re-parsea el JSON de `presets` y remapea en CADA lectura, y
475
+ // todos los consumidores reales pasan presets custom por prop: se resuelve
476
+ // UNA vez por tecla y se pasa por parámetro, no dos veces por getter.
477
+ const groups = this.presetGroups;
478
+ const presets = flattenGroups(groups);
479
+ const n = presets.length;
480
+ if (!n)
481
+ return;
482
+ // Un `focusedIndex` fuera de rango (los presets cambiaron con el panel
483
+ // abierto) se clampea en vez de indexar `undefined`.
484
+ const current = Math.min(Math.max(this.focusedIndex, 0), n - 1);
485
+ let next = current;
486
+ switch (e.key) {
487
+ // Wrap cíclico: regla de SLDS. APG lo trata como opcional.
488
+ case 'ArrowRight':
489
+ next = (current + 1) % n;
490
+ break;
491
+ case 'ArrowLeft':
492
+ next = (current - 1 + n) % n;
493
+ break;
494
+ case 'ArrowDown':
495
+ next = this.verticalNeighbor(groups, current, 1);
496
+ break;
497
+ case 'ArrowUp':
498
+ next = this.verticalNeighbor(groups, current, -1);
499
+ break;
500
+ case 'Home':
501
+ next = 0;
502
+ break;
503
+ case 'End':
504
+ next = n - 1;
505
+ break;
506
+ case 'Enter':
507
+ case ' ':
508
+ e.preventDefault();
509
+ this.handleSwatchClick(presets[current].value);
510
+ return;
511
+ default: return;
512
+ }
513
+ e.preventDefault();
514
+ this.focusedIndex = next;
515
+ // Query, NO `children`: los swatches cuelgan de dos `role=group`, así que
516
+ // el índice plano no coincide con los hijos directos del listbox.
517
+ (_a = this.optionEls()[next]) === null || _a === void 0 ? void 0 : _a.focus();
518
+ };
519
+ /**
520
+ * Tipear PREVISUALIZA (`coInput`), no commitea.
521
+ *
522
+ * El campo es el único control del panel donde el gesto se estira en el
523
+ * tiempo, y tratarlo como commit por caracter tiene un costo que no se ve
524
+ * hasta que se mira de cerca: corregir un typo de `0263EB` a `026` emitiría
525
+ * `coChange('#002266')` — el usuario está BORRANDO y el componente commitea
526
+ * un color nuevo. Con el preview, el campo queda igual que sus tres hermanos
527
+ * (área, matiz, swatches): en vivo mientras dura el gesto, commit al
528
+ * soltarlo. El `#002266` que pinta al pasar por `026` es un frame intermedio
529
+ * de preview, ni más ni menos que cualquier frame de arrastre.
530
+ */
531
+ this.handleHexInput = (e) => {
532
+ var _a, _b;
533
+ if (this.disabled)
534
+ return;
535
+ const el = e.target;
536
+ const raw = this.escapeHex(el.value);
537
+ // El escape se fuerza en el DOM: si el texto escapado no cambió (tipear `zz`
538
+ // sobre `12` sigue dando `12`), el vdom no ve diferencia y no repinta — y el
539
+ // usuario se queda mirando `12zz` en el campo.
540
+ if (el.value !== raw) {
541
+ // Reasignar `value` manda el caret al final: con `1234` y el caret en 2,
542
+ // tipear `z` lo mandaba al 4 y el siguiente caracter salía en otro lugar.
543
+ // La posición se recalcula contando cuántos caracteres SOBREVIVEN al
544
+ // escape por delante del caret.
545
+ const caretIn = (_a = el.selectionStart) !== null && _a !== void 0 ? _a : el.value.length;
546
+ const caretOut = Math.min(this.escapeHex(el.value.slice(0, caretIn)).length, raw.length);
547
+ el.value = raw;
548
+ (_b = el.setSelectionRange) === null || _b === void 0 ? void 0 : _b.call(el, caretOut, caretOut);
549
+ }
550
+ this.hexEditing = true;
551
+ this.hexDraft = raw;
552
+ if (isValidHex(raw))
553
+ this.previewHex(this.expandHex(raw));
554
+ };
555
+ this.handleHexBlur = () => {
556
+ this.finishHexEdit();
557
+ };
558
+ /** Enter cierra el gesto sin salir del campo (y no submitea ningún form). */
559
+ this.handleHexKeyDown = (e) => {
560
+ if (e.key !== 'Enter')
561
+ return;
562
+ e.preventDefault();
563
+ this.finishHexEdit();
564
+ };
565
+ /**
566
+ * Sin interceptar el pegado, el escape convierte `rgb(2, 99, 235)` en
567
+ * `299235` — basura silenciosa que ADEMÁS commitea sola, porque el `input` que
568
+ * sigue al pegado nativo ve 6 dígitos válidos.
569
+ *
570
+ * `parseCssColor` no cubre nombres CSS (ver color.ts): `rebeccapurple` escapa
571
+ * a `EBECCA`, un hex perfectamente válido que nadie eligió. Por eso lo que no
572
+ * es un color se CANCELA en vez de dejarse caer al escape; lo único que pasa
573
+ * de largo es un hex o el principio de uno, para poder pegar `02` y seguir
574
+ * tipeando.
575
+ */
576
+ this.handleHexPaste = (e) => {
577
+ var _a, _b;
578
+ if (this.disabled)
579
+ return;
580
+ const text = ((_b = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) !== null && _b !== void 0 ? _b : '').trim();
581
+ const parsed = parseCssColor(text);
582
+ if (parsed) {
583
+ e.preventDefault();
584
+ // Un pegado entrega un color COMPLETO en un acto atómico, como clickear
585
+ // un swatch: commitea al instante en vez de esperar al fin de gesto, y
586
+ // por lo mismo CIERRA cualquier edición de texto que estuviera abierta
587
+ // (si no, el blur posterior volvería a commitear lo mismo).
588
+ this.hexEditing = false;
589
+ this.hexDraft = this.escapeHex(parsed);
590
+ this.commit(parsed);
591
+ return;
592
+ }
593
+ if (!HEX_FRAGMENT.test(text))
594
+ e.preventDefault();
595
+ };
596
+ /**
597
+ * El cuentagotas entrega un color COMPLETO en un acto atómico, igual que un
598
+ * swatch o un pegado: entra por `commit` —no se duplica ni la asignación ni
599
+ * el emit— y se normaliza con `parseCssColor`, porque la API devuelve el hex
600
+ * en minúscula (`#ff0000`) y el resto del picker trabaja en mayúscula.
601
+ *
602
+ * ⚠️ `finishHexEdit` va PRIMERO y SÍNCRONO, antes del `await`: clickear otro
603
+ * control del panel es el fin del gesto del campo hex, y ese gesto puede
604
+ * durar lo que el usuario tarde en recorrer la pantalla. Sin esto, un texto a
605
+ * medias (`12`) se queda escrito y `hexEditing` colgado durante todo el
606
+ * cuentagotas, y si el usuario CANCELA nadie lo deshace: el preview vivo
607
+ * sobrevive a un gesto que no commiteó nada. Es el mismo cierre que hace el
608
+ * pegado, por la misma razón. Correrlo dos veces es inocuo (el blur real del
609
+ * navegador lo dispara también): la segunda pasada ve `hexEditing` en false y
610
+ * `value === committed`, y sale sin emitir.
611
+ */
612
+ this.handleEyeDropper = async () => {
613
+ this.finishHexEdit();
614
+ // El guard va DESPUÉS del cierre del gesto, y eso es lo único que tiene de
615
+ // interesante. `hasEyeDropper` no es reactivo: la presencia del botón se
616
+ // decide en el render y nunca se re-evalúa, así que existe el camino "API
617
+ // presente al renderizar, ausente al clickear" — el botón sigue en el DOM.
618
+ // Con el guard ADELANTE, ese click no hacía nada Y dejaba la edición del
619
+ // hex abierta: un control visible que se comporta distinto a todos sus
620
+ // hermanos del panel. Acá abajo el camino raro cierra el gesto igual que
621
+ // los demás y sólo se saltea el cuentagotas.
622
+ //
623
+ // Puesto así el guard ya no cambia nada observable —sin él, `new Ctor()`
624
+ // tira un TypeError que el `catch` atrapa y el estado queda idéntico—, y
625
+ // por eso ningún test lo distingue. Se queda por ser explícito sobre una
626
+ // precondición, no por un caso que lo necesite.
627
+ if (!this.hasEyeDropper)
628
+ return;
629
+ try {
630
+ const Ctor = window.EyeDropper;
631
+ const { sRGBHex } = await new Ctor().open();
632
+ const hex = parseCssColor(sRGBHex);
633
+ // Lo que no es un color no se commitea: el picker no inventa negro.
634
+ if (hex)
635
+ this.commit(hex);
636
+ }
637
+ catch (_a) {
638
+ /* El usuario canceló con Escape: no es un error que valga reportar. */
639
+ }
640
+ };
641
+ }
642
+ /**
643
+ * Un valor entrante que YA es el que acabamos de emitir se descarta.
644
+ *
645
+ * Sin esto, un host controlado (el que guarda lo emitido y lo devuelve por la
646
+ * prop) reinyecta el hex derivado, que se re-convierte a HSV con otro
647
+ * redondeo y mueve el cursor solo en pleno arrastre. La comparación es
648
+ * case-insensitive porque el host normaliza el string —guardar en minúsculas
649
+ * es lo habitual— y el mismo color escrito distinto no es un cambio.
650
+ */
651
+ syncFromValue(next) {
652
+ // El campo hex espeja el valor por esta vía ÚNICA, ANTES del guard: todo
653
+ // camino que cambia el color pasa por acá (el arrastre y el commit escriben
654
+ // `value`, y el host también). Si el espejo viviera después del guard, el
655
+ // campo quedaría congelado en el color anterior justo en el caso más común
656
+ // —arrastrar el área—, porque ese camino sella el caché antes de asignar.
657
+ this.syncHexDraft(next);
658
+ if ((next || '').toUpperCase() === (this.emitted || '').toUpperCase())
659
+ return;
660
+ // Un valor que llega de afuera ES la verdad del host, PARSEE O NO: pasa a
661
+ // ser la línea de base a la que vuelve un gesto que termina sin commitear.
662
+ //
663
+ // ⛔ Va ANTES del guard de parseo, y eso es lo único que separa esto de un
664
+ // bug de pérdida de datos: si el host BORRA el color (`value = ''`) o pone
665
+ // algo que no es un hex (`var(--co-brand)`), con la línea abajo `committed`
666
+ // se quedaba en el color VIEJO — y como el cierre del panel deshace todo
667
+ // preview colgado, abrir y cerrar sin tocar nada le devolvía al host el
668
+ // color que acababa de borrar, por `value` y por `coInput`.
669
+ //
670
+ // Y va DESPUÉS del guard de `emitted`, que es igual de deliberado: un host
671
+ // controlado que espeja `coInput` de vuelta a la prop nos devuelve nuestro
672
+ // propio preview, y tomar eso por un commit del host haría irreversible
673
+ // justo lo que este mecanismo existe para revertir.
674
+ this.committed = next;
675
+ // `emitted` se sella acá arriba por la misma razón, y también está medido:
676
+ // gateado por el parseo, un host que PASA por un valor no-hex y vuelve a un
677
+ // color que ya habíamos tenido lo dejaba stale apuntando a ese color, el
678
+ // guard de arriba tomaba el regreso por eco propio, `committed` no se
679
+ // actualizaba y el cierre del panel reemplazaba el color del host por el
680
+ // valor intermedio. Sellar lo que el host escribió —parsee o no— es además
681
+ // lo que el guard significa: "esto ya lo tenemos, no hay nada que
682
+ // re-derivar", que de un valor no parseable es trivialmente cierto.
683
+ this.emitted = next;
684
+ const parsed = hexToHsv(next || '');
685
+ // Un hex inválido no se convierte en un color: se ignora y el estado
686
+ // anterior sobrevive (el picker no tiene por qué inventar negro).
687
+ if (!parsed)
688
+ return;
689
+ this.hsv = parsed;
690
+ }
691
+ /**
692
+ * Siembra del estado. Es OBLIGATORIA acá, no basta el initializer del campo:
693
+ * - los @Watch no corren para el valor inicial de la prop;
694
+ * - el initializer de un miembro DECORADO no sobrevive en el entorno de spec
695
+ * (@stencil/vitest define el accessor encima del campo ya inicializado, así
696
+ * que `this.hsv` llega `undefined` al primer render y el destructuring de
697
+ * `renderArea` tira). Los otros @State del componente lo toleraban porque
698
+ * `undefined` es falsy justo donde se usan.
699
+ * Sin hex válido el estado arranca en `EMPTY_HSV` —rojo puro, el vértice
700
+ * VIVO—, no en negro: ver su docstring, que explica por qué el vértice negro
701
+ * dejaría dos de los tres controles sin poder producir color. Es un seed de
702
+ * display; `value` sigue vacío y el trigger sigue mostrando el placeholder.
703
+ */
704
+ componentWillLoad() {
705
+ const parsed = hexToHsv(this.value || '');
706
+ this.hsv = parsed !== null && parsed !== void 0 ? parsed : EMPTY_HSV;
707
+ // Mismo motivo que `hsv`: el tab stop del área arranca en la saturación.
708
+ this.areaAxis = 's';
709
+ // El campo hex arranca del VALOR, no del seed del área.
710
+ //
711
+ // Es una siembra DEFENSIVA, y conviene decirlo con precisión porque el
712
+ // comentario anterior mentía: quitarla no pinta `FF0000` en ningún frame
713
+ // —`hexDraft` se queda en su initializer `''`—, y midiendo el shadow DOM
714
+ // cada 5ms desde el keydown del trigger, el input ya nace con el valor
715
+ // correcto porque `coOpen` (y con él `resetHexDraft`) llega ANTES de que el
716
+ // panel sea alcanzable. O sea: la re-siembra del popover le gana la carrera
717
+ // en todo entorno medido, y por eso ningún test la distingue. Se queda
718
+ // igual —sembrar en el load es correcto por construcción y no cuesta nada—,
719
+ // pero como cobertura no vale nada.
720
+ this.resetHexDraft();
721
+ // ⛔ NINGUNO de los dos sellos va detrás de `if (parsed)`, y no es simetría:
722
+ // cada uno abre su propia puerta al mismo bug de pérdida de datos, porque en
723
+ // Stencil el @Watch NO corre para el valor inicial y este es el único lugar
724
+ // donde se pueden sembrar.
725
+ //
726
+ // · `committed` es la línea de base del deshacer. Gateado, un `value`
727
+ // inicial que no parsea (`var(--co-brand)`, un nombre CSS) lo dejaba en
728
+ // `''`, y como el cierre del panel deshace todo preview colgado, abrir y
729
+ // cerrar SIN TOCAR NADA le borraba el valor al host y se lo anunciaba por
730
+ // `coInput`. Es el mismo razonamiento que el del @Watch, con el síntoma
731
+ // invertido: allá resucitaba el color viejo, acá borra el nuevo, porque
732
+ // el initializer es `''` en vez de un hex.
733
+ //
734
+ // · `emitted` es el caché anti-drift, no la línea de base — pero gatearlo
735
+ // abre la MISMA pérdida por composición, y está medido: con `committed`
736
+ // ya arreglado y `emitted` en `''`, un host que BORRA el color escribe
737
+ // justo el `''` que el guard toma por "esto ya lo emitimos nosotros",
738
+ // corta antes de actualizar `committed`, y el cierre del panel le
739
+ // devuelve el token que acababa de borrar. Sembrarlo con el valor inicial
740
+ // además es lo correcto por definición: el guard existe para saltear la
741
+ // re-derivación de un valor que ya tenemos, y al montar `value` ES lo que
742
+ // tenemos (`componentWillLoad` acaba de derivarlo).
743
+ this.committed = this.value;
744
+ this.emitted = this.value;
745
+ }
746
+ /**
747
+ * Movimiento en vivo: actualiza la UI y avisa, sin commitear.
748
+ *
749
+ * ⚠️ El caché se sella ANTES de tocar `this.value`: el setter de una @Prop
750
+ * corre sus @Watch de forma SÍNCRONA, así que con el caché todavía en el
751
+ * color anterior `syncFromValue` vería un color "nuevo", re-parsearía el hex
752
+ * y pisaría este HSV flotante con el redondeado — el temblor, en el mismo
753
+ * frame y sin que el host haya hecho nada. Guard: area.spec.
754
+ */
755
+ previewHsv(next) {
756
+ this.hsv = Object.assign(Object.assign({}, this.hsv), next);
757
+ this.emitPreview(hsvToHex(this.hsv));
758
+ }
759
+ /**
760
+ * Lo mismo, pero entrando por un hex ENTERO en vez de por un eje: es lo que
761
+ * produce el campo de texto, donde el color no llega como "más saturación"
762
+ * sino como un color completo. Comparte el sellado con `previewHsv` para que
763
+ * el orden crítico (sellar → asignar → avisar) exista en UN solo lugar.
764
+ */
765
+ previewHex(hex) {
766
+ const parsed = hexToHsv(hex);
767
+ if (parsed)
768
+ this.hsv = parsed;
769
+ this.emitPreview(hex);
770
+ }
771
+ emitPreview(hex) {
772
+ this.emitted = hex;
773
+ this.value = hex;
774
+ this.coInput.emit(hex);
775
+ }
776
+ /**
777
+ * Commit: lo que los consumidores ya escuchan hoy (soltar el arrastre,
778
+ * clickear un swatch).
779
+ *
780
+ * El HSV se re-deriva SÓLO si el hex viene de afuera —un swatch, un hex
781
+ * tipeado—, y eso se detecta preguntándole al propio estado si ese hex es el
782
+ * que produce. Re-derivar siempre tiene dos daños:
783
+ *
784
+ * 1. 🔴 En un color ACROMÁTICO el hex no lleva matiz: `#000000` es negro y
785
+ * punto, así que `hexToHsv` devuelve h=0 (rojo) y le BORRA al usuario el
786
+ * matiz que acababa de elegir. Con el campo vacío —el estado inicial de
787
+ * tres consumidores de suite-v2— el área se ponía azul al arrastrar el
788
+ * matiz y volvía a roja al soltar.
789
+ * 2. En un color cromático no lo borra pero lo REDONDEA (200 → 199.875):
790
+ * el estado interno pasando por la grilla del hex es justo lo que esta
791
+ * task existe para evitar.
792
+ */
793
+ commit(hex) {
794
+ if (hsvToHex(this.hsv) !== hex) {
795
+ const parsed = hexToHsv(hex);
796
+ if (parsed)
797
+ this.hsv = parsed;
798
+ }
799
+ this.emitted = hex;
800
+ this.committed = hex;
801
+ this.value = hex;
802
+ this.coChange.emit(hex);
803
+ }
804
+ get strings() {
805
+ return getColorPickerStrings(this.locale);
70
806
  }
71
807
  get parsedPresets() {
72
808
  if (Array.isArray(this.presets)) {
73
- return this.presets.map(p => typeof p === 'string' ? { name: p, value: p } : p);
809
+ return this.presets.map(resolvePreset);
74
810
  }
75
811
  if (typeof this.presets === 'string' && this.presets.trim()) {
76
812
  try {
77
813
  const parsed = JSON.parse(this.presets);
78
814
  if (Array.isArray(parsed)) {
79
- return parsed.map((p) => typeof p === 'string' ? { name: p, value: p } : p);
815
+ return parsed.map((p) => resolvePreset(p));
80
816
  }
81
817
  }
82
818
  catch ( /* ignore */_a) { /* ignore */ }
83
819
  }
84
820
  return DEFAULT_PRESETS;
85
821
  }
822
+ /**
823
+ * Los grupos EN EL ORDEN EN QUE SE RENDERIZAN, cada uno con el índice plano
824
+ * de su primer swatch (`from`). La navegación por flechas se indexa contra
825
+ * este aplanado, no contra `parsedPresets`: si el orden del render y el del
826
+ * array divergieran, una flecha movería el foco a otro swatch.
827
+ *
828
+ * La frontera neutros/marca sale de `NEUTRAL_PRESET_KEYS` — la única fuente
829
+ * de la paleta. Nada de `slice(0, 5)`: ese `5` ya estaba duplicado en tres
830
+ * lugares y es lo que la task anterior vino a eliminar.
831
+ */
832
+ get presetGroups() {
833
+ const presets = this.parsedPresets;
834
+ // La partición sale de la MEMBRESÍA de `key` (`splitPaletteGroups`), no de
835
+ // comparar identidad contra `DEFAULT_PRESETS`: el consumidor real manda la
836
+ // misma paleta re-serializada con los nombres traducidos, y por identidad
837
+ // eso caía siempre en "custom" — los rótulos no se anunciaban nunca.
838
+ const split = splitPaletteGroups(presets);
839
+ // Sin partición que signifique algo (hexes sueltos, keys desconocidas, un
840
+ // solo lado) va todo en un grupo, sin rótulo inventado.
841
+ if (!split) {
842
+ return [{ label: undefined, items: presets, from: 0 }];
843
+ }
844
+ return [
845
+ { label: this.strings.groupNeutrals, items: split.neutrals, from: 0 },
846
+ { label: this.strings.groupBrand, items: split.brand, from: split.neutrals.length },
847
+ ];
848
+ }
849
+ /** Los swatches aplanados en orden de render: la lista que recorren las flechas. */
850
+ get flatPresets() {
851
+ return flattenGroups(this.presetGroups);
852
+ }
86
853
  /** Devuelve el foco al trigger al cerrar el panel (Escape, selección),
87
854
  * salvo que el cierre venga de un click-outside que ya movió el foco a
88
855
  * otro elemento — en ese caso no robarlo. */
@@ -94,11 +861,134 @@ const CoColorPicker = class {
94
861
  }
95
862
  }
96
863
  handleSwatchClick(hex) {
97
- this.value = hex;
98
- this.coChange.emit(hex);
864
+ // Mismo guard que el resto de los controles del panel: el host puede
865
+ // deshabilitar el campo CON EL PANEL ABIERTO, y un swatch deshabilitado no
866
+ // commitea. El `pointer-events:none` del CSS tapa el mouse, no el teclado.
867
+ if (this.disabled)
868
+ return;
869
+ // Elegir un preset es un commit como cualquier otro: la asignación y el
870
+ // emit viven en `commit`, no duplicados acá (si no, el swatch dejaría el
871
+ // HSV del color anterior y el área abriría en el color equivocado).
872
+ this.commit(hex);
99
873
  this.isOpen = false;
100
874
  this.restoreTriggerFocus();
101
875
  }
876
+ /** Mueve el tab stop del área (y el foco) al eje pedido. */
877
+ focusAxis(axis) {
878
+ this.areaAxis = axis;
879
+ const el = axis === 's' ? this.satEl : this.valEl;
880
+ if (!el)
881
+ return;
882
+ // El render de Stencil es ASÍNCRONO: enfocar mientras el input todavía
883
+ // tiene `aria-hidden` puede hacer que el lector de pantalla se coma el
884
+ // anuncio (el nodo no está en el árbol en el instante del evento), y un
885
+ // frame después no hay ningún evento nuevo que lo dispare. Se sincroniza a
886
+ // mano y el próximo render converge al mismo valor. Guard: area.spec.
887
+ //
888
+ // El `tabindex` NO hace falta tocarlo: `focus()` entra igual en un
889
+ // `tabindex=-1` —es exactamente lo que hace operable al eje oculto— y el
890
+ // tab order se corrige en el render, dentro del mismo frame.
891
+ el.removeAttribute('aria-hidden');
892
+ el.focus();
893
+ }
894
+ optionEls() {
895
+ var _a, _b;
896
+ // `Array.from`, NO spread: el build de Stencil tipa con `lib: ["dom","es2020"]`
897
+ // SIN `dom.iterable`, así que spreadear un NodeList no compila (y `tsc --noEmit`
898
+ // con este tsconfig no lo detecta — sólo revienta en `stencil build`).
899
+ return Array.from((_b = (_a = this.gridEl) === null || _a === void 0 ? void 0 : _a.querySelectorAll('[role="option"]')) !== null && _b !== void 0 ? _b : []);
900
+ }
901
+ /**
902
+ * Vecino de arriba/abajo EN PANTALLA.
903
+ *
904
+ * La grilla no es una matriz única: son N grillas de 6 columnas apiladas, una
905
+ * por grupo, y la de neutros tiene 5 celdas. Por eso un stride plano de ±6
906
+ * sobre el índice global se corre una columna al cruzar la frontera (Black,
907
+ * columna 0, caía en Olive, columna 1). Fila y columna se calculan DENTRO del
908
+ * grupo; al cruzar al grupo vecino se conserva la columna, que es lo que
909
+ * "fila anterior / siguiente" significa visualmente.
910
+ *
911
+ * En el borde de la grilla el foco NO se mueve: colapsarlo al extremo mandaba
912
+ * cualquier neutro de la primera fila a Black.
913
+ *
914
+ * Asimetría DELIBERADA con las flechas horizontales, que sí wrappean (0↔16):
915
+ * el wrap cíclico en un eje y el tope duro en el otro es lo que hace APG para
916
+ * grillas, y es lo que deja claro dónde termina la paleta.
917
+ */
918
+ verticalNeighbor(groups, current, dir) {
919
+ const gi = groups.findIndex((g) => current >= g.from && current < g.from + g.items.length);
920
+ if (gi < 0)
921
+ return current;
922
+ const g = groups[gi];
923
+ const j = current - g.from;
924
+ const col = j % GRID_COLS;
925
+ const rows = Math.ceil(g.items.length / GRID_COLS);
926
+ const targetRow = Math.floor(j / GRID_COLS) + dir;
927
+ // Hay fila dentro del MISMO grupo. La última puede estar incompleta.
928
+ if (targetRow >= 0 && targetRow < rows) {
929
+ return g.from + Math.min(targetRow * GRID_COLS + col, g.items.length - 1);
930
+ }
931
+ const neighbor = groups[gi + dir];
932
+ if (!neighbor)
933
+ return current;
934
+ // Entrando desde arriba se aterriza en la primera fila; desde abajo, en la última.
935
+ const nRows = Math.ceil(neighbor.items.length / GRID_COLS) || 1;
936
+ const landingRow = dir === 1 ? 0 : nRows - 1;
937
+ return neighbor.from + Math.min(landingRow * GRID_COLS + col, neighbor.items.length - 1);
938
+ }
939
+ /**
940
+ * El área saturación×brillo.
941
+ *
942
+ * Es un `role="group"` con UN `<input type="range">` invisible por eje —el
943
+ * modelo de React Aria—, en vez de un `role="slider"` 2D a mano: así el eje
944
+ * lo maneja un control nativo (teclado, repetición de tecla, anuncio del
945
+ * lector de pantalla) y sólo el arrastre queda de nuestro lado.
946
+ *
947
+ * El matiz viaja al CSS por custom property: el gradiente es CSS puro, sin
948
+ * canvas y sin un hex literal en la hoja de estilos.
949
+ */
950
+ renderArea() {
951
+ const { h: hue, s, v } = this.hsv;
952
+ // El eje enfocado es el único con tab stop y el único anunciado.
953
+ const satFocused = this.areaAxis === 's';
954
+ return (h("div", { class: "co-color-picker__area", role: "group", "aria-label": this.strings.area, ref: (el) => (this.areaEl = el), style: { '--co-color-picker-hue': `${hue}` }, onPointerDown: this.handleAreaPointerDown, onPointerMove: this.handleAreaPointerMove, onPointerUp: this.handleAreaPointerUp, onPointerCancel: this.handleAreaPointerCancel }, h("span", { class: "co-color-picker__area-thumb", role: "presentation", style: { left: `${s}%`, top: `${100 - v}%`, background: this.value } }), h("input", { type: "range", min: "0", max: "100", step: "1", class: "co-color-picker__channel", "data-channel": "s", value: Math.round(s), ref: (el) => (this.satEl = el), tabIndex: satFocused ? 0 : -1, "aria-hidden": satFocused ? undefined : 'true', "aria-label": this.strings.saturation, "aria-roledescription": this.strings.area2D, "aria-valuetext": fillTemplate(this.strings.satValue, { n: Math.round(s) }), "aria-orientation": "horizontal", disabled: this.disabled, onFocus: () => (this.areaAxis = 's'), onInput: (e) => this.previewHsv({ s: +e.target.value }), onChange: () => this.commit(hsvToHex(this.hsv)), onKeyDown: this.handleAreaKeyDown }), h("input", { type: "range", min: "0", max: "100", step: "1", class: "co-color-picker__channel", "data-channel": "v", value: Math.round(v), ref: (el) => (this.valEl = el), tabIndex: satFocused ? -1 : 0, "aria-hidden": satFocused ? 'true' : undefined, "aria-label": this.strings.brightness, "aria-roledescription": this.strings.area2D, "aria-valuetext": fillTemplate(this.strings.briValue, { n: Math.round(v) }), "aria-orientation": "vertical", disabled: this.disabled, onFocus: () => (this.areaAxis = 'v'), onInput: (e) => this.previewHsv({ v: +e.target.value }), onChange: () => this.commit(hsvToHex(this.hsv)), onKeyDown: this.handleAreaKeyDown })));
955
+ }
956
+ renderHue() {
957
+ return (h("input", { type: "range", min: "0", max: "360", step: "1", class: "co-color-picker__hue-input", value: Math.round(this.hsv.h), "aria-label": this.strings.hue, "aria-valuetext": fillTemplate(this.strings.hueValue, { n: Math.round(this.hsv.h) }), disabled: this.disabled, onInput: (e) => this.previewHsv({ h: +e.target.value }), onChange: () => this.commit(hsvToHex(this.hsv)), onKeyDown: this.handleHueKeyDown }));
958
+ }
959
+ renderSwatches() {
960
+ return (h("div", { class: "co-color-picker__grid", role: "listbox", "aria-label": this.strings.swatches, ref: (el) => (this.gridEl = el), onKeyDown: this.handleGridKeyDown }, this.presetGroups.map((g) => (
961
+ // Agrupación SÓLO para lectores de pantalla: en pantalla los separa el
962
+ // gap, sin rótulos (costaban ~56px y no aportaban — spec §4).
963
+ // `key` por el índice plano de arranque (0 / 5), NO por el rótulo:
964
+ // el rótulo cambia con `locale` y remontaría los grupos al traducir.
965
+ //
966
+ // Sin rótulo el contenedor es PRESENTACIONAL: un `role="group"`
967
+ // anónimo particiona el listbox para el lector de pantalla anunciando
968
+ // una frontera que no significa nada. El div igual tiene que existir
969
+ // —es el que da las 6 columnas—, así que `presentation` lo saca del
970
+ // árbol de accesibilidad y las opciones quedan colgando del listbox.
971
+ h("div", { class: "co-color-picker__grid-group", key: g.from, role: g.label ? 'group' : 'presentation', "aria-label": g.label }, g.items.map((preset, j) => {
972
+ const i = g.from + j;
973
+ const selected = preset.value.toUpperCase() === (this.value || '').toUpperCase();
974
+ return (h("div", { key: preset.value, role: "option", "aria-selected": selected ? 'true' : 'false', "aria-label": preset.name,
975
+ // El `aria-label` cubre al lector de pantalla; al usuario con
976
+ // mouse no le dice nada. Sin el `title`, la paleta por default
977
+ // deja dos grises contiguos ("Humo" y "Hueso") indistinguibles
978
+ // salvo por el pixel de color. El tooltip nativo es la
979
+ // convención de este design system para celdas de grilla
980
+ // —co-emoji-picker:419 hace exactamente esto, y el propio
981
+ // panel ya lo usa en gotero y copiar—; la regla que lo prohíbe
982
+ // es de suite-v2, no de cobalt core.
983
+ title: preset.name, tabIndex: i === this.focusedIndex ? 0 : -1, class: {
984
+ 'co-color-picker__grid-item': true,
985
+ 'co-color-picker__grid-item--selected': selected,
986
+ // Un swatch claro se pierde contra el panel: se decide por
987
+ // luminancia, no por una lista de hex hardcodeada.
988
+ 'co-color-picker__grid-item--light': isLightColor(preset.value),
989
+ }, style: { background: preset.value }, onFocus: () => (this.focusedIndex = i), onClick: () => this.handleSwatchClick(preset.value) }, selected && (h("co-icon", { name: "check", size: 16, weight: "bold", class: "co-color-picker__grid-check" }))));
990
+ }))))));
991
+ }
102
992
  get statusIcon() {
103
993
  const map = {
104
994
  error: 'warning-circle',
@@ -107,6 +997,150 @@ const CoColorPicker = class {
107
997
  };
108
998
  return map[this.status] || null;
109
999
  }
1000
+ /**
1001
+ * Lo que se puede TIPEAR en el campo: dígitos hex, hasta 6. El 7º caracter y
1002
+ * el `#` no entran, y con 8 dígitos (hex con alpha) se queda con los 6 de
1003
+ * color — este picker no maneja alpha.
1004
+ */
1005
+ escapeHex(v) {
1006
+ return (v || '').replace(/[^0-9a-f]/gi, '').substring(0, 6).toUpperCase();
1007
+ }
1008
+ /** `F00` → `#FF0000`: lo emitido es SIEMPRE de 6 dígitos. */
1009
+ expandHex(v) {
1010
+ const hx = v.replace('#', '');
1011
+ const full = hx.length === 3 ? hx[0] + hx[0] + hx[1] + hx[1] + hx[2] + hx[2] : hx;
1012
+ return `#${full.toUpperCase()}`;
1013
+ }
1014
+ /**
1015
+ * Siembra el campo desde el valor REAL y cierra cualquier edición abierta.
1016
+ *
1017
+ * Con `value` vacío queda vacío: el estado interno arranca en EMPTY_HSV (rojo
1018
+ * puro) para que el área tenga de dónde partir, pero eso es un seed de
1019
+ * DISPLAY del área — espejarlo pondría `FF0000` escrito en un campo que el
1020
+ * usuario nunca tocó, anunciando un color que nadie eligió.
1021
+ */
1022
+ resetHexDraft() {
1023
+ // Apagar la edición va PRIMERO y es lo que hace incondicional a la
1024
+ // siembra: `syncHexDraft` se abstiene mientras el flag esté prendido, así
1025
+ // que sin esto un flag colgado dejaría la re-siembra en no-op.
1026
+ //
1027
+ // Hoy es defensivo y conviene decirlo: `finishHexEdit` —que corre en todo
1028
+ // cierre de panel— ya apaga el flag antes de cualquier otra cosa, así que
1029
+ // ningún test lo distingue. Se queda porque es la precondición de la línea
1030
+ // de abajo, no por un caso conocido que lo necesite.
1031
+ this.hexEditing = false;
1032
+ this.syncHexDraft(this.value);
1033
+ }
1034
+ /**
1035
+ * Espeja el valor real en el campo, salvo mientras el usuario lo está
1036
+ * tipeando.
1037
+ *
1038
+ * Sólo espeja lo que YA es un color (o el vacío, que limpia). `escapeHex`
1039
+ * sobre cualquier otra cosa fabrica un hex verosímil: un host que pase
1040
+ * `rebeccapurple` o `var(--co-color-primary-verde)` vería el campo mostrando
1041
+ * `EBECCA` / `ACCAED`. Es exactamente la falla que el pegado cancela unas
1042
+ * líneas más abajo, y entraba igual por la puerta de la prop. Los frames de
1043
+ * arrastre siempre escriben un hex de 6, así que no se pierde nada legítimo.
1044
+ */
1045
+ syncHexDraft(hex) {
1046
+ if (this.hexEditing)
1047
+ return;
1048
+ if (hex && !isValidHex(hex))
1049
+ return;
1050
+ this.hexDraft = this.escapeHex(hex);
1051
+ }
1052
+ /**
1053
+ * Fin del gesto del campo: blur, Enter, o el cierre del panel.
1054
+ *
1055
+ * Commitea SIEMPRE que haya un color tipeado, sin comparar contra `value`
1056
+ * —que a esta altura ya vale el color previsualizado, así que "commitear si
1057
+ * cambió" no dispararía nunca—. Es el precedente del `pointerup` del área: el
1058
+ * fin de gesto commitea, y si el usuario retipeó el mismo color, el `coChange`
1059
+ * redundante es el precio.
1060
+ *
1061
+ * ⚠️ Consecuencia documentada de esa regla: tipear un hex válido y después
1062
+ * clickear un swatch emite DOS `coChange` — el blur commitea el color
1063
+ * tipeado, y el swatch el suyo. Es el precio explícito de que el fin de gesto
1064
+ * no adivine intenciones, no un bug.
1065
+ *
1066
+ * Y si no hay nada que commitear, se DESHACE el preview vivo. Eso cubre dos
1067
+ * casos con el mismo movimiento: el texto que quedó a medias (`12`), y el
1068
+ * arrastre abortado —que emitía `coInput`, escribía `value` y no commiteaba
1069
+ * nunca, dejando al picker mostrando un color que el host jamás recibió—.
1070
+ */
1071
+ finishHexEdit() {
1072
+ const editing = this.hexEditing;
1073
+ this.hexEditing = false;
1074
+ // Un picker deshabilitado no emite ni escribe, ni siquiera para deshacer:
1075
+ // si el host lo apagó con un preview colgado, el `value` es asunto suyo.
1076
+ if (this.disabled)
1077
+ return;
1078
+ if (editing && isValidHex(this.hexDraft)) {
1079
+ const hex = this.expandHex(this.hexDraft);
1080
+ this.commit(hex);
1081
+ // El espejo se hace acá a mano porque el @Watch NO dispara: `commit`
1082
+ // reasigna a `value` el mismo hex que el preview ya había escrito, y
1083
+ // Stencil no corre el watcher cuando el valor no cambió. Sin esto, tipear
1084
+ // `F00` deja el campo mostrando `F00` mientras el color real ya es
1085
+ // `#FF0000` — el texto y el trigger diciendo cosas distintas.
1086
+ this.syncHexDraft(hex);
1087
+ return;
1088
+ }
1089
+ this.revertToCommitted();
1090
+ }
1091
+ /** Vuelve al último color commiteado y retira el preview que quedó colgado. */
1092
+ revertToCommitted() {
1093
+ const target = this.committed;
1094
+ // Por `syncHexDraft` y no por `escapeHex` a pelo: `committed` puede no ser
1095
+ // un hex (el host puede haber puesto `var(--co-brand)`), y escaparlo
1096
+ // fabricaría el mismo `ACBAD` verosímil que el guard de allá evita.
1097
+ this.syncHexDraft(target);
1098
+ // Volver a "sin color" devuelve el área a su vértice vivo. Si el gesto
1099
+ // abandonado terminó con `v=0`, reabrir dejaba el campo vacío Y el área en
1100
+ // negro, donde mover matiz o saturación no produce color alguno: es
1101
+ // exactamente el estado que EMPTY_HSV existe para evitar.
1102
+ if (!target)
1103
+ this.hsv = EMPTY_HSV;
1104
+ if ((this.value || '').toUpperCase() === (target || '').toUpperCase())
1105
+ return;
1106
+ // SIN sellar a mano: el @Watch re-deriva el HSV —que es lo que hace volver
1107
+ // el área al color commiteado en vez de quedarse en el abandonado— y sella
1108
+ // `emitted` él mismo, ANTES del guard de parseo, así que también cubre el
1109
+ // caso en que `target` no es un hex (nunca se commiteó nada y el campo
1110
+ // vuelve a vacío).
1111
+ //
1112
+ // Acá vivía un `this.emitted = target` con un comentario que describía el
1113
+ // orden VIEJO de `syncFromValue` (sellado gateado por el parseo). Desde que
1114
+ // el sellado subió, la línea era muerta por dos vías: o el @Watch ya la
1115
+ // dejó idéntica, o entró por su guard de eco —que compara contra `emitted`—
1116
+ // y entonces `emitted` ya era `target` salvo por mayúsculas, que es el único
1117
+ // lector que tiene. Medido: una sonda en esa línea sobre la suite entera la
1118
+ // alcanza cuatro veces y las cuatro con `emitted === target` estricto.
1119
+ this.value = target;
1120
+ // El preview se anunció por `coInput`; retirarlo también. Un host que
1121
+ // previsualiza en vivo se quedaría si no con el color que nadie eligió.
1122
+ this.coInput.emit(target);
1123
+ }
1124
+ /**
1125
+ * Chrome/Edge 95+ solamente (MDN, 2026-09-02): Firefox, Safari y Chrome
1126
+ * Android no la tienen. Se resuelve en el render, no en una prop: si no está,
1127
+ * el botón no existe. Un control deshabilitado sin explicar es peor que su
1128
+ * ausencia — y una prop obligaría a cada host a repetir la detección.
1129
+ *
1130
+ * El `typeof window` es por el build de hydrate, donde no hay `window` y el
1131
+ * `in` tiraría.
1132
+ */
1133
+ get hasEyeDropper() {
1134
+ return typeof window !== 'undefined' && 'EyeDropper' in window;
1135
+ }
1136
+ renderHexRow() {
1137
+ const hasValue = !!this.value;
1138
+ return (h("div", { class: "co-color-picker__hex-row" }, h("span", { class: "co-color-picker__hex-prefix" }, "#"), h("input", { type: "text", class: "co-color-picker__hex-input", value: this.hexDraft, spellcheck: false, autocomplete: "off", maxLength: 6, "aria-label": this.strings.hexField, disabled: this.disabled, onInput: this.handleHexInput, onBlur: this.handleHexBlur, onKeyDown: this.handleHexKeyDown, onPaste: this.handleHexPaste }), this.hasEyeDropper && (h("button", { type: "button", class: "co-color-picker__eyedropper", title: this.strings.eyedropper, "aria-label": this.strings.eyedropper, disabled: this.disabled, onClick: this.handleEyeDropper }, h("co-icon", { name: "eyedropper", size: 16 }))), h("button", { type: "button", class: `co-color-picker__copy-btn ${this.copied ? 'co-color-picker__copy-btn--copied' : ''}`, title: this.strings.copy, "aria-label": this.strings.copy,
1139
+ // La fila ya no está detrás de `hasValue` —hay que poder tipear el
1140
+ // primer color—, así que el que se apaga es el botón: sin valor no
1141
+ // hay nada que copiar.
1142
+ disabled: this.disabled || !hasValue, onClick: () => this.handleCopy() }, h("co-icon", { name: this.copied ? 'check' : 'copy', size: 16 }))));
1143
+ }
110
1144
  async handleCopy() {
111
1145
  if (!this.value)
112
1146
  return;
@@ -118,15 +1152,21 @@ const CoColorPicker = class {
118
1152
  catch ( /* ignore */_a) { /* ignore */ }
119
1153
  }
120
1154
  render() {
121
- const presets = this.parsedPresets;
122
1155
  const hasValue = !!this.value;
123
1156
  const statusClass = this.status !== 'default' ? `co-color-picker--${this.status}` : '';
124
- return (h("div", { key: '5b99c6a39399a6731d09115e7fd2ce2d64baffb2', class: `co-color-picker co-color-picker--${this.size} ${statusClass} ${this.isOpen ? 'co-color-picker--open' : ''} ${this.disabled ? 'co-color-picker--disabled' : ''}` }, this.label && (h("label", { key: '816392c0b3cebcb2e84ea28ea7e6b7976503b6f9', class: "co-color-picker__label" }, this.label, h(RequiredMark, { key: 'e0e1c97522f4516763fc663878203e2dafb783b3', required: this.required }))), h("co-popover", { key: 'd49ba1f9cd64d2498940247f3ba02897dcc9d2d7', open: this.isOpen, placement: "bottom-start", matchWidth: true, offset: 4, onCoOpen: this.handlePopoverOpen, onCoClose: this.handlePopoverClose }, h("div", { key: '1121b429c89fb9cc066cc66564ae547687bf8ed3', slot: "trigger", class: "co-color-picker__trigger", role: "combobox", "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "dialog", "aria-controls": this.isOpen ? CoColorPicker.PANEL_ID : undefined, "aria-label": this.label || undefined, "aria-disabled": this.disabled ? 'true' : undefined, tabIndex: this.disabled ? -1 : 0, ref: (el) => (this.triggerEl = el), onKeyDown: this.handleTriggerKeyDown }, h("span", { key: '2567db35022b5ffdd9921d8bec263c90103fd5f3', class: "co-color-picker__swatch", style: { background: hasValue ? this.value : 'transparent' } }), h("span", { key: '7fecc93b5ecc91acf2c874a26ed1f9d8770d9adf', class: `co-color-picker__value ${!hasValue ? 'co-color-picker__value--empty' : ''}` }, hasValue ? this.value : this.placeholder)), this.isOpen && (h("div", { key: '44d904e4156fac15b302ffe86d68cef72bc7518e', class: "co-color-picker__panel", id: CoColorPicker.PANEL_ID, role: "dialog", "aria-label": this.label || this.placeholder }, h("div", { key: 'a566f189c87792f0af3e493c00eed7240dcd49c9', class: "co-color-picker__grid" }, presets.map((preset) => {
125
- var _a;
126
- return (h("button", { type: "button", key: preset.value, class: `co-color-picker__grid-item ${preset.value.toUpperCase() === ((_a = this.value) === null || _a === void 0 ? void 0 : _a.toUpperCase()) ? 'co-color-picker__grid-item--selected' : ''}`, style: { background: preset.value }, title: preset.name, onClick: () => this.handleSwatchClick(preset.value) }));
127
- })), hasValue && (h("div", { key: 'bae8ffe387fe30710b654975379e70a4b3724ec9', class: "co-color-picker__hex-row" }, h("span", { key: '671a5a64abc2f824c8d1ef8c2404023d8d51c28d', class: "co-color-picker__hex-prefix" }, "#"), h("span", { key: '3a6742eb528c5a92fe16b2f2e5d8b2ebdf885450', class: "co-color-picker__hex-value" }, this.value.replace(/^#/, '')), h("button", { key: 'f53957b494dbed0648d32fcb743673a2ada063b4', type: "button", class: `co-color-picker__copy-btn ${this.copied ? 'co-color-picker__copy-btn--copied' : ''}`, title: "Copy", onClick: () => this.handleCopy() }, h("co-icon", { key: 'c99e611beddc2108f3973ecee4f6012423cffd23', name: this.copied ? 'check' : 'copy', size: 16 }))))))), this.helperText && (h("div", { key: '1d6a6e97eab1eafcb9265944693cb0d1121e04ee', class: "co-color-picker__helper" }, this.statusIcon && (h("co-icon", { key: 'bcf943836fddf264cede2f339844f35aa167002f', name: this.statusIcon, size: 14, weight: "fill", class: "co-color-picker__helper-icon" })), h("span", { key: 'a439c4d102d17d0d6c9e55757dcf43ec8b3ade8f', class: "co-color-picker__helper-text" }, this.helperText)))));
1157
+ return (h("div", { key: '5e4239ff9ef0dc3f15004898d2d891f8d231e95d', class: `co-color-picker co-color-picker--${this.size} ${statusClass} ${this.isOpen ? 'co-color-picker--open' : ''} ${this.disabled ? 'co-color-picker--disabled' : ''}` }, this.label && (h("label", { key: '003a893c3c840cd03d87c4291795499ac80b8b73', class: "co-color-picker__label" }, this.label, h(RequiredMark, { key: '4c14eaf668b0677b91b23a00f001ffaa4c21f5c5', required: this.required }))), h("co-popover", { key: 'f4a489f77c2d629ea1d9b69786cfad0f95d5422b', open: this.isOpen, placement: "bottom-start",
1158
+ // Sin `matchWidth`: el panel tiene ancho INTRÍNSECO (grilla de 8
1159
+ // swatches fijos de 32px). Copiar el ancho del trigger achica los
1160
+ // tracks bajo 32px con un campo angosto (media columna de un modal) y
1161
+ // los swatches desbordan el card — guard: panel-width.spec.
1162
+ offset: 4, onCoOpen: this.handlePopoverOpen, onCoClose: this.handlePopoverClose }, h("div", { key: '229e0095d6b6a723e77cf0d001d780cf51116851', slot: "trigger", class: "co-color-picker__trigger", role: "combobox", "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "dialog", "aria-controls": this.isOpen ? CoColorPicker.PANEL_ID : undefined, "aria-label": this.label || undefined, "aria-disabled": this.disabled ? 'true' : undefined, tabIndex: this.disabled ? -1 : 0, ref: (el) => (this.triggerEl = el), onKeyDown: this.handleTriggerKeyDown }, h("span", { key: '9267f104b7f0542653038ef381fb81a7f7f0188e', class: "co-color-picker__swatch", style: { background: hasValue ? this.value : 'transparent' } }), h("span", { key: '64efb900a60576022b3f487db56380973d2934c9', class: `co-color-picker__value ${!hasValue ? 'co-color-picker__value--empty' : ''}` }, hasValue ? this.value : this.placeholder)), this.isOpen && (h("div", { key: '22abcb6c79531f41a6655fc48320e4c108a33049', class: "co-color-picker__panel", id: CoColorPicker.PANEL_ID, role: "dialog", "aria-label": this.label || this.placeholder }, this.renderArea(), this.renderHue(), this.renderSwatches(), this.renderHexRow()))), this.helperText && (h("div", { key: '901b7094f7da8c09ea25cad568eda8d5fcaf2d6e', class: "co-color-picker__helper" }, this.statusIcon && (h("co-icon", { key: 'fb341f791466f133f6a6c4bd04a8dd71c519c7c0', name: this.statusIcon, size: 14, weight: "fill", class: "co-color-picker__helper-icon" })), h("span", { key: '0ecfc7d46a07c741d42b59660979559fb78117df', class: "co-color-picker__helper-text" }, this.helperText)))));
128
1163
  }
129
1164
  get el() { return getElement(this); }
1165
+ static get watchers() { return {
1166
+ "value": [{
1167
+ "syncFromValue": 0
1168
+ }]
1169
+ }; }
130
1170
  };
131
1171
  /**
132
1172
  * Id del panel de presets, target de `aria-controls` del trigger. Constante
@@ -137,6 +1177,17 @@ const CoColorPicker = class {
137
1177
  * on-demand, así que cerrado el IDREF quedaría colgante.
138
1178
  */
139
1179
  CoColorPicker.PANEL_ID = 'co-color-picker-panel';
1180
+ /**
1181
+ * Qué eje mueve cada flecha DENTRO del área, y en qué sentido. Un range
1182
+ * horizontal nativo también responde a ↑/↓ moviendo SU eje, así que sin esta
1183
+ * tabla (y su `preventDefault`) la flecha de arriba subía la saturación.
1184
+ */
1185
+ CoColorPicker.AREA_KEYS = {
1186
+ ArrowRight: { axis: 's', dir: 1 },
1187
+ ArrowLeft: { axis: 's', dir: -1 },
1188
+ ArrowUp: { axis: 'v', dir: 1 },
1189
+ ArrowDown: { axis: 'v', dir: -1 },
1190
+ };
140
1191
  CoColorPicker.style = coColorPickerCss();
141
1192
 
142
1193
  export { CoColorPicker as co_color_picker };