@devalok/shilp-sutra 0.56.0 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/MIGRATION.md +198 -0
  2. package/dist/_chunks/badge-group.js +75 -174
  3. package/dist/_chunks/badge-group.js.map +1 -1
  4. package/dist/_chunks/chat.js +270 -253
  5. package/dist/_chunks/chat.js.map +1 -1
  6. package/dist/_chunks/document-preview.js +1 -1
  7. package/dist/_chunks/document-preview.js.map +1 -1
  8. package/dist/_chunks/emoji-suggestion.js +1 -1
  9. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  10. package/dist/_chunks/image-preview.js +71 -70
  11. package/dist/_chunks/image-preview.js.map +1 -1
  12. package/dist/_chunks/mention-suggestion.js +2 -2
  13. package/dist/_chunks/mention-suggestion.js.map +1 -1
  14. package/dist/_chunks/motion-preference.js +15 -0
  15. package/dist/_chunks/motion-preference.js.map +1 -0
  16. package/dist/_chunks/motion-provider.js +1 -1
  17. package/dist/_chunks/motion-provider.js.map +1 -1
  18. package/dist/_chunks/oauth-button.js +1 -1
  19. package/dist/_chunks/oauth-button.js.map +1 -1
  20. package/dist/_chunks/popover.js +50 -49
  21. package/dist/_chunks/popover.js.map +1 -1
  22. package/dist/_chunks/primitives-internal.js +29 -29
  23. package/dist/_chunks/primitives-internal.js.map +1 -1
  24. package/dist/_chunks/shared.js +48 -47
  25. package/dist/_chunks/shared.js.map +1 -1
  26. package/dist/_chunks/success.js +36 -36
  27. package/dist/_chunks/success.js.map +1 -1
  28. package/dist/_chunks/tree-view.js +1 -1
  29. package/dist/_chunks/tree-view.js.map +1 -1
  30. package/dist/_chunks/use-calendar.js +4 -4
  31. package/dist/_chunks/use-calendar.js.map +1 -1
  32. package/dist/ai/block-renderer.js +8 -8
  33. package/dist/ai/blocks/text.js +1 -1
  34. package/dist/ai/blocks/text.js.map +1 -1
  35. package/dist/ai/command-bar.js +67 -67
  36. package/dist/ai/command-bar.js.map +1 -1
  37. package/dist/ai/conversation.js +35 -35
  38. package/dist/ai/conversation.js.map +1 -1
  39. package/dist/ai/index.js +4 -4
  40. package/dist/composed/activity-feed.d.ts.map +1 -1
  41. package/dist/composed/activity-feed.js +109 -108
  42. package/dist/composed/activity-feed.js.map +1 -1
  43. package/dist/composed/avatar-group.d.ts +7 -2
  44. package/dist/composed/avatar-group.d.ts.map +1 -1
  45. package/dist/composed/avatar-group.js +3 -3
  46. package/dist/composed/avatar-group.js.map +1 -1
  47. package/dist/composed/command-palette.js +137 -137
  48. package/dist/composed/command-palette.js.map +1 -1
  49. package/dist/composed/content-card.js +2 -2
  50. package/dist/composed/content-card.js.map +1 -1
  51. package/dist/composed/date-picker/index.js +9 -9
  52. package/dist/composed/date-picker/index.js.map +1 -1
  53. package/dist/composed/diff.d.ts +23 -2
  54. package/dist/composed/diff.d.ts.map +1 -1
  55. package/dist/composed/diff.js +341 -260
  56. package/dist/composed/diff.js.map +1 -1
  57. package/dist/composed/emoji-picker.js +3 -3
  58. package/dist/composed/emoji-picker.js.map +1 -1
  59. package/dist/composed/empty-state.js +4 -4
  60. package/dist/composed/error-boundary.js +2 -2
  61. package/dist/composed/error-boundary.js.map +1 -1
  62. package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
  63. package/dist/composed/file-preview/shared.d.ts.map +1 -1
  64. package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
  65. package/dist/composed/file-preview.js +152 -151
  66. package/dist/composed/file-preview.js.map +1 -1
  67. package/dist/composed/filter-bar.d.ts.map +1 -1
  68. package/dist/composed/filter-bar.js +53 -52
  69. package/dist/composed/filter-bar.js.map +1 -1
  70. package/dist/composed/form-section.d.ts.map +1 -1
  71. package/dist/composed/form-section.js +38 -37
  72. package/dist/composed/form-section.js.map +1 -1
  73. package/dist/composed/inline-edit.js +1 -1
  74. package/dist/composed/inline-edit.js.map +1 -1
  75. package/dist/composed/loading-skeleton.js +3 -3
  76. package/dist/composed/loading-skeleton.js.map +1 -1
  77. package/dist/composed/master-detail.d.ts.map +1 -1
  78. package/dist/composed/master-detail.js +1 -1
  79. package/dist/composed/master-detail.js.map +1 -1
  80. package/dist/composed/member-picker.js +1 -1
  81. package/dist/composed/member-picker.js.map +1 -1
  82. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  83. package/dist/composed/multi-select-popover.js +109 -108
  84. package/dist/composed/multi-select-popover.js.map +1 -1
  85. package/dist/composed/page-skeletons.js +4 -4
  86. package/dist/composed/page-skeletons.js.map +1 -1
  87. package/dist/composed/responsive-modal.js +1 -1
  88. package/dist/composed/responsive-modal.js.map +1 -1
  89. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  90. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  91. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  92. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  93. package/dist/composed/rich-chat-input.js +473 -472
  94. package/dist/composed/rich-chat-input.js.map +1 -1
  95. package/dist/composed/rich-text-editor.js +6 -6
  96. package/dist/composed/rich-text-editor.js.map +1 -1
  97. package/dist/composed/schedule-view.js +5 -5
  98. package/dist/composed/schedule-view.js.map +1 -1
  99. package/dist/composed/status-badge.d.ts.map +1 -1
  100. package/dist/composed/status-badge.js +29 -28
  101. package/dist/composed/status-badge.js.map +1 -1
  102. package/dist/hooks/index.d.ts +1 -0
  103. package/dist/hooks/index.d.ts.map +1 -1
  104. package/dist/hooks/index.js +4 -3
  105. package/dist/hooks/use-container-size.d.ts +18 -0
  106. package/dist/hooks/use-container-size.d.ts.map +1 -0
  107. package/dist/hooks/use-container-size.js +28 -0
  108. package/dist/hooks/use-container-size.js.map +1 -0
  109. package/dist/motion/index.d.ts +1 -0
  110. package/dist/motion/index.d.ts.map +1 -1
  111. package/dist/motion/index.js +2 -15
  112. package/dist/motion/motion-preference.d.ts +36 -0
  113. package/dist/motion/motion-preference.d.ts.map +1 -0
  114. package/dist/motion/motion-provider.d.ts +2 -1
  115. package/dist/motion/motion-provider.d.ts.map +1 -1
  116. package/dist/motion/primitives-index.js +103 -102
  117. package/dist/motion/primitives-index.js.map +1 -1
  118. package/dist/motion/primitives.d.ts.map +1 -1
  119. package/dist/shell/app-shell.d.ts +101 -0
  120. package/dist/shell/app-shell.d.ts.map +1 -0
  121. package/dist/shell/app-shell.js +76 -0
  122. package/dist/shell/app-shell.js.map +1 -0
  123. package/dist/shell/bottom-navbar.js +21 -21
  124. package/dist/shell/bottom-navbar.js.map +1 -1
  125. package/dist/shell/index.d.ts +2 -1
  126. package/dist/shell/index.d.ts.map +1 -1
  127. package/dist/shell/index.js +6 -5
  128. package/dist/shell/notification-center.d.ts +17 -0
  129. package/dist/shell/notification-center.d.ts.map +1 -1
  130. package/dist/shell/notification-center.js +110 -105
  131. package/dist/shell/notification-center.js.map +1 -1
  132. package/dist/shell/notification-preferences.js +1 -1
  133. package/dist/shell/notification-preferences.js.map +1 -1
  134. package/dist/shell/top-bar.js +7 -7
  135. package/dist/shell/top-bar.js.map +1 -1
  136. package/dist/tokens/generate-scale.d.ts +49 -0
  137. package/dist/tokens/generate-scale.d.ts.map +1 -1
  138. package/dist/tokens/index.css +1 -0
  139. package/dist/tokens/palettes.css +292 -0
  140. package/dist/tokens/primitives.css +29 -26
  141. package/dist/tokens/semantic.css +170 -47
  142. package/dist/tokens/shilp-sutra.css +1 -0
  143. package/dist/tokens/utilities.css +10 -7
  144. package/dist/tokens/variants.css +1 -1
  145. package/dist/ui/accordion.d.ts.map +1 -1
  146. package/dist/ui/accordion.js +27 -26
  147. package/dist/ui/accordion.js.map +1 -1
  148. package/dist/ui/alert-dialog.d.ts.map +1 -1
  149. package/dist/ui/alert-dialog.js +60 -59
  150. package/dist/ui/alert-dialog.js.map +1 -1
  151. package/dist/ui/alert.d.ts.map +1 -1
  152. package/dist/ui/alert.js +55 -113
  153. package/dist/ui/alert.js.map +1 -1
  154. package/dist/ui/autocomplete.js +80 -80
  155. package/dist/ui/autocomplete.js.map +1 -1
  156. package/dist/ui/avatar.d.ts.map +1 -1
  157. package/dist/ui/avatar.js +71 -70
  158. package/dist/ui/avatar.js.map +1 -1
  159. package/dist/ui/badge-indicator.d.ts +4 -8
  160. package/dist/ui/badge-indicator.d.ts.map +1 -1
  161. package/dist/ui/badge-indicator.js +3 -8
  162. package/dist/ui/badge-indicator.js.map +1 -1
  163. package/dist/ui/badge.d.ts +55 -34
  164. package/dist/ui/badge.d.ts.map +1 -1
  165. package/dist/ui/banner.d.ts.map +1 -1
  166. package/dist/ui/banner.js +43 -41
  167. package/dist/ui/banner.js.map +1 -1
  168. package/dist/ui/button-group.d.ts.map +1 -1
  169. package/dist/ui/button-group.js +3 -23
  170. package/dist/ui/button-group.js.map +1 -1
  171. package/dist/ui/button.d.ts +10 -1
  172. package/dist/ui/button.d.ts.map +1 -1
  173. package/dist/ui/button.js +79 -212
  174. package/dist/ui/button.js.map +1 -1
  175. package/dist/ui/card.d.ts.map +1 -1
  176. package/dist/ui/card.js +78 -75
  177. package/dist/ui/card.js.map +1 -1
  178. package/dist/ui/charts/radar-chart.d.ts.map +1 -1
  179. package/dist/ui/charts/radar-chart.js +1 -1
  180. package/dist/ui/charts/radar-chart.js.map +1 -1
  181. package/dist/ui/chat/date-separator.d.ts +8 -1
  182. package/dist/ui/chat/date-separator.d.ts.map +1 -1
  183. package/dist/ui/chat/message-list.d.ts.map +1 -1
  184. package/dist/ui/chat/message.d.ts.map +1 -1
  185. package/dist/ui/chat/typing-indicator.d.ts.map +1 -1
  186. package/dist/ui/checkbox.js +1 -1
  187. package/dist/ui/checkbox.js.map +1 -1
  188. package/dist/ui/code.js +2 -2
  189. package/dist/ui/code.js.map +1 -1
  190. package/dist/ui/color-input.d.ts.map +1 -1
  191. package/dist/ui/color-input.js +151 -150
  192. package/dist/ui/color-input.js.map +1 -1
  193. package/dist/ui/combobox.d.ts +14 -0
  194. package/dist/ui/combobox.d.ts.map +1 -1
  195. package/dist/ui/combobox.js +156 -152
  196. package/dist/ui/combobox.js.map +1 -1
  197. package/dist/ui/context-menu.d.ts.map +1 -1
  198. package/dist/ui/context-menu.js +70 -69
  199. package/dist/ui/context-menu.js.map +1 -1
  200. package/dist/ui/data-table-body.d.ts +3 -1
  201. package/dist/ui/data-table-body.d.ts.map +1 -1
  202. package/dist/ui/data-table-body.js +93 -92
  203. package/dist/ui/data-table-body.js.map +1 -1
  204. package/dist/ui/data-table-bulk-actions.d.ts +7 -1
  205. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
  206. package/dist/ui/data-table-bulk-actions.js +14 -8
  207. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  208. package/dist/ui/data-table-card.d.ts.map +1 -1
  209. package/dist/ui/data-table-card.js +66 -47
  210. package/dist/ui/data-table-card.js.map +1 -1
  211. package/dist/ui/data-table-context.d.ts +4 -0
  212. package/dist/ui/data-table-context.d.ts.map +1 -1
  213. package/dist/ui/data-table-context.js +2 -2
  214. package/dist/ui/data-table-context.js.map +1 -1
  215. package/dist/ui/data-table-header.d.ts.map +1 -1
  216. package/dist/ui/data-table-header.js +50 -46
  217. package/dist/ui/data-table-header.js.map +1 -1
  218. package/dist/ui/data-table-pagination.js +3 -3
  219. package/dist/ui/data-table-pagination.js.map +1 -1
  220. package/dist/ui/data-table-toolbar.d.ts +11 -1
  221. package/dist/ui/data-table-toolbar.d.ts.map +1 -1
  222. package/dist/ui/data-table-toolbar.js +7 -7
  223. package/dist/ui/data-table-toolbar.js.map +1 -1
  224. package/dist/ui/data-table.d.ts +52 -5
  225. package/dist/ui/data-table.d.ts.map +1 -1
  226. package/dist/ui/data-table.js +181 -169
  227. package/dist/ui/data-table.js.map +1 -1
  228. package/dist/ui/dialog.d.ts.map +1 -1
  229. package/dist/ui/dialog.js +62 -61
  230. package/dist/ui/dialog.js.map +1 -1
  231. package/dist/ui/dot.d.ts.map +1 -1
  232. package/dist/ui/dot.js +10 -41
  233. package/dist/ui/dot.js.map +1 -1
  234. package/dist/ui/dropdown-menu.d.ts.map +1 -1
  235. package/dist/ui/dropdown-menu.js +79 -78
  236. package/dist/ui/dropdown-menu.js.map +1 -1
  237. package/dist/ui/file-upload.d.ts.map +1 -1
  238. package/dist/ui/file-upload.js +117 -116
  239. package/dist/ui/file-upload.js.map +1 -1
  240. package/dist/ui/form.d.ts.map +1 -1
  241. package/dist/ui/form.js +27 -26
  242. package/dist/ui/form.js.map +1 -1
  243. package/dist/ui/hover-card.d.ts.map +1 -1
  244. package/dist/ui/hover-card.js +26 -25
  245. package/dist/ui/hover-card.js.map +1 -1
  246. package/dist/ui/icon.js +7 -7
  247. package/dist/ui/index.d.ts +2 -2
  248. package/dist/ui/index.d.ts.map +1 -1
  249. package/dist/ui/index.js +3 -3
  250. package/dist/ui/index.js.map +1 -1
  251. package/dist/ui/input-otp.js +1 -1
  252. package/dist/ui/input-otp.js.map +1 -1
  253. package/dist/ui/input.js +8 -8
  254. package/dist/ui/input.js.map +1 -1
  255. package/dist/ui/menubar.d.ts.map +1 -1
  256. package/dist/ui/menubar.js +73 -72
  257. package/dist/ui/menubar.js.map +1 -1
  258. package/dist/ui/navigation-menu.d.ts.map +1 -1
  259. package/dist/ui/navigation-menu.js +80 -79
  260. package/dist/ui/navigation-menu.js.map +1 -1
  261. package/dist/ui/number-input.js +3 -3
  262. package/dist/ui/number-input.js.map +1 -1
  263. package/dist/ui/pagination.js +1 -1
  264. package/dist/ui/pagination.js.map +1 -1
  265. package/dist/ui/popover.d.ts.map +1 -1
  266. package/dist/ui/progress-ring.js +2 -2
  267. package/dist/ui/progress-ring.js.map +1 -1
  268. package/dist/ui/progress.d.ts.map +1 -1
  269. package/dist/ui/progress.js +82 -74
  270. package/dist/ui/progress.js.map +1 -1
  271. package/dist/ui/radio.d.ts.map +1 -1
  272. package/dist/ui/radio.js +32 -31
  273. package/dist/ui/radio.js.map +1 -1
  274. package/dist/ui/search-input.d.ts.map +1 -1
  275. package/dist/ui/search-input.js +28 -27
  276. package/dist/ui/search-input.js.map +1 -1
  277. package/dist/ui/select.d.ts.map +1 -1
  278. package/dist/ui/select.js +67 -66
  279. package/dist/ui/select.js.map +1 -1
  280. package/dist/ui/sheet.js +1 -1
  281. package/dist/ui/sheet.js.map +1 -1
  282. package/dist/ui/sidebar.d.ts.map +1 -1
  283. package/dist/ui/sidebar.js +14 -14
  284. package/dist/ui/sidebar.js.map +1 -1
  285. package/dist/ui/slider.d.ts +63 -9
  286. package/dist/ui/slider.d.ts.map +1 -1
  287. package/dist/ui/slider.js +75 -33
  288. package/dist/ui/slider.js.map +1 -1
  289. package/dist/ui/split-button.d.ts +8 -2
  290. package/dist/ui/split-button.d.ts.map +1 -1
  291. package/dist/ui/split-button.js +49 -95
  292. package/dist/ui/split-button.js.map +1 -1
  293. package/dist/ui/stat-card.d.ts.map +1 -1
  294. package/dist/ui/stat-card.js +89 -88
  295. package/dist/ui/stat-card.js.map +1 -1
  296. package/dist/ui/stat-flash.js +16 -16
  297. package/dist/ui/stepper.d.ts.map +1 -1
  298. package/dist/ui/stepper.js +63 -62
  299. package/dist/ui/stepper.js.map +1 -1
  300. package/dist/ui/surface.d.ts.map +1 -1
  301. package/dist/ui/surface.js +2 -2
  302. package/dist/ui/surface.js.map +1 -1
  303. package/dist/ui/switch.js +1 -1
  304. package/dist/ui/switch.js.map +1 -1
  305. package/dist/ui/table.js +3 -3
  306. package/dist/ui/table.js.map +1 -1
  307. package/dist/ui/tabs.d.ts.map +1 -1
  308. package/dist/ui/tabs.js +68 -67
  309. package/dist/ui/tabs.js.map +1 -1
  310. package/dist/ui/textarea.js +5 -5
  311. package/dist/ui/textarea.js.map +1 -1
  312. package/dist/ui/toast.d.ts.map +1 -1
  313. package/dist/ui/toast.js +196 -195
  314. package/dist/ui/toast.js.map +1 -1
  315. package/dist/ui/toggle.d.ts.map +1 -1
  316. package/dist/ui/toggle.js +26 -24
  317. package/dist/ui/toggle.js.map +1 -1
  318. package/dist/ui/tooltip.d.ts.map +1 -1
  319. package/dist/ui/tooltip.js +37 -36
  320. package/dist/ui/tooltip.js.map +1 -1
  321. package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
  322. package/docs/components/composed/avatar-group.md +4 -4
  323. package/docs/components/composed/diff.md +10 -2
  324. package/docs/components/composed/schedule-view.md +1 -1
  325. package/docs/components/shell/app-shell.md +132 -0
  326. package/docs/components/ui/avatar.md +1 -1
  327. package/docs/components/ui/button.md +1 -1
  328. package/docs/components/ui/chat.md +7 -1
  329. package/docs/components/ui/color-swatch.md +1 -1
  330. package/docs/components/ui/data-table-toolbar.md +6 -2
  331. package/docs/components/ui/data-table.md +41 -7
  332. package/docs/components/ui/dot.md +1 -1
  333. package/docs/components/ui/progress.md +1 -0
  334. package/docs/components/ui/surface.md +3 -3
  335. package/docs/components/ui/table.md +2 -2
  336. package/docs/recipes/customize-brand.md +58 -0
  337. package/docs/recipes/install-astro.md +1 -0
  338. package/docs/recipes/install-next-app-router.md +1 -0
  339. package/docs/recipes/install-next-pages.md +22 -1
  340. package/docs/recipes/install-remix.md +1 -0
  341. package/docs/recipes/install-tanstack-start.md +1 -0
  342. package/docs/recipes/install-vite.md +2 -0
  343. package/docs/recipes/server-components.md +7 -4
  344. package/docs/recipes/troubleshoot.md +1 -0
  345. package/llms.txt +2 -1
  346. package/make-kit/Guidelines.md +2 -2
  347. package/make-kit/components/button.md +1 -1
  348. package/make-kit/components/card.md +6 -6
  349. package/make-kit/components/surface.md +4 -4
  350. package/make-kit/foundations/color.md +4 -4
  351. package/make-kit/foundations/dark-mode.md +1 -1
  352. package/make-kit/foundations/radius.md +1 -1
  353. package/make-kit/foundations/surfaces.md +9 -9
  354. package/mcp-manifest.json +358 -35
  355. package/package.json +8 -4
  356. package/skill/SKILL.md +12 -6
  357. package/skill/references/components.md +2 -1
  358. package/skill/references/customize-brand.md +58 -0
  359. package/skill/references/server-components.md +7 -4
  360. package/skill/references/setup-astro.md +1 -0
  361. package/skill/references/setup-next-app-router.md +1 -0
  362. package/skill/references/setup-next-pages.md +22 -1
  363. package/skill/references/setup-remix.md +1 -0
  364. package/skill/references/setup-tanstack-start.md +1 -0
  365. package/skill/references/setup-vite.md +2 -0
  366. package/skill/references/troubleshoot.md +1 -0
  367. package/dist/motion/check-motion-provider.d.ts +0 -2
  368. package/dist/motion/check-motion-provider.d.ts.map +0 -1
  369. package/dist/motion/index.js.map +0 -1
  370. package/dist/primitives/react-toast.d.ts +0 -120
  371. package/dist/ui/charts/_internal/scales.d.ts +0 -5
  372. package/dist/ui/charts/_internal/scales.d.ts.map +0 -1
  373. package/dist/ui/lib/slot.d.ts +0 -8
  374. package/dist/ui/lib/slot.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"color-input.js","names":[],"sources":["../../src/ui/color-input.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\nimport { HexColorPicker } from 'react-colorful'\n\nimport { useFormField } from './form'\nimport { durations,springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\n// ── Color conversion helpers ──\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex)\n if (!m) return null\n const n = parseInt(m[1], 16)\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 }\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('')\n}\n\nfunction hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255\n const max = Math.max(r, g, b), min = Math.min(r, g, b)\n const l = (max + min) / 2\n if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) }\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max - min)\n let h = 0\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n else if (max === g) h = ((b - r) / d + 2) / 6\n else h = ((r - g) / d + 4) / 6\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) }\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n const sn = s / 100, ln = l / 100\n const a = sn * Math.min(ln, 1 - ln)\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n const c = ln - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n return Math.round(255 * c)\n }\n return rgbToHex(f(0), f(8), f(4))\n}\n\n// ── Named color presets ──\n// Brand spectrum derived from our OKLCH scales (step-9), spanning the wheel —\n// intentional and on-brand, NOT the raw framework palette. Led by red, not indigo.\n\nconst NAMED_PRESETS: { hex: string; label: string }[] = [\n { hex: '#C53637', label: 'Red' },\n { hex: '#BE5A0A', label: 'Orange' },\n { hex: '#DF911A', label: 'Amber' },\n { hex: '#308639', label: 'Green' },\n { hex: '#118659', label: 'Emerald' },\n { hex: '#11846E', label: 'Teal' },\n { hex: '#028A9B', label: 'Cyan' },\n { hex: '#1479B0', label: 'Blue' },\n { hex: '#7D5FAD', label: 'Purple' },\n { hex: '#C22D6D', label: 'Pink' },\n]\n\n// ── Contrast helper ──\n\nfunction isLightColor(hex: string): boolean {\n const rgb = hexToRgb(hex)\n if (!rgb) return false\n // Relative luminance (sRGB)\n const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {\n const s = c / 255\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)\n })\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.4\n}\n\n// ── Format mode type ──\n\ntype ColorFormat = 'hex' | 'rgb' | 'hsl'\n\n// ── Props ──\n\nexport interface ColorInputProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Current color value (hex string, e.g. \"#d33163\") */\n value?: string\n /** Called when the color changes */\n onChange?: (value: string) => void\n /** Preset color swatches. Defaults to 10 named colors. Pass `false` to hide. */\n presets?: { hex: string; label: string }[] | string[] | false\n /** Whether the input is disabled */\n disabled?: boolean\n /** Show the interactive color picker. Default: true. */\n showPicker?: boolean\n /** Default format for the input fields. Default: 'hex'. */\n defaultFormat?: ColorFormat\n /** Popover alignment. Default: 'start'. */\n align?: 'start' | 'center' | 'end'\n /**\n * Trigger style variant.\n * - `default`: Swatch bleeds to left edge + hex text\n * - `inline`: Entire trigger is the selected color with hex text overlaid\n */\n variant?: 'default' | 'inline'\n}\n\n// ── Small format input ──\n\nfunction FormatInput({\n label,\n value,\n onChange,\n onBlur,\n disabled,\n maxLength = 3,\n prefix,\n className,\n id,\n}: {\n label: string\n value: string\n onChange: (v: string) => void\n onBlur?: () => void\n disabled?: boolean\n maxLength?: number\n prefix?: string\n className?: string\n id: string\n}) {\n return (\n <div className={cn('flex flex-col gap-ds-01', className)}>\n <label htmlFor={id} className=\"text-label-xs font-medium uppercase tracking-wider text-surface-fg-muted\">\n {label}\n </label>\n <div className=\"flex items-center\">\n {prefix && (\n <span className=\"text-body-sm text-surface-fg-muted\">{prefix}</span>\n )}\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n maxLength={maxLength}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control-inner border border-surface-border bg-surface-overlay px-ds-02 font-mono text-body-sm text-surface-fg transition-colors',\n 'focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n />\n </div>\n </div>\n )\n}\n\n// ── Main component ──\n\nconst ColorInput = React.forwardRef<HTMLDivElement, ColorInputProps>(\n ({\n value = '#000000',\n onChange,\n presets,\n disabled = false,\n showPicker = true,\n defaultFormat = 'hex',\n align = 'start',\n variant = 'default',\n className,\n id: externalId,\n ...props\n }, ref) => {\n const [format, setFormat] = React.useState<ColorFormat>(defaultFormat)\n const [open, setOpen] = React.useState(false)\n const instanceId = React.useId()\n const fieldCtx = useFormField()\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor> resolves\n // onto the (labelable) trigger button. The root is a <div>, which can't be a label target.\n const triggerId = externalId ?? fieldCtx.inputId\n\n // Internal color state — syncs with prop, allows uncontrolled use\n const [internalColor, setInternalColor] = React.useState(value)\n // Draft state for the hex field so in-progress (<6 char) typing isn't clobbered\n // by re-renders off internalColor. null = show the committed color.\n const [hexDraft, setHexDraft] = React.useState<string | null>(null)\n React.useEffect(() => { setInternalColor(value); setHexDraft(null) }, [value])\n\n // Track color when popover opened (for reset) + undo history\n const [openColor, setOpenColor] = React.useState(value)\n const [undoStack, setUndoStack] = React.useState<string[]>([])\n // Track whether current change is from continuous drag (skip undo push)\n const isDragging = React.useRef(false)\n\n const handleOpenChange = (isOpen: boolean) => {\n if (disabled) return\n if (isOpen) {\n setOpenColor(internalColor)\n setUndoStack([])\n }\n setHexDraft(null)\n setOpen(isOpen)\n }\n\n // Discrete change (preset click, field commit) — pushes to undo\n const handleDiscreteChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n setInternalColor(hex)\n setHexDraft(null)\n onChange?.(hex)\n }\n\n // Continuous change (picker drag) — updates color but only pushes undo on drag start\n const handleChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n if (!isDragging.current) {\n // First change in a drag sequence — push current color to undo\n isDragging.current = true\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n }\n setInternalColor(hex)\n onChange?.(hex)\n }\n\n // Called when picker drag ends\n const handlePickerChangeComplete = () => {\n isDragging.current = false\n }\n\n const handleUndo = () => {\n if (undoStack.length === 0) return\n const prev = undoStack[undoStack.length - 1]\n setUndoStack((s) => s.slice(0, -1))\n setInternalColor(prev)\n onChange?.(prev)\n }\n\n const handleReset = () => {\n setInternalColor(openColor)\n onChange?.(openColor)\n setUndoStack([])\n }\n\n // Resolve presets\n const resolvedPresets = presets === false\n ? []\n : presets\n ? presets.map((p) =>\n typeof p === 'string' ? { hex: p, label: p } : p\n )\n : NAMED_PRESETS\n\n // Parsed color values — use internal state\n const rgb = hexToRgb(internalColor)\n const hsl = hexToHsl(internalColor)\n\n // RGB field handlers (clamped 0-255)\n const handleRgbChange = (channel: 'r' | 'g' | 'b', v: string) => {\n if (!rgb) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const clamped = Math.max(0, Math.min(255, num))\n handleDiscreteChange(rgbToHex(\n channel === 'r' ? clamped : rgb.r,\n channel === 'g' ? clamped : rgb.g,\n channel === 'b' ? clamped : rgb.b,\n ))\n }\n\n // HSL field handlers (H: 0-360, S/L: 0-100)\n const handleHslChange = (channel: 'h' | 's' | 'l', v: string) => {\n if (!hsl) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const max = channel === 'h' ? 360 : 100\n const clamped = Math.max(0, Math.min(max, num))\n handleDiscreteChange(hslToHex(\n channel === 'h' ? clamped : hsl.h,\n channel === 's' ? clamped : hsl.s,\n channel === 'l' ? clamped : hsl.l,\n ))\n }\n\n const formats: ColorFormat[] = ['hex', 'rgb', 'hsl']\n\n return (\n <div ref={ref} className={cn('inline-flex flex-col', className)} {...props}>\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n {variant === 'inline' ? (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium',\n 'focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n animate={{\n backgroundColor: internalColor,\n color: isLightColor(internalColor) ? 'rgba(0,0,0,0.8)' : 'rgba(255,255,255,0.95)',\n }}\n whileHover={{ y: -1, boxShadow: '0 4px 12px rgba(0,0,0,0.12)' }}\n whileTap={{ scale: 0.97 }}\n transition={springs.smooth}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {internalColor.toUpperCase()}\n </motion.button>\n ) : (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong',\n 'hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {/* Gradient background: color → surface */}\n <motion.span\n className=\"absolute inset-0\"\n animate={{\n background: `linear-gradient(to right, ${internalColor} 0%, ${internalColor} 35%, transparent 70%)`,\n }}\n /* Between durations.moderate02 (0.24) and durations.slow01 (0.4) — gradient lerp feel */\n transition={{ duration: 0.3 }}\n />\n <span className=\"absolute inset-0 bg-surface-overlay/60\" style={{\n maskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n WebkitMaskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n }} />\n {/* Hex value */}\n <span className=\"relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg\">\n {internalColor.toUpperCase()}\n </span>\n </motion.button>\n )}\n </PopoverTrigger>\n\n <PopoverContent\n role=\"dialog\"\n aria-label=\"Color picker\"\n align={align}\n sideOffset={8}\n className=\"w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n >\n <div className=\"flex flex-col\">\n {/* Interactive picker */}\n {showPicker && (\n <div className=\"p-ds-04 pb-ds-03\" onPointerUp={handlePickerChangeComplete} onPointerLeave={handlePickerChangeComplete}>\n <HexColorPicker\n color={internalColor}\n onChange={handleChange}\n className=\"w-full!\"\n style={{ height: 160 }}\n />\n </div>\n )}\n\n {/* Format inputs */}\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n {/* Format switcher */}\n <div className=\"mb-ds-03 flex items-center gap-ds-01\">\n {formats.map((f) => (\n <button\n key={f}\n type=\"button\"\n onClick={() => setFormat(f)}\n className={cn(\n 'relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors',\n format === f\n ? 'text-accent-11'\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {format === f && (\n <motion.span\n layoutId={`color-input-format-pill-${instanceId}`}\n className=\"absolute inset-0 rounded-control-inner bg-accent-3\"\n transition={springs.snappy}\n />\n )}\n <span className=\"relative z-10\">{f}</span>\n </button>\n ))}\n </div>\n\n {/* Format fields — animated swap */}\n <AnimatePresence mode=\"wait\">\n {format === 'hex' && (\n <motion.div\n key=\"hex\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput\n id={`${instanceId}-hex`}\n label=\"Hex\"\n value={hexDraft ?? internalColor.replace('#', '').toUpperCase()}\n onChange={(v) => {\n const clean = v.replace(/[^0-9a-fA-F]/g, '').slice(0, 6)\n setHexDraft(clean.toUpperCase())\n if (clean.length === 6) handleDiscreteChange(`#${clean}`)\n }}\n onBlur={() => {\n // Drop any incomplete draft; display falls back to the\n // committed color. A complete value already committed onChange.\n setHexDraft(null)\n }}\n disabled={disabled}\n maxLength={6}\n prefix=\"#\"\n className=\"flex-1\"\n />\n </motion.div>\n )}\n\n {format === 'rgb' && rgb && (\n <motion.div\n key=\"rgb\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-r`} label=\"R\" value={String(rgb.r)} onChange={(v) => handleRgbChange('r', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-g`} label=\"G\" value={String(rgb.g)} onChange={(v) => handleRgbChange('g', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-b`} label=\"B\" value={String(rgb.b)} onChange={(v) => handleRgbChange('b', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n\n {format === 'hsl' && hsl && (\n <motion.div\n key=\"hsl\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-h`} label=\"H\" value={String(hsl.h)} onChange={(v) => handleHslChange('h', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-s`} label=\"S\" value={String(hsl.s)} onChange={(v) => handleHslChange('s', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-l`} label=\"L\" value={String(hsl.l)} onChange={(v) => handleHslChange('l', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Preset swatches */}\n {resolvedPresets.length > 0 && (\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n <div className=\"flex flex-wrap gap-ds-02\">\n {resolvedPresets.map((preset, i) => {\n const isSelected = internalColor.toLowerCase() === preset.hex.toLowerCase()\n return (\n <motion.button\n key={preset.hex}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleDiscreteChange(preset.hex)}\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: isSelected ? 1.15 : 1 }}\n whileHover={{ scale: isSelected ? 1.15 : 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={{ ...springs.bouncy, delay: i * 0.02 }}\n className={cn(\n 'h-6 w-6 rounded-control-inner border',\n isSelected\n ? 'border-accent-7 ring-2 ring-accent-9/30'\n : 'border-surface-border hover:border-surface-border-strong',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n style={{ backgroundColor: preset.hex }}\n title={preset.label}\n aria-label={`${preset.label}: ${preset.hex}`}\n />\n )\n })}\n </div>\n </div>\n )}\n\n {/* Reset / Undo footer */}\n {(undoStack.length > 0 || internalColor !== openColor) && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n className=\"flex items-center gap-ds-02 border-t border-surface-border px-ds-04 py-ds-02\"\n >\n {/* Original color preview */}\n <span\n className=\"h-4 w-4 shrink-0 rounded-pill border border-surface-border\"\n style={{ backgroundColor: openColor }}\n title={`Original: ${openColor}`}\n />\n <span className=\"text-caption text-surface-fg-muted\">\n {openColor.toUpperCase()}\n </span>\n <span className=\"flex-1\" />\n {undoStack.length > 0 && (\n <button\n type=\"button\"\n onClick={handleUndo}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg\"\n >\n Undo\n </button>\n )}\n {internalColor !== openColor && (\n <button\n type=\"button\"\n onClick={handleReset}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11\"\n >\n Reset\n </button>\n )}\n </motion.div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n )\n },\n)\nColorInput.displayName = 'ColorInput'\n\nexport { ColorInput }\n"],"mappings":"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"}
