@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
package/dist/ui/card.js CHANGED
@@ -1,26 +1,27 @@
1
1
  "use client";
2
2
  import { motionProps as e, springs as t } from "./lib/motion.js";
3
- import { cn as n } from "./lib/utils.js";
4
- import * as r from "react";
5
- import { jsx as i } from "react/jsx-runtime";
6
- import { motion as a } from "framer-motion";
7
- import { cva as o } from "class-variance-authority";
3
+ import { MotionPreference as n } from "../_chunks/motion-preference.js";
4
+ import { cn as r } from "./lib/utils.js";
5
+ import * as i from "react";
6
+ import { jsx as a } from "react/jsx-runtime";
7
+ import { motion as o } from "framer-motion";
8
+ import { cva as s } from "class-variance-authority";
8
9
  //#region src/ui/card.tsx
9
- var s = o("relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard", {
10
+ var c = s("relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard", {
10
11
  variants: {
11
12
  variant: {
12
- default: "bg-surface-raised border border-card shadow-none",
13
- elevated: "bg-surface-raised border border-transparent shadow-raised-hover",
13
+ default: "bg-surface-panel border border-card shadow-none",
14
+ elevated: "bg-surface-panel border border-transparent shadow-raised-hover",
14
15
  outline: "bg-transparent border border-surface-border-strong shadow-none",
15
- flat: "bg-surface-raised border-none shadow-none"
16
+ flat: "bg-surface-panel border-none shadow-none"
16
17
  },
17
18
  color: {
18
19
  default: "",
19
- accent: "border-accent-7",
20
- error: "border-error-7",
21
- success: "border-success-7",
22
- warning: "border-warning-7",
23
- info: "border-info-7",
20
+ accent: "border-palette-border",
21
+ error: "border-palette-border",
22
+ success: "border-palette-border",
23
+ warning: "border-palette-border",
24
+ info: "border-palette-border",
24
25
  neutral: ""
25
26
  },
26
27
  size: {
@@ -39,90 +40,92 @@ var s = o("relative flex text-surface-fg rounded-surface transition-shadow durat
39
40
  size: "md",
40
41
  orientation: "vertical"
41
42
  }
42
- }), c = r.forwardRef(({ className: r, variant: o, color: c, size: l, orientation: u, interactive: d, children: f, ...p }, m) => {
43
- typeof process < "u" && process.env.NODE_ENV !== "production" && x(f);
44
- let h = n(s({
45
- variant: o,
46
- color: c,
47
- size: l,
48
- orientation: u
49
- }), d && "hover:shadow-raised-hover cursor-pointer transition-shadow duration-fast-02 ease-productive-standard", r);
50
- return d ? /* @__PURE__ */ i(a.div, {
51
- ref: m,
43
+ }), l = i.forwardRef(({ className: i, variant: s, color: l, size: u, orientation: d, interactive: f, children: p, ...m }, h) => {
44
+ typeof process < "u" && process.env.NODE_ENV !== "production" && S(p);
45
+ let g = r(c({
46
+ variant: s,
47
+ color: l,
48
+ size: u,
49
+ orientation: d
50
+ }), f && "hover:bg-surface-panel-hover cursor-pointer transition-colors duration-fast-02 ease-productive-standard", i);
51
+ return f ? /* @__PURE__ */ a(n, { children: /* @__PURE__ */ a(o.div, {
52
+ ref: h,
52
53
  whileHover: { y: -3 },
53
54
  whileTap: { scale: .98 },
54
55
  transition: t.snappy,
55
- className: h,
56
- ...e(p),
57
- children: f
58
- }) : /* @__PURE__ */ i("div", {
59
- ref: m,
60
- className: h,
61
- ...p,
62
- children: f
56
+ "data-palette": l ?? void 0,
57
+ className: g,
58
+ ...e(m),
59
+ children: p
60
+ }) }) : /* @__PURE__ */ a("div", {
61
+ ref: h,
62
+ "data-palette": l ?? void 0,
63
+ className: g,
64
+ ...m,
65
+ children: p
63
66
  });
64
67
  });
65
- c.displayName = "Card";
66
- var l = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
67
- ref: r,
68
- className: n("flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
68
+ l.displayName = "Card";
69
+ var u = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
70
+ ref: n,
71
+ className: r("flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
69
72
  ...t
70
73
  }));
71
- l.displayName = "CardHeader";
72
- var u = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
73
- ref: r,
74
- className: n("font-sans font-semibold leading-ds-none tracking-normal text-surface-fg", e),
74
+ u.displayName = "CardHeader";
75
+ var d = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
76
+ ref: n,
77
+ className: r("font-sans font-semibold leading-ds-none tracking-normal text-surface-fg", e),
75
78
  ...t
76
79
  }));
77
- u.displayName = "CardTitle";
78
- var d = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
79
- ref: r,
80
- className: n("text-body-md text-surface-fg-muted", e),
80
+ d.displayName = "CardTitle";
81
+ var f = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
82
+ ref: n,
83
+ className: r("text-body-md text-surface-fg-muted", e),
81
84
  ...t
82
85
  }));
83
- d.displayName = "CardDescription";
84
- var f = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
85
- ref: r,
86
- className: n("px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
86
+ f.displayName = "CardDescription";
87
+ var p = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
88
+ ref: n,
89
+ className: r("px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0", e),
87
90
  ...t
88
91
  }));
89
- f.displayName = "CardContent";
90
- var p = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
91
- ref: r,
92
- className: n("flex items-center gap-ds-03 px-(--card-spacing)", e),
92
+ p.displayName = "CardContent";
93
+ var m = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
94
+ ref: n,
95
+ className: r("flex items-center gap-ds-03 px-(--card-spacing)", e),
93
96
  ...t
94
97
  }));
