@devalok/shilp-sutra 0.34.1 → 0.36.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 (439) hide show
  1. package/LICENSE +21 -21
  2. package/dist/_chunks/badge-group.js +95 -95
  3. package/dist/_chunks/badge-group.js.map +1 -0
  4. package/dist/_chunks/chat.js +7 -2
  5. package/dist/_chunks/chat.js.map +1 -0
  6. package/dist/_chunks/date-picker.js.map +1 -0
  7. package/dist/_chunks/document-preview.js.map +1 -0
  8. package/dist/_chunks/file-preview.js.map +1 -0
  9. package/dist/_chunks/framer.js +62 -62
  10. package/dist/_chunks/framer.js.map +1 -0
  11. package/dist/_chunks/image-preview.js +1 -1
  12. package/dist/_chunks/image-preview.js.map +1 -0
  13. package/dist/_chunks/keybinding.js.map +1 -0
  14. package/dist/_chunks/link-context.js.map +1 -0
  15. package/dist/_chunks/mention-suggestion.js.map +1 -0
  16. package/dist/_chunks/motion-provider.js.map +1 -0
  17. package/dist/_chunks/popover.js +32 -36
  18. package/dist/_chunks/popover.js.map +1 -0
  19. package/dist/_chunks/primitives.js +686 -686
  20. package/dist/_chunks/primitives.js.map +1 -0
  21. package/dist/_chunks/rich-chat-input.js +650 -649
  22. package/dist/_chunks/rich-chat-input.js.map +1 -0
  23. package/dist/_chunks/shared.js.map +1 -0
  24. package/dist/_chunks/sonner.js.map +1 -0
  25. package/dist/_chunks/stat-row.js +158 -158
  26. package/dist/_chunks/stat-row.js.map +1 -0
  27. package/dist/_chunks/tiptap.js +11 -11
  28. package/dist/_chunks/tiptap.js.map +1 -0
  29. package/dist/_chunks/tree-view.js +1 -1
  30. package/dist/_chunks/tree-view.js.map +1 -0
  31. package/dist/_chunks/use-calendar.js.map +1 -0
  32. package/dist/_chunks/vendor-client.js +1 -1
  33. package/dist/_chunks/vendor-client.js.map +1 -0
  34. package/dist/_chunks/vendor-utils.js.map +1 -0
  35. package/dist/ai/ai-command-provider.js.map +1 -0
  36. package/dist/ai/block-renderer.js.map +1 -0
  37. package/dist/ai/blocks/loading.d.ts.map +1 -1
  38. package/dist/ai/command-bar.js.map +1 -0
  39. package/dist/ai/conversation.js +76 -76
  40. package/dist/ai/conversation.js.map +1 -0
  41. package/dist/ai/devadoot-icon.d.ts.map +1 -1
  42. package/dist/ai/index.js.map +1 -0
  43. package/dist/composed/activity-feed.js.map +1 -0
  44. package/dist/composed/avatar-group.js +1 -1
  45. package/dist/composed/avatar-group.js.map +1 -0
  46. package/dist/composed/bulk-action-bar.js +13 -21
  47. package/dist/composed/bulk-action-bar.js.map +1 -0
  48. package/dist/composed/command-palette.js.map +1 -0
  49. package/dist/composed/confirm-dialog.js.map +1 -0
  50. package/dist/composed/content-card.js.map +1 -0
  51. package/dist/composed/deadline-indicator.js.map +1 -0
  52. package/dist/composed/emoji-picker.js.map +1 -0
  53. package/dist/composed/empty-state.d.ts.map +1 -1
  54. package/dist/composed/empty-state.js +30 -30
  55. package/dist/composed/empty-state.js.map +1 -0
  56. package/dist/composed/error-boundary.js.map +1 -0
  57. package/dist/composed/filter-bar.js.map +1 -0
  58. package/dist/composed/form-section.js.map +1 -0
  59. package/dist/composed/global-loading.js.map +1 -0
  60. package/dist/composed/inline-edit.js.map +1 -0
  61. package/dist/composed/lib/string-utils.js.map +1 -0
  62. package/dist/composed/loading-skeleton.js.map +1 -0
  63. package/dist/composed/markdown-viewer.js.map +1 -0
  64. package/dist/composed/master-detail.js.map +1 -0
  65. package/dist/composed/member-picker.js.map +1 -0
  66. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  67. package/dist/composed/multi-select-popover.js +4 -0
  68. package/dist/composed/multi-select-popover.js.map +1 -0
  69. package/dist/composed/page-header.js.map +1 -0
  70. package/dist/composed/page-skeletons.js.map +1 -0
  71. package/dist/composed/priority-indicator.js.map +1 -0
  72. package/dist/composed/responsive-overlay.js.map +1 -0
  73. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  74. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  75. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  76. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  77. package/dist/composed/rich-text-editor.js.map +1 -0
  78. package/dist/composed/schedule-view.js.map +1 -0
  79. package/dist/composed/simple-tooltip.js.map +1 -0
  80. package/dist/composed/status-badge.d.ts.map +1 -1
  81. package/dist/composed/status-badge.js.map +1 -0
  82. package/dist/hooks/use-color-mode.js.map +1 -0
  83. package/dist/hooks/use-mobile.js.map +1 -0
  84. package/dist/hooks/use-touch-device.js.map +1 -0
  85. package/dist/hooks/use-viewport-height.js.map +1 -0
  86. package/dist/motion/check-motion-provider.d.ts +3 -0
  87. package/dist/motion/check-motion-provider.d.ts.map +1 -0
  88. package/dist/motion/index.js +14 -0
  89. package/dist/motion/index.js.map +1 -0
  90. package/dist/motion/primitives-index.js.map +1 -0
  91. package/dist/primitives/react-accordion.d.ts +114 -114
  92. package/dist/primitives/react-alert-dialog.d.ts +51 -51
  93. package/dist/primitives/react-aspect-ratio.d.ts +11 -11
  94. package/dist/primitives/react-avatar.d.ts +24 -24
  95. package/dist/primitives/react-checkbox.d.ts +50 -50
  96. package/dist/primitives/react-collapsible.d.ts +33 -33
  97. package/dist/primitives/react-context-menu.d.ts +96 -96
  98. package/dist/primitives/react-dialog.d.ts +103 -103
  99. package/dist/primitives/react-dropdown-menu.d.ts +97 -97
  100. package/dist/primitives/react-hover-card.d.ts +79 -79
  101. package/dist/primitives/react-label.d.ts +10 -10
  102. package/dist/primitives/react-menu.d.ts +169 -169
  103. package/dist/primitives/react-menubar.d.ts +115 -115
  104. package/dist/primitives/react-navigation-menu.d.ts +126 -126
  105. package/dist/primitives/react-popover.d.ts +85 -85
  106. package/dist/primitives/react-progress.d.ts +19 -19
  107. package/dist/primitives/react-radio-group.d.ts +58 -58
  108. package/dist/primitives/react-roving-focus.d.ts +49 -49
  109. package/dist/primitives/react-select.d.ts +137 -137
  110. package/dist/primitives/react-separator.d.ts +21 -21
  111. package/dist/primitives/react-slider.d.ts +75 -75
  112. package/dist/primitives/react-switch.d.ts +21 -21
  113. package/dist/primitives/react-tabs.d.ts +56 -56
  114. package/dist/primitives/react-toast.d.ts +120 -120
  115. package/dist/primitives/react-toggle-group.d.ts +75 -75
  116. package/dist/primitives/react-toggle.d.ts +24 -24
  117. package/dist/primitives/react-tooltip.d.ts +101 -101
  118. package/dist/primitives/react-visually-hidden.d.ts +22 -22
  119. package/dist/shell/app-command-palette.d.ts +2 -0
  120. package/dist/shell/app-command-palette.d.ts.map +1 -1
  121. package/dist/shell/app-command-palette.js +42 -155
  122. package/dist/shell/app-command-palette.js.map +1 -0
  123. package/dist/shell/bottom-navbar.js +1 -1
  124. package/dist/shell/bottom-navbar.js.map +1 -0
  125. package/dist/shell/command-registry.js.map +1 -0
  126. package/dist/shell/notification-center.d.ts.map +1 -1
  127. package/dist/shell/notification-center.js +194 -169
  128. package/dist/shell/notification-center.js.map +1 -0
  129. package/dist/shell/notification-preferences.js.map +1 -0
  130. package/dist/shell/sidebar.js.map +1 -0
  131. package/dist/shell/top-bar.js +1 -1
  132. package/dist/shell/top-bar.js.map +1 -0
  133. package/dist/tailwind/index.cjs +48 -1
  134. package/dist/tailwind/preset.d.ts.map +1 -1
  135. package/dist/tailwind/preset.js +48 -1
  136. package/dist/tailwind/preset.js.map +1 -0
  137. package/dist/tokens/index.css +4 -4
  138. package/dist/tokens/primitives.css +442 -442
  139. package/dist/tokens/semantic.css +742 -547
  140. package/dist/tokens/typography-semantic.css +123 -100
  141. package/dist/tokens/typography.css +422 -422
  142. package/dist/ui/accordion.js +13 -13
  143. package/dist/ui/accordion.js.map +1 -0
  144. package/dist/ui/alert-dialog.d.ts +6 -2
  145. package/dist/ui/alert-dialog.d.ts.map +1 -1
  146. package/dist/ui/alert-dialog.js +43 -42
  147. package/dist/ui/alert-dialog.js.map +1 -0
  148. package/dist/ui/alert.d.ts +3 -2
  149. package/dist/ui/alert.d.ts.map +1 -1
  150. package/dist/ui/alert.js +31 -5
  151. package/dist/ui/alert.js.map +1 -0
  152. package/dist/ui/aspect-ratio.js +1 -1
  153. package/dist/ui/aspect-ratio.js.map +1 -0
  154. package/dist/ui/autocomplete.d.ts.map +1 -1
  155. package/dist/ui/autocomplete.js +92 -67
  156. package/dist/ui/autocomplete.js.map +1 -0
  157. package/dist/ui/avatar.js +9 -9
  158. package/dist/ui/avatar.js.map +1 -0
  159. package/dist/ui/badge-indicator.js.map +1 -0
  160. package/dist/ui/banner.js.map +1 -0
  161. package/dist/ui/breadcrumb.js +1 -1
  162. package/dist/ui/breadcrumb.js.map +1 -0
  163. package/dist/ui/button-group.js.map +1 -0
  164. package/dist/ui/button-processing.d.ts.map +1 -1
  165. package/dist/ui/button-processing.js +61 -40
  166. package/dist/ui/button-processing.js.map +1 -0
  167. package/dist/ui/button.js +8 -8
  168. package/dist/ui/button.js.map +1 -0
  169. package/dist/ui/card.js.map +1 -0
  170. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  171. package/dist/ui/charts/chart-container.d.ts +2 -0
  172. package/dist/ui/charts/chart-container.d.ts.map +1 -1
  173. package/dist/ui/charts/index.js +88 -65
  174. package/dist/ui/charts/index.js.map +1 -0
  175. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  176. package/dist/ui/chat/message-input.d.ts.map +1 -1
  177. package/dist/ui/chat/message-list.d.ts +1 -1
  178. package/dist/ui/chat/message-list.d.ts.map +1 -1
  179. package/dist/ui/chat/message.d.ts.map +1 -1
  180. package/dist/ui/chat/system-message.d.ts.map +1 -1
  181. package/dist/ui/checkbox.d.ts.map +1 -1
  182. package/dist/ui/checkbox.js +33 -28
  183. package/dist/ui/checkbox.js.map +1 -0
  184. package/dist/ui/code.js.map +1 -0
  185. package/dist/ui/collapsible.js +1 -1
  186. package/dist/ui/collapsible.js.map +1 -0
  187. package/dist/ui/color-input.d.ts.map +1 -1
  188. package/dist/ui/color-input.js +165 -163
  189. package/dist/ui/color-input.js.map +1 -0
  190. package/dist/ui/color-swatch.js.map +1 -0
  191. package/dist/ui/combobox.d.ts +7 -0
  192. package/dist/ui/combobox.d.ts.map +1 -1
  193. package/dist/ui/combobox.js +147 -113
  194. package/dist/ui/combobox.js.map +1 -0
  195. package/dist/ui/container.js +1 -1
  196. package/dist/ui/container.js.map +1 -0
  197. package/dist/ui/context-menu.js.map +1 -0
  198. package/dist/ui/data-table-body.js.map +1 -0
  199. package/dist/ui/data-table-bulk-actions.js +1 -1
  200. package/dist/ui/data-table-bulk-actions.js.map +1 -0
  201. package/dist/ui/data-table-card.js.map +1 -0
  202. package/dist/ui/data-table-context.js.map +1 -0
  203. package/dist/ui/data-table-header.js.map +1 -0
  204. package/dist/ui/data-table-pagination.js.map +1 -0
  205. package/dist/ui/data-table-toolbar.js.map +1 -0
  206. package/dist/ui/data-table.js +34 -31
  207. package/dist/ui/data-table.js.map +1 -0
  208. package/dist/ui/devalok-grain.js.map +1 -0
  209. package/dist/ui/dialog.js +31 -35
  210. package/dist/ui/dialog.js.map +1 -0
  211. package/dist/ui/dropdown-menu.js.map +1 -0
  212. package/dist/ui/file-upload.js +120 -120
  213. package/dist/ui/file-upload.js.map +1 -0
  214. package/dist/ui/form.d.ts +8 -0
  215. package/dist/ui/form.d.ts.map +1 -1
  216. package/dist/ui/form.js +14 -12
  217. package/dist/ui/form.js.map +1 -0
  218. package/dist/ui/hover-card.js.map +1 -0
  219. package/dist/ui/icon-button.js.map +1 -0
  220. package/dist/ui/icon-context.js.map +1 -0
  221. package/dist/ui/icon-group.js.map +1 -0
  222. package/dist/ui/icon.js.map +1 -0
  223. package/dist/ui/index.d.ts +4 -4
  224. package/dist/ui/index.d.ts.map +1 -1
  225. package/dist/ui/index.js +82 -66
  226. package/dist/ui/index.js.map +1 -0
  227. package/dist/ui/input-otp.d.ts +12 -3
  228. package/dist/ui/input-otp.d.ts.map +1 -1
  229. package/dist/ui/input-otp.js +41 -27
  230. package/dist/ui/input-otp.js.map +1 -0
  231. package/dist/ui/input.d.ts.map +1 -1
  232. package/dist/ui/input.js +16 -15
  233. package/dist/ui/input.js.map +1 -0
  234. package/dist/ui/label.d.ts.map +1 -1
  235. package/dist/ui/label.js +19 -14
  236. package/dist/ui/label.js.map +1 -0
  237. package/dist/ui/lib/check-tokens.d.ts +3 -0
  238. package/dist/ui/lib/check-tokens.d.ts.map +1 -0
  239. package/dist/ui/lib/date-utils.js.map +1 -0
  240. package/dist/ui/lib/motion.d.ts +15 -4
  241. package/dist/ui/lib/motion.d.ts.map +1 -1
  242. package/dist/ui/lib/motion.js +18 -9
  243. package/dist/ui/lib/motion.js.map +1 -0
  244. package/dist/ui/lib/utils.js.map +1 -0
  245. package/dist/ui/link.js +2 -2
  246. package/dist/ui/link.js.map +1 -0
  247. package/dist/ui/menubar.js.map +1 -0
  248. package/dist/ui/navigation-menu.js.map +1 -0
  249. package/dist/ui/number-input.d.ts +16 -1
  250. package/dist/ui/number-input.d.ts.map +1 -1
  251. package/dist/ui/number-input.js +79 -49
  252. package/dist/ui/number-input.js.map +1 -0
  253. package/dist/ui/pagination.js +1 -1
  254. package/dist/ui/pagination.js.map +1 -0
  255. package/dist/ui/progress-ring.d.ts.map +1 -1
  256. package/dist/ui/progress-ring.js.map +1 -0
  257. package/dist/ui/progress.js.map +1 -0
  258. package/dist/ui/radio.d.ts.map +1 -1
  259. package/dist/ui/radio.js +27 -20
  260. package/dist/ui/radio.js.map +1 -0
  261. package/dist/ui/search-input.js.map +1 -0
  262. package/dist/ui/segmented-control.d.ts +1 -1
  263. package/dist/ui/segmented-control.d.ts.map +1 -1
  264. package/dist/ui/segmented-control.js +2 -0
  265. package/dist/ui/segmented-control.js.map +1 -0
  266. package/dist/ui/select.d.ts.map +1 -1
  267. package/dist/ui/select.js +54 -48
  268. package/dist/ui/select.js.map +1 -0
  269. package/dist/ui/separator.d.ts.map +1 -1
  270. package/dist/ui/separator.js +10 -7
  271. package/dist/ui/separator.js.map +1 -0
  272. package/dist/ui/sheet.js +29 -29
  273. package/dist/ui/sheet.js.map +1 -0
  274. package/dist/ui/sidebar.js +7 -7
  275. package/dist/ui/sidebar.js.map +1 -0
  276. package/dist/ui/skeleton.js.map +1 -0
  277. package/dist/ui/slider.d.ts +22 -3
  278. package/dist/ui/slider.d.ts.map +1 -1
  279. package/dist/ui/slider.js +57 -19
  280. package/dist/ui/slider.js.map +1 -0
  281. package/dist/ui/spinner.js.map +1 -0
  282. package/dist/ui/split-button.d.ts.map +1 -1
  283. package/dist/ui/split-button.js +77 -76
  284. package/dist/ui/split-button.js.map +1 -0
  285. package/dist/ui/stack.js.map +1 -0
  286. package/dist/ui/stat-card.js.map +1 -0
  287. package/dist/ui/status-dot.js.map +1 -0
  288. package/dist/ui/stepper.d.ts +10 -0
  289. package/dist/ui/stepper.d.ts.map +1 -1
  290. package/dist/ui/stepper.js +80 -75
  291. package/dist/ui/stepper.js.map +1 -0
  292. package/dist/ui/switch.d.ts.map +1 -1
  293. package/dist/ui/switch.js +26 -22
  294. package/dist/ui/switch.js.map +1 -0
  295. package/dist/ui/table.js.map +1 -0
  296. package/dist/ui/tabs.d.ts +3 -1
  297. package/dist/ui/tabs.d.ts.map +1 -1
  298. package/dist/ui/tabs.js +68 -48
  299. package/dist/ui/tabs.js.map +1 -0
  300. package/dist/ui/text.d.ts +1 -1
  301. package/dist/ui/text.d.ts.map +1 -1
  302. package/dist/ui/text.js +10 -2
  303. package/dist/ui/text.js.map +1 -0
  304. package/dist/ui/textarea.js +1 -1
  305. package/dist/ui/textarea.js.map +1 -0
  306. package/dist/ui/toast-registry.d.ts +8 -0
  307. package/dist/ui/toast-registry.d.ts.map +1 -0
  308. package/dist/ui/toast-registry.js +13 -0
  309. package/dist/ui/toast-registry.js.map +1 -0
  310. package/dist/ui/toast.d.ts.map +1 -1
  311. package/dist/ui/toast.js +141 -136
  312. package/dist/ui/toast.js.map +1 -0
  313. package/dist/ui/toaster.d.ts.map +1 -1
  314. package/dist/ui/toaster.js +15 -14
  315. package/dist/ui/toaster.js.map +1 -0
  316. package/dist/ui/toggle-group.d.ts +2 -0
  317. package/dist/ui/toggle-group.d.ts.map +1 -1
  318. package/dist/ui/toggle-group.js +23 -16
  319. package/dist/ui/toggle-group.js.map +1 -0
  320. package/dist/ui/toggle.d.ts +2 -0
  321. package/dist/ui/toggle.d.ts.map +1 -1
  322. package/dist/ui/toggle.js +14 -6
  323. package/dist/ui/toggle.js.map +1 -0
  324. package/dist/ui/tooltip.js.map +1 -0
  325. package/dist/ui/visually-hidden.js.map +1 -0
  326. package/docs/components/_header.md +85 -85
  327. package/docs/components/composed/activity-feed.md +62 -62
  328. package/docs/components/composed/avatar-group.md +65 -65
  329. package/docs/components/composed/bulk-action-bar.md +40 -40
  330. package/docs/components/composed/command-palette.md +40 -40
  331. package/docs/components/composed/confirm-dialog.md +46 -46
  332. package/docs/components/composed/content-card.md +36 -36
  333. package/docs/components/composed/date-picker.md +130 -130
  334. package/docs/components/composed/deadline-indicator.md +27 -27
  335. package/docs/components/composed/emoji-picker.md +52 -52
  336. package/docs/components/composed/empty-state.md +53 -53
  337. package/docs/components/composed/error-boundary.md +29 -29
  338. package/docs/components/composed/file-preview.md +40 -40
  339. package/docs/components/composed/filter-bar.md +57 -57
  340. package/docs/components/composed/form-section.md +31 -31
  341. package/docs/components/composed/global-loading.md +27 -27
  342. package/docs/components/composed/inline-edit.md +35 -35
  343. package/docs/components/composed/loading-skeleton.md +51 -51
  344. package/docs/components/composed/markdown-viewer.md +27 -27
  345. package/docs/components/composed/master-detail.md +48 -48
  346. package/docs/components/composed/member-picker.md +35 -35
  347. package/docs/components/composed/multi-select-popover.md +62 -62
  348. package/docs/components/composed/page-header.md +41 -41
  349. package/docs/components/composed/page-skeletons.md +32 -32
  350. package/docs/components/composed/priority-indicator.md +32 -32
  351. package/docs/components/composed/responsive-overlay.md +34 -34
  352. package/docs/components/composed/rich-text-editor.md +82 -82
  353. package/docs/components/composed/schedule-view.md +39 -39
  354. package/docs/components/composed/simple-tooltip.md +33 -33
  355. package/docs/components/composed/status-badge.md +55 -55
  356. package/docs/components/shell/app-command-palette.md +44 -44
  357. package/docs/components/shell/bottom-navbar.md +52 -52
  358. package/docs/components/shell/command-registry.md +48 -48
  359. package/docs/components/shell/link-context.md +41 -41
  360. package/docs/components/shell/notification-center.md +63 -63
  361. package/docs/components/shell/notification-preferences.md +42 -42
  362. package/docs/components/shell/sidebar.md +92 -92
  363. package/docs/components/shell/top-bar.md +143 -143
  364. package/docs/components/ui/accordion.md +51 -51
  365. package/docs/components/ui/alert-dialog.md +61 -61
  366. package/docs/components/ui/alert.md +46 -46
  367. package/docs/components/ui/aspect-ratio.md +25 -25
  368. package/docs/components/ui/autocomplete.md +48 -48
  369. package/docs/components/ui/avatar.md +56 -56
  370. package/docs/components/ui/badge.md +83 -82
  371. package/docs/components/ui/banner.md +42 -42
  372. package/docs/components/ui/breadcrumb.md +37 -37
  373. package/docs/components/ui/button-group.md +41 -41
  374. package/docs/components/ui/button.md +94 -93
  375. package/docs/components/ui/card.md +52 -52
  376. package/docs/components/ui/charts.md +43 -43
  377. package/docs/components/ui/checkbox.md +36 -36
  378. package/docs/components/ui/chip.md +47 -47
  379. package/docs/components/ui/code.md +28 -28
  380. package/docs/components/ui/collapsible.md +40 -40
  381. package/docs/components/ui/color-input.md +91 -91
  382. package/docs/components/ui/color-swatch.md +25 -25
  383. package/docs/components/ui/combobox.md +54 -54
  384. package/docs/components/ui/container.md +26 -26
  385. package/docs/components/ui/context-menu.md +43 -43
  386. package/docs/components/ui/data-table-body.md +1 -1
  387. package/docs/components/ui/data-table-bulk-actions.md +1 -1
  388. package/docs/components/ui/data-table-card.md +1 -1
  389. package/docs/components/ui/data-table-context.md +1 -1
  390. package/docs/components/ui/data-table-header.md +1 -1
  391. package/docs/components/ui/data-table-pagination.md +1 -1
  392. package/docs/components/ui/data-table-toolbar.md +44 -44
  393. package/docs/components/ui/data-table.md +94 -94
  394. package/docs/components/ui/dialog.md +54 -54
  395. package/docs/components/ui/dropdown-menu.md +48 -48
  396. package/docs/components/ui/file-upload.md +41 -41
  397. package/docs/components/ui/form.md +51 -51
  398. package/docs/components/ui/hover-card.md +32 -32
  399. package/docs/components/ui/icon-button.md +40 -40
  400. package/docs/components/ui/input-otp.md +44 -44
  401. package/docs/components/ui/input.md +74 -74
  402. package/docs/components/ui/label.md +25 -25
  403. package/docs/components/ui/link.md +29 -29
  404. package/docs/components/ui/menubar.md +44 -44
  405. package/docs/components/ui/navigation-menu.md +46 -46
  406. package/docs/components/ui/number-input.md +44 -44
  407. package/docs/components/ui/pagination.md +48 -48
  408. package/docs/components/ui/popover.md +30 -30
  409. package/docs/components/ui/progress-ring.md +41 -41
  410. package/docs/components/ui/progress.md +34 -34
  411. package/docs/components/ui/radio.md +34 -34
  412. package/docs/components/ui/search-input.md +43 -43
  413. package/docs/components/ui/segmented-control.md +50 -50
  414. package/docs/components/ui/select.md +53 -53
  415. package/docs/components/ui/separator.md +32 -32
  416. package/docs/components/ui/sheet.md +47 -47
  417. package/docs/components/ui/sidebar.md +72 -72
  418. package/docs/components/ui/skeleton.md +77 -77
  419. package/docs/components/ui/slider.md +29 -29
  420. package/docs/components/ui/spinner.md +54 -54
  421. package/docs/components/ui/stack.md +39 -39
  422. package/docs/components/ui/stat-card.md +61 -61
  423. package/docs/components/ui/status-dot.md +26 -26
  424. package/docs/components/ui/stepper.md +49 -49
  425. package/docs/components/ui/switch.md +47 -47
  426. package/docs/components/ui/table.md +47 -47
  427. package/docs/components/ui/tabs.md +60 -60
  428. package/docs/components/ui/text.md +37 -37
  429. package/docs/components/ui/textarea.md +39 -39
  430. package/docs/components/ui/toast.md +65 -65
  431. package/docs/components/ui/toaster.md +47 -47
  432. package/docs/components/ui/toggle-group.md +43 -43
  433. package/docs/components/ui/toggle.md +37 -37
  434. package/docs/components/ui/tooltip.md +38 -38
  435. package/docs/components/ui/tree-view.md +65 -65
  436. package/docs/components/ui/visually-hidden.md +21 -21
  437. package/llms-full.txt +5266 -5264
  438. package/llms.txt +624 -580
  439. package/package.json +7 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.js","names":[],"sources":["../../src/ui/label.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as LabelPrimitive from '@primitives/react-label'\n\nimport { cn } from './lib/utils'\nimport { useFormField } from './form'\n\nexport interface LabelProps\n extends React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> {\n required?: boolean\n}\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n LabelProps\n>(({ className, required, children, htmlFor, ...props }, ref) => {\n const fieldCtx = useFormField()\n // Explicit htmlFor wins; otherwise fall back to FormField's inputId.\n const resolvedHtmlFor = htmlFor ?? fieldCtx.inputId\n const resolvedRequired = required ?? fieldCtx.required\n return (\n <LabelPrimitive.Root\n ref={ref}\n htmlFor={resolvedHtmlFor}\n className={cn(\n 'font-sans text-ds-md font-medium text-surface-fg leading-none transition-opacity duration-fast-01 ease-productive-standard peer-disabled:opacity-action-disabled',\n className,\n )}\n {...props}\n >\n {children}\n {resolvedRequired && (\n <span className=\"text-error-11 ml-ds-01\" aria-hidden=\"true\">*</span>\n )}\n </LabelPrimitive.Root>\n )\n})\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label }\n"],"mappings":";;;;;;;AAaA,IAAM,IAAQ,EAAM,YAGjB,EAAE,cAAW,aAAU,aAAU,YAAS,GAAG,KAAS,MAAQ;CAC/D,IAAM,IAAW,GAAc,EAEzB,IAAkB,KAAW,EAAS,SACtC,IAAmB,KAAY,EAAS;AAC9C,QACE,kBAAC,GAAD;EACO;EACL,SAAS;EACT,WAAW,EACT,oKACA,EACD;EACD,GAAI;YAPN,CASG,GACA,KACC,kBAAC,QAAD;GAAM,WAAU;GAAyB,eAAY;aAAO;GAAQ,CAAA,CAElD;;EAExB;AACF,EAAM,cAAA,EAAkC"}
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ export declare function checkTokensLoaded(): void;
3
+ //# sourceMappingURL=check-tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-tokens.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/check-tokens.ts"],"names":[],"mappings":"AAYA,wBAAgB,iBAAiB,IAAI,IAAI,CAuBxC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-utils.js","names":[],"sources":["../../../src/ui/lib/date-utils.ts"],"sourcesContent":["// @server-safe\n/**\n * Shared relative-time formatting utility.\n */\nexport function formatRelativeTime(dateInput: Date | string): string {\n const date = typeof dateInput === 'string' ? new Date(dateInput) : dateInput\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffMin = Math.floor(diffMs / 60000)\n\n if (diffMin < 1) return 'Just now'\n if (diffMin < 60) return `${diffMin}m ago`\n\n const diffHour = Math.floor(diffMin / 60)\n if (diffHour < 24) return `${diffHour}h ago`\n\n const diffDay = Math.floor(diffHour / 24)\n if (diffDay < 7) return `${diffDay}d ago`\n\n return date.toLocaleDateString('en-IN', { month: 'short', day: 'numeric' })\n}\n"],"mappings":";AAIA,SAAgB,EAAmB,GAAkC;CACnE,IAAM,IAAO,OAAO,KAAc,WAAW,IAAI,KAAK,EAAU,GAAG,GAE7D,qBADM,IAAI,MAAM,EACH,SAAS,GAAG,EAAK,SAAS,EACvC,IAAU,KAAK,MAAM,IAAS,IAAM;AAE1C,KAAI,IAAU,EAAG,QAAO;AACxB,KAAI,IAAU,GAAI,QAAO,GAAG,EAAQ;CAEpC,IAAM,IAAW,KAAK,MAAM,IAAU,GAAG;AACzC,KAAI,IAAW,GAAI,QAAO,GAAG,EAAS;CAEtC,IAAM,IAAU,KAAK,MAAM,IAAW,GAAG;AAGzC,QAFI,IAAU,IAAU,GAAG,EAAQ,SAE5B,EAAK,mBAAmB,SAAS;EAAE,OAAO;EAAS,KAAK;EAAW,CAAC"}
@@ -1,4 +1,15 @@
1
1
  import { Transition } from 'framer-motion';
2
+ export declare const durations: {
3
+ readonly instant: 0;
4
+ readonly fast01: 0.07;
5
+ readonly fast02: 0.11;
6
+ readonly moderate01: 0.15;
7
+ readonly moderate01b: 0.2;
8
+ readonly moderate02: 0.24;
9
+ readonly slow01: 0.4;
10
+ readonly slow02: 0.7;
11
+ };
12
+ export type DurationPreset = keyof typeof durations;
2
13
  export declare const springs: {
3
14
  /** Micro-interactions: buttons, hover, form inputs */
4
15
  readonly snappy: Transition;
@@ -12,13 +23,13 @@ export declare const springs: {
12
23
  readonly responsive: Transition;
13
24
  };
14
25
  export declare const tweens: {
15
- /** Opacity enter/exit */
26
+ /** Opacity enter/exit — matches --duration-fast-02 (110ms) */
16
27
  readonly fade: Transition;
17
- /** Hover color, bg, border transitions */
28
+ /** Hover color, bg, border transitions — matches --duration-fast-01 (70ms) */
18
29
  readonly colorShift: Transition;
19
- /** Greeting fade, hint crossfade — unhurried, confident */
30
+ /** Greeting fade, hint crossfade — matches --duration-slow-01 (400ms) */
20
31
  readonly elegant: Transition;
21
- /** Button/element layout transitions — smooth width/height changes, no overshoot */
32
+ /** Button/element layout transitions — matches --duration-moderate-01b (200ms) */
22
33
  readonly layout: Transition;
23
34
  };
24
35
  export declare function stagger(delay?: number): {
@@ -1 +1 @@
1
- {"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/motion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI/C,eAAO,MAAM,OAAO;IAClB,sDAAsD;qBACgB,UAAU;IAChF,0CAA0C;qBAC4B,UAAU;IAChF,4CAA4C;qBAC0B,UAAU;IAChF,iDAAiD;qBACqB,UAAU;IAChF,qEAAqE;yBACK,UAAU;CAC5E,CAAA;AAIV,eAAO,MAAM,MAAM;IACjB,yBAAyB;mBACmC,UAAU;IACtE,0CAA0C;yBACwB,UAAU;IAC5E,2DAA2D;sBACc,UAAU;IACnF,oFAAoF;qBACZ,UAAU;CAC1E,CAAA;AAIV,wBAAgB,OAAO,CAAC,KAAK,SAAO;;;;;;;;;;;EAKnC;AAID,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAEpE;AAID,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,OAAO,CAAA;AAC/C,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,MAAM,CAAA;AAQ7C;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhG"}
1
+ {"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../../../src/ui/lib/motion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI/C,eAAO,MAAM,SAAS;;;;;;;;;CASZ,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,SAAS,CAAA;AAInD,eAAO,MAAM,OAAO;IAClB,sDAAsD;qBACgB,UAAU;IAChF,0CAA0C;qBAC4B,UAAU;IAChF,4CAA4C;qBAC0B,UAAU;IAChF,iDAAiD;qBACqB,UAAU;IAChF,qEAAqE;yBACK,UAAU;CAC5E,CAAA;AAIV,eAAO,MAAM,MAAM;IACjB,8DAA8D;mBACU,UAAU;IAClF,8EAA8E;yBACA,UAAU;IACxF,yEAAyE;sBACa,UAAU;IAChG,kFAAkF;qBACQ,UAAU;CAC5F,CAAA;AAIV,wBAAgB,OAAO,CAAC,KAAK,SAAO;;;;;;;;;;;EAKnC;AAID,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAEpE;AAID,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,OAAO,CAAA;AAC/C,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,MAAM,CAAA;AAQ7C;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEhG"}
@@ -1,5 +1,14 @@
1
1
  //#region src/ui/lib/motion.ts
2
2
  var e = {
3
+ instant: 0,
4
+ fast01: .07,
5
+ fast02: .11,
6
+ moderate01: .15,
7
+ moderate01b: .2,
8
+ moderate02: .24,
9
+ slow01: .4,
10
+ slow02: .7
11
+ }, t = {
3
12
  snappy: {
4
13
  type: "spring",
5
14
  stiffness: 500,
@@ -30,20 +39,20 @@ var e = {
30
39
  damping: 28,
31
40
  mass: .6
32
41
  }
33
- }, t = {
42
+ }, n = {
34
43
  fade: {
35
44
  type: "tween",
36
- duration: .11,
45
+ duration: e.fast02,
37
46
  ease: "easeOut"
38
47
  },
39
48
  colorShift: {
40
49
  type: "tween",
41
- duration: .07,
50
+ duration: e.fast01,
42
51
  ease: "easeOut"
43
52
  },
44
53
  elegant: {
45
54
  type: "tween",
46
- duration: .4,
55
+ duration: e.slow01,
47
56
  ease: [
48
57
  .25,
49
58
  .1,
@@ -53,7 +62,7 @@ var e = {
53
62
  },
54
63
  layout: {
55
64
  type: "tween",
56
- duration: .2,
65
+ duration: e.moderate01b,
57
66
  ease: [
58
67
  .25,
59
68
  .1,
@@ -62,20 +71,20 @@ var e = {
62
71
  ]
63
72
  }
64
73
  };
65
- function n(e = .04) {
74
+ function r(e = .04) {
66
75
  return {
67
76
  visible: { transition: { staggerChildren: e } },
68
77
  hidden: { transition: { staggerChildren: e } }
69
78
  };
70
79
  }
71
- function r(e) {
80
+ function i(e) {
72
81
  return {
73
82
  ...e,
74
83
  duration: 0
75
84
  };
76
85
  }
77
- function i(e) {
86
+ function a(e) {
78
87
  return e;
79
88
  }
80
89
  //#endregion
81
- export { i as motionProps, e as springs, n as stagger, t as tweens, r as withReducedMotion };
90
+ export { e as durations, a as motionProps, t as springs, r as stagger, n as tweens, i as withReducedMotion };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion.js","names":[],"sources":["../../../src/ui/lib/motion.ts"],"sourcesContent":["// @server-safe\nimport type { Transition } from 'framer-motion'\n\n// ── Duration constants (mirrors CSS --duration-* tokens, in seconds for Framer Motion) ──\n\nexport const durations = {\n instant: 0,\n fast01: 0.07,\n fast02: 0.11,\n moderate01: 0.15,\n moderate01b: 0.2,\n moderate02: 0.24,\n slow01: 0.4,\n slow02: 0.7,\n} as const\n\nexport type DurationPreset = keyof typeof durations\n\n// ── Spring configs (spatial: position, scale, size, rotation) ──\n\nexport const springs = {\n /** Micro-interactions: buttons, hover, form inputs */\n snappy: { type: 'spring', stiffness: 500, damping: 30, mass: 0.5 } as Transition,\n /** Dialogs, sheets, panels, navigation */\n smooth: { type: 'spring', stiffness: 300, damping: 30, mass: 0.8 } as Transition,\n /** Toasts, pop-ins, celebration feedback */\n bouncy: { type: 'spring', stiffness: 400, damping: 15, mass: 0.5 } as Transition,\n /** Collapse/expand, accordion, height changes */\n gentle: { type: 'spring', stiffness: 200, damping: 25, mass: 0.8 } as Transition,\n /** AI response blocks — snappier than smooth, feels \"intelligent\" */\n responsive: { type: 'spring', stiffness: 350, damping: 28, mass: 0.6 } as Transition,\n} as const\n\n// ── Tween configs (non-spatial: opacity, color, background) ──\n\nexport const tweens = {\n /** Opacity enter/exit — matches --duration-fast-02 (110ms) */\n fade: { type: 'tween', duration: durations.fast02, ease: 'easeOut' } as Transition,\n /** Hover color, bg, border transitions — matches --duration-fast-01 (70ms) */\n colorShift: { type: 'tween', duration: durations.fast01, ease: 'easeOut' } as Transition,\n /** Greeting fade, hint crossfade — matches --duration-slow-01 (400ms) */\n elegant: { type: 'tween', duration: durations.slow01, ease: [0.25, 0.1, 0.25, 1] } as Transition,\n /** Button/element layout transitions — matches --duration-moderate-01b (200ms) */\n layout: { type: 'tween', duration: durations.moderate01b, ease: [0.25, 0.1, 0.25, 1] } as Transition,\n} as const\n\n// ── Stagger helper ──\n\nexport function stagger(delay = 0.04) {\n return {\n visible: { transition: { staggerChildren: delay } },\n hidden: { transition: { staggerChildren: delay } },\n }\n}\n\n// ── Reduced motion helper ──\n\nexport function withReducedMotion(transition: Transition): Transition {\n return { ...transition, duration: 0 }\n}\n\n// ── Preset types ──\n\nexport type SpringPreset = keyof typeof springs\nexport type TweenPreset = keyof typeof tweens\n\n// ── React ↔ Framer Motion event-handler compatibility ──\n// Framer Motion redefines several React event handlers (onDrag*, onAnimationStart,\n// etc.) with different signatures. When spreading React HTML props onto a motion.*\n// element, a type-level cast is needed to bridge the mismatch. At runtime the\n// handlers are identical DOM events — only the TS types conflict.\n\n/**\n * Cast React HTML props so they can be safely spread onto a Framer Motion\n * `motion.*` element without type conflicts on shared event-handler names.\n *\n * Returns `Record<string, unknown>` rather than `any` to keep the spread safe\n * while avoiding a full `any` leak. A truly generic passthrough (`T`) would\n * re-surface the exact type conflicts this function exists to erase, because\n * the React event-handler types on `T` still clash with Framer Motion's\n * overloaded signatures. `Record<string, unknown>` is the narrowest type that\n * satisfies both sides.\n */\nexport function motionProps<T extends Record<string, unknown>>(props: T): Record<string, unknown> {\n return props\n}\n"],"mappings":";AAKA,IAAa,IAAY;CACvB,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,aAAa;CACb,YAAY;CACZ,QAAQ;CACR,QAAQ;CACT,EAMY,IAAU;CAErB,QAAQ;EAAE,MAAM;EAAU,WAAW;EAAK,SAAS;EAAI,MAAM;EAAK;CAElE,QAAQ;EAAE,MAAM;EAAU,WAAW;EAAK,SAAS;EAAI,MAAM;EAAK;CAElE,QAAQ;EAAE,MAAM;EAAU,WAAW;EAAK,SAAS;EAAI,MAAM;EAAK;CAElE,QAAQ;EAAE,MAAM;EAAU,WAAW;EAAK,SAAS;EAAI,MAAM;EAAK;CAElE,YAAY;EAAE,MAAM;EAAU,WAAW;EAAK,SAAS;EAAI,MAAM;EAAK;CACvE,EAIY,IAAS;CAEpB,MAAM;EAAE,MAAM;EAAS,UAAU,EAAU;EAAQ,MAAM;EAAW;CAEpE,YAAY;EAAE,MAAM;EAAS,UAAU,EAAU;EAAQ,MAAM;EAAW;CAE1E,SAAS;EAAE,MAAM;EAAS,UAAU,EAAU;EAAQ,MAAM;GAAC;GAAM;GAAK;GAAM;GAAE;EAAE;CAElF,QAAQ;EAAE,MAAM;EAAS,UAAU,EAAU;EAAa,MAAM;GAAC;GAAM;GAAK;GAAM;GAAE;EAAE;CACvF;AAID,SAAgB,EAAQ,IAAQ,KAAM;AACpC,QAAO;EACL,SAAS,EAAE,YAAY,EAAE,iBAAiB,GAAO,EAAE;EACnD,QAAQ,EAAE,YAAY,EAAE,iBAAiB,GAAO,EAAE;EACnD;;AAKH,SAAgB,EAAkB,GAAoC;AACpE,QAAO;EAAE,GAAG;EAAY,UAAU;EAAG;;AAyBvC,SAAgB,EAA+C,GAAmC;AAChG,QAAO"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/ui/lib/utils.ts"],"sourcesContent":["// @server-safe\nimport { clsx, type ClassValue } from 'clsx'\nimport { extendTailwindMerge } from 'tailwind-merge'\n\nconst twMerge = extendTailwindMerge({\n extend: {\n theme: {\n spacing: ['ds-01', 'ds-02', 'ds-02b', 'ds-03', 'ds-04', 'ds-05', 'ds-05b', 'ds-06', 'ds-06b', 'ds-07', 'ds-08', 'ds-09', 'ds-10', 'ds-11', 'ds-12', 'ds-13'],\n },\n classGroups: {\n 'font-size': [{ 'text-ds': ['xs', 'sm', 'md', 'base', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl'] }],\n },\n },\n})\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";;AAIA,IAAM,IAAU,EAAoB,EAClC,QAAQ;CACN,OAAO,EACL,SAAS;EAAC;EAAS;EAAS;EAAU;EAAS;EAAS;EAAS;EAAU;EAAS;EAAU;EAAS;EAAS;EAAS;EAAS;EAAS;EAAS;EAAQ,EAC7J;CACD,aAAa,EACX,aAAa,CAAC,EAAE,WAAW;EAAC;EAAM;EAAM;EAAM;EAAQ;EAAM;EAAM;EAAO;EAAO;EAAO;EAAO;EAAM,EAAE,CAAC,EACxG;CACF,EACF,CAAC;AAEF,SAAgB,EAAG,GAAG,GAAsB;AAC1C,QAAO,EAAQ,EAAK,EAAO,CAAC"}
package/dist/ui/link.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { Ln as e } from "../_chunks/primitives.js";
2
+ import { Hn as e } from "../_chunks/primitives.js";
3
3
  import { cn as t } from "./lib/utils.js";
4
4
  import * as n from "react";
5
5
  import { jsx as r } from "react/jsx-runtime";
6
6
  //#region src/ui/link.tsx
7
7
  var i = n.forwardRef(({ className: n, inline: i = !0, asChild: a = !1, ...o }, s) => /* @__PURE__ */ r(a ? e : "a", {
8
8
  ref: s,
9
- className: t("text-accent-11 underline decoration-transparent hover:decoration-current underline-offset-2", "hover:text-accent-12 active:opacity-80 transition-[color,text-decoration-color,opacity] duration-fast-01 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 rounded-ds-sm", i ? "inline" : "block", n),
9
+ className: t("text-accent-11 underline decoration-transparent hover:decoration-current underline-offset-2", "hover:text-accent-12 active:opacity-80 transition-[color,text-decoration-color,opacity] duration-fast-01 ease-productive-standard", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 rounded-ds-sm", i ? "inline" : "block", n),
10
10
  ...o
11
11
  }));
12
12
  i.displayName = "Link";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","names":[],"sources":["../../src/ui/link.tsx"],"sourcesContent":["'use client'\n\nimport { Slot } from '@primitives/react-slot'\nimport * as React from 'react'\nimport { cn } from './lib/utils'\n\nexport interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n inline?: boolean\n asChild?: boolean\n}\n\nconst Link = React.forwardRef<HTMLAnchorElement, LinkProps>(\n ({ className, inline = true, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a'\n\n return (\n <Comp\n ref={ref}\n className={cn(\n 'text-accent-11 underline decoration-transparent hover:decoration-current underline-offset-2',\n 'hover:text-accent-12 active:opacity-80 transition-[color,text-decoration-color,opacity] 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 rounded-ds-sm',\n inline ? 'inline' : 'block',\n className,\n )}\n {...props}\n />\n )\n },\n)\nLink.displayName = 'Link'\n\nexport { Link }\n"],"mappings":";;;;;;AAWA,IAAM,IAAO,EAAM,YAChB,EAAE,cAAW,YAAS,IAAM,aAAU,IAAO,GAAG,KAAS,MAItD,kBAHW,IAAU,IAAO,KAG5B;CACO;CACL,WAAW,EACT,+FACA,qIACA,2HACA,IAAS,WAAW,SACpB,EACD;CACD,GAAI;CACJ,CAAA,CAGP;AACD,EAAK,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menubar.js","names":[],"sources":["../../src/ui/menubar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as MenubarPrimitive from '@primitives/react-menubar'\nimport { IconCheck, IconChevronRight, IconCircle } from '@tabler/icons-react'\nimport { motion, AnimatePresence } from 'framer-motion'\n\nimport { cn } from './lib/utils'\nimport { springs, tweens } from './lib/motion'\nimport { Icon } from './icon'\n\n// ── Internal contexts to thread open state ──\n\nconst MenubarSubOpenContext = React.createContext(false)\n\nconst MenubarMenu: React.FC<React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Menu>> = (props) => {\n // MenubarPrimitive.Menu doesn't expose open/onOpenChange directly.\n // We derive open from data-state on the trigger via a callback ref approach,\n // but the cleanest way is to use the Menubar root's value prop.\n // Since MenubarMenu doesn't have open/onOpenChange, we track via a wrapper\n // that observes the trigger's data-state.\n //\n // Alternative: MenubarPrimitive.Menu has a `value` that the root uses.\n // We'll use a simpler approach: track open via content mount state.\n return <MenubarPrimitive.Menu {...props} />\n}\nMenubarMenu.displayName = 'MenubarMenu'\n\n// For Menubar, the Menu doesn't expose open/onOpenChange. Instead, we'll use a\n// different approach: wrap Content to use a local presence state based on data-state.\n// We create a wrapper component that tracks whether content should be shown.\n\nconst MenubarGroup: typeof MenubarPrimitive.Group = MenubarPrimitive.Group\n\nconst MenubarPortal: typeof MenubarPrimitive.Portal = MenubarPrimitive.Portal\n\nconst MenubarSub: React.FC<React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Sub>> = ({\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n ...props\n}) => {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n const isControlled = controlledOpen !== undefined\n const open = isControlled ? controlledOpen : uncontrolledOpen\n\n const handleOpenChange = React.useCallback(\n (value: boolean) => {\n if (!isControlled) setUncontrolledOpen(value)\n onOpenChange?.(value)\n },\n [isControlled, onOpenChange],\n )\n\n return (\n <MenubarSubOpenContext.Provider value={open}>\n <MenubarPrimitive.Sub open={open} onOpenChange={handleOpenChange} {...props} />\n </MenubarSubOpenContext.Provider>\n )\n}\nMenubarSub.displayName = 'MenubarSub'\n\nconst MenubarRadioGroup: typeof MenubarPrimitive.RadioGroup =\n MenubarPrimitive.RadioGroup\n\nconst Menubar = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Root\n ref={ref}\n className={cn(\n 'flex h-ds-sm-plus items-center space-x-ds-02 rounded-ds-lg border border-surface-border-strong bg-surface-overlay p-ds-02 shadow-raised',\n className,\n )}\n {...props}\n />\n))\nMenubar.displayName = MenubarPrimitive.Root.displayName\n\nconst MenubarTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Trigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center rounded-ds-sm px-ds-04 py-ds-02 text-ds-md font-medium outline-hidden transition-colors hover:bg-surface-raised-hover focus-visible:bg-surface-raised-hover data-[state=open]:bg-surface-raised-hover',\n className,\n )}\n {...props}\n />\n))\nMenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName\n\nconst MenubarSubTrigger = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <MenubarPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b text-ds-md outline-hidden focus:bg-surface-raised data-[state=open]:bg-surface-raised [&_svg]:pointer-events-none [&_svg]:h-ico-sm [&_svg]:w-ico-sm [&_svg]:shrink-0',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n >\n {children}\n <Icon icon={IconChevronRight} size=\"sm\" className=\"ml-auto\" />\n </MenubarPrimitive.SubTrigger>\n))\nMenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName\n\nconst MenubarSubContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.SubContent>\n>(({ className, children, ...props }, ref) => {\n const open = React.useContext(MenubarSubOpenContext)\n\n return (\n <AnimatePresence>\n {open && (\n <MenubarPrimitive.SubContent\n ref={ref}\n forceMount\n asChild\n {...props}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={{ ...springs.snappy, opacity: tweens.fade }}\n className={cn(\n 'z-popover min-w-[8rem] overflow-hidden rounded-ds-lg border border-surface-border-strong bg-surface-overlay p-ds-02 text-surface-fg shadow-floating',\n className,\n )}\n >\n {children}\n </motion.div>\n </MenubarPrimitive.SubContent>\n )}\n </AnimatePresence>\n )\n})\nMenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName\n\n// For MenubarContent, since MenubarMenu doesn't expose open/onOpenChange,\n// we use a wrapper that reads presence from a callback approach.\n// The cleanest solution: use a local state tracker via onCloseAutoFocus/onOpenAutoFocus\n// or simply keep CSS-free and let Radix handle mount/unmount naturally.\n//\n// Since Menubar menus are opened by the Menubar root (which tracks which menu value is open),\n// and MenubarPrimitive.Content already handles mount/unmount, we can use a ref-based approach\n// to detect the data-state attribute. However, the simplest reliable approach is to use\n// a wrapper that detects mount via useEffect.\n\n// MenubarContent uses CSS data-state animations instead of framer-motion because\n// MenubarPrimitive.Menu doesn't expose open/onOpenChange, making AnimatePresence\n// impossible to wire up for exit animations. The popover-in/popover-out keyframes\n// are defined in the tailwind preset and triggered by Radix's data-state attribute.\nconst MenubarContent = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>\n>(\n (\n { className, align = 'start', alignOffset = -4, sideOffset = 8, children, ...props },\n ref,\n ) => (\n <MenubarPrimitive.Portal>\n <MenubarPrimitive.Content\n ref={ref}\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n 'z-popover min-w-[12rem] rounded-ds-lg border border-surface-border-strong bg-surface-overlay p-ds-02 text-surface-fg shadow-floating',\n 'data-[state=open]:animate-popover-in data-[state=closed]:animate-popover-out',\n className,\n )}\n {...props}\n >\n {children}\n </MenubarPrimitive.Content>\n </MenubarPrimitive.Portal>\n ),\n)\nMenubarContent.displayName = MenubarPrimitive.Content.displayName\n\nconst MenubarItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center gap-ds-03 rounded-ds-md px-ds-03 py-ds-02b text-ds-md outline-hidden transition-colors focus:bg-surface-raised focus:text-surface-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled [&>svg]:h-ico-sm [&>svg]:w-ico-sm [&>svg]:shrink-0',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n />\n))\nMenubarItem.displayName = MenubarPrimitive.Item.displayName\n\nconst MenubarCheckboxItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <MenubarPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-ds-md py-ds-02b pl-ds-07 pr-ds-03 text-ds-md outline-hidden transition-colors focus:bg-surface-raised focus:text-surface-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled',\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-ds-03 flex h-ico-sm w-ico-sm items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <Icon icon={IconCheck} size=\"sm\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n))\nMenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName\n\nconst MenubarRadioItem = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <MenubarPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-ds-md py-ds-02b pl-ds-07 pr-ds-03 text-ds-md outline-hidden transition-colors focus:bg-surface-raised focus:text-surface-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-action-disabled',\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-ds-03 flex h-ico-sm w-ico-sm items-center justify-center\">\n <MenubarPrimitive.ItemIndicator>\n <IconCircle className=\"h-2 w-2 fill-current\" />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n))\nMenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName\n\nconst MenubarLabel = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <MenubarPrimitive.Label\n ref={ref}\n className={cn(\n 'px-ds-03 py-ds-02b text-ds-md font-semibold',\n inset && 'pl-ds-07',\n className,\n )}\n {...props}\n />\n))\nMenubarLabel.displayName = MenubarPrimitive.Label.displayName\n\nconst MenubarSeparator = React.forwardRef<\n React.ElementRef<typeof MenubarPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <MenubarPrimitive.Separator\n ref={ref}\n className={cn('-mx-ds-01 my-ds-02 h-px bg-surface-border', className)}\n {...props}\n />\n))\nMenubarSeparator.displayName = MenubarPrimitive.Separator.displayName\n\nconst MenubarShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn(\n 'ml-auto text-ds-sm text-surface-fg-subtle',\n className,\n )}\n {...props}\n />\n )\n}\nMenubarShortcut.displayName = 'MenubarShortcut'\n\nexport type MenubarContentProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>\nexport type MenubarItemProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item>\n\nexport {\n Menubar,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarItem,\n MenubarSeparator,\n MenubarLabel,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarPortal,\n MenubarGroup,\n MenubarSub,\n MenubarSubContent,\n MenubarSubTrigger,\n MenubarShortcut,\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-menu.js","names":[],"sources":["../../src/ui/navigation-menu.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as NavigationMenuPrimitive from '@primitives/react-navigation-menu'\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\n\nimport { cn } from './lib/utils'\nimport { springs, tweens } from './lib/motion'\nimport { Icon } from './icon'\n\nconst NavigationMenu = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n <NavigationMenuPrimitive.Root\n ref={ref}\n className={cn(\n 'relative z-raised flex max-w-max flex-1 items-center justify-center',\n className,\n )}\n {...props}\n >\n {children}\n <NavigationMenuViewport />\n </NavigationMenuPrimitive.Root>\n))\nNavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName\n\nconst NavigationMenuList = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.List>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n <NavigationMenuPrimitive.List\n ref={ref}\n className={cn(\n 'group flex flex-1 list-none items-center justify-center space-x-ds-02',\n className,\n )}\n {...props}\n />\n))\nNavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName\n\nconst NavigationMenuItem = NavigationMenuPrimitive.Item\n\nconst NavigationMenuTrigger = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <NavigationMenuPrimitive.Trigger\n ref={ref}\n className={cn(\n 'group inline-flex h-ds-sm-plus w-max items-center justify-center rounded-ds-md bg-transparent px-ds-05 py-ds-03 text-ds-md font-medium transition-colors hover:bg-surface-raised-hover focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 disabled:pointer-events-none disabled:opacity-action-disabled',\n className,\n )}\n {...props}\n >\n {children}{' '}\n <Icon icon={IconChevronDown} size=\"sm\" className=\"relative top-[1px] ml-ds-02 transition-transform duration-moderate-02 group-data-[state=open]:rotate-180\" />\n </NavigationMenuPrimitive.Trigger>\n))\nNavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName\n\n// ── NavigationMenuContent — directional slide using data-motion ──\n\nconst contentSlideVariants = {\n 'from-start': { x: '-13rem', opacity: 0 },\n 'from-end': { x: '13rem', opacity: 0 },\n 'to-start': { x: '-13rem', opacity: 0 },\n 'to-end': { x: '13rem', opacity: 0 },\n center: { x: 0, opacity: 1 },\n} as const\n\nconst NavigationMenuContent = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => {\n const innerRef = React.useRef<HTMLDivElement>(null)\n const composedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n (innerRef 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 [ref],\n )\n\n const [motionDir, setMotionDir] = React.useState<string | null>(null)\n\n // Observe data-motion attribute changes from Radix\n React.useEffect(() => {\n const el = innerRef.current\n if (!el) return\n\n // Read initial value\n const initial = el.getAttribute('data-motion')\n if (initial) setMotionDir(initial)\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === 'data-motion') {\n const val = el.getAttribute('data-motion')\n setMotionDir(val)\n }\n }\n })\n observer.observe(el, { attributes: true, attributeFilter: ['data-motion'] })\n return () => observer.disconnect()\n }, [])\n\n const initial = motionDir && motionDir.startsWith('from-')\n ? contentSlideVariants[motionDir as keyof typeof contentSlideVariants]\n : motionDir && motionDir.startsWith('to-')\n ? contentSlideVariants.center\n : { x: 0, opacity: 0 }\n\n const animate = motionDir && motionDir.startsWith('from-')\n ? contentSlideVariants.center\n : motionDir && motionDir.startsWith('to-')\n ? contentSlideVariants[motionDir as keyof typeof contentSlideVariants]\n : contentSlideVariants.center\n\n return (\n <NavigationMenuPrimitive.Content\n ref={composedRef}\n className={cn(\n 'left-0 top-0 w-full md:absolute md:w-auto',\n className,\n )}\n {...props}\n >\n <motion.div\n key={motionDir}\n initial={initial}\n animate={animate}\n transition={{ ...springs.smooth, opacity: tweens.fade }}\n className=\"w-full\"\n >\n {props.children}\n </motion.div>\n </NavigationMenuPrimitive.Content>\n )\n})\nNavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName\n\nconst NavigationMenuLink = NavigationMenuPrimitive.Link\n\n// ── NavigationMenuViewport — scale + fade with layout for size changes ──\n\nconst NavigationMenuViewport = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => {\n const innerRef = React.useRef<HTMLDivElement>(null)\n const composedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n (innerRef 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 [ref],\n )\n\n const [isOpen, setIsOpen] = React.useState(false)\n\n React.useEffect(() => {\n const el = innerRef.current\n if (!el) return\n\n const initial = el.getAttribute('data-state')\n setIsOpen(initial === 'open')\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === 'data-state') {\n setIsOpen(el.getAttribute('data-state') === 'open')\n }\n }\n })\n observer.observe(el, { attributes: true, attributeFilter: ['data-state'] })\n return () => observer.disconnect()\n }, [])\n\n return (\n <div className={cn('absolute left-0 top-full flex justify-center')}>\n <NavigationMenuPrimitive.Viewport\n className={cn(\n 'origin-top-center relative mt-ds-02b h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-ds-lg border border-surface-border-strong bg-surface-overlay shadow-floating md:w-[var(--radix-navigation-menu-viewport-width)]',\n className,\n )}\n ref={composedRef}\n {...props}\n />\n {/* Overlay motion element for scale+fade animation */}\n <motion.div\n aria-hidden\n className=\"absolute inset-0 pointer-events-none\"\n initial={false}\n animate={isOpen ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.95 }}\n transition={{ ...springs.smooth, opacity: tweens.fade }}\n />\n </div>\n )\n})\nNavigationMenuViewport.displayName =\n NavigationMenuPrimitive.Viewport.displayName\n\n// ── NavigationMenuIndicator — fade + layout position sliding ──\n\nconst NavigationMenuIndicator = React.forwardRef<\n React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,\n React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => {\n const innerRef = React.useRef<HTMLDivElement>(null)\n const composedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n (innerRef 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 [ref],\n )\n\n const [isVisible, setIsVisible] = React.useState(false)\n\n React.useEffect(() => {\n const el = innerRef.current\n if (!el) return\n\n const initial = el.getAttribute('data-state')\n setIsVisible(initial === 'visible')\n\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n if (m.attributeName === 'data-state') {\n setIsVisible(el.getAttribute('data-state') === 'visible')\n }\n }\n })\n observer.observe(el, { attributes: true, attributeFilter: ['data-state'] })\n return () => observer.disconnect()\n }, [])\n\n return (\n <NavigationMenuPrimitive.Indicator\n ref={composedRef}\n className={cn(\n 'top-full z-base flex h-ds-02b items-end justify-center overflow-hidden',\n className,\n )}\n {...props}\n >\n <motion.div\n layout\n initial={false}\n animate={isVisible ? { opacity: 1 } : { opacity: 0 }}\n transition={tweens.fade}\n className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-surface-border shadow-raised-hover\"\n />\n </NavigationMenuPrimitive.Indicator>\n )\n})\nNavigationMenuIndicator.displayName =\n NavigationMenuPrimitive.Indicator.displayName\n\nexport type NavigationMenuProps = React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\nexport type NavigationMenuContentProps = React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n\nexport {\n NavigationMenu,\n NavigationMenuList,\n NavigationMenuItem,\n NavigationMenuContent,\n NavigationMenuTrigger,\n NavigationMenuLink,\n NavigationMenuIndicator,\n NavigationMenuViewport,\n}\n"],"mappings":"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"}
@@ -1,5 +1,11 @@
1
1
  "use client";
2
+ import { VariantProps } from 'class-variance-authority';
2
3
  import * as React from 'react';
4
+ export type NumberInputState = 'default' | 'error' | 'warning' | 'success';
5
+ declare const numberInputWrapperVariants: (props?: ({
6
+ size?: "xs" | "sm" | "md" | "lg" | null | undefined;
7
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
8
+ export type NumberInputSize = NonNullable<VariantProps<typeof numberInputWrapperVariants>['size']>;
3
9
  /**
4
10
  * Props for NumberInput — a stepper control with "−" and "+" buttons flanking a numeric input,
5
11
  * clamped between `min` and `max`. The decrement/increment buttons are disabled when bounds are reached.
@@ -10,6 +16,11 @@ import * as React from 'react';
10
16
  * **Step:** The `step` prop controls how much each button press increments/decrements (default 1).
11
17
  * Direct text input is also clamped to `[min, max]` on change.
12
18
  *
19
+ * **Sizes:** `xs` (28px) | `sm` (32px) | `md` (40px, default) | `lg` (48px)
20
+ *
21
+ * **Validation states:** `state="error"` colors the border red.
22
+ * Use with `<FormField>` to show helper text below the input.
23
+ *
13
24
  * @example
14
25
  * // Quantity selector with 1–99 range:
15
26
  * <NumberInput value={qty} onValueChange={setQty} min={1} max={99} />
@@ -33,7 +44,11 @@ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInp
33
44
  min?: number;
34
45
  max?: number;
35
46
  step?: number;
47
+ /** Size of the number input. Controls height, button sizes, text size. */
48
+ size?: NumberInputSize;
49
+ /** Validation state controlling border color. */
50
+ state?: NumberInputState;
36
51
  }
37
52
  declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
38
- export { NumberInput };
53
+ export { NumberInput, numberInputWrapperVariants };
39
54
  //# sourceMappingURL=number-input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/ui/number-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAM9B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACjI,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,QAAA,MAAM,WAAW,2FA8FhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/ui/number-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAMjE,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;AAE1E,QAAA,MAAM,0BAA0B;;8EAa/B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAkClG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACjI,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,IAAI,CAAC,EAAE,eAAe,CAAA;IACtB,iDAAiD;IACjD,KAAK,CAAC,EAAE,gBAAgB,CAAA;CACzB;AAED,QAAA,MAAM,WAAW,2FAwHhB,CAAA;AAGD,OAAO,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAA"}
@@ -1,73 +1,103 @@
1
1
  "use client";
2
- import { cn as e } from "./lib/utils.js";
3
- import { Icon as t } from "./icon.js";
4
- import { useFormField as n } from "./form.js";
5
- import * as r from "react";
6
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
- import { IconMinus as o, IconPlus as s } from "@tabler/icons-react";
2
+ import { t as e } from "../_chunks/vendor-utils.js";
3
+ import { cn as t } from "./lib/utils.js";
4
+ import { Icon as n } from "./icon.js";
5
+ import { useFormField as r } from "./form.js";
6
+ import * as i from "react";
7
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
8
+ import { IconMinus as s, IconPlus as c } from "@tabler/icons-react";
8
9
  //#region src/ui/number-input.tsx
9
- var c = r.forwardRef(({ value: r = 0, onValueChange: c, min: l = -(2 ** 53 - 1), max: u = 2 ** 53 - 1, step: d = 1, disabled: f = !1, className: p, "aria-label": m, ...h }, g) => {
10
- let _ = n(), v = m ?? (h.id || _.helperTextId ? void 0 : "Numeric value"), y = (e) => {
10
+ var l = e("flex items-center justify-between rounded-ds-md border border-surface-border-strong", {
11
+ variants: { size: {
12
+ xs: "h-ds-xs-plus",
13
+ sm: "h-ds-sm",
14
+ md: "h-ds-md",
15
+ lg: "h-ds-lg"
16
+ } },
17
+ defaultVariants: { size: "md" }
18
+ }), u = {
19
+ xs: "h-[22px] w-[22px]",
20
+ sm: "h-ds-sm w-ds-sm",
21
+ md: "h-ds-sm w-ds-sm",
22
+ lg: "h-ds-md w-ds-md"
23
+ }, d = {
24
+ xs: "xs",
25
+ sm: "sm",
26
+ md: "sm",
27
+ lg: "md"
28
+ }, f = {
29
+ xs: "text-ds-sm w-[28px]",
30
+ sm: "text-ds-sm w-ds-sm-plus",
31
+ md: "text-ds-md w-ds-sm-plus",
32
+ lg: "text-ds-md w-ds-md"
33
+ }, p = {
34
+ default: "",
35
+ error: "border-error-7",
36
+ warning: "border-warning-7",
37
+ success: "border-success-7"
38
+ }, m = i.forwardRef(({ value: e = 0, onValueChange: i, min: m = -(2 ** 53 - 1), max: h = 2 ** 53 - 1, step: g = 1, disabled: _ = !1, className: v, size: y = "md", state: b, "aria-label": x, ...S }, C) => {
39
+ let w = y ?? "md", T = r(), E = x ?? (S.id || T.helperTextId ? void 0 : "Numeric value"), D = b ?? (T.state === "helper" ? "default" : T.state) ?? "default", O = (e) => {
11
40
  let t = e.target.value.trim();
12
41
  if (t === "" || t === "-") {
13
- c?.(l >= 0 ? l : 0);
42
+ i?.(m >= 0 ? m : 0);
14
43
  return;
15
44
  }
16
45
  let n = Number(t);
17
- Number.isNaN(n) || c?.(Math.min(Math.max(n, l), u));
18
- }, b = (e) => {
19
- e.preventDefault();
20
- let t = r + d;
21
- t <= u && c?.(t);
22
- };
23
- return /* @__PURE__ */ a("div", {
24
- className: e("flex items-center justify-between rounded-ds-full border border-surface-border-strong", p),
46
+ Number.isNaN(n) || i?.(Math.min(Math.max(n, m), h));
47
+ }, k = (t) => {
48
+ t.preventDefault();
49
+ let n = e + g;
50
+ n <= h && i?.(n);
51
+ }, A = (t) => {
52
+ t.preventDefault();
53
+ let n = e - g;
54
+ n >= m && i?.(n);
55
+ }, j = u[w], M = d[w], N = f[w];
56
+ return /* @__PURE__ */ o("div", {
57
+ className: t(l({ size: w }), p[D], v),
25
58
  children: [
26
- /* @__PURE__ */ i("button", {
59
+ /* @__PURE__ */ a("button", {
27
60
  type: "button",
28
- onClick: (e) => {
29
- e.preventDefault();
30
- let t = r - d;
31
- t >= l && c?.(t);
32
- },
33
- disabled: f || r <= l,
61
+ onClick: A,
62
+ disabled: _ || e <= m,
34
63
  "aria-label": "Decrease value",
35
64
  title: "Decrease",
36
- className: "flex h-ds-sm w-ds-sm items-center justify-center border-0 text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,transform] duration-fast-01 ease-productive-standard",
37
- children: /* @__PURE__ */ i(t, {
38
- icon: o,
39
- size: "sm"
65
+ className: t("flex items-center justify-center border-0 rounded-ds-sm text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,background-color,transform] duration-fast-01 ease-productive-standard disabled:opacity-action-disabled disabled:pointer-events-none", j),
66
+ children: /* @__PURE__ */ a(n, {
67
+ icon: s,
68
+ size: M
40
69
  })
41
70
  }),
42
- /* @__PURE__ */ i("input", {
43
- ref: g,
71
+ /* @__PURE__ */ a("input", {
72
+ ref: C,
44
73
  type: "number",
45
- value: r,
46
- onChange: y,
47
- min: l,
48
- max: u,
49
- step: d,
50
- disabled: f,
51
- "aria-label": v,
52
- "aria-describedby": h["aria-describedby"] ?? _.helperTextId,
53
- className: "bg-transparent text-ds-md font-semibold w-ds-sm-plus border-0 text-center text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
54
- ...h
74
+ value: e,
75
+ onChange: O,
76
+ min: m,
77
+ max: h,
78
+ step: g,
79
+ disabled: _,
80
+ "aria-label": E,
81
+ "aria-invalid": D === "error" || void 0,
82
+ "aria-describedby": S["aria-describedby"] ?? T.helperTextId,
83
+ className: t("bg-transparent font-semibold border-0 text-center text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none", N),
84
+ ...S
55
85
  }),
56
- /* @__PURE__ */ i("button", {
86
+ /* @__PURE__ */ a("button", {
57
87
  type: "button",
58
- onClick: b,
59
- disabled: f || r >= u,
88
+ onClick: k,
89
+ disabled: _ || e >= h,
60
90
  "aria-label": "Increase value",
61
91
  title: "Increase",
62
- className: "flex h-ds-sm w-ds-sm items-center justify-center border-0 text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,transform] duration-fast-01 ease-productive-standard",
63
- children: /* @__PURE__ */ i(t, {
64
- icon: s,
65
- size: "sm"
92
+ className: t("flex items-center justify-center border-0 rounded-ds-sm text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,background-color,transform] duration-fast-01 ease-productive-standard disabled:opacity-action-disabled disabled:pointer-events-none", j),
93
+ children: /* @__PURE__ */ a(n, {
94
+ icon: c,
95
+ size: M
66
96
  })
67
97
  })
68
98
  ]
69
99
  });
70
100
  });
71
- c.displayName = "NumberInput";
101
+ m.displayName = "NumberInput";
72
102
  //#endregion
73
- export { c as NumberInput };
103
+ export { m as NumberInput, l as numberInputWrapperVariants };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-input.js","names":[],"sources":["../../src/ui/number-input.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { IconMinus, IconPlus } from '@tabler/icons-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from './lib/utils'\nimport { useFormField } from './form'\nimport { Icon } from './icon'\nimport type { IconSize } from './icon-context'\n\nexport type NumberInputState = 'default' | 'error' | 'warning' | 'success'\n\nconst numberInputWrapperVariants = cva(\n 'flex items-center justify-between rounded-ds-md border border-surface-border-strong',\n {\n variants: {\n size: {\n xs: 'h-ds-xs-plus',\n sm: 'h-ds-sm',\n md: 'h-ds-md',\n lg: 'h-ds-lg',\n },\n },\n defaultVariants: { size: 'md' },\n },\n)\n\nexport type NumberInputSize = NonNullable<VariantProps<typeof numberInputWrapperVariants>['size']>\n\n/** Maps size to stepper button dimensions */\nconst buttonSizeMap: Record<NonNullable<NumberInputSize>, string> = {\n xs: 'h-[22px] w-[22px]',\n sm: 'h-ds-sm w-ds-sm',\n md: 'h-ds-sm w-ds-sm',\n lg: 'h-ds-md w-ds-md',\n}\n\n/** Maps size to Icon component size */\nconst iconSizeMap: Record<NonNullable<NumberInputSize>, IconSize> = {\n xs: 'xs',\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n}\n\n/** Maps size to input text and width classes */\nconst inputSizeMap: Record<NonNullable<NumberInputSize>, string> = {\n xs: 'text-ds-sm w-[28px]',\n sm: 'text-ds-sm w-ds-sm-plus',\n md: 'text-ds-md w-ds-sm-plus',\n lg: 'text-ds-md w-ds-md',\n}\n\n/** Maps state to border color classes */\nconst stateColorMap: Record<NonNullable<NumberInputState>, string> = {\n default: '',\n error: 'border-error-7',\n warning: 'border-warning-7',\n success: 'border-success-7',\n}\n\n/**\n * Props for NumberInput — a stepper control with \"−\" and \"+\" buttons flanking a numeric input,\n * clamped between `min` and `max`. The decrement/increment buttons are disabled when bounds are reached.\n *\n * **Controlled only:** Pass `value` + `onValueChange` for controlled usage. Uncontrolled usage is\n * possible but the buttons won't update the displayed value without `onValueChange`.\n *\n * **Step:** The `step` prop controls how much each button press increments/decrements (default 1).\n * Direct text input is also clamped to `[min, max]` on change.\n *\n * **Sizes:** `xs` (28px) | `sm` (32px) | `md` (40px, default) | `lg` (48px)\n *\n * **Validation states:** `state=\"error\"` colors the border red.\n * Use with `<FormField>` to show helper text below the input.\n *\n * @example\n * // Quantity selector with 1–99 range:\n * <NumberInput value={qty} onValueChange={setQty} min={1} max={99} />\n *\n * @example\n * // Rating input (1–10, step 1):\n * <NumberInput value={rating} onValueChange={setRating} min={1} max={10} />\n *\n * @example\n * // Fine-grained opacity control (0–100, step 5):\n * <NumberInput value={opacity} onValueChange={setOpacity} min={0} max={100} step={5} />\n *\n * @example\n * // Disabled number display (read-only-like):\n * <NumberInput value={autoCalcValue} onValueChange={() => {}} disabled />\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'type' | 'size'> {\n value?: number\n onValueChange?: (value: number) => void\n min?: number\n max?: number\n step?: number\n /** Size of the number input. Controls height, button sizes, text size. */\n size?: NumberInputSize\n /** Validation state controlling border color. */\n state?: NumberInputState\n}\n\nconst NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(\n (\n {\n value = 0,\n onValueChange,\n min = Number.MIN_SAFE_INTEGER,\n max = Number.MAX_SAFE_INTEGER,\n step = 1,\n disabled = false,\n className,\n size: sizeProp = 'md',\n state: stateProp,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const size = sizeProp ?? 'md'\n const fieldCtx = useFormField()\n // If no explicit aria-label and not inside a FormField (no id to associate with Label),\n // provide a sensible default\n const ariaLabel = ariaLabelProp ?? (rest.id || fieldCtx.helperTextId ? undefined : 'Numeric value')\n\n // Merge FormField context — explicit props always win\n const state =\n stateProp ??\n (fieldCtx.state === 'helper'\n ? 'default'\n : (fieldCtx.state as NumberInputState | undefined)) ??\n 'default'\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value.trim()\n if (raw === '' || raw === '-') {\n onValueChange?.(min >= 0 ? min : 0)\n return\n }\n const parsed = Number(raw)\n if (Number.isNaN(parsed)) return\n const clamped = Math.min(Math.max(parsed, min), max)\n onValueChange?.(clamped)\n }\n\n const handleIncrement = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.preventDefault() // Prevent form submission\n const newValue = value + step\n if (newValue <= max) {\n onValueChange?.(newValue)\n }\n }\n\n const handleDecrement = (e: React.MouseEvent<HTMLButtonElement>) => {\n e.preventDefault() // Prevent form submission\n const newValue = value - step\n if (newValue >= min) {\n onValueChange?.(newValue)\n }\n }\n\n const resolvedButtonSize = buttonSizeMap[size]\n const resolvedIconSize = iconSizeMap[size]\n const resolvedInputSize = inputSizeMap[size]\n\n return (\n <div\n className={cn(\n numberInputWrapperVariants({ size }),\n stateColorMap[state],\n className,\n )}\n >\n <button\n type=\"button\"\n onClick={handleDecrement}\n disabled={disabled || value <= min}\n aria-label=\"Decrease value\"\n title=\"Decrease\"\n className={cn(\n 'flex items-center justify-center border-0 rounded-ds-sm text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,background-color,transform] duration-fast-01 ease-productive-standard disabled:opacity-action-disabled disabled:pointer-events-none',\n resolvedButtonSize,\n )}\n >\n <Icon icon={IconMinus} size={resolvedIconSize} />\n </button>\n\n <input\n ref={ref}\n type=\"number\"\n value={value}\n onChange={handleInputChange}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-invalid={state === 'error' || undefined}\n aria-describedby={rest['aria-describedby'] ?? fieldCtx.helperTextId}\n className={cn(\n 'bg-transparent font-semibold border-0 text-center text-surface-fg-muted focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n resolvedInputSize,\n )}\n {...rest}\n />\n\n <button\n type=\"button\"\n onClick={handleIncrement}\n disabled={disabled || value >= max}\n aria-label=\"Increase value\"\n title=\"Increase\"\n className={cn(\n 'flex items-center justify-center border-0 rounded-ds-sm text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg-muted active:scale-90 transition-[color,background-color,transform] duration-fast-01 ease-productive-standard disabled:opacity-action-disabled disabled:pointer-events-none',\n resolvedButtonSize,\n )}\n >\n <Icon icon={IconPlus} size={resolvedIconSize} />\n </button>\n </div>\n )\n },\n)\nNumberInput.displayName = 'NumberInput'\n\nexport { NumberInput, numberInputWrapperVariants }\n"],"mappings":";;;;;;;;;AAYA,IAAM,IAA6B,EACjC,uFACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,EACF;CACD,iBAAiB,EAAE,MAAM,MAAM;CAChC,CACF,EAKK,IAA8D;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAGK,IAA8D;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAGK,IAA6D;CACjE,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAGK,IAA+D;CACnE,SAAS;CACT,OAAO;CACP,SAAS;CACT,SAAS;CACV,EA8CK,IAAc,EAAM,YAEtB,EACE,WAAQ,GACR,kBACA,SAAM,gBACN,sBACA,UAAO,GACP,cAAW,IACX,cACA,MAAM,IAAW,MACjB,OAAO,GACP,cAAc,GACd,GAAG,KAEL,MACG;CACH,IAAM,IAAO,KAAY,MACnB,IAAW,GAAc,EAGzB,IAAY,MAAkB,EAAK,MAAM,EAAS,eAAe,KAAA,IAAY,kBAG7E,IACJ,MACC,EAAS,UAAU,WAChB,YACC,EAAS,UACd,WAEI,KAAqB,MAA2C;EACpE,IAAM,IAAM,EAAE,OAAO,MAAM,MAAM;AACjC,MAAI,MAAQ,MAAM,MAAQ,KAAK;AAC7B,OAAgB,KAAO,IAAI,IAAM,EAAE;AACnC;;EAEF,IAAM,IAAS,OAAO,EAAI;AACtB,SAAO,MAAM,EAAO,IAExB,IADgB,KAAK,IAAI,KAAK,IAAI,GAAQ,EAAI,EAAE,EAAI,CAC5B;IAGpB,KAAmB,MAA2C;AAClE,IAAE,gBAAgB;EAClB,IAAM,IAAW,IAAQ;AACzB,EAAI,KAAY,KACd,IAAgB,EAAS;IAIvB,KAAmB,MAA2C;AAClE,IAAE,gBAAgB;EAClB,IAAM,IAAW,IAAQ;AACzB,EAAI,KAAY,KACd,IAAgB,EAAS;IAIvB,IAAqB,EAAc,IACnC,IAAmB,EAAY,IAC/B,IAAoB,EAAa;AAEvC,QACE,kBAAC,OAAD;EACE,WAAW,EACT,EAA2B,EAAE,SAAM,CAAC,EACpC,EAAc,IACd,EACD;YALH;GAOE,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,UAAU,KAAY,KAAS;IAC/B,cAAW;IACX,OAAM;IACN,WAAW,EACT,kTACA,EACD;cAED,kBAAC,GAAD;KAAM,MAAM;KAAW,MAAM;KAAoB,CAAA;IAC1C,CAAA;GAET,kBAAC,SAAD;IACO;IACL,MAAK;IACE;IACP,UAAU;IACL;IACA;IACC;IACI;IACV,cAAY;IACZ,gBAAc,MAAU,WAAW,KAAA;IACnC,oBAAkB,EAAK,uBAAuB,EAAS;IACvD,WAAW,EACT,8QACA,EACD;IACD,GAAI;IACJ,CAAA;GAEF,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,UAAU,KAAY,KAAS;IAC/B,cAAW;IACX,OAAM;IACN,WAAW,EACT,kTACA,EACD;cAED,kBAAC,GAAD;KAAM,MAAM;KAAU,MAAM;KAAoB,CAAA;IACzC,CAAA;GACL;;EAGX;AACD,EAAY,cAAc"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Ln as e } from "../_chunks/primitives.js";
2
+ import { Hn as e } from "../_chunks/primitives.js";
3
3
  import { cn as t } from "./lib/utils.js";
4
4
  import { Icon as n } from "./icon.js";
5
5
  import * as r from "react";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","names":[],"sources":["../../src/ui/pagination.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Slot } from '@primitives/react-slot'\nimport { IconChevronLeft, IconChevronRight, IconDots } from '@tabler/icons-react'\nimport { cn } from './lib/utils'\nimport { Icon } from './icon'\n\nconst PaginationRoot = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<'nav'>\n>(({ className, ...props }, ref) => (\n <nav\n ref={ref}\n role=\"navigation\"\n aria-label=\"pagination\"\n className={cn('mx-auto flex w-full justify-center', className)}\n {...props}\n />\n))\nPaginationRoot.displayName = 'PaginationRoot'\n\nconst PaginationContent = React.forwardRef<\n HTMLUListElement,\n React.ComponentPropsWithoutRef<'ul'>\n>(({ className, ...props }, ref) => (\n <ul\n ref={ref}\n className={cn('flex flex-row items-center gap-ds-02', className)}\n {...props}\n />\n))\nPaginationContent.displayName = 'PaginationContent'\n\nconst PaginationItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<'li'>\n>(({ className, ...props }, ref) => (\n <li ref={ref} className={cn('', className)} {...props} />\n))\nPaginationItem.displayName = 'PaginationItem'\n\n/**\n * Props for PaginationLink — a single page number button in a pagination row.\n * When `isActive` is true, the button gets the brand interactive fill and `aria-current=\"page\"`.\n *\n * @example\n * // Active page button:\n * <PaginationLink isActive onClick={() => goToPage(3)}>3</PaginationLink>\n *\n * @example\n * // Render as a Next.js Link via asChild:\n * <PaginationLink asChild isActive={currentPage === 5}>\n * <Link href=\"/posts?page=5\">5</Link>\n * </PaginationLink>\n */\nexport interface PaginationLinkProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n isActive?: boolean\n asChild?: boolean\n}\n\nconst PaginationLink = React.forwardRef<HTMLButtonElement, PaginationLinkProps>(\n ({ className, isActive = false, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button'\n return (\n <Comp\n ref={ref}\n aria-current={isActive ? 'page' : undefined}\n className={cn(\n 'inline-flex items-center justify-center h-ds-sm-plus w-ds-sm-plus rounded-ds-md text-ds-md font-medium tabular-nums transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled active:scale-95',\n isActive\n ? 'bg-accent-9 text-accent-fg'\n : 'hover:bg-surface-raised-hover text-surface-fg',\n className,\n )}\n {...props}\n />\n )\n },\n)\nPaginationLink.displayName = 'PaginationLink'\n\nconst PaginationPrevious = React.forwardRef<\n HTMLButtonElement,\n PaginationLinkProps\n>(({ className, ...props }, ref) => (\n <PaginationLink\n ref={ref}\n aria-label=\"Go to previous page\"\n className={cn('w-auto gap-ds-02 pl-ds-03 pr-ds-04', className)}\n {...props}\n >\n <Icon icon={IconChevronLeft} size=\"sm\" />\n <span>Previous</span>\n </PaginationLink>\n))\nPaginationPrevious.displayName = 'PaginationPrevious'\n\nconst PaginationNext = React.forwardRef<\n HTMLButtonElement,\n PaginationLinkProps\n>(({ className, ...props }, ref) => (\n <PaginationLink\n ref={ref}\n aria-label=\"Go to next page\"\n className={cn('w-auto gap-ds-02 pl-ds-04 pr-ds-03', className)}\n {...props}\n >\n <span>Next</span>\n <Icon icon={IconChevronRight} size=\"sm\" />\n </PaginationLink>\n))\nPaginationNext.displayName = 'PaginationNext'\n\nconst PaginationEllipsis = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<'span'>\n>(({ className, ...props }, ref) => (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n 'flex h-ds-sm-plus w-ds-sm-plus items-center justify-center text-surface-fg-muted',\n className,\n )}\n {...props}\n >\n <Icon icon={IconDots} size=\"sm\" />\n <span className=\"sr-only\">More pages</span>\n </span>\n))\nPaginationEllipsis.displayName = 'PaginationEllipsis'\n\n/* ------------------------------------------------------------------ */\n/* generatePagination helper */\n/* ------------------------------------------------------------------ */\n\ntype PageItem = number | 'ellipsis'\n\n/**\n * Pure function that builds an array of page numbers and ellipsis markers.\n * Always shows first and last page, plus `siblingCount` pages around `current`.\n *\n * @example generatePagination(5, 10, 1) → [1, 'ellipsis', 4, 5, 6, 'ellipsis', 10]\n */\nfunction generatePagination(\n current: number,\n total: number,\n siblingCount: number,\n): PageItem[] {\n // When total pages fit without any ellipsis\n const totalSlots = siblingCount * 2 + 5 // first + last + current + 2*siblings + 2 ellipsis slots\n if (total <= totalSlots) {\n return Array.from({ length: total }, (_, i) => i + 1)\n }\n\n const leftSibling = Math.max(current - siblingCount, 1)\n const rightSibling = Math.min(current + siblingCount, total)\n\n const showLeftEllipsis = leftSibling > 2\n const showRightEllipsis = rightSibling < total - 1\n\n if (!showLeftEllipsis && showRightEllipsis) {\n // e.g. [1, 2, 3, 4, 5, '...', 10]\n const leftCount = siblingCount * 2 + 3\n const leftPages = Array.from({ length: leftCount }, (_, i) => i + 1)\n return [...leftPages, 'ellipsis', total]\n }\n\n if (showLeftEllipsis && !showRightEllipsis) {\n // e.g. [1, '...', 6, 7, 8, 9, 10]\n const rightCount = siblingCount * 2 + 3\n const rightPages = Array.from(\n { length: rightCount },\n (_, i) => total - rightCount + 1 + i,\n )\n return [1, 'ellipsis', ...rightPages]\n }\n\n // Both ellipses: [1, '...', 4, 5, 6, '...', 10]\n const middlePages = Array.from(\n { length: rightSibling - leftSibling + 1 },\n (_, i) => leftSibling + i,\n )\n return [1, 'ellipsis', ...middlePages, 'ellipsis', total]\n}\n\n/* ------------------------------------------------------------------ */\n/* PaginationNav — controlled convenience wrapper */\n/* ------------------------------------------------------------------ */\n\n/**\n * Props for PaginationNav — a fully self-contained controlled pagination component that renders\n * Previous / page numbers (with ellipsis) / Next — using `generatePagination` internally.\n *\n * **1-indexed:** `currentPage` starts at 1 (not 0). `onPageChange` also receives 1-indexed values.\n *\n * **`siblingCount`:** Number of page buttons shown on each side of the current page (default 1).\n * A wider `siblingCount` shows more page buttons before switching to ellipsis.\n *\n * @example\n * // Basic controlled pagination:\n * <PaginationNav\n * totalPages={24}\n * currentPage={currentPage}\n * onPageChange={setCurrentPage}\n * />\n *\n * @example\n * // Wider sibling range for a results grid (shows more page context):\n * <PaginationNav\n * totalPages={100}\n * currentPage={currentPage}\n * onPageChange={setCurrentPage}\n * siblingCount={2}\n * />\n * // These are just a few ways — feel free to combine props creatively!\n */\nexport interface PaginationNavProps\n extends React.HTMLAttributes<HTMLElement> {\n /** Total number of pages */\n totalPages: number\n /** Current active page (1-indexed) */\n currentPage: number\n /** Called when the user requests a different page */\n onPageChange: (page: number) => void\n /** Number of sibling page buttons shown on each side of the current page (default: 1) */\n siblingCount?: number\n}\n\nconst PaginationNav = React.forwardRef<HTMLElement, PaginationNavProps>(\n (\n {\n totalPages,\n currentPage,\n onPageChange,\n siblingCount = 1,\n className,\n ...props\n },\n ref,\n ) => {\n const pages = generatePagination(currentPage, totalPages, siblingCount)\n\n return (\n <PaginationRoot ref={ref} className={className} {...props}>\n <PaginationContent>\n <PaginationItem>\n <PaginationPrevious\n onClick={() => onPageChange(Math.max(1, currentPage - 1))}\n disabled={currentPage <= 1}\n />\n </PaginationItem>\n\n {pages.map((page, i) =>\n page === 'ellipsis' ? (\n <PaginationItem key={`e${i}`}>\n <PaginationEllipsis />\n </PaginationItem>\n ) : (\n <PaginationItem key={page}>\n <PaginationLink\n isActive={page === currentPage}\n onClick={() => onPageChange(page)}\n >\n {page}\n </PaginationLink>\n </PaginationItem>\n ),\n )}\n\n <PaginationItem>\n <PaginationNext\n onClick={() =>\n onPageChange(Math.min(totalPages, currentPage + 1))\n }\n disabled={currentPage >= totalPages}\n />\n </PaginationItem>\n </PaginationContent>\n </PaginationRoot>\n )\n },\n)\nPaginationNav.displayName = 'PaginationNav'\n\nexport {\n PaginationRoot,\n PaginationContent,\n PaginationItem,\n PaginationLink,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n PaginationNav,\n generatePagination,\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"progress-ring.d.ts","sourceRoot":"","sources":["../../src/ui/progress-ring.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B;;;;;;GAMG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAC1F,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,yBAAyB;IACzB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAC5D,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,YAAY,yFA2EjB,CAAA;AAGD;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAC/F,KAAK,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;QAC5D,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;IACF,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAED,QAAA,MAAM,iBAAiB,8FAuDtB,CAAA;AAGD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"progress-ring.d.ts","sourceRoot":"","sources":["../../src/ui/progress-ring.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAmB9B;;;;;;GAMG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAC1F,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,yBAAyB;IACzB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;IAC5D,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,QAAA,MAAM,YAAY,yFA4EjB,CAAA;AAGD;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAC/F,KAAK,EAAE,KAAK,CAAC;QACX,KAAK,EAAE,MAAM,CAAA;QACb,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;QAC5D,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;IACF,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAED,QAAA,MAAM,iBAAiB,8FAuDtB,CAAA;AAGD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-ring.js","names":[],"sources":["../../src/ui/progress-ring.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, useMotionValue, useTransform, animate, useReducedMotion } from 'framer-motion'\nimport { springs } from './lib/motion'\nimport { cn } from './lib/utils'\n\nconst colorMap: Record<string, string> = {\n default: 'var(--color-accent-9)',\n success: 'var(--color-success-9)',\n warning: 'var(--color-warning-9)',\n error: 'var(--color-error-9)',\n info: 'var(--color-info-9)',\n}\n\nconst sizeConfig = {\n sm: { size: 32, strokeWidth: 3, fontSize: 'text-ds-xs' },\n md: { size: 48, strokeWidth: 3.5, fontSize: 'text-ds-sm' },\n lg: { size: 64, strokeWidth: 4, fontSize: 'text-ds-md' },\n} as const\n\n/**\n * A circular progress indicator with optional label and animated fill.\n *\n * @example\n * <ProgressRing value={75} />\n * <ProgressRing value={3} max={12} size=\"lg\" color=\"warning\" showValue />\n */\nexport interface ProgressRingProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'color'> {\n /** Current progress value */\n value: number\n /** Maximum value @default 100 */\n max?: number\n /** @default 'md' */\n size?: 'sm' | 'md' | 'lg'\n /** @default 'default' */\n color?: 'default' | 'success' | 'warning' | 'error' | 'info'\n /** Show percentage text in center */\n showValue?: boolean\n /** Accessible label */\n label?: string\n}\n\nconst ProgressRing = React.forwardRef<SVGSVGElement, ProgressRingProps>(\n ({ value, max = 100, size = 'md', color = 'default', showValue = false, label, className, ...props }, ref) => {\n const prefersReducedMotion = useReducedMotion()\n const config = sizeConfig[size]\n const radius = (config.size - config.strokeWidth) / 2\n const circumference = 2 * Math.PI * radius\n const progress = Math.min(Math.max(value / max, 0), 1)\n const offset = circumference * (1 - progress)\n const center = config.size / 2\n const percentage = Math.round(progress * 100)\n\n // Animated counter — drives from 0 → target percentage in sync with the ring fill\n const motionVal = useMotionValue(0)\n const displayValue = useTransform(motionVal, (v) => `${Math.round(v)}%`)\n\n React.useEffect(() => {\n const controls = animate(motionVal, progress * 100, prefersReducedMotion\n ? { type: 'tween', duration: 0 }\n /* Intentionally slower than springs.gentle (200/25/0.8) for smooth ring fill */\n : { stiffness: 100, damping: 30, type: 'spring' },\n )\n return () => controls.stop()\n }, [progress, motionVal, prefersReducedMotion])\n\n return (\n <svg\n ref={ref}\n width={config.size}\n height={config.size}\n viewBox={`0 0 ${config.size} ${config.size}`}\n role=\"progressbar\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={label ?? `${percentage}% progress`}\n className={cn('shrink-0', className)}\n {...props}\n >\n {/* Track */}\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n stroke=\"var(--color-surface-raised-hover)\"\n strokeWidth={config.strokeWidth}\n />\n {/* Value */}\n <motion.circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n stroke={colorMap[color]}\n strokeWidth={config.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n initial={{ strokeDashoffset: circumference }}\n animate={{ strokeDashoffset: offset }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.smooth}\n transform={`rotate(-90 ${center} ${center})`}\n />\n {showValue && (\n <motion.text\n x={center}\n y={center}\n textAnchor=\"middle\"\n dominantBaseline=\"central\"\n className={cn(config.fontSize, 'fill-surface-fg font-sans font-semibold')}\n >\n {displayValue}\n </motion.text>\n )}\n </svg>\n )\n },\n)\nProgressRing.displayName = 'ProgressRing'\n\n/**\n * Multi-ring progress display (Activity Ring style).\n *\n * @example\n * <MultiProgressRing rings={[\n * { value: 80, color: 'error', label: 'Move' },\n * { value: 60, color: 'success', label: 'Exercise' },\n * ]} size=\"lg\" />\n */\nexport interface MultiProgressRingProps extends Omit<React.SVGAttributes<SVGSVGElement>, 'color'> {\n rings: Array<{\n value: number\n max?: number\n color?: 'default' | 'success' | 'warning' | 'error' | 'info'\n label?: string\n }>\n /** @default 'md' */\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst MultiProgressRing = React.forwardRef<SVGSVGElement, MultiProgressRingProps>(\n ({ rings, size = 'md', className, ...props }, ref) => {\n const prefersReducedMotion = useReducedMotion()\n const config = sizeConfig[size]\n const center = config.size / 2\n const gap = config.strokeWidth + 2\n\n return (\n <svg\n ref={ref}\n width={config.size}\n height={config.size}\n viewBox={`0 0 ${config.size} ${config.size}`}\n role=\"group\"\n aria-label=\"Progress rings\"\n className={cn('shrink-0', className)}\n {...props}\n >\n {rings.map((ring, i) => {\n const radius = (config.size - config.strokeWidth) / 2 - i * gap\n if (radius <= 0) return null\n const circumference = 2 * Math.PI * radius\n const progress = Math.min(Math.max((ring.value) / (ring.max ?? 100), 0), 1)\n const offset = circumference * (1 - progress)\n\n return (\n <React.Fragment key={i}>\n <circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n stroke=\"var(--color-surface-raised-hover)\"\n strokeWidth={config.strokeWidth}\n />\n <motion.circle\n cx={center}\n cy={center}\n r={radius}\n fill=\"none\"\n stroke={colorMap[ring.color ?? 'default']}\n strokeWidth={config.strokeWidth}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n initial={{ strokeDashoffset: circumference }}\n animate={{ strokeDashoffset: offset }}\n transition={prefersReducedMotion ? { duration: 0 } : springs.smooth}\n transform={`rotate(-90 ${center} ${center})`}\n />\n </React.Fragment>\n )\n })}\n </svg>\n )\n },\n)\nMultiProgressRing.displayName = 'MultiProgressRing'\n\nexport { ProgressRing, MultiProgressRing }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","names":[],"sources":["../../src/ui/progress.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as ProgressPrimitive from '@primitives/react-progress'\nimport { motion } from 'framer-motion'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from './lib/utils'\nimport { springs } from './lib/motion'\n\n/* ---------------------------------------------------------------------------\n * CVA Variants\n * ------------------------------------------------------------------------ */\n\nconst progressTrackVariants = cva(\n 'relative w-full overflow-hidden rounded-ds-full bg-surface-raised',\n {\n variants: {\n size: {\n sm: 'h-1',\n md: 'h-2',\n lg: 'h-3',\n },\n },\n defaultVariants: { size: 'md' },\n },\n)\n\nconst progressIndicatorVariants = cva(\n 'h-full w-full flex-1 transition-[width] duration-moderate-02 ease-expressive-standard',\n {\n variants: {\n color: {\n default: 'bg-accent-9',\n success: 'bg-success-9',\n warning: 'bg-warning-9',\n error: 'bg-error-9',\n },\n },\n defaultVariants: { color: 'default' },\n },\n)\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------ */\n\n/**\n * Props for Progress — a horizontal progress bar with size and color variants, an optional\n * percentage label, and an indeterminate animation when `value` is undefined/null.\n *\n * **Track size:** `sm` (4px) | `md` (8px, default) | `lg` (12px)\n *\n * **Indicator color:** `default` (brand interactive) | `success` | `warning` | `error`\n *\n * **Indeterminate:** Omit `value` (or pass `undefined`) to show an animated indeterminate bar.\n * When `value` is provided, it should be a number between 0–100.\n *\n * **`showLabel`:** Renders the percentage value next to the bar (only when `value` is set).\n *\n * @example\n * // Determinate upload progress:\n * <Progress value={uploadPercent} color=\"default\" showLabel />\n *\n * @example\n * // Indeterminate loading bar (while waiting for an async operation):\n * <Progress size=\"sm\" />\n *\n * @example\n * // Success-colored completion bar (e.g. after all tasks done):\n * <Progress value={100} color=\"success\" size=\"md\" />\n *\n * @example\n * // Warning threshold indicator (disk usage at 80%):\n * <Progress value={80} color=\"warning\" showLabel size=\"lg\" />\n * // These are just a few ways — feel free to combine props creatively!\n */\ninterface ProgressProps\n extends Omit<\n React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>,\n 'color'\n >,\n VariantProps<typeof progressTrackVariants>,\n VariantProps<typeof progressIndicatorVariants> {\n /** Additional class names for the indicator element */\n indicatorClassName?: string\n /** Display the percentage label next to the progress bar */\n showLabel?: boolean\n /** When true, color auto-shifts by value: 0-59 = default (accent), 60-84 = warning, 85-100 = success, >100 = error. @default false */\n autoColor?: boolean\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------ */\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n ProgressProps\n>(\n (\n {\n className,\n value,\n size,\n color,\n indicatorClassName,\n showLabel,\n autoColor,\n ...props\n },\n ref,\n ) => {\n const isIndeterminate = value === undefined || value === null\n\n const effectiveColor =\n autoColor && value != null\n ? value > 100\n ? 'error'\n : value >= 85\n ? 'success'\n : value >= 60\n ? 'warning'\n : 'default'\n : color\n\n return (\n <div className={cn('flex items-center gap-ds-03', showLabel && 'w-full')}>\n <ProgressPrimitive.Root\n ref={ref}\n value={isIndeterminate ? null : value}\n className={cn(progressTrackVariants({ size }), className)}\n {...props}\n >\n {isIndeterminate ? (\n <ProgressPrimitive.Indicator\n className={cn(\n progressIndicatorVariants({ color: effectiveColor }),\n 'w-2/5 animate-progress-indeterminate motion-reduce:animate-none',\n indicatorClassName,\n )}\n />\n ) : (\n <ProgressPrimitive.Indicator\n className={cn('h-full', indicatorClassName)}\n asChild\n >\n <motion.div\n className={cn(\n progressIndicatorVariants({ color: effectiveColor }),\n 'transition-colors duration-moderate-01 ease-productive-standard',\n )}\n initial={false}\n animate={{ width: `${value || 0}%` }}\n transition={springs.smooth}\n />\n </ProgressPrimitive.Indicator>\n )}\n </ProgressPrimitive.Root>\n\n {showLabel && !isIndeterminate && (\n <span className=\"shrink-0 text-ds-xs text-surface-fg-muted tabular-nums\">\n {value}%\n </span>\n )}\n </div>\n )\n },\n)\nProgress.displayName = ProgressPrimitive.Root.displayName\n\nexport { Progress, progressTrackVariants, progressIndicatorVariants }\nexport type { ProgressProps }\n"],"mappings":";;;;;;;;;AAcA,IAAM,IAAwB,EAC5B,qEACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,EACF;CACD,iBAAiB,EAAE,MAAM,MAAM;CAChC,CACF,EAEK,IAA4B,EAChC,yFACA;CACE,UAAU,EACR,OAAO;EACL,SAAS;EACT,SAAS;EACT,SAAS;EACT,OAAO;EACR,EACF;CACD,iBAAiB,EAAE,OAAO,WAAW;CACtC,CACF,EAuDK,IAAW,EAAM,YAKnB,EACE,cACA,UACA,SACA,UACA,uBACA,cACA,cACA,GAAG,KAEL,MACG;CACH,IAAM,IAAkB,KAAiC,MAEnD,IACJ,KAAa,KAAS,OAClB,IAAQ,MACN,UACA,KAAS,KACP,YACA,KAAS,KACP,YACA,YACN;AAEN,QACE,kBAAC,OAAD;EAAK,WAAW,EAAG,+BAA+B,KAAa,SAAS;YAAxE,CACE,kBAAC,GAAD;GACO;GACL,OAAO,IAAkB,OAAO;GAChC,WAAW,EAAG,EAAsB,EAAE,SAAM,CAAC,EAAE,EAAU;GACzD,GAAI;aAEH,IACC,kBAAC,GAAD,EACE,WAAW,EACT,EAA0B,EAAE,OAAO,GAAgB,CAAC,EACpD,mEACA,EACD,EACD,CAAA,GAEF,kBAAC,GAAD;IACE,WAAW,EAAG,UAAU,EAAmB;IAC3C,SAAA;cAEA,kBAAC,EAAO,KAAR;KACE,WAAW,EACT,EAA0B,EAAE,OAAO,GAAgB,CAAC,EACpD,kEACD;KACD,SAAS;KACT,SAAS,EAAE,OAAO,GAAG,KAAS,EAAE,IAAI;KACpC,YAAY,EAAQ;KACpB,CAAA;IAC0B,CAAA;GAET,CAAA,EAExB,KAAa,CAAC,KACb,kBAAC,QAAD;GAAM,WAAU;aAAhB,CACG,GAAM,IACF;KAEL;;EAGX;AACD,EAAS,cAAA,EAAqC"}
@@ -1 +1 @@
1
- {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../src/ui/radio.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,mBAAmB,MAAM,+BAA+B,CAAA;AAGpE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,QAAA,MAAM,UAAU,+JAKd,CAAA;AAGF,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC;IAC1G,qFAAqF;IACrF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAcD,QAAA,MAAM,cAAc,+FAgClB,CAAA;AAGF,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAA;AAE7F,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,CAAA"}
1
+ {"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../src/ui/radio.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,mBAAmB,MAAM,+BAA+B,CAAA;AAGpE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,QAAA,MAAM,UAAU,+JAmBd,CAAA;AAGF,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC;IAC1G,qFAAqF;IACrF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B;AAcD,QAAA,MAAM,cAAc,+FAgClB,CAAA;AAGF,MAAM,MAAM,eAAe,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAA;AAE7F,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,CAAA"}