1
+ {"version":3,"file":"color-input.js","names":[],"sources":["../../src/ui/color-input.tsx"],"sourcesContent":["'use client'\n\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\nimport { HexColorPicker } from 'react-colorful'\n\nimport { MotionPreference } from '../motion/motion-preference'\nimport { useFormField } from './form'\nimport { durations,springs } from './lib/motion'\nimport { cn } from './lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from './popover'\n\n// ── Color conversion helpers ──\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex)\n if (!m) return null\n const n = parseInt(m[1], 16)\n return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 }\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('')\n}\n\nfunction hexToHsl(hex: string): { h: number; s: number; l: number } | null {\n const rgb = hexToRgb(hex)\n if (!rgb) return null\n const r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255\n const max = Math.max(r, g, b), min = Math.min(r, g, b)\n const l = (max + min) / 2\n if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) }\n const d = max - min\n const s = l > 0.5 ? d / (2 - max - min) : d / (max - min)\n let h = 0\n if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6\n else if (max === g) h = ((b - r) / d + 2) / 6\n else h = ((r - g) / d + 4) / 6\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) }\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n const sn = s / 100, ln = l / 100\n const a = sn * Math.min(ln, 1 - ln)\n const f = (n: number) => {\n const k = (n + h / 30) % 12\n const c = ln - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n return Math.round(255 * c)\n }\n return rgbToHex(f(0), f(8), f(4))\n}\n\n// ── Named color presets ──\n// Brand spectrum derived from our OKLCH scales (step-9), spanning the wheel —\n// intentional and on-brand, NOT the raw framework palette. Led by red, not indigo.\n\nconst NAMED_PRESETS: { hex: string; label: string }[] = [\n { hex: '#C53637', label: 'Red' },\n { hex: '#BE5A0A', label: 'Orange' },\n { hex: '#DF911A', label: 'Amber' },\n { hex: '#308639', label: 'Green' },\n { hex: '#118659', label: 'Emerald' },\n { hex: '#11846E', label: 'Teal' },\n { hex: '#028A9B', label: 'Cyan' },\n { hex: '#1479B0', label: 'Blue' },\n { hex: '#7D5FAD', label: 'Purple' },\n { hex: '#C22D6D', label: 'Pink' },\n]\n\n// ── Contrast helper ──\n\nfunction isLightColor(hex: string): boolean {\n const rgb = hexToRgb(hex)\n if (!rgb) return false\n // Relative luminance (sRGB)\n const [r, g, b] = [rgb.r, rgb.g, rgb.b].map((c) => {\n const s = c / 255\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4)\n })\n return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.4\n}\n\n// ── Format mode type ──\n\ntype ColorFormat = 'hex' | 'rgb' | 'hsl'\n\n// ── Props ──\n\nexport interface ColorInputProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Current color value (hex string, e.g. \"#d33163\") */\n value?: string\n /** Called when the color changes */\n onChange?: (value: string) => void\n /** Preset color swatches. Defaults to 10 named colors. Pass `false` to hide. */\n presets?: { hex: string; label: string }[] | string[] | false\n /** Whether the input is disabled */\n disabled?: boolean\n /** Show the interactive color picker. Default: true. */\n showPicker?: boolean\n /** Default format for the input fields. Default: 'hex'. */\n defaultFormat?: ColorFormat\n /** Popover alignment. Default: 'start'. */\n align?: 'start' | 'center' | 'end'\n /**\n * Trigger style variant.\n * - `default`: Swatch bleeds to left edge + hex text\n * - `inline`: Entire trigger is the selected color with hex text overlaid\n */\n variant?: 'default' | 'inline'\n}\n\n// ── Small format input ──\n\nfunction FormatInput({\n label,\n value,\n onChange,\n onBlur,\n disabled,\n maxLength = 3,\n prefix,\n className,\n id,\n}: {\n label: string\n value: string\n onChange: (v: string) => void\n onBlur?: () => void\n disabled?: boolean\n maxLength?: number\n prefix?: string\n className?: string\n id: string\n}) {\n return (\n <div className={cn('flex flex-col gap-ds-01', className)}>\n <label htmlFor={id} className=\"text-label-xs font-medium uppercase tracking-wider text-surface-fg-muted\">\n {label}\n </label>\n <div className=\"flex items-center\">\n {prefix && (\n <span className=\"text-body-sm text-surface-fg-muted\">{prefix}</span>\n )}\n <input\n id={id}\n type=\"text\"\n value={value}\n disabled={disabled}\n onChange={(e) => onChange(e.target.value)}\n onBlur={onBlur}\n maxLength={maxLength}\n className={cn(\n 'h-ds-xs-plus w-full rounded-control-inner border border-surface-border-interactive bg-surface-overlay px-ds-02 font-mono text-body-sm text-surface-fg transition-colors',\n 'focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n />\n </div>\n </div>\n )\n}\n\n// ── Main component ──\n\nconst ColorInput = React.forwardRef<HTMLDivElement, ColorInputProps>(\n ({\n value = '#000000',\n onChange,\n presets,\n disabled = false,\n showPicker = true,\n defaultFormat = 'hex',\n align = 'start',\n variant = 'default',\n className,\n id: externalId,\n ...props\n }, ref) => {\n const [format, setFormat] = React.useState<ColorFormat>(defaultFormat)\n const [open, setOpen] = React.useState(false)\n const instanceId = React.useId()\n const fieldCtx = useFormField()\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor> resolves\n // onto the (labelable) trigger button. The root is a <div>, which can't be a label target.\n const triggerId = externalId ?? fieldCtx.inputId\n\n // Internal color state — syncs with prop, allows uncontrolled use\n const [internalColor, setInternalColor] = React.useState(value)\n // Draft state for the hex field so in-progress (<6 char) typing isn't clobbered\n // by re-renders off internalColor. null = show the committed color.\n const [hexDraft, setHexDraft] = React.useState<string | null>(null)\n React.useEffect(() => { setInternalColor(value); setHexDraft(null) }, [value])\n\n // Track color when popover opened (for reset) + undo history\n const [openColor, setOpenColor] = React.useState(value)\n const [undoStack, setUndoStack] = React.useState<string[]>([])\n // Track whether current change is from continuous drag (skip undo push)\n const isDragging = React.useRef(false)\n\n const handleOpenChange = (isOpen: boolean) => {\n if (disabled) return\n if (isOpen) {\n setOpenColor(internalColor)\n setUndoStack([])\n }\n setHexDraft(null)\n setOpen(isOpen)\n }\n\n // Discrete change (preset click, field commit) — pushes to undo\n const handleDiscreteChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n setInternalColor(hex)\n setHexDraft(null)\n onChange?.(hex)\n }\n\n // Continuous change (picker drag) — updates color but only pushes undo on drag start\n const handleChange = (newValue: string) => {\n if (disabled) return\n const normalized = newValue.startsWith('#') ? newValue : `#${newValue}`\n const hex = normalized.toLowerCase()\n if (!isDragging.current) {\n // First change in a drag sequence — push current color to undo\n isDragging.current = true\n setUndoStack((prev) => {\n if (prev[prev.length - 1] === internalColor) return prev\n return [...prev.slice(-19), internalColor]\n })\n }\n setInternalColor(hex)\n onChange?.(hex)\n }\n\n // Called when picker drag ends\n const handlePickerChangeComplete = () => {\n isDragging.current = false\n }\n\n const handleUndo = () => {\n if (undoStack.length === 0) return\n const prev = undoStack[undoStack.length - 1]\n setUndoStack((s) => s.slice(0, -1))\n setInternalColor(prev)\n onChange?.(prev)\n }\n\n const handleReset = () => {\n setInternalColor(openColor)\n onChange?.(openColor)\n setUndoStack([])\n }\n\n // Resolve presets\n const resolvedPresets = presets === false\n ? []\n : presets\n ? presets.map((p) =>\n typeof p === 'string' ? { hex: p, label: p } : p\n )\n : NAMED_PRESETS\n\n // Parsed color values — use internal state\n const rgb = hexToRgb(internalColor)\n const hsl = hexToHsl(internalColor)\n\n // RGB field handlers (clamped 0-255)\n const handleRgbChange = (channel: 'r' | 'g' | 'b', v: string) => {\n if (!rgb) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const clamped = Math.max(0, Math.min(255, num))\n handleDiscreteChange(rgbToHex(\n channel === 'r' ? clamped : rgb.r,\n channel === 'g' ? clamped : rgb.g,\n channel === 'b' ? clamped : rgb.b,\n ))\n }\n\n // HSL field handlers (H: 0-360, S/L: 0-100)\n const handleHslChange = (channel: 'h' | 's' | 'l', v: string) => {\n if (!hsl) return\n const num = parseInt(v, 10)\n if (isNaN(num)) return\n const max = channel === 'h' ? 360 : 100\n const clamped = Math.max(0, Math.min(max, num))\n handleDiscreteChange(hslToHex(\n channel === 'h' ? clamped : hsl.h,\n channel === 's' ? clamped : hsl.s,\n channel === 'l' ? clamped : hsl.l,\n ))\n }\n\n const formats: ColorFormat[] = ['hex', 'rgb', 'hsl']\n\n return (\n <MotionPreference>\n <div ref={ref} className={cn('inline-flex flex-col', className)} {...props}>\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger asChild>\n {variant === 'inline' ? (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium',\n 'focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n animate={{\n backgroundColor: internalColor,\n color: isLightColor(internalColor) ? 'rgba(0,0,0,0.8)' : 'rgba(255,255,255,0.95)',\n }}\n whileHover={{ y: -1, boxShadow: '0 4px 12px rgba(0,0,0,0.12)' }}\n whileTap={{ scale: 0.97 }}\n transition={springs.smooth}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {internalColor.toUpperCase()}\n </motion.button>\n ) : (\n <motion.button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'group relative flex items-center overflow-hidden rounded-control border border-surface-border-interactive',\n 'hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n id={triggerId}\n aria-describedby={fieldCtx.helperTextId}\n aria-invalid={fieldCtx.state === 'error' || undefined}\n // Inside a FormField, let the visible <Label> name the trigger; else describe it.\n aria-label={fieldCtx.inputId ? undefined : `Color picker: ${internalColor}`}\n >\n {/* Gradient background: color → surface */}\n <motion.span\n className=\"absolute inset-0\"\n animate={{\n background: `linear-gradient(to right, ${internalColor} 0%, ${internalColor} 35%, transparent 70%)`,\n }}\n /* Between durations.moderate02 (0.24) and durations.slow01 (0.4) — gradient lerp feel */\n transition={{ duration: 0.3 }}\n />\n <span className=\"absolute inset-0 bg-surface-overlay/60\" style={{\n maskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n WebkitMaskImage: 'linear-gradient(to right, transparent 0%, black 40%)',\n }} />\n {/* Hex value */}\n <span className=\"relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg\">\n {internalColor.toUpperCase()}\n </span>\n </motion.button>\n )}\n </PopoverTrigger>\n\n <PopoverContent\n role=\"dialog\"\n aria-label=\"Color picker\"\n align={align}\n sideOffset={8}\n className=\"w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating\"\n >\n <div className=\"flex flex-col\">\n {/* Interactive picker */}\n {showPicker && (\n <div className=\"p-ds-04 pb-ds-03\" onPointerUp={handlePickerChangeComplete} onPointerLeave={handlePickerChangeComplete}>\n <HexColorPicker\n color={internalColor}\n onChange={handleChange}\n className=\"w-full!\"\n style={{ height: 160 }}\n />\n </div>\n )}\n\n {/* Format inputs */}\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n {/* Format switcher */}\n <div className=\"mb-ds-03 flex items-center gap-ds-01\">\n {formats.map((f) => (\n <button\n key={f}\n type=\"button\"\n onClick={() => setFormat(f)}\n className={cn(\n 'relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors',\n format === f\n ? 'text-accent-11'\n : 'text-surface-fg-muted hover:text-surface-fg',\n )}\n >\n {format === f && (\n <motion.span\n layoutId={`color-input-format-pill-${instanceId}`}\n className=\"absolute inset-0 rounded-control-inner bg-accent-4\"\n transition={springs.snappy}\n />\n )}\n <span className=\"relative z-10\">{f}</span>\n </button>\n ))}\n </div>\n\n {/* Format fields — animated swap */}\n <AnimatePresence mode=\"wait\">\n {format === 'hex' && (\n <motion.div\n key=\"hex\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput\n id={`${instanceId}-hex`}\n label=\"Hex\"\n value={hexDraft ?? internalColor.replace('#', '').toUpperCase()}\n onChange={(v) => {\n const clean = v.replace(/[^0-9a-fA-F]/g, '').slice(0, 6)\n setHexDraft(clean.toUpperCase())\n if (clean.length === 6) handleDiscreteChange(`#${clean}`)\n }}\n onBlur={() => {\n // Drop any incomplete draft; display falls back to the\n // committed color. A complete value already committed onChange.\n setHexDraft(null)\n }}\n disabled={disabled}\n maxLength={6}\n prefix=\"#\"\n className=\"flex-1\"\n />\n </motion.div>\n )}\n\n {format === 'rgb' && rgb && (\n <motion.div\n key=\"rgb\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-r`} label=\"R\" value={String(rgb.r)} onChange={(v) => handleRgbChange('r', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-g`} label=\"G\" value={String(rgb.g)} onChange={(v) => handleRgbChange('g', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-b`} label=\"B\" value={String(rgb.b)} onChange={(v) => handleRgbChange('b', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n\n {format === 'hsl' && hsl && (\n <motion.div\n key=\"hsl\"\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: durations.moderate01 }}\n className=\"flex gap-ds-02\"\n >\n <FormatInput id={`${instanceId}-h`} label=\"H\" value={String(hsl.h)} onChange={(v) => handleHslChange('h', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-s`} label=\"S\" value={String(hsl.s)} onChange={(v) => handleHslChange('s', v)} disabled={disabled} className=\"flex-1\" />\n <FormatInput id={`${instanceId}-l`} label=\"L\" value={String(hsl.l)} onChange={(v) => handleHslChange('l', v)} disabled={disabled} className=\"flex-1\" />\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* Preset swatches */}\n {resolvedPresets.length > 0 && (\n <div className=\"border-t border-surface-border px-ds-04 py-ds-03\">\n <div className=\"flex flex-wrap gap-ds-02\">\n {resolvedPresets.map((preset, i) => {\n const isSelected = internalColor.toLowerCase() === preset.hex.toLowerCase()\n return (\n <motion.button\n key={preset.hex}\n type=\"button\"\n disabled={disabled}\n onClick={() => handleDiscreteChange(preset.hex)}\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: isSelected ? 1.15 : 1 }}\n whileHover={{ scale: isSelected ? 1.15 : 1.1 }}\n whileTap={{ scale: 0.9 }}\n transition={{ ...springs.bouncy, delay: i * 0.02 }}\n className={cn(\n 'h-6 w-6 rounded-control-inner border',\n isSelected\n ? 'border-accent-7 ring-2 ring-accent-9/30'\n : 'border-surface-border-interactive hover:border-surface-border-interactive-strong',\n disabled && 'cursor-not-allowed opacity-50',\n )}\n style={{ backgroundColor: preset.hex }}\n title={preset.label}\n aria-label={`${preset.label}: ${preset.hex}`}\n />\n )\n })}\n </div>\n </div>\n )}\n\n {/* Reset / Undo footer */}\n {(undoStack.length > 0 || internalColor !== openColor) && (\n <motion.div\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n className=\"flex items-center gap-ds-02 border-t border-surface-border px-ds-04 py-ds-02\"\n >\n {/* Original color preview */}\n <span\n className=\"h-4 w-4 shrink-0 rounded-pill border border-surface-border\"\n style={{ backgroundColor: openColor }}\n title={`Original: ${openColor}`}\n />\n <span className=\"text-caption text-surface-fg-muted\">\n {openColor.toUpperCase()}\n </span>\n <span className=\"flex-1\" />\n {undoStack.length > 0 && (\n <button\n type=\"button\"\n onClick={handleUndo}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg\"\n >\n Undo\n </button>\n )}\n {internalColor !== openColor && (\n <button\n type=\"button\"\n onClick={handleReset}\n className=\"min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11\"\n >\n Reset\n </button>\n )}\n </motion.div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n </MotionPreference>\n )\n },\n)\nColorInput.displayName = 'ColorInput'\n\nexport { ColorInput }\n"],"mappings":"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"}
@@ -6,6 +6,8 @@ export declare const comboboxTriggerVariants: (props?: ({
6
6
  size?: "xs" | "sm" | "md" | "lg" | null | undefined;
7
7
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
8
8
  export type ComboboxSize = NonNullable<VariantProps<typeof comboboxTriggerVariants>['size']>;
9
+ /** Colour treatment for a selected pill. See `ComboboxProps.pillTone`. */
10
+ export type ComboboxPillTone = 'neutral' | 'accent';
9
11
  /**
10
12
  * Option shape for a Combobox dropdown item.
11
13
  * `value` must be unique across all options — it is the key used in selection state.
@@ -85,6 +87,18 @@ interface ComboboxBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, '
85
87
  size?: ComboboxSize;
86
88
  /** Validation/feedback state. `'error'` also sets `aria-invalid`. Inherited from `FormField` when omitted. */
87
89
  state?: FieldState;
90
+ /**
91
+ * How a selected pill is coloured.
92
+ *
93
+ * - `neutral` (default) — grey. A pill here is a removable token, not a
94
+ * selection, so the brand colour stays reserved for things that ARE
95
+ * selected. 1.12:1 light / 1.16:1 dark against the trigger.
96
+ * - `accent` — brand-tinted, for pickers where the tokens should feel like
97
+ * part of the brand. 1.30:1 light / 1.05:1 dark.
98
+ *
99
+ * @default 'neutral'
100
+ */
101
+ pillTone?: ComboboxPillTone;
88
102
  }
89
103
  interface ComboboxSingleProps extends ComboboxBaseProps {
90
104
  multiple?: false;
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAYjD,eAAO,MAAM,uBAAuB;;8EAsBnC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AA0B5F;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,UAAU,iBAAkB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACxF,+CAA+C;IAC/C,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oGAAoG;IACpG,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC7E,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,8GAA8G;IAC9G,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC;AAED,UAAU,qBAAsB,SAAQ,iBAAiB;IACvD,QAAQ,EAAE,IAAI,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAQvE,QAAA,MAAM,QAAQ,sFAyab,CAAA;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../src/ui/combobox.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAYjD,eAAO,MAAM,uBAAuB;;8EAsBnC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAE5F,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,CAAA;AAmCnD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,UAAU,iBAAkB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACxF,+CAA+C;IAC/C,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oGAAoG;IACpG,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC7E,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iFAAiF;IACjF,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,8GAA8G;IAC9G,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CAC5B;AAED,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC;AAED,UAAU,qBAAsB,SAAQ,iBAAiB;IACvD,QAAQ,EAAE,IAAI,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAQvE,QAAA,MAAM,QAAQ,sFA4ab,CAAA;AAGD,OAAO,EAAE,QAAQ,EAAE,CAAA"}