95
- p.displayName = "CardFooter";
96
- var m = r.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ i("div", {
97
- ref: r,
98
- className: n("flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)", e),
98
+ m.displayName = "CardFooter";
99
+ var h = i.forwardRef(({ className: e, ...t }, n) => /* @__PURE__ */ a("div", {
100
+ ref: n,
101
+ className: r("flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)", e),
99
102
  ...t
100
103
  }));
101
- m.displayName = "CardSection";
102
- var h = {
104
+ h.displayName = "CardSection";
105
+ var g = {
103
106
  x: "-mx-(--card-spacing)",
104
107
  top: "-mt-(--card-spacing) rounded-t-surface overflow-hidden",
105
108
  bottom: "-mb-(--card-spacing) rounded-b-surface overflow-hidden",
106
109
  y: "-my-(--card-spacing) rounded-surface overflow-hidden",
107
110
  all: "-my-(--card-spacing) -mx-(--card-spacing) rounded-surface overflow-hidden"
108
- }, g = r.forwardRef(({ className: e, side: t = "x", ...r }, a) => /* @__PURE__ */ i("div", {
109
- ref: a,
110
- className: n(h[t], e),
111
- ...r
111
+ }, _ = i.forwardRef(({ className: e, side: t = "x", ...n }, i) => /* @__PURE__ */ a("div", {
112
+ ref: i,
113
+ className: r(g[t], e),
114
+ ...n
112
115
  }));
113
- g.displayName = "CardBleed";
114
- var _ = {
116
+ _.displayName = "CardBleed";
117
+ var v = {
115
118
  "top-right": "top-(--card-spacing) right-(--card-spacing)",
116
119
  "top-left": "top-(--card-spacing) left-(--card-spacing)",
117
120
  "bottom-right": "bottom-(--card-spacing) right-(--card-spacing)",
118
121
  "bottom-left": "bottom-(--card-spacing) left-(--card-spacing)"
119
- }, v = r.forwardRef(({ className: e, placement: t = "top-right", tuck: r, ...a }, o) => /* @__PURE__ */ i("div", {
122
+ }, y = i.forwardRef(({ className: e, placement: t = "top-right", tuck: n, ...i }, o) => /* @__PURE__ */ a("div", {
120
123
  ref: o,
121
- className: n("absolute z-[1] flex items-center gap-ds-02", _[t], r && "-m-ds-02", e),
122
- ...a
124
+ className: r("absolute z-[1] flex items-center gap-ds-02", v[t], n && "-m-ds-02", e),
125
+ ...i
123
126
  }));
124
- v.displayName = "CardAction";
125
- var y = /* @__PURE__ */ new Set([
127
+ y.displayName = "CardAction";
128
+ var b = /* @__PURE__ */ new Set([
126
129
  "p",
127
130
  "span",
128
131
  "h1",
@@ -136,12 +139,12 @@ var y = /* @__PURE__ */ new Set([
136
139
  "small",
137
140
  "strong",
138
141
  "em"
139
- ]), b = !1;
140
- function x(e) {
141
- b || r.Children.forEach(e, (e) => {
142
- let t = typeof e == "string" && e.trim() !== "", n = r.isValidElement(e) && typeof e.type == "string" && y.has(e.type);
143
- (t || n) && (b = !0, console.warn("[shilp-sutra] <Card> received text content as a direct child. Direct children span the full card width and get no horizontal inset — wrap text in <CardContent> (or <CardHeader>/<CardFooter>). See the Card docs, \"Composition\"."));
142
+ ]), x = !1;
143
+ function S(e) {
144
+ x || i.Children.forEach(e, (e) => {
145
+ let t = typeof e == "string" && e.trim() !== "", n = i.isValidElement(e) && typeof e.type == "string" && b.has(e.type);
146
+ (t || n) && (x = !0, console.warn("[shilp-sutra] <Card> received text content as a direct child. Direct children span the full card width and get no horizontal inset — wrap text in <CardContent> (or <CardHeader>/<CardFooter>). See the Card docs, \"Composition\"."));
144
147
  });
145
148
  }
146
149
  //#endregion
147
- export { c as Card, v as CardAction, g as CardBleed, f as CardContent, d as CardDescription, p as CardFooter, l as CardHeader, m as CardSection, u as CardTitle, s as cardVariants };
150
+ export { l as Card, y as CardAction, _ as CardBleed, p as CardContent, f as CardDescription, m as CardFooter, u as CardHeader, h as CardSection, d as CardTitle, c as cardVariants };
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","names":[],"sources":["../../src/ui/card.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { motionProps, springs } from './lib/motion'\nimport { cn } from './lib/utils'\n\n// Bundlers (Vite, Next.js, webpack) define process.env.NODE_ENV; guard for raw ESM.\ndeclare const process: { env: { NODE_ENV?: string } } | undefined\n\ntype CardSize = 'sm' | 'md' | 'lg'\n\nconst cardVariants = cva(\n // Gap model, variable-driven: `size` sets --card-spacing / --card-gap once on the\n // container; the container reads them for its vertical edge (py) and inter-slot\n // rhythm (gap), slots read the same variables for their horizontal inset (px), and\n // CardAction/CardBleed read them for corner offsets / negative margins. One variable\n // pair is the whole size system — override it with a single arbitrary property\n // (`[--card-spacing:var(--spacing-ds-07)]`) and every part follows.\n // No per-slot py, no pt-0, no per-element margins — adding/removing a slot can't\n // unbalance the bottom edge (make-kit rule: shadow ring is the edge, gap is the rhythm).\n // `relative` establishes the positioning context for <CardAction> corner slots.\n 'relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard',\n {\n variants: {\n variant: {\n // Tonal (default): depth from a surface-tone shift + a whisper hairline in the\n // surface's own colour (`border-card`), NO shadow — the DS-wide anti-slop edge\n // (Setu tonal-elevation). The `color` prop overrides the hairline colour to paint\n // a deliberate accent/status edge.\n default: 'bg-surface-raised border border-card shadow-none',\n // Elevation-led: the shadow's own ring is the edge (make-kit rule #6 — no\n // border+shadow double-edge). Reach for it when a card should visibly pop\n // (a dragged tile, a spotlight panel). border-transparent keeps `color` paintable.\n elevated: 'bg-surface-raised border border-transparent shadow-raised-hover',\n // Border-led, strong: a firmly visible edge, no shadow.\n outline: 'bg-transparent border border-surface-border-strong shadow-none',\n flat: 'bg-surface-raised border-none shadow-none',\n },\n color: {\n default: '',\n accent: 'border-accent-7',\n error: 'border-error-7',\n success: 'border-success-7',\n warning: 'border-warning-7',\n info: 'border-info-7',\n neutral: '',\n },\n // size only assigns the two variables; the orientation axis decides where\n // they're consumed (container in vertical, <CardSection> in horizontal).\n size: {\n sm: '[--card-spacing:var(--spacing-ds-05)] [--card-gap:var(--spacing-ds-03)]',\n md: '[--card-spacing:var(--spacing-ds-05b)] [--card-gap:var(--spacing-ds-04)]',\n lg: '[--card-spacing:var(--spacing-ds-06)] [--card-gap:var(--spacing-ds-05)]',\n },\n // vertical: the container owns py + gap (the default gap model).\n // horizontal: the container is a padding-less row; a <CardSection> child\n // re-establishes py + gap for the text column while a media pane owns an edge.\n orientation: {\n vertical: 'flex-col py-(--card-spacing) gap-(--card-gap)',\n horizontal: 'flex-row items-stretch',\n },\n },\n defaultVariants: { variant: 'default', color: 'default', size: 'md', orientation: 'vertical' },\n },\n)\n\n/**\n * Props for Card — a general-purpose content container with 4 elevation/style variants and\n * an optional interactive hover state.\n *\n * **Variants (tonal, elevation-led, or border-led — never border+shadow together):** `default`\n * (tonal — surface shift + `border-card` hairline, no shadow) | `elevated` (shadow-raised-hover,\n * no border — use when a card should visibly pop) | `outline` (strong visible border, no shadow) |\n * `flat` (filled background, no edge). The shadow tokens carry their own 1px ring, so `elevated`\n * needs no explicit border (make-kit rule #6).\n *\n * **Composition:** Use sub-components `<CardHeader>`, `<CardTitle>`, `<CardDescription>`,\n * `<CardContent>`, and `<CardFooter>` for consistent internal spacing. Text content must live\n * inside a slot — raw text as a direct child gets no horizontal inset (direct children span the\n * full card width by design, which is what makes full-width dividers and bands free).\n *\n * **Spacing:** `size` sets `--card-spacing` / `--card-gap` once; container, slots, `CardAction`,\n * and `CardBleed` all read the same pair. Retune a card with a single override:\n * `className=\"[--card-spacing:var(--spacing-ds-07)]\"`.\n *\n * **Interactive:** Pass `interactive` to enable hover shadow lift and pointer cursor —\n * useful for clickable cards in grids.\n *\n * @example\n * // Standard content card with header and body:\n * <Card>\n * <CardHeader>\n * <CardTitle>Project Alpha</CardTitle>\n * <CardDescription>Last updated 2 hours ago</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Sprint 4 is in progress with 12 open tasks.</p>\n * </CardContent>\n * </Card>\n *\n * @example\n * // Full-bleed cover image + edge-to-edge divider:\n * <Card>\n * <CardBleed side=\"top\"><img src={cover} alt=\"\" /></CardBleed>\n * <CardHeader><CardTitle>Muhurat launch site</CardTitle></CardHeader>\n * <Separator />\n * <CardFooter><Badge color=\"success\">On track</Badge></CardFooter>\n * </Card>\n *\n * @example\n * // Horizontal media card — media pane owns the left edge, CardSection restores rhythm:\n * <Card orientation=\"horizontal\">\n * <div className=\"w-32 shrink-0 rounded-l-surface overflow-hidden\">\n * <img src={thumb} alt=\"\" className=\"h-full w-full object-cover\" />\n * </div>\n * <CardSection>\n * <CardHeader><CardTitle>Field notes</CardTitle></CardHeader>\n * <CardFooter>edited yesterday</CardFooter>\n * </CardSection>\n * </Card>\n *\n * @example\n * // Flat card for a sidebar panel section (no shadow):\n * <Card variant=\"flat\">\n * <CardContent>\n * <p className=\"text-surface-fg-muted text-body-sm\">No recent activity</p>\n * </CardContent>\n * </Card>\n */\nexport interface CardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n VariantProps<typeof cardVariants> {\n interactive?: boolean\n}\n\nexport type { CardSize }\n\nconst Card = React.forwardRef<HTMLDivElement, CardProps>(\n ({ className, variant, color, size, orientation, interactive, children, ...props }, ref) => {\n if (typeof process !== 'undefined' && process?.env.NODE_ENV !== 'production') {\n warnOnUnwrappedTextChildren(children)\n }\n const classes = cn(\n cardVariants({ variant, color, size, orientation }),\n interactive && 'hover:shadow-raised-hover cursor-pointer transition-shadow duration-fast-02 ease-productive-standard',\n className,\n )\n\n if (interactive) {\n return (\n <motion.div\n ref={ref}\n whileHover={{ y: -3 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n className={classes}\n {...motionProps(props)}\n >\n {children}\n </motion.div>\n )\n }\n\n return (\n <div ref={ref} className={classes} {...props}>\n {children}\n </div>\n )\n },\n)\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0',\n className,\n )}\n {...props}\n />\n))\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('font-sans font-semibold leading-ds-none tracking-normal text-surface-fg', className)}\n {...props}\n />\n))\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('text-body-md text-surface-fg-muted', className)}\n {...props}\n />\n))\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n // Reset first/last child margins so a raw <p>/<h*>'s UA margin can't leak\n // past the slot onto the container's gap-model padding (the bottom-heavy bug).\n 'px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0',\n className,\n )}\n {...props}\n />\n))\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-ds-03 px-(--card-spacing)', className)}\n {...props}\n />\n))\nCardFooter.displayName = 'CardFooter'\n\n/**\n * A vertical stack that re-establishes the card's padding + gap rhythm — the text column\n * of a `<Card orientation=\"horizontal\">`. Reads the same `--card-spacing` / `--card-gap`\n * variables the container sets, so the horizontal card's content column matches a vertical\n * card of the same `size` exactly.\n */\nconst CardSection = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)', className)}\n {...props}\n />\n))\nCardSection.displayName = 'CardSection'\n\ntype CardBleedSide = 'x' | 'top' | 'bottom' | 'y' | 'all'\n\nconst bleedSideClasses: Record<CardBleedSide, string> = {\n // Inside a slot: escape the slot's horizontal inset.\n x: '-mx-(--card-spacing)',\n // As a direct child: escape the container's vertical edge (direct children are\n // already full-width — never add `x` bleed to a direct child, it would overflow).\n top: '-mt-(--card-spacing) rounded-t-surface overflow-hidden',\n bottom: '-mb-(--card-spacing) rounded-b-surface overflow-hidden',\n y: '-my-(--card-spacing) rounded-surface overflow-hidden',\n // Inside a slot, escaping every edge (e.g. an image-only card body).\n all: '-my-(--card-spacing) -mx-(--card-spacing) rounded-surface overflow-hidden',\n}\n\nexport interface CardBleedProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Which card padding to negate. `top`/`bottom`/`y` are for direct children of Card\n * (full-bleed media, edge bands) and inherit the card's corner radius; `x`/`all` are\n * for content INSIDE a slot that needs to escape the slot's horizontal inset.\n * Direct children of Card already span its full width — don't use `x`/`all` there.\n * @default 'x'\n */\n side?: CardBleedSide\n}\n\n/**\n * Escape hatch from the card's padding — the shilp-sutra equivalent of Radix Themes'\n * `Inset` / Polaris `Bleed`. Negates the same `--card-spacing` variable the padding\n * reads, so it stays exact across sizes and overrides.\n *\n * @example\n * // Cover image touching the card's top + side edges:\n * <Card>\n * <CardBleed side=\"top\"><img src={cover} alt=\"\" /></CardBleed>\n * <CardHeader><CardTitle>Project</CardTitle></CardHeader>\n * </Card>\n *\n * @example\n * // A tinted band inside CardContent, running edge-to-edge:\n * <CardContent>\n * <CardBleed><div className=\"bg-accent-2 px-(--card-spacing) py-ds-03\">Heads up…</div></CardBleed>\n * </CardContent>\n */\nconst CardBleed = React.forwardRef<HTMLDivElement, CardBleedProps>(\n ({ className, side = 'x', ...props }, ref) => (\n <div ref={ref} className={cn(bleedSideClasses[side], className)} {...props} />\n ),\n)\nCardBleed.displayName = 'CardBleed'\n\ntype CardActionPlacement = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\n\n// Corner inset reads --card-spacing so an action's edge lines up with the slot\n// content edge at every size.\nconst cornerPositions: Record<CardActionPlacement, string> = {\n 'top-right': 'top-(--card-spacing) right-(--card-spacing)',\n 'top-left': 'top-(--card-spacing) left-(--card-spacing)',\n 'bottom-right': 'bottom-(--card-spacing) right-(--card-spacing)',\n 'bottom-left': 'bottom-(--card-spacing) left-(--card-spacing)',\n}\n\nexport interface CardActionProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Which corner the action sits in. @default 'top-right' */\n placement?: CardActionPlacement\n /**\n * Pull the action a step toward its corner (`-m-ds-02`) so an icon button's GLYPH —\n * not its padding box — aligns to the content-edge line. Use for ghost/icon buttons\n * placed in a corner; leave off for badges/text where the padding box is the edge.\n */\n tuck?: boolean\n}\n\n/**\n * An absolutely-positioned corner slot for a Card — a menu/icon button, a status badge,\n * an overflow action. The Card is `relative`, so this pins to one of its four corners\n * with an inset that matches the card's content padding.\n *\n * @example\n * <Card>\n * <CardAction><IconButton aria-label=\"More\" icon={<IconDots />} variant=\"ghost\" tuck /></CardAction>\n * <CardHeader><CardTitle>Project Alpha</CardTitle></CardHeader>\n * </Card>\n *\n * @example\n * // Accent status badge in the top-right:\n * <Card>\n * <CardAction><Badge color=\"accent\" size=\"xs\">LIVE</Badge></CardAction>\n * ...\n * </Card>\n */\nconst CardAction = React.forwardRef<HTMLDivElement, CardActionProps>(\n ({ className, placement = 'top-right', tuck, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'absolute z-[1] flex items-center gap-ds-02',\n cornerPositions[placement],\n tuck && '-m-ds-02',\n className,\n )}\n {...props}\n />\n ),\n)\nCardAction.displayName = 'CardAction'\n\n// Text-shaped tags that almost certainly expected a slot's horizontal inset.\n// Structural tags (div, section, img, table, hr…) are legitimate full-width direct\n// children, so they stay silent.\nconst TEXTUAL_TAGS = new Set(['p', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'a', 'label', 'small', 'strong', 'em'])\nlet warnedUnwrappedText = false\n\nfunction warnOnUnwrappedTextChildren(children: React.ReactNode): void {\n if (warnedUnwrappedText) return\n React.Children.forEach(children, (child) => {\n const isBareText = typeof child === 'string' && child.trim() !== ''\n const isTextualTag =\n React.isValidElement(child) &&\n typeof child.type === 'string' &&\n TEXTUAL_TAGS.has(child.type)\n if (isBareText || isTextualTag) {\n warnedUnwrappedText = true\n console.warn(\n '[shilp-sutra] <Card> received text content as a direct child. Direct children span the full card width and get no horizontal inset — wrap text in <CardContent> (or <CardHeader>/<CardFooter>). See the Card docs, \"Composition\".',\n )\n }\n })\n}\n\nexport { Card, CardAction, CardBleed, CardContent, CardDescription, CardFooter, CardHeader, CardSection, CardTitle, cardVariants }\nexport type { CardActionPlacement, CardBleedSide }\n"],"mappings":"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"}
1
+ {"version":3,"file":"card.js","names":[],"sources":["../../src/ui/card.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { MotionPreference } from '../motion/motion-preference'\nimport { motionProps, springs } from './lib/motion'\nimport { cn } from './lib/utils'\n\n// Bundlers (Vite, Next.js, webpack) define process.env.NODE_ENV; guard for raw ESM.\ndeclare const process: { env: { NODE_ENV?: string } } | undefined\n\ntype CardSize = 'sm' | 'md' | 'lg'\n\nconst cardVariants = cva(\n // Gap model, variable-driven: `size` sets --card-spacing / --card-gap once on the\n // container; the container reads them for its vertical edge (py) and inter-slot\n // rhythm (gap), slots read the same variables for their horizontal inset (px), and\n // CardAction/CardBleed read them for corner offsets / negative margins. One variable\n // pair is the whole size system — override it with a single arbitrary property\n // (`[--card-spacing:var(--spacing-ds-07)]`) and every part follows.\n // No per-slot py, no pt-0, no per-element margins — adding/removing a slot can't\n // unbalance the bottom edge (make-kit rule: shadow ring is the edge, gap is the rhythm).\n // `relative` establishes the positioning context for <CardAction> corner slots.\n 'relative flex text-surface-fg rounded-surface transition-shadow duration-fast-02 ease-productive-standard',\n {\n variants: {\n variant: {\n // Tonal (default): depth from a surface-tone shift + a whisper hairline in the\n // surface's own colour (`border-card`), NO shadow — the DS-wide anti-slop edge\n // (Setu tonal-elevation). The `color` prop overrides the hairline colour to paint\n // a deliberate accent/status edge.\n default: 'bg-surface-panel border border-card shadow-none',\n // Elevation-led: the shadow's own ring is the edge (make-kit rule #6 — no\n // border+shadow double-edge). Reach for it when a card should visibly pop\n // (a dragged tile, a spotlight panel). border-transparent keeps `color` paintable.\n elevated: 'bg-surface-panel border border-transparent shadow-raised-hover',\n // Border-led, strong: a firmly visible edge, no shadow.\n outline: 'bg-transparent border border-surface-border-strong shadow-none',\n flat: 'bg-surface-panel border-none shadow-none',\n },\n // A coloured card is its edge. That edge is now the `border` role, so a\n // palette registered in CSS colours a Card without touching this file.\n // `default` and `neutral` keep the surface edge from the variant above.\n color: {\n default: '',\n accent: 'border-palette-border',\n error: 'border-palette-border',\n success: 'border-palette-border',\n warning: 'border-palette-border',\n info: 'border-palette-border',\n neutral: '',\n },\n // size only assigns the two variables; the orientation axis decides where\n // they're consumed (container in vertical, <CardSection> in horizontal).\n size: {\n sm: '[--card-spacing:var(--spacing-ds-05)] [--card-gap:var(--spacing-ds-03)]',\n md: '[--card-spacing:var(--spacing-ds-05b)] [--card-gap:var(--spacing-ds-04)]',\n lg: '[--card-spacing:var(--spacing-ds-06)] [--card-gap:var(--spacing-ds-05)]',\n },\n // vertical: the container owns py + gap (the default gap model).\n // horizontal: the container is a padding-less row; a <CardSection> child\n // re-establishes py + gap for the text column while a media pane owns an edge.\n orientation: {\n vertical: 'flex-col py-(--card-spacing) gap-(--card-gap)',\n horizontal: 'flex-row items-stretch',\n },\n },\n defaultVariants: { variant: 'default', color: 'default', size: 'md', orientation: 'vertical' },\n },\n)\n\n/**\n * Props for Card — a general-purpose content container with 4 elevation/style variants and\n * an optional interactive hover state.\n *\n * **Variants (tonal, elevation-led, or border-led — never border+shadow together):** `default`\n * (tonal — surface shift + `border-card` hairline, no shadow) | `elevated` (shadow-raised-hover,\n * no border — use when a card should visibly pop) | `outline` (strong visible border, no shadow) |\n * `flat` (filled background, no edge). The shadow tokens carry their own 1px ring, so `elevated`\n * needs no explicit border (make-kit rule #6).\n *\n * **Composition:** Use sub-components `<CardHeader>`, `<CardTitle>`, `<CardDescription>`,\n * `<CardContent>`, and `<CardFooter>` for consistent internal spacing. Text content must live\n * inside a slot — raw text as a direct child gets no horizontal inset (direct children span the\n * full card width by design, which is what makes full-width dividers and bands free).\n *\n * **Spacing:** `size` sets `--card-spacing` / `--card-gap` once; container, slots, `CardAction`,\n * and `CardBleed` all read the same pair. Retune a card with a single override:\n * `className=\"[--card-spacing:var(--spacing-ds-07)]\"`.\n *\n * **Interactive:** Pass `interactive` to enable hover shadow lift and pointer cursor —\n * useful for clickable cards in grids.\n *\n * @example\n * // Standard content card with header and body:\n * <Card>\n * <CardHeader>\n * <CardTitle>Project Alpha</CardTitle>\n * <CardDescription>Last updated 2 hours ago</CardDescription>\n * </CardHeader>\n * <CardContent>\n * <p>Sprint 4 is in progress with 12 open tasks.</p>\n * </CardContent>\n * </Card>\n *\n * @example\n * // Full-bleed cover image + edge-to-edge divider:\n * <Card>\n * <CardBleed side=\"top\"><img src={cover} alt=\"\" /></CardBleed>\n * <CardHeader><CardTitle>Muhurat launch site</CardTitle></CardHeader>\n * <Separator />\n * <CardFooter><Badge color=\"success\">On track</Badge></CardFooter>\n * </Card>\n *\n * @example\n * // Horizontal media card — media pane owns the left edge, CardSection restores rhythm:\n * <Card orientation=\"horizontal\">\n * <div className=\"w-32 shrink-0 rounded-l-surface overflow-hidden\">\n * <img src={thumb} alt=\"\" className=\"h-full w-full object-cover\" />\n * </div>\n * <CardSection>\n * <CardHeader><CardTitle>Field notes</CardTitle></CardHeader>\n * <CardFooter>edited yesterday</CardFooter>\n * </CardSection>\n * </Card>\n *\n * @example\n * // Flat card for a sidebar panel section (no shadow):\n * <Card variant=\"flat\">\n * <CardContent>\n * <p className=\"text-surface-fg-muted text-body-sm\">No recent activity</p>\n * </CardContent>\n * </Card>\n */\nexport interface CardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n VariantProps<typeof cardVariants> {\n interactive?: boolean\n}\n\nexport type { CardSize }\n\nconst Card = React.forwardRef<HTMLDivElement, CardProps>(\n ({ className, variant, color, size, orientation, interactive, children, ...props }, ref) => {\n if (typeof process !== 'undefined' && process?.env.NODE_ENV !== 'production') {\n warnOnUnwrappedTextChildren(children)\n }\n const classes = cn(\n cardVariants({ variant, color, size, orientation }),\n interactive && 'hover:bg-surface-panel-hover cursor-pointer transition-colors duration-fast-02 ease-productive-standard',\n className,\n )\n\n if (interactive) {\n return (\n <MotionPreference>\n <motion.div\n ref={ref}\n whileHover={{ y: -3 }}\n whileTap={{ scale: 0.98 }}\n transition={springs.snappy}\n data-palette={color ?? undefined}\n className={classes}\n {...motionProps(props)}\n >\n {children}\n </motion.div>\n </MotionPreference>\n )\n }\n\n return (\n <div ref={ref} data-palette={color ?? undefined} className={classes} {...props}>\n {children}\n </div>\n )\n },\n)\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-ds-02b px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0',\n className,\n )}\n {...props}\n />\n))\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('font-sans font-semibold leading-ds-none tracking-normal text-surface-fg', className)}\n {...props}\n />\n))\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('text-body-md text-surface-fg-muted', className)}\n {...props}\n />\n))\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n // Reset first/last child margins so a raw <p>/<h*>'s UA margin can't leak\n // past the slot onto the container's gap-model padding (the bottom-heavy bug).\n 'px-(--card-spacing) [&>:first-child]:mt-0 [&>:last-child]:mb-0',\n className,\n )}\n {...props}\n />\n))\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-ds-03 px-(--card-spacing)', className)}\n {...props}\n />\n))\nCardFooter.displayName = 'CardFooter'\n\n/**\n * A vertical stack that re-establishes the card's padding + gap rhythm — the text column\n * of a `<Card orientation=\"horizontal\">`. Reads the same `--card-spacing` / `--card-gap`\n * variables the container sets, so the horizontal card's content column matches a vertical\n * card of the same `size` exactly.\n */\nconst CardSection = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex min-w-0 flex-1 flex-col py-(--card-spacing) gap-(--card-gap)', className)}\n {...props}\n />\n))\nCardSection.displayName = 'CardSection'\n\ntype CardBleedSide = 'x' | 'top' | 'bottom' | 'y' | 'all'\n\nconst bleedSideClasses: Record<CardBleedSide, string> = {\n // Inside a slot: escape the slot's horizontal inset.\n x: '-mx-(--card-spacing)',\n // As a direct child: escape the container's vertical edge (direct children are\n // already full-width — never add `x` bleed to a direct child, it would overflow).\n top: '-mt-(--card-spacing) rounded-t-surface overflow-hidden',\n bottom: '-mb-(--card-spacing) rounded-b-surface overflow-hidden',\n y: '-my-(--card-spacing) rounded-surface overflow-hidden',\n // Inside a slot, escaping every edge (e.g. an image-only card body).\n all: '-my-(--card-spacing) -mx-(--card-spacing) rounded-surface overflow-hidden',\n}\n\nexport interface CardBleedProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Which card padding to negate. `top`/`bottom`/`y` are for direct children of Card\n * (full-bleed media, edge bands) and inherit the card's corner radius; `x`/`all` are\n * for content INSIDE a slot that needs to escape the slot's horizontal inset.\n * Direct children of Card already span its full width — don't use `x`/`all` there.\n * @default 'x'\n */\n side?: CardBleedSide\n}\n\n/**\n * Escape hatch from the card's padding — the shilp-sutra equivalent of Radix Themes'\n * `Inset` / Polaris `Bleed`. Negates the same `--card-spacing` variable the padding\n * reads, so it stays exact across sizes and overrides.\n *\n * @example\n * // Cover image touching the card's top + side edges:\n * <Card>\n * <CardBleed side=\"top\"><img src={cover} alt=\"\" /></CardBleed>\n * <CardHeader><CardTitle>Project</CardTitle></CardHeader>\n * </Card>\n *\n * @example\n * // A tinted band inside CardContent, running edge-to-edge:\n * <CardContent>\n * <CardBleed><div className=\"bg-accent-2 px-(--card-spacing) py-ds-03\">Heads up…</div></CardBleed>\n * </CardContent>\n */\nconst CardBleed = React.forwardRef<HTMLDivElement, CardBleedProps>(\n ({ className, side = 'x', ...props }, ref) => (\n <div ref={ref} className={cn(bleedSideClasses[side], className)} {...props} />\n ),\n)\nCardBleed.displayName = 'CardBleed'\n\ntype CardActionPlacement = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'\n\n// Corner inset reads --card-spacing so an action's edge lines up with the slot\n// content edge at every size.\nconst cornerPositions: Record<CardActionPlacement, string> = {\n 'top-right': 'top-(--card-spacing) right-(--card-spacing)',\n 'top-left': 'top-(--card-spacing) left-(--card-spacing)',\n 'bottom-right': 'bottom-(--card-spacing) right-(--card-spacing)',\n 'bottom-left': 'bottom-(--card-spacing) left-(--card-spacing)',\n}\n\nexport interface CardActionProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Which corner the action sits in. @default 'top-right' */\n placement?: CardActionPlacement\n /**\n * Pull the action a step toward its corner (`-m-ds-02`) so an icon button's GLYPH —\n * not its padding box — aligns to the content-edge line. Use for ghost/icon buttons\n * placed in a corner; leave off for badges/text where the padding box is the edge.\n */\n tuck?: boolean\n}\n\n/**\n * An absolutely-positioned corner slot for a Card — a menu/icon button, a status badge,\n * an overflow action. The Card is `relative`, so this pins to one of its four corners\n * with an inset that matches the card's content padding.\n *\n * @example\n * <Card>\n * <CardAction><IconButton aria-label=\"More\" icon={<IconDots />} variant=\"ghost\" tuck /></CardAction>\n * <CardHeader><CardTitle>Project Alpha</CardTitle></CardHeader>\n * </Card>\n *\n * @example\n * // Accent status badge in the top-right:\n * <Card>\n * <CardAction><Badge color=\"accent\" size=\"xs\">LIVE</Badge></CardAction>\n * ...\n * </Card>\n */\nconst CardAction = React.forwardRef<HTMLDivElement, CardActionProps>(\n ({ className, placement = 'top-right', tuck, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'absolute z-[1] flex items-center gap-ds-02',\n cornerPositions[placement],\n tuck && '-m-ds-02',\n className,\n )}\n {...props}\n />\n ),\n)\nCardAction.displayName = 'CardAction'\n\n// Text-shaped tags that almost certainly expected a slot's horizontal inset.\n// Structural tags (div, section, img, table, hr…) are legitimate full-width direct\n// children, so they stay silent.\nconst TEXTUAL_TAGS = new Set(['p', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'a', 'label', 'small', 'strong', 'em'])\nlet warnedUnwrappedText = false\n\nfunction warnOnUnwrappedTextChildren(children: React.ReactNode): void {\n if (warnedUnwrappedText) return\n React.Children.forEach(children, (child) => {\n const isBareText = typeof child === 'string' && child.trim() !== ''\n const isTextualTag =\n React.isValidElement(child) &&\n typeof child.type === 'string' &&\n TEXTUAL_TAGS.has(child.type)\n if (isBareText || isTextualTag) {\n warnedUnwrappedText = true\n console.warn(\n '[shilp-sutra] <Card> received text content as a direct child. Direct children span the full card width and get no horizontal inset — wrap text in <CardContent> (or <CardHeader>/<CardFooter>). See the Card docs, \"Composition\".',\n )\n }\n })\n}\n\nexport { Card, CardAction, CardBleed, CardContent, CardDescription, CardFooter, CardHeader, CardSection, CardTitle, cardVariants }\nexport type { CardActionPlacement, CardBleedSide }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"radar-chart.d.ts","sourceRoot":"","sources":["../../../src/ui/charts/radar-chart.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC7F,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IACvC;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,qBAAqB;IACrB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,CAAA;IAC5C,2HAA2H;IAC3H,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,uFAAuF;IACvF,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnD,gHAAgH;IAChH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4BAA4B;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,UAAU,wFAyXtB,CAAA"}
1
+ {"version":3,"file":"radar-chart.d.ts","sourceRoot":"","sources":["../../../src/ui/charts/radar-chart.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC7F,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IACvC;;;;OAIG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,qBAAqB;IACrB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACxD;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,QAAQ,CAAA;IAC5C,2HAA2H;IAC3H,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,uFAAuF;IACvF,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnD,gHAAgH;IAChH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4BAA4B;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,kBAAkB;IAClB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,UAAU,wFA2XtB,CAAA"}
@@ -150,7 +150,7 @@ var v = c.forwardRef(({ data: c, axes: v, series: y, maxValue: b, levels: x = 5,
150
150
  cy: a,
151
151
  r: 4,
152
152
  fill: J[t],
153
- stroke: "var(--color-surface-base)",
153
+ stroke: "var(--color-surface-panel)",
154
154
  strokeWidth: 2,
155
155
  className: "transition-opacity"
156
156
  }, `dot-${e.key}-${r}`);
@@ -1 +1 @@
1
- {"version":3,"file":"radar-chart.js","names":[],"sources":["../../../src/ui/charts/radar-chart.tsx"],"sourcesContent":["'use client'\n\nimport { curveLinearClosed,lineRadial } from 'd3-shape'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\nimport { useEffect,useRef, useState } from 'react'\n\nimport { motionProps,tweens } from '../lib/motion'\nimport { cn } from '../lib/utils'\nimport { useReducedMotion } from './_internal/animation'\nimport { resolveColor } from './_internal/colors'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\n\nexport interface RadarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array (one entry per data point / axis) */\n data: Record<string, string | number>[]\n /**\n * Axis labels. Reads best at 3–8; supported up to ~16 — past ~10 labels\n * auto-switch to radial (rotated) orientation and truncate. For very high\n * counts a horizontal bar list is clearer than a radar.\n */\n axes: string[]\n /** Series to plot */\n series: { key: string; label: string; color?: string }[]\n /**\n * Axis-label orientation. `horizontal` (anchored, best ≤8 axes), `radial`\n * (rotated along each spoke, best for many axes), or `auto` (radial past 10).\n * @default 'auto'\n */\n labelMode?: 'auto' | 'horizontal' | 'radial'\n /** Truncate axis labels to N characters (full text stays in the tooltip). Defaults to 16 in radial mode, off otherwise. */\n maxLabelChars?: number\n /** Draw a dashed benchmark/target ring — one value for a uniform target, or one per axis. */\n target?: number | number[]\n /** Called when an axis label or vertex is clicked (drill-down into that dimension). */\n onAxisClick?: (axis: string, index: number) => void\n /** Per-axis descriptions (aligned to `axes`). When set, hovering a label shows the description in a tooltip. */\n axisDescriptions?: string[]\n /** Max value (auto-detect if not set) */\n maxValue?: number\n /** Number of concentric grid rings (default: 5) */\n levels?: number\n /** Fill opacity for the data polygon (default: 0.25) */\n fillOpacity?: number\n /** Show dots at vertices */\n showDots?: boolean\n /** Chart height (default: 300) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const RadarChart = React.forwardRef<HTMLDivElement, RadarChartProps>(\n (\n {\n data,\n axes,\n series,\n maxValue: maxValueProp,\n levels = 5,\n fillOpacity = 0.25,\n showDots = false,\n height = 300,\n showTooltip = true,\n showLegend = false,\n animate = true,\n labelMode = 'auto',\n maxLabelChars,\n target,\n onAxisClick,\n axisDescriptions,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Radar chart is square — use the smaller of width/height\n const svgSize = containerWidth > 0 ? Math.min(containerWidth, height) : height\n\n // Label layout: past ~10 axes, horizontal labels collide, so switch to\n // radial (rotated along each spoke) and truncate. Margin is derived from the\n // longest displayed label instead of a fixed 40px, so labels never clip.\n const effectiveLabelMode = labelMode === 'auto' ? (axes.length > 10 ? 'radial' : 'horizontal') : labelMode\n const truncLen = maxLabelChars ?? (effectiveLabelMode === 'radial' ? 16 : undefined)\n const displayLabel = (s: string) => (truncLen && s.length > truncLen ? `${s.slice(0, truncLen - 1)}…` : s)\n const longestChars = Math.max(1, ...axes.map((a) => displayLabel(a).length))\n const LABEL_FONT = 11 // ≈ text-body-xs\n const labelPx = longestChars * LABEL_FONT * 0.58\n const labelMargin =\n effectiveLabelMode === 'horizontal'\n ? Math.min(labelPx + 14, svgSize * 0.36)\n : Math.min(labelPx * 0.7 + 18, svgSize * 0.3)\n const radius = Math.max(svgSize / 2 - labelMargin, 48) // leave room for labels\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Auto-detect maxValue if not provided\n const maxValue =\n maxValueProp ??\n Math.max(\n ...data.flatMap((d) => series.map((s) => Number(d[s.key]) || 0)),\n 1,\n )\n\n // Angle per axis slice\n const angleSlice = (2 * Math.PI) / axes.length\n\n // D3 radial line generator for the data polygon\n const radarLine = lineRadial<number>()\n .radius((d) => (radius * d) / maxValue)\n .angle((_, i) => i * angleSlice)\n .curve(curveLinearClosed)\n\n // Convert a data row into an array of values aligned with axes\n const getSeriesValues = (seriesKey: string): number[] =>\n axes.map((_, i) => Number(data[i]?.[seriesKey]) || 0)\n\n // Optional benchmark/target ring — uniform value or per-axis array.\n const targetValues =\n target == null ? null : axes.map((_, i) => (Array.isArray(target) ? Number(target[i]) || 0 : target))\n const targetPath = targetValues ? radarLine(targetValues) : null\n\n // Convert polar to cartesian for a given axis index and value\n const polarToXY = (axisIndex: number, value: number) => {\n const angle = angleSlice * axisIndex - Math.PI / 2\n const r = (radius * value) / maxValue\n return {\n x: r * Math.cos(angle),\n y: r * Math.sin(angle),\n }\n }\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Radar chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {/* Concentric grid polygons */}\n {Array.from({ length: levels }, (_, i) => {\n const levelRadius = (radius / levels) * (i + 1)\n const points = axes\n .map((_, j) => {\n const angle = angleSlice * j - Math.PI / 2\n return `${levelRadius * Math.cos(angle)},${levelRadius * Math.sin(angle)}`\n })\n .join(' ')\n return (\n <polygon\n key={`grid-${i}`}\n points={points}\n fill=\"none\"\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis lines from center to outer edge */}\n {axes.map((_, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const x = radius * Math.cos(angle)\n const y = radius * Math.sin(angle)\n return (\n <line\n key={`axis-${i}`}\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"var(--color-surface-border)\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis labels */}\n {axes.map((label, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const display = displayLabel(label)\n const clickable = !!onAxisClick\n const desc = axisDescriptions?.[i]\n const common = {\n className: cn(\n 'fill-surface-fg-muted text-body-xs',\n clickable && 'cursor-pointer hover:fill-surface-fg',\n !clickable && desc && 'cursor-help hover:fill-surface-fg',\n ),\n onClick: clickable ? () => onAxisClick(label, i) : undefined,\n role: clickable ? 'button' : undefined,\n tabIndex: clickable ? 0 : undefined,\n onMouseMove: desc\n ? (e: React.MouseEvent<SVGTextElement>) => {\n const rect = e.currentTarget.closest('div')?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{label}</div>\n <div className=\"max-w-[220px] text-surface-fg-muted\">{desc}</div>\n </div>,\n )\n }\n : undefined,\n onMouseLeave: desc ? hide : undefined,\n }\n const titleEl = display !== label ? <title>{label}</title> : null\n\n if (effectiveLabelMode === 'radial') {\n const labelRadius = radius + 10\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n let deg = (angle * 180) / Math.PI\n let anchor: 'start' | 'end' = 'start'\n // Flip labels on the left half so they read upright.\n if (deg > 90 || deg < -90) {\n deg += 180\n anchor = 'end'\n }\n return (\n <text\n key={`label-${i}`}\n x={x}\n y={y}\n textAnchor={anchor}\n dominantBaseline=\"central\"\n transform={`rotate(${deg} ${x} ${y})`}\n {...common}\n >\n {titleEl}\n {display}\n </text>\n )\n }\n\n const labelRadius = radius + 18\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n let textAnchor: 'start' | 'middle' | 'end' = 'middle'\n if (Math.abs(Math.cos(angle)) > 0.1) {\n textAnchor = Math.cos(angle) > 0 ? 'start' : 'end'\n }\n return (\n <text key={`label-${i}`} x={x} y={y} textAnchor={textAnchor} dominantBaseline=\"central\" {...common}>\n {titleEl}\n {display}\n </text>\n )\n })}\n\n {/* Level value labels on the first axis */}\n {Array.from({ length: levels }, (_, i) => {\n const levelValue = Math.round((maxValue / levels) * (i + 1))\n const levelRadius = (radius / levels) * (i + 1)\n const angle = -Math.PI / 2 // first axis is at top\n const x = levelRadius * Math.cos(angle) + 4\n const y = levelRadius * Math.sin(angle)\n return (\n <text\n key={`level-label-${i}`}\n x={x}\n y={y}\n textAnchor=\"start\"\n dominantBaseline=\"auto\"\n className=\"fill-surface-fg-subtle text-body-xs\"\n >\n {levelValue}\n </text>\n )\n })}\n\n {/* Target / benchmark ring */}\n {targetPath && (\n <path\n d={targetPath}\n fill=\"none\"\n stroke=\"var(--color-accent-9)\"\n strokeWidth={1.5}\n strokeDasharray=\"4,3\"\n opacity={0.75}\n />\n )}\n\n {/* Data polygons — one per series */}\n {series.map((s, seriesIdx) => {\n const values = getSeriesValues(s.key)\n const pathD = radarLine(values)\n if (!pathD) return null\n\n return (\n <g key={s.key}>\n <path\n d={pathD}\n fill={colors[seriesIdx]}\n fillOpacity={fillOpacity}\n stroke={colors[seriesIdx]}\n strokeWidth={2}\n strokeLinejoin=\"round\"\n />\n\n {/* Vertex dots */}\n {showDots &&\n values.map((v, i) => {\n const { x, y } = polarToXY(i, v)\n return (\n <circle\n key={`dot-${s.key}-${i}`}\n cx={x}\n cy={y}\n r={4}\n fill={colors[seriesIdx]}\n stroke=\"var(--color-surface-base)\"\n strokeWidth={2}\n className=\"transition-opacity\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover areas at each vertex for tooltips */}\n {showTooltip &&\n axes.map((axisLabel, i) => {\n // Place a transparent circle at the outermost series point\n // for hit detection. Use the max value point for the axis.\n const angle = angleSlice * i - Math.PI / 2\n const hitX = radius * Math.cos(angle)\n const hitY = radius * Math.sin(angle)\n\n return (\n <circle\n key={`hover-${i}`}\n cx={hitX}\n cy={hitY}\n r={16}\n fill=\"transparent\"\n className=\"cursor-pointer\"\n onClick={onAxisClick ? () => onAxisClick(axisLabel, i) : undefined}\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{axisLabel}</div>\n {series.map((s, sIdx) => {\n const val = Number(data[i]?.[s.key]) || 0\n return (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-pill\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {val.toLocaleString()}\n </div>\n )\n })}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })}\n </g>\n </svg>\n\n {/* Tooltip overlay — for vertex values and/or axis descriptions */}\n {(showTooltip || axisDescriptions) && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nRadarChart.displayName = 'RadarChart'\n"],"mappings":"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"}
1
+ {"version":3,"file":"radar-chart.js","names":[],"sources":["../../../src/ui/charts/radar-chart.tsx"],"sourcesContent":["'use client'\n\nimport { curveLinearClosed,lineRadial } from 'd3-shape'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\nimport { useEffect,useRef, useState } from 'react'\n\nimport { motionProps,tweens } from '../lib/motion'\nimport { cn } from '../lib/utils'\nimport { useReducedMotion } from './_internal/animation'\nimport { resolveColor } from './_internal/colors'\nimport { Legend } from './_internal/legend'\nimport { ChartTooltip, useChartTooltip } from './_internal/tooltip'\n\nexport interface RadarChartProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Data array (one entry per data point / axis) */\n data: Record<string, string | number>[]\n /**\n * Axis labels. Reads best at 3–8; supported up to ~16 — past ~10 labels\n * auto-switch to radial (rotated) orientation and truncate. For very high\n * counts a horizontal bar list is clearer than a radar.\n */\n axes: string[]\n /** Series to plot */\n series: { key: string; label: string; color?: string }[]\n /**\n * Axis-label orientation. `horizontal` (anchored, best ≤8 axes), `radial`\n * (rotated along each spoke, best for many axes), or `auto` (radial past 10).\n * @default 'auto'\n */\n labelMode?: 'auto' | 'horizontal' | 'radial'\n /** Truncate axis labels to N characters (full text stays in the tooltip). Defaults to 16 in radial mode, off otherwise. */\n maxLabelChars?: number\n /** Draw a dashed benchmark/target ring — one value for a uniform target, or one per axis. */\n target?: number | number[]\n /** Called when an axis label or vertex is clicked (drill-down into that dimension). */\n onAxisClick?: (axis: string, index: number) => void\n /** Per-axis descriptions (aligned to `axes`). When set, hovering a label shows the description in a tooltip. */\n axisDescriptions?: string[]\n /** Max value (auto-detect if not set) */\n maxValue?: number\n /** Number of concentric grid rings (default: 5) */\n levels?: number\n /** Fill opacity for the data polygon (default: 0.25) */\n fillOpacity?: number\n /** Show dots at vertices */\n showDots?: boolean\n /** Chart height (default: 300) */\n height?: number\n /** Show tooltip on hover */\n showTooltip?: boolean\n /** Show legend */\n showLegend?: boolean\n /** Animate on mount */\n animate?: boolean\n /** Accessible label for the chart */\n ariaLabel?: string\n className?: string\n}\n\nexport const RadarChart = React.forwardRef<HTMLDivElement, RadarChartProps>(\n (\n {\n data,\n axes,\n series,\n maxValue: maxValueProp,\n levels = 5,\n fillOpacity = 0.25,\n showDots = false,\n height = 300,\n showTooltip = true,\n showLegend = false,\n animate = true,\n labelMode = 'auto',\n maxLabelChars,\n target,\n onAxisClick,\n axisDescriptions,\n ariaLabel,\n className,\n ...props\n },\n ref,\n ) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const [containerWidth, setContainerWidth] = useState(0)\n const { tooltip, show, hide } = useChartTooltip()\n const reducedMotion = useReducedMotion()\n const shouldAnimate = animate && !reducedMotion\n\n useEffect(() => {\n if (!containerRef.current) return\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setContainerWidth(entry.contentRect.width)\n })\n observer.observe(containerRef.current)\n return () => observer.disconnect()\n }, [])\n\n // Radar chart is square — use the smaller of width/height\n const svgSize = containerWidth > 0 ? Math.min(containerWidth, height) : height\n\n // Label layout: past ~10 axes, horizontal labels collide, so switch to\n // radial (rotated along each spoke) and truncate. Margin is derived from the\n // longest displayed label instead of a fixed 40px, so labels never clip.\n const effectiveLabelMode = labelMode === 'auto' ? (axes.length > 10 ? 'radial' : 'horizontal') : labelMode\n const truncLen = maxLabelChars ?? (effectiveLabelMode === 'radial' ? 16 : undefined)\n const displayLabel = (s: string) => (truncLen && s.length > truncLen ? `${s.slice(0, truncLen - 1)}…` : s)\n const longestChars = Math.max(1, ...axes.map((a) => displayLabel(a).length))\n const LABEL_FONT = 11 // ≈ text-body-xs\n const labelPx = longestChars * LABEL_FONT * 0.58\n const labelMargin =\n effectiveLabelMode === 'horizontal'\n ? Math.min(labelPx + 14, svgSize * 0.36)\n : Math.min(labelPx * 0.7 + 18, svgSize * 0.3)\n const radius = Math.max(svgSize / 2 - labelMargin, 48) // leave room for labels\n\n // Resolve colors for each series\n const colors = series.map((s, i) => resolveColor(s.color, i))\n\n // Auto-detect maxValue if not provided\n const maxValue =\n maxValueProp ??\n Math.max(\n ...data.flatMap((d) => series.map((s) => Number(d[s.key]) || 0)),\n 1,\n )\n\n // Angle per axis slice\n const angleSlice = (2 * Math.PI) / axes.length\n\n // D3 radial line generator for the data polygon\n const radarLine = lineRadial<number>()\n .radius((d) => (radius * d) / maxValue)\n .angle((_, i) => i * angleSlice)\n .curve(curveLinearClosed)\n\n // Convert a data row into an array of values aligned with axes\n const getSeriesValues = (seriesKey: string): number[] =>\n axes.map((_, i) => Number(data[i]?.[seriesKey]) || 0)\n\n // Optional benchmark/target ring — uniform value or per-axis array.\n const targetValues =\n target == null ? null : axes.map((_, i) => (Array.isArray(target) ? Number(target[i]) || 0 : target))\n const targetPath = targetValues ? radarLine(targetValues) : null\n\n // Convert polar to cartesian for a given axis index and value\n const polarToXY = (axisIndex: number, value: number) => {\n const angle = angleSlice * axisIndex - Math.PI / 2\n const r = (radius * value) / maxValue\n return {\n x: r * Math.cos(angle),\n y: r * Math.sin(angle),\n }\n }\n\n return (\n <motion.div\n ref={(node) => {\n (containerRef as React.MutableRefObject<HTMLDivElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node\n }}\n className={cn('relative w-full', className)}\n {...(shouldAnimate\n ? { initial: { opacity: 0, scale: 0.96 }, animate: { opacity: 1, scale: 1 }, transition: tweens.fade }\n : {})}\n {...motionProps(props)}\n >\n {containerWidth > 0 && (\n <>\n <svg\n width={containerWidth}\n height={height}\n role=\"img\"\n aria-label={ariaLabel ?? 'Radar chart'}\n >\n <g transform={`translate(${containerWidth / 2},${height / 2})`}>\n {/* Concentric grid polygons */}\n {Array.from({ length: levels }, (_, i) => {\n const levelRadius = (radius / levels) * (i + 1)\n const points = axes\n .map((_, j) => {\n const angle = angleSlice * j - Math.PI / 2\n return `${levelRadius * Math.cos(angle)},${levelRadius * Math.sin(angle)}`\n })\n .join(' ')\n return (\n <polygon\n key={`grid-${i}`}\n points={points}\n fill=\"none\"\n stroke=\"var(--color-surface-border)\"\n strokeDasharray=\"3,3\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis lines from center to outer edge */}\n {axes.map((_, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const x = radius * Math.cos(angle)\n const y = radius * Math.sin(angle)\n return (\n <line\n key={`axis-${i}`}\n x1={0}\n y1={0}\n x2={x}\n y2={y}\n stroke=\"var(--color-surface-border)\"\n strokeWidth={1}\n />\n )\n })}\n\n {/* Axis labels */}\n {axes.map((label, i) => {\n const angle = angleSlice * i - Math.PI / 2\n const display = displayLabel(label)\n const clickable = !!onAxisClick\n const desc = axisDescriptions?.[i]\n const common = {\n className: cn(\n 'fill-surface-fg-muted text-body-xs',\n clickable && 'cursor-pointer hover:fill-surface-fg',\n !clickable && desc && 'cursor-help hover:fill-surface-fg',\n ),\n onClick: clickable ? () => onAxisClick(label, i) : undefined,\n role: clickable ? 'button' : undefined,\n tabIndex: clickable ? 0 : undefined,\n onMouseMove: desc\n ? (e: React.MouseEvent<SVGTextElement>) => {\n const rect = e.currentTarget.closest('div')?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{label}</div>\n <div className=\"max-w-[220px] text-surface-fg-muted\">{desc}</div>\n </div>,\n )\n }\n : undefined,\n onMouseLeave: desc ? hide : undefined,\n }\n const titleEl = display !== label ? <title>{label}</title> : null\n\n if (effectiveLabelMode === 'radial') {\n const labelRadius = radius + 10\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n let deg = (angle * 180) / Math.PI\n let anchor: 'start' | 'end' = 'start'\n // Flip labels on the left half so they read upright.\n if (deg > 90 || deg < -90) {\n deg += 180\n anchor = 'end'\n }\n return (\n <text\n key={`label-${i}`}\n x={x}\n y={y}\n textAnchor={anchor}\n dominantBaseline=\"central\"\n transform={`rotate(${deg} ${x} ${y})`}\n {...common}\n >\n {titleEl}\n {display}\n </text>\n )\n }\n\n const labelRadius = radius + 18\n const x = labelRadius * Math.cos(angle)\n const y = labelRadius * Math.sin(angle)\n let textAnchor: 'start' | 'middle' | 'end' = 'middle'\n if (Math.abs(Math.cos(angle)) > 0.1) {\n textAnchor = Math.cos(angle) > 0 ? 'start' : 'end'\n }\n return (\n <text key={`label-${i}`} x={x} y={y} textAnchor={textAnchor} dominantBaseline=\"central\" {...common}>\n {titleEl}\n {display}\n </text>\n )\n })}\n\n {/* Level value labels on the first axis */}\n {Array.from({ length: levels }, (_, i) => {\n const levelValue = Math.round((maxValue / levels) * (i + 1))\n const levelRadius = (radius / levels) * (i + 1)\n const angle = -Math.PI / 2 // first axis is at top\n const x = levelRadius * Math.cos(angle) + 4\n const y = levelRadius * Math.sin(angle)\n return (\n <text\n key={`level-label-${i}`}\n x={x}\n y={y}\n textAnchor=\"start\"\n dominantBaseline=\"auto\"\n className=\"fill-surface-fg-subtle text-body-xs\"\n >\n {levelValue}\n </text>\n )\n })}\n\n {/* Target / benchmark ring */}\n {targetPath && (\n <path\n d={targetPath}\n fill=\"none\"\n stroke=\"var(--color-accent-9)\"\n strokeWidth={1.5}\n strokeDasharray=\"4,3\"\n opacity={0.75}\n />\n )}\n\n {/* Data polygons — one per series */}\n {series.map((s, seriesIdx) => {\n const values = getSeriesValues(s.key)\n const pathD = radarLine(values)\n if (!pathD) return null\n\n return (\n <g key={s.key}>\n <path\n d={pathD}\n fill={colors[seriesIdx]}\n fillOpacity={fillOpacity}\n stroke={colors[seriesIdx]}\n strokeWidth={2}\n strokeLinejoin=\"round\"\n />\n\n {/* Vertex dots */}\n {showDots &&\n values.map((v, i) => {\n const { x, y } = polarToXY(i, v)\n return (\n <circle\n key={`dot-${s.key}-${i}`}\n cx={x}\n cy={y}\n r={4}\n fill={colors[seriesIdx]}\n // knockout, so it has to match the ground the chart sits on.\n // surface-base is DARKER than a card in dark and drew a halo.\n stroke=\"var(--color-surface-panel)\"\n strokeWidth={2}\n className=\"transition-opacity\"\n />\n )\n })}\n </g>\n )\n })}\n\n {/* Invisible hover areas at each vertex for tooltips */}\n {showTooltip &&\n axes.map((axisLabel, i) => {\n // Place a transparent circle at the outermost series point\n // for hit detection. Use the max value point for the axis.\n const angle = angleSlice * i - Math.PI / 2\n const hitX = radius * Math.cos(angle)\n const hitY = radius * Math.sin(angle)\n\n return (\n <circle\n key={`hover-${i}`}\n cx={hitX}\n cy={hitY}\n r={16}\n fill=\"transparent\"\n className=\"cursor-pointer\"\n onClick={onAxisClick ? () => onAxisClick(axisLabel, i) : undefined}\n onMouseMove={(e) => {\n const rect = e.currentTarget\n .closest('div')\n ?.getBoundingClientRect()\n show(\n e.clientX - (rect?.left ?? 0),\n e.clientY - (rect?.top ?? 0),\n <div>\n <div className=\"font-medium\">{axisLabel}</div>\n {series.map((s, sIdx) => {\n const val = Number(data[i]?.[s.key]) || 0\n return (\n <div\n key={s.key}\n className=\"flex items-center gap-ds-02\"\n >\n <span\n className=\"inline-block h-2 w-2 rounded-pill\"\n style={{ backgroundColor: colors[sIdx] }}\n />\n <span className=\"text-surface-fg-muted\">\n {s.label}:\n </span>{' '}\n {val.toLocaleString()}\n </div>\n )\n })}\n </div>,\n )\n }}\n onMouseLeave={hide}\n />\n )\n })}\n </g>\n </svg>\n\n {/* Tooltip overlay — for vertex values and/or axis descriptions */}\n {(showTooltip || axisDescriptions) && <ChartTooltip state={tooltip} />}\n </>\n )}\n\n {/* Legend */}\n {showLegend && (\n <Legend\n items={series.map((s, i) => ({\n label: s.label,\n color: colors[i],\n }))}\n className=\"mt-ds-04\"\n />\n )}\n </motion.div>\n )\n },\n)\nRadarChart.displayName = 'RadarChart'\n"],"mappings":"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"}
@@ -3,8 +3,15 @@ export interface DateSeparatorProps {
3
3
  date: Date | string;
4
4
  format?: (date: Date) => string;
5
5
  className?: string;
6
+ /** BCP 47 locale for the default label's month name. @default 'en-US' */
7
+ locale?: string;
8
+ /**
9
+ * IANA time zone used for the "Today"/"Yesterday" day-boundary comparison
10
+ * and for formatting. Defaults to the browser's local time zone.
11
+ */
12
+ timeZone?: string;
6
13
  }
7
- declare function DateSeparator({ date, format, className }: DateSeparatorProps): React.JSX.Element;
14
+ declare function DateSeparator({ date, format, className, locale, timeZone }: DateSeparatorProps): React.JSX.Element;
8
15
  declare namespace DateSeparator {
9
16
  var displayName: string;
10
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"date-separator.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/date-separator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAsBD,iBAAS,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,qBAarE;kBAbQ,aAAa;;;AAgBtB,OAAO,EAAE,aAAa,EAAE,CAAA"}
1
+ {"version":3,"file":"date-separator.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/date-separator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAkCD,iBAAS,aAAa,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAgB,EAAE,QAAQ,EAAE,EAAE,kBAAkB,qBAajG;kBAbQ,aAAa;;;AAgBtB,OAAO,EAAE,aAAa,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-list.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/message-list.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5E,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mDAAmD;IACnD,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACpC,sEAAsE;IACtE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B;AAED,QAAA,MAAM,WAAW,yFAkIhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"message-list.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/message-list.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5E,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC7B,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,mDAAmD;IACnD,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACpC,sEAAsE;IACtE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B;AAED,QAAA,MAAM,WAAW,yFAoIhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/message.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/message.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/typing-indicator.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAQD,iBAAS,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,oBAAoB,qBA+BlE;kBA/BQ,eAAe;;;AAkCxB,OAAO,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"typing-indicator.d.ts","sourceRoot":"","sources":["../../../src/ui/chat/typing-indicator.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACzC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAQD,iBAAS,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,oBAAoB,qBAiClE;kBAjCQ,eAAe;;;AAoCxB,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -29,7 +29,7 @@ var u = {
29
29
  checked: S || h ? k : void 0,
30
30
  defaultChecked: !S && !h ? y : void 0,
31
31
  onCheckedChange: j,
32
- className: t("touch-target peer flex items-center justify-center shrink-0 rounded-control-inner", d[g], "border border-surface-border-strong", "bg-surface-raised-hover", "transition-colors duration-fast-01 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:opacity-action-disabled", "data-[state=unchecked]:hover:border-accent-7 data-[state=unchecked]:hover:bg-surface-raised-active", "data-[state=checked]:bg-accent-9 data-[state=checked]:border-accent-7 data-[state=checked]:text-accent-fg", "data-[state=indeterminate]:bg-accent-9 data-[state=indeterminate]:border-accent-7 data-[state=indeterminate]:text-accent-fg", E && u[E], p),
32
+ className: t("touch-target peer flex items-center justify-center shrink-0 rounded-control-inner", d[g], "border border-surface-border-interactive", "bg-surface-panel-hover", "transition-colors duration-fast-01 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", "disabled:cursor-not-allowed disabled:opacity-action-disabled", "data-[state=unchecked]:hover:border-accent-7 data-[state=unchecked]:hover:bg-surface-panel-active", "data-[state=checked]:bg-accent-9 data-[state=checked]:border-accent-7 data-[state=checked]:text-accent-fg", "data-[state=indeterminate]:bg-accent-9 data-[state=indeterminate]:border-accent-7 data-[state=indeterminate]:text-accent-fg", E && u[E], p),
33
33
  "aria-invalid": E === "error" || void 0,
34
34
  "aria-describedby": D,
35
35
  "aria-required": O || void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox.js","names":[],"sources":["../../src/ui/checkbox.tsx"],"sourcesContent":["'use client'\n\nimport * as CheckboxPrimitive from '@primitives/react-checkbox'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useFormField } from './form'\nimport { type FieldState, resolveFieldState } from './lib/field-state'\nimport { durations } from './lib/motion'\nimport { cn } from './lib/utils'\n\n/** Border + background tint per validation state (checked state uses accent regardless). */\nconst stateTintClasses: Record<Exclude<FieldState, 'default'>, string> = {\n error: 'border-error-7 bg-error-3',\n warning: 'border-warning-7 bg-warning-3',\n success: 'border-success-7 bg-success-3',\n}\n\n/**\n * Props for Checkbox — a Radix-powered accessible checkbox with error state styling and\n * an indeterminate state for \"select all\" row controls.\n *\n * **Indeterminate:** Pass `indeterminate={true}` to show the \"−\" dash (overrides `checked`).\n * This is correct for \"select all\" headers when only some rows are selected.\n *\n * **Controlled:** Use `checked` + `onCheckedChange` for controlled usage.\n * `onCheckedChange` receives `true | false | 'indeterminate'` from Radix.\n *\n * @example\n * // Basic controlled checkbox:\n * <Checkbox checked={agreed} onCheckedChange={(v) => setAgreed(v === true)} />\n *\n * @example\n * // Error state when required checkbox is not checked:\n * <Checkbox state={!termsAccepted ? 'error' : 'default'} checked={termsAccepted} onCheckedChange={(v) => setTerms(v === true)} />\n *\n * @example\n * // \"Select all\" checkbox with indeterminate state:\n * <Checkbox\n * indeterminate={someSelected && !allSelected}\n * checked={allSelected}\n * onCheckedChange={(v) => toggleAll(v === true)}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface CheckboxProps extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {\n /** Validation/feedback state. `'error'` also sets `aria-invalid`. Inherited from `FormField` when omitted. */\n state?: FieldState\n indeterminate?: boolean\n /** Control size — `sm` (20px), `md` (24px, default, WCAG compliant), `lg` (28px). */\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst checkboxSizeClasses = {\n sm: 'h-5 w-5',\n md: 'h-6 w-6',\n lg: 'h-7 w-7',\n} as const\n\nconst checkboxIconClasses = {\n sm: 'h-[14px] w-[14px]',\n md: 'h-[18px] w-[18px]',\n lg: 'h-5 w-5',\n} as const\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n CheckboxProps\n>(({ className, state: stateProp, indeterminate, size = 'md', checked, onCheckedChange, defaultChecked, ...props }, ref) => {\n // Track internal state so AnimatePresence works for both controlled & uncontrolled usage\n const isControlled = checked !== undefined\n const [internalChecked, setInternalChecked] = React.useState<boolean | 'indeterminate'>(\n indeterminate ? 'indeterminate' : (defaultChecked ? true : false),\n )\n\n const fieldCtx = useFormField()\n const state = resolveFieldState(stateProp, fieldCtx.state)\n const ariaDescribedBy = props['aria-describedby'] ?? fieldCtx.helperTextId\n const ariaRequired = props['aria-required'] ?? fieldCtx.required\n\n const actualChecked = indeterminate ? 'indeterminate' : (isControlled ? checked : internalChecked)\n const isActive = actualChecked === true || actualChecked === 'indeterminate'\n\n const handleCheckedChange = React.useCallback(\n (value: boolean | 'indeterminate') => {\n if (!isControlled) setInternalChecked(value)\n onCheckedChange?.(value)\n },\n [isControlled, onCheckedChange],\n )\n\n return (\n <CheckboxPrimitive.Root\n ref={ref}\n checked={isControlled || indeterminate ? actualChecked : undefined}\n defaultChecked={!isControlled && !indeterminate ? defaultChecked : undefined}\n onCheckedChange={handleCheckedChange}\n className={cn(\n 'touch-target peer flex items-center justify-center shrink-0 rounded-control-inner',\n checkboxSizeClasses[size],\n 'border border-surface-border-strong',\n 'bg-surface-raised-hover',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-action-disabled',\n 'data-[state=unchecked]:hover:border-accent-7 data-[state=unchecked]:hover:bg-surface-raised-active',\n 'data-[state=checked]:bg-accent-9 data-[state=checked]:border-accent-7 data-[state=checked]:text-accent-fg',\n 'data-[state=indeterminate]:bg-accent-9 data-[state=indeterminate]:border-accent-7 data-[state=indeterminate]:text-accent-fg',\n state && stateTintClasses[state],\n className,\n )}\n aria-invalid={state === 'error' || undefined}\n aria-describedby={ariaDescribedBy}\n aria-required={ariaRequired || undefined}\n {...props}\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor>\n // resolves. Without this the label renders, points at nothing, and the\n // control has NO accessible name — a screen reader announces an unnamed\n // checkbox even though the consumer wrote FormField + Label correctly.\n id={props.id ?? fieldCtx.inputId}\n >\n <AnimatePresence>\n {isActive && (\n <CheckboxPrimitive.Indicator forceMount asChild>\n <motion.span\n className=\"flex items-center justify-center text-current\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: durations.fast01 }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n className={checkboxIconClasses[size]}\n >\n {actualChecked === 'indeterminate' ? (\n <motion.line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n exit={{ pathLength: 0 }}\n transition={{ duration: durations.moderate02, ease: 'easeOut' }}\n />\n ) : (\n <motion.path\n d=\"M3.5 8.5l3 3 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill=\"none\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n exit={{ pathLength: 0 }}\n transition={{ duration: durations.moderate02, ease: 'easeOut' }}\n />\n )}\n </svg>\n </motion.span>\n </CheckboxPrimitive.Indicator>\n )}\n </AnimatePresence>\n </CheckboxPrimitive.Root>\n )\n})\nCheckbox.displayName = CheckboxPrimitive.Root.displayName\n\nexport { Checkbox }\n"],"mappings":";;;;;;;;;;AAYA,IAAM,IAAmE;CACvE,OAAO;CACP,SAAS;CACT,SAAS;AACX,GAqCM,IAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEM,IAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEM,IAAW,EAAM,YAGpB,EAAE,cAAW,OAAO,GAAW,kBAAe,UAAO,MAAM,YAAS,oBAAiB,mBAAgB,GAAG,KAAS,MAAQ;CAE1H,IAAM,IAAe,MAAY,KAAA,GAC3B,CAAC,GAAiB,KAAsB,EAAM,SAClD,IAAgB,kBAAmB,GACrC,GAEM,IAAW,EAAa,GACxB,IAAQ,EAAkB,GAAW,EAAS,KAAK,GACnD,IAAkB,EAAM,uBAAuB,EAAS,cACxD,IAAe,EAAM,oBAAoB,EAAS,UAElD,IAAgB,IAAgB,kBAAmB,IAAe,IAAU,GAC5E,IAAW,MAAkB,MAAQ,MAAkB,iBAEvD,IAAsB,EAAM,aAC/B,MAAqC;EAEpC,AADK,KAAc,EAAmB,CAAK,GAC3C,IAAkB,CAAK;CACzB,GACA,CAAC,GAAc,CAAe,CAChC;CAEA,OACE,kBAAC,GAAD;EACO;EACL,SAAS,KAAgB,IAAgB,IAAgB,KAAA;EACzD,gBAAgB,CAAC,KAAgB,CAAC,IAAgB,IAAiB,KAAA;EACnE,iBAAiB;EACjB,WAAW,EACT,qFACA,EAAoB,IACpB,uCACA,2BACA,+DACA,6GACA,gEACA,sGACA,6GACA,+HACA,KAAS,EAAiB,IAC1B,CACF;EACA,gBAAc,MAAU,WAAW,KAAA;EACnC,oBAAkB;EAClB,iBAAe,KAAgB,KAAA;EAC/B,GAAI;EAKJ,IAAI,EAAM,MAAM,EAAS;YAEzB,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,GAAD;GAA6B,YAAA;GAAW,SAAA;aACtC,kBAAC,EAAO,MAAR;IACE,WAAU;IACV,SAAS,EAAE,SAAS,EAAE;IACtB,SAAS,EAAE,SAAS,EAAE;IACtB,MAAM,EAAE,SAAS,EAAE;IACnB,YAAY,EAAE,UAAU,EAAU,OAAO;cAEzC,kBAAC,OAAD;KACE,OAAM;KACN,QAAO;KACP,SAAQ;KACR,MAAK;KACL,WAAW,EAAoB;eAE9B,MAAkB,kBACjB,kBAAC,EAAO,MAAR;MACE,IAAG;MACH,IAAG;MACH,IAAG;MACH,IAAG;MACH,QAAO;MACP,aAAY;MACZ,eAAc;MACd,SAAS,EAAE,YAAY,EAAE;MACzB,SAAS,EAAE,YAAY,EAAE;MACzB,MAAM,EAAE,YAAY,EAAE;MACtB,YAAY;OAAE,UAAU,EAAU;OAAY,MAAM;MAAU;KAC/D,CAAA,IAED,kBAAC,EAAO,MAAR;MACE,GAAE;MACF,QAAO;MACP,aAAY;MACZ,eAAc;MACd,gBAAe;MACf,MAAK;MACL,SAAS,EAAE,YAAY,EAAE;MACzB,SAAS,EAAE,YAAY,EAAE;MACzB,MAAM,EAAE,YAAY,EAAE;MACtB,YAAY;OAAE,UAAU,EAAU;OAAY,MAAM;MAAU;KAC/D,CAAA;IAEA,CAAA;GACM,CAAA;EACc,CAAA,EAEhB,CAAA;CACK,CAAA;AAE5B,CAAC;AACD,EAAS,cAAA,EAAqC"}
1
+ {"version":3,"file":"checkbox.js","names":[],"sources":["../../src/ui/checkbox.tsx"],"sourcesContent":["'use client'\n\nimport * as CheckboxPrimitive from '@primitives/react-checkbox'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useFormField } from './form'\nimport { type FieldState, resolveFieldState } from './lib/field-state'\nimport { durations } from './lib/motion'\nimport { cn } from './lib/utils'\n\n/** Border + background tint per validation state (checked state uses accent regardless). */\nconst stateTintClasses: Record<Exclude<FieldState, 'default'>, string> = {\n error: 'border-error-7 bg-error-3',\n warning: 'border-warning-7 bg-warning-3',\n success: 'border-success-7 bg-success-3',\n}\n\n/**\n * Props for Checkbox — a Radix-powered accessible checkbox with error state styling and\n * an indeterminate state for \"select all\" row controls.\n *\n * **Indeterminate:** Pass `indeterminate={true}` to show the \"−\" dash (overrides `checked`).\n * This is correct for \"select all\" headers when only some rows are selected.\n *\n * **Controlled:** Use `checked` + `onCheckedChange` for controlled usage.\n * `onCheckedChange` receives `true | false | 'indeterminate'` from Radix.\n *\n * @example\n * // Basic controlled checkbox:\n * <Checkbox checked={agreed} onCheckedChange={(v) => setAgreed(v === true)} />\n *\n * @example\n * // Error state when required checkbox is not checked:\n * <Checkbox state={!termsAccepted ? 'error' : 'default'} checked={termsAccepted} onCheckedChange={(v) => setTerms(v === true)} />\n *\n * @example\n * // \"Select all\" checkbox with indeterminate state:\n * <Checkbox\n * indeterminate={someSelected && !allSelected}\n * checked={allSelected}\n * onCheckedChange={(v) => toggleAll(v === true)}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface CheckboxProps extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> {\n /** Validation/feedback state. `'error'` also sets `aria-invalid`. Inherited from `FormField` when omitted. */\n state?: FieldState\n indeterminate?: boolean\n /** Control size — `sm` (20px), `md` (24px, default, WCAG compliant), `lg` (28px). */\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst checkboxSizeClasses = {\n sm: 'h-5 w-5',\n md: 'h-6 w-6',\n lg: 'h-7 w-7',\n} as const\n\nconst checkboxIconClasses = {\n sm: 'h-[14px] w-[14px]',\n md: 'h-[18px] w-[18px]',\n lg: 'h-5 w-5',\n} as const\n\nconst Checkbox = React.forwardRef<\n React.ElementRef<typeof CheckboxPrimitive.Root>,\n CheckboxProps\n>(({ className, state: stateProp, indeterminate, size = 'md', checked, onCheckedChange, defaultChecked, ...props }, ref) => {\n // Track internal state so AnimatePresence works for both controlled & uncontrolled usage\n const isControlled = checked !== undefined\n const [internalChecked, setInternalChecked] = React.useState<boolean | 'indeterminate'>(\n indeterminate ? 'indeterminate' : (defaultChecked ? true : false),\n )\n\n const fieldCtx = useFormField()\n const state = resolveFieldState(stateProp, fieldCtx.state)\n const ariaDescribedBy = props['aria-describedby'] ?? fieldCtx.helperTextId\n const ariaRequired = props['aria-required'] ?? fieldCtx.required\n\n const actualChecked = indeterminate ? 'indeterminate' : (isControlled ? checked : internalChecked)\n const isActive = actualChecked === true || actualChecked === 'indeterminate'\n\n const handleCheckedChange = React.useCallback(\n (value: boolean | 'indeterminate') => {\n if (!isControlled) setInternalChecked(value)\n onCheckedChange?.(value)\n },\n [isControlled, onCheckedChange],\n )\n\n return (\n <CheckboxPrimitive.Root\n ref={ref}\n checked={isControlled || indeterminate ? actualChecked : undefined}\n defaultChecked={!isControlled && !indeterminate ? defaultChecked : undefined}\n onCheckedChange={handleCheckedChange}\n className={cn(\n 'touch-target peer flex items-center justify-center shrink-0 rounded-control-inner',\n checkboxSizeClasses[size],\n 'border border-surface-border-interactive',\n 'bg-surface-panel-hover',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-action-disabled',\n 'data-[state=unchecked]:hover:border-accent-7 data-[state=unchecked]:hover:bg-surface-panel-active',\n 'data-[state=checked]:bg-accent-9 data-[state=checked]:border-accent-7 data-[state=checked]:text-accent-fg',\n 'data-[state=indeterminate]:bg-accent-9 data-[state=indeterminate]:border-accent-7 data-[state=indeterminate]:text-accent-fg',\n state && stateTintClasses[state],\n className,\n )}\n aria-invalid={state === 'error' || undefined}\n aria-describedby={ariaDescribedBy}\n aria-required={ariaRequired || undefined}\n {...props}\n // Explicit id wins; otherwise adopt FormField's inputId so <Label htmlFor>\n // resolves. Without this the label renders, points at nothing, and the\n // control has NO accessible name — a screen reader announces an unnamed\n // checkbox even though the consumer wrote FormField + Label correctly.\n id={props.id ?? fieldCtx.inputId}\n >\n <AnimatePresence>\n {isActive && (\n <CheckboxPrimitive.Indicator forceMount asChild>\n <motion.span\n className=\"flex items-center justify-center text-current\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: durations.fast01 }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n className={checkboxIconClasses[size]}\n >\n {actualChecked === 'indeterminate' ? (\n <motion.line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n exit={{ pathLength: 0 }}\n transition={{ duration: durations.moderate02, ease: 'easeOut' }}\n />\n ) : (\n <motion.path\n d=\"M3.5 8.5l3 3 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill=\"none\"\n initial={{ pathLength: 0 }}\n animate={{ pathLength: 1 }}\n exit={{ pathLength: 0 }}\n transition={{ duration: durations.moderate02, ease: 'easeOut' }}\n />\n )}\n </svg>\n </motion.span>\n </CheckboxPrimitive.Indicator>\n )}\n </AnimatePresence>\n </CheckboxPrimitive.Root>\n )\n})\nCheckbox.displayName = CheckboxPrimitive.Root.displayName\n\nexport { Checkbox }\n"],"mappings":";;;;;;;;;;AAYA,IAAM,IAAmE;CACvE,OAAO;CACP,SAAS;CACT,SAAS;AACX,GAqCM,IAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEM,IAAsB;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEM,IAAW,EAAM,YAGpB,EAAE,cAAW,OAAO,GAAW,kBAAe,UAAO,MAAM,YAAS,oBAAiB,mBAAgB,GAAG,KAAS,MAAQ;CAE1H,IAAM,IAAe,MAAY,KAAA,GAC3B,CAAC,GAAiB,KAAsB,EAAM,SAClD,IAAgB,kBAAmB,GACrC,GAEM,IAAW,EAAa,GACxB,IAAQ,EAAkB,GAAW,EAAS,KAAK,GACnD,IAAkB,EAAM,uBAAuB,EAAS,cACxD,IAAe,EAAM,oBAAoB,EAAS,UAElD,IAAgB,IAAgB,kBAAmB,IAAe,IAAU,GAC5E,IAAW,MAAkB,MAAQ,MAAkB,iBAEvD,IAAsB,EAAM,aAC/B,MAAqC;EAEpC,AADK,KAAc,EAAmB,CAAK,GAC3C,IAAkB,CAAK;CACzB,GACA,CAAC,GAAc,CAAe,CAChC;CAEA,OACE,kBAAC,GAAD;EACO;EACL,SAAS,KAAgB,IAAgB,IAAgB,KAAA;EACzD,gBAAgB,CAAC,KAAgB,CAAC,IAAgB,IAAiB,KAAA;EACnE,iBAAiB;EACjB,WAAW,EACT,qFACA,EAAoB,IACpB,4CACA,0BACA,+DACA,6GACA,gEACA,qGACA,6GACA,+HACA,KAAS,EAAiB,IAC1B,CACF;EACA,gBAAc,MAAU,WAAW,KAAA;EACnC,oBAAkB;EAClB,iBAAe,KAAgB,KAAA;EAC/B,GAAI;EAKJ,IAAI,EAAM,MAAM,EAAS;YAEzB,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,GAAD;GAA6B,YAAA;GAAW,SAAA;aACtC,kBAAC,EAAO,MAAR;IACE,WAAU;IACV,SAAS,EAAE,SAAS,EAAE;IACtB,SAAS,EAAE,SAAS,EAAE;IACtB,MAAM,EAAE,SAAS,EAAE;IACnB,YAAY,EAAE,UAAU,EAAU,OAAO;cAEzC,kBAAC,OAAD;KACE,OAAM;KACN,QAAO;KACP,SAAQ;KACR,MAAK;KACL,WAAW,EAAoB;eAE9B,MAAkB,kBACjB,kBAAC,EAAO,MAAR;MACE,IAAG;MACH,IAAG;MACH,IAAG;MACH,IAAG;MACH,QAAO;MACP,aAAY;MACZ,eAAc;MACd,SAAS,EAAE,YAAY,EAAE;MACzB,SAAS,EAAE,YAAY,EAAE;MACzB,MAAM,EAAE,YAAY,EAAE;MACtB,YAAY;OAAE,UAAU,EAAU;OAAY,MAAM;MAAU;KAC/D,CAAA,IAED,kBAAC,EAAO,MAAR;MACE,GAAE;MACF,QAAO;MACP,aAAY;MACZ,eAAc;MACd,gBAAe;MACf,MAAK;MACL,SAAS,EAAE,YAAY,EAAE;MACzB,SAAS,EAAE,YAAY,EAAE;MACzB,MAAM,EAAE,YAAY,EAAE;MACtB,YAAY;OAAE,UAAU,EAAU;OAAY,MAAM;MAAU;KAC/D,CAAA;IAEA,CAAA;GACM,CAAA;EACc,CAAA,EAEhB,CAAA;CACK,CAAA;AAE5B,CAAC;AACD,EAAS,cAAA,EAAqC"}
package/dist/ui/code.js CHANGED
@@ -4,12 +4,12 @@ import { jsx as n } from "react/jsx-runtime";
4
4
  //#region src/ui/code.tsx
5
5
  var r = t.forwardRef(({ className: t, variant: r = "inline", children: i, ...a }, o) => r === "block" ? /* @__PURE__ */ n("pre", {
6
6
  ref: o,
7
- className: e("overflow-x-auto rounded-surface border border-card-strong bg-surface-raised p-ds-05 font-mono text-body-sm leading-ds-relaxed text-surface-fg", t),
7
+ className: e("overflow-x-auto rounded-surface border border-card-strong bg-surface-sunken p-ds-05 font-mono text-body-sm leading-ds-relaxed text-surface-fg", t),
8
8
  ...a,
9
9
  children: /* @__PURE__ */ n("code", { children: i })
10
10
  }) : /* @__PURE__ */ n("code", {
11
11
  ref: o,
12
- className: e("rounded-control-inner bg-surface-raised-hover border border-card px-ds-02 py-ds-01 font-mono text-body-sm text-surface-fg", t),
12
+ className: e("rounded-control-inner bg-surface-panel-hover border border-card px-ds-02 py-ds-01 font-mono text-body-sm text-surface-fg", t),
13
13
  ...a,
14
14
  children: i
15
15
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"code.js","names":[],"sources":["../../src/ui/code.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\n/**\n * Props for Code — a typography component that renders either inline `<code>` or block `<pre><code>`\n * monospace text, styled with the design system's layer tokens.\n *\n * **`variant` options:**\n * - `\"inline\"` (default) — renders as `<code>` with a subtle layer-03 background, suitable for\n * short snippets within prose (e.g. \"Use the `onClick` prop to...\").\n * - `\"block\"` — renders as `<pre>` with a bordered, padded, horizontally-scrollable block for\n * multi-line code samples.\n *\n * @example\n * // Inline code reference in documentation:\n * <p>Pass <Code>loading={true}</Code> to show the spinner.</p>\n *\n * @example\n * // Block code sample (e.g. in a README or docs page):\n * <Code variant=\"block\">{`const greeting = \"Hello, world!\"\\nconsole.log(greeting)`}</Code>\n *\n * @example\n * // Inline API key display:\n * <p>Your API key: <Code>sk-dev-abc123xyz</Code></p>\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface CodeProps extends React.HTMLAttributes<HTMLElement> {\n variant?: 'inline' | 'block'\n}\n\nconst Code = React.forwardRef<HTMLPreElement | HTMLElement, CodeProps>(\n ({ className, variant = 'inline', children, ...props }, ref) => {\n if (variant === 'block') {\n return (\n <pre\n ref={ref as React.Ref<HTMLPreElement>}\n className={cn(\n 'overflow-x-auto rounded-surface border border-card-strong bg-surface-raised p-ds-05 font-mono text-body-sm leading-ds-relaxed text-surface-fg',\n className,\n )}\n {...props}\n >\n <code>{children}</code>\n </pre>\n )\n }\n\n return (\n <code\n ref={ref}\n className={cn(\n 'rounded-control-inner bg-surface-raised-hover border border-card px-ds-02 py-ds-01 font-mono text-body-sm text-surface-fg',\n className,\n )}\n {...props}\n >\n {children}\n </code>\n )\n },\n)\nCode.displayName = 'Code'\n\nexport { Code }\n"],"mappings":";;;;AAgCA,IAAM,IAAO,EAAM,YAChB,EAAE,cAAW,aAAU,UAAU,aAAU,GAAG,KAAS,MAClD,MAAY,UAEZ,kBAAC,OAAD;CACO;CACL,WAAW,EACT,iJACA,CACF;CACA,GAAI;WAEJ,kBAAC,QAAD,EAAO,YAAe,CAAA;AACnB,CAAA,IAKP,kBAAC,QAAD;CACO;CACL,WAAW,EACT,6HACA,CACF;CACA,GAAI;CAEH;AACG,CAAA,CAGZ;AACA,EAAK,cAAc"}
1
+ {"version":3,"file":"code.js","names":[],"sources":["../../src/ui/code.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from './lib/utils'\n\n/**\n * Props for Code — a typography component that renders either inline `<code>` or block `<pre><code>`\n * monospace text, styled with the design system's layer tokens.\n *\n * **`variant` options:**\n * - `\"inline\"` (default) — renders as `<code>` with a subtle layer-03 background, suitable for\n * short snippets within prose (e.g. \"Use the `onClick` prop to...\").\n * - `\"block\"` — renders as `<pre>` with a bordered, padded, horizontally-scrollable block for\n * multi-line code samples.\n *\n * @example\n * // Inline code reference in documentation:\n * <p>Pass <Code>loading={true}</Code> to show the spinner.</p>\n *\n * @example\n * // Block code sample (e.g. in a README or docs page):\n * <Code variant=\"block\">{`const greeting = \"Hello, world!\"\\nconsole.log(greeting)`}</Code>\n *\n * @example\n * // Inline API key display:\n * <p>Your API key: <Code>sk-dev-abc123xyz</Code></p>\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface CodeProps extends React.HTMLAttributes<HTMLElement> {\n variant?: 'inline' | 'block'\n}\n\nconst Code = React.forwardRef<HTMLPreElement | HTMLElement, CodeProps>(\n ({ className, variant = 'inline', children, ...props }, ref) => {\n if (variant === 'block') {\n return (\n <pre\n ref={ref as React.Ref<HTMLPreElement>}\n className={cn(\n 'overflow-x-auto rounded-surface border border-card-strong bg-surface-sunken p-ds-05 font-mono text-body-sm leading-ds-relaxed text-surface-fg',\n className,\n )}\n {...props}\n >\n <code>{children}</code>\n </pre>\n )\n }\n\n return (\n <code\n ref={ref}\n className={cn(\n 'rounded-control-inner bg-surface-panel-hover border border-card px-ds-02 py-ds-01 font-mono text-body-sm text-surface-fg',\n className,\n )}\n {...props}\n >\n {children}\n </code>\n )\n },\n)\nCode.displayName = 'Code'\n\nexport { Code }\n"],"mappings":";;;;AAgCA,IAAM,IAAO,EAAM,YAChB,EAAE,cAAW,aAAU,UAAU,aAAU,GAAG,KAAS,MAClD,MAAY,UAEZ,kBAAC,OAAD;CACO;CACL,WAAW,EACT,iJACA,CACF;CACA,GAAI;WAEJ,kBAAC,QAAD,EAAO,YAAe,CAAA;AACnB,CAAA,IAKP,kBAAC,QAAD;CACO;CACL,WAAW,EACT,4HACA,CACF;CACA,GAAI;CAEH;AACG,CAAA,CAGZ;AACA,EAAK,cAAc"}