@devalok/shilp-sutra 0.34.1 → 0.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) 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 +651 -650
  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 +1 -1
  78. package/dist/composed/rich-text-editor.js.map +1 -0
  79. package/dist/composed/schedule-view.js.map +1 -0
  80. package/dist/composed/simple-tooltip.js.map +1 -0
  81. package/dist/composed/status-badge.d.ts.map +1 -1
  82. package/dist/composed/status-badge.js.map +1 -0
  83. package/dist/hooks/use-color-mode.js.map +1 -0
  84. package/dist/hooks/use-mobile.js.map +1 -0
  85. package/dist/hooks/use-touch-device.js.map +1 -0
  86. package/dist/hooks/use-viewport-height.js.map +1 -0
  87. package/dist/motion/check-motion-provider.d.ts +3 -0
  88. package/dist/motion/check-motion-provider.d.ts.map +1 -0
  89. package/dist/motion/index.js +14 -0
  90. package/dist/motion/index.js.map +1 -0
  91. package/dist/motion/primitives-index.js.map +1 -0
  92. package/dist/primitives/react-accordion.d.ts +114 -114
  93. package/dist/primitives/react-alert-dialog.d.ts +51 -51
  94. package/dist/primitives/react-aspect-ratio.d.ts +11 -11
  95. package/dist/primitives/react-avatar.d.ts +24 -24
  96. package/dist/primitives/react-checkbox.d.ts +50 -50
  97. package/dist/primitives/react-collapsible.d.ts +33 -33
  98. package/dist/primitives/react-context-menu.d.ts +96 -96
  99. package/dist/primitives/react-dialog.d.ts +103 -103
  100. package/dist/primitives/react-dropdown-menu.d.ts +97 -97
  101. package/dist/primitives/react-hover-card.d.ts +79 -79
  102. package/dist/primitives/react-label.d.ts +10 -10
  103. package/dist/primitives/react-menu.d.ts +169 -169
  104. package/dist/primitives/react-menubar.d.ts +115 -115
  105. package/dist/primitives/react-navigation-menu.d.ts +126 -126
  106. package/dist/primitives/react-popover.d.ts +85 -85
  107. package/dist/primitives/react-progress.d.ts +19 -19
  108. package/dist/primitives/react-radio-group.d.ts +58 -58
  109. package/dist/primitives/react-roving-focus.d.ts +49 -49
  110. package/dist/primitives/react-select.d.ts +137 -137
  111. package/dist/primitives/react-separator.d.ts +21 -21
  112. package/dist/primitives/react-slider.d.ts +75 -75
  113. package/dist/primitives/react-switch.d.ts +21 -21
  114. package/dist/primitives/react-tabs.d.ts +56 -56
  115. package/dist/primitives/react-toast.d.ts +120 -120
  116. package/dist/primitives/react-toggle-group.d.ts +75 -75
  117. package/dist/primitives/react-toggle.d.ts +24 -24
  118. package/dist/primitives/react-tooltip.d.ts +101 -101
  119. package/dist/primitives/react-visually-hidden.d.ts +22 -22
  120. package/dist/shell/app-command-palette.d.ts +2 -0
  121. package/dist/shell/app-command-palette.d.ts.map +1 -1
  122. package/dist/shell/app-command-palette.js +42 -155
  123. package/dist/shell/app-command-palette.js.map +1 -0
  124. package/dist/shell/bottom-navbar.js +1 -1
  125. package/dist/shell/bottom-navbar.js.map +1 -0
  126. package/dist/shell/command-registry.js.map +1 -0
  127. package/dist/shell/notification-center.d.ts.map +1 -1
  128. package/dist/shell/notification-center.js +194 -169
  129. package/dist/shell/notification-center.js.map +1 -0
  130. package/dist/shell/notification-preferences.js.map +1 -0
  131. package/dist/shell/sidebar.js.map +1 -0
  132. package/dist/shell/top-bar.js +1 -1
  133. package/dist/shell/top-bar.js.map +1 -0
  134. package/dist/tailwind/index.cjs +48 -1
  135. package/dist/tailwind/preset.d.ts.map +1 -1
  136. package/dist/tailwind/preset.js +48 -1
  137. package/dist/tailwind/preset.js.map +1 -0
  138. package/dist/tokens/index.css +4 -4
  139. package/dist/tokens/primitives.css +442 -442
  140. package/dist/tokens/semantic.css +742 -547
  141. package/dist/tokens/typography-semantic.css +123 -100
  142. package/dist/tokens/typography.css +422 -422
  143. package/dist/ui/accordion.js +13 -13
  144. package/dist/ui/accordion.js.map +1 -0
  145. package/dist/ui/alert-dialog.d.ts +6 -2
  146. package/dist/ui/alert-dialog.d.ts.map +1 -1
  147. package/dist/ui/alert-dialog.js +43 -42
  148. package/dist/ui/alert-dialog.js.map +1 -0
  149. package/dist/ui/alert.d.ts +3 -2
  150. package/dist/ui/alert.d.ts.map +1 -1
  151. package/dist/ui/alert.js +31 -5
  152. package/dist/ui/alert.js.map +1 -0
  153. package/dist/ui/aspect-ratio.js +1 -1
  154. package/dist/ui/aspect-ratio.js.map +1 -0
  155. package/dist/ui/autocomplete.d.ts.map +1 -1
  156. package/dist/ui/autocomplete.js +92 -67
  157. package/dist/ui/autocomplete.js.map +1 -0
  158. package/dist/ui/avatar.js +9 -9
  159. package/dist/ui/avatar.js.map +1 -0
  160. package/dist/ui/badge-indicator.js.map +1 -0
  161. package/dist/ui/banner.js.map +1 -0
  162. package/dist/ui/breadcrumb.js +1 -1
  163. package/dist/ui/breadcrumb.js.map +1 -0
  164. package/dist/ui/button-group.js.map +1 -0
  165. package/dist/ui/button-processing.d.ts.map +1 -1
  166. package/dist/ui/button-processing.js +61 -40
  167. package/dist/ui/button-processing.js.map +1 -0
  168. package/dist/ui/button.js +8 -8
  169. package/dist/ui/button.js.map +1 -0
  170. package/dist/ui/card.js.map +1 -0
  171. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  172. package/dist/ui/charts/chart-container.d.ts +2 -0
  173. package/dist/ui/charts/chart-container.d.ts.map +1 -1
  174. package/dist/ui/charts/index.js +88 -65
  175. package/dist/ui/charts/index.js.map +1 -0
  176. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  177. package/dist/ui/chat/message-input.d.ts.map +1 -1
  178. package/dist/ui/chat/message-list.d.ts +1 -1
  179. package/dist/ui/chat/message-list.d.ts.map +1 -1
  180. package/dist/ui/chat/message.d.ts.map +1 -1
  181. package/dist/ui/chat/system-message.d.ts.map +1 -1
  182. package/dist/ui/checkbox.d.ts.map +1 -1
  183. package/dist/ui/checkbox.js +33 -28
  184. package/dist/ui/checkbox.js.map +1 -0
  185. package/dist/ui/code.js.map +1 -0
  186. package/dist/ui/collapsible.js +1 -1
  187. package/dist/ui/collapsible.js.map +1 -0
  188. package/dist/ui/color-input.d.ts.map +1 -1
  189. package/dist/ui/color-input.js +165 -163
  190. package/dist/ui/color-input.js.map +1 -0
  191. package/dist/ui/color-swatch.js.map +1 -0
  192. package/dist/ui/combobox.d.ts +7 -0
  193. package/dist/ui/combobox.d.ts.map +1 -1
  194. package/dist/ui/combobox.js +147 -113
  195. package/dist/ui/combobox.js.map +1 -0
  196. package/dist/ui/container.js +1 -1
  197. package/dist/ui/container.js.map +1 -0
  198. package/dist/ui/context-menu.js.map +1 -0
  199. package/dist/ui/data-table-body.js.map +1 -0
  200. package/dist/ui/data-table-bulk-actions.js +1 -1
  201. package/dist/ui/data-table-bulk-actions.js.map +1 -0
  202. package/dist/ui/data-table-card.js.map +1 -0
  203. package/dist/ui/data-table-context.js.map +1 -0
  204. package/dist/ui/data-table-header.js.map +1 -0
  205. package/dist/ui/data-table-pagination.js.map +1 -0
  206. package/dist/ui/data-table-toolbar.js.map +1 -0
  207. package/dist/ui/data-table.js +34 -31
  208. package/dist/ui/data-table.js.map +1 -0
  209. package/dist/ui/devalok-grain.js.map +1 -0
  210. package/dist/ui/dialog.js +31 -35
  211. package/dist/ui/dialog.js.map +1 -0
  212. package/dist/ui/dropdown-menu.js.map +1 -0
  213. package/dist/ui/file-upload.js +120 -120
  214. package/dist/ui/file-upload.js.map +1 -0
  215. package/dist/ui/form.d.ts +8 -0
  216. package/dist/ui/form.d.ts.map +1 -1
  217. package/dist/ui/form.js +14 -12
  218. package/dist/ui/form.js.map +1 -0
  219. package/dist/ui/hover-card.js.map +1 -0
  220. package/dist/ui/icon-button.js.map +1 -0
  221. package/dist/ui/icon-context.js.map +1 -0
  222. package/dist/ui/icon-group.js.map +1 -0
  223. package/dist/ui/icon.js.map +1 -0
  224. package/dist/ui/index.d.ts +4 -4
  225. package/dist/ui/index.d.ts.map +1 -1
  226. package/dist/ui/index.js +82 -66
  227. package/dist/ui/index.js.map +1 -0
  228. package/dist/ui/input-otp.d.ts +12 -3
  229. package/dist/ui/input-otp.d.ts.map +1 -1
  230. package/dist/ui/input-otp.js +41 -27
  231. package/dist/ui/input-otp.js.map +1 -0
  232. package/dist/ui/input.d.ts.map +1 -1
  233. package/dist/ui/input.js +16 -15
  234. package/dist/ui/input.js.map +1 -0
  235. package/dist/ui/label.d.ts.map +1 -1
  236. package/dist/ui/label.js +19 -14
  237. package/dist/ui/label.js.map +1 -0
  238. package/dist/ui/lib/check-tokens.d.ts +3 -0
  239. package/dist/ui/lib/check-tokens.d.ts.map +1 -0
  240. package/dist/ui/lib/date-utils.js.map +1 -0
  241. package/dist/ui/lib/motion.d.ts +15 -4
  242. package/dist/ui/lib/motion.d.ts.map +1 -1
  243. package/dist/ui/lib/motion.js +18 -9
  244. package/dist/ui/lib/motion.js.map +1 -0
  245. package/dist/ui/lib/utils.js.map +1 -0
  246. package/dist/ui/link.js +2 -2
  247. package/dist/ui/link.js.map +1 -0
  248. package/dist/ui/menubar.js.map +1 -0
  249. package/dist/ui/navigation-menu.js.map +1 -0
  250. package/dist/ui/number-input.d.ts +16 -1
  251. package/dist/ui/number-input.d.ts.map +1 -1
  252. package/dist/ui/number-input.js +79 -49
  253. package/dist/ui/number-input.js.map +1 -0
  254. package/dist/ui/pagination.js +1 -1
  255. package/dist/ui/pagination.js.map +1 -0
  256. package/dist/ui/progress-ring.d.ts.map +1 -1
  257. package/dist/ui/progress-ring.js.map +1 -0
  258. package/dist/ui/progress.js.map +1 -0
  259. package/dist/ui/radio.d.ts.map +1 -1
  260. package/dist/ui/radio.js +27 -20
  261. package/dist/ui/radio.js.map +1 -0
  262. package/dist/ui/search-input.js.map +1 -0
  263. package/dist/ui/segmented-control.d.ts +1 -1
  264. package/dist/ui/segmented-control.d.ts.map +1 -1
  265. package/dist/ui/segmented-control.js +3 -1
  266. package/dist/ui/segmented-control.js.map +1 -0
  267. package/dist/ui/select.d.ts.map +1 -1
  268. package/dist/ui/select.js +54 -48
  269. package/dist/ui/select.js.map +1 -0
  270. package/dist/ui/separator.d.ts.map +1 -1
  271. package/dist/ui/separator.js +10 -7
  272. package/dist/ui/separator.js.map +1 -0
  273. package/dist/ui/sheet.js +29 -29
  274. package/dist/ui/sheet.js.map +1 -0
  275. package/dist/ui/sidebar.js +9 -9
  276. package/dist/ui/sidebar.js.map +1 -0
  277. package/dist/ui/skeleton.js.map +1 -0
  278. package/dist/ui/slider.d.ts +22 -3
  279. package/dist/ui/slider.d.ts.map +1 -1
  280. package/dist/ui/slider.js +57 -19
  281. package/dist/ui/slider.js.map +1 -0
  282. package/dist/ui/spinner.js.map +1 -0
  283. package/dist/ui/split-button.d.ts.map +1 -1
  284. package/dist/ui/split-button.js +77 -76
  285. package/dist/ui/split-button.js.map +1 -0
  286. package/dist/ui/stack.js.map +1 -0
  287. package/dist/ui/stat-card.js.map +1 -0
  288. package/dist/ui/status-dot.js.map +1 -0
  289. package/dist/ui/stepper.d.ts +10 -0
  290. package/dist/ui/stepper.d.ts.map +1 -1
  291. package/dist/ui/stepper.js +80 -75
  292. package/dist/ui/stepper.js.map +1 -0
  293. package/dist/ui/switch.d.ts.map +1 -1
  294. package/dist/ui/switch.js +26 -22
  295. package/dist/ui/switch.js.map +1 -0
  296. package/dist/ui/table.js.map +1 -0
  297. package/dist/ui/tabs.d.ts +3 -1
  298. package/dist/ui/tabs.d.ts.map +1 -1
  299. package/dist/ui/tabs.js +68 -48
  300. package/dist/ui/tabs.js.map +1 -0
  301. package/dist/ui/text.d.ts +1 -1
  302. package/dist/ui/text.d.ts.map +1 -1
  303. package/dist/ui/text.js +10 -2
  304. package/dist/ui/text.js.map +1 -0
  305. package/dist/ui/textarea.js +1 -1
  306. package/dist/ui/textarea.js.map +1 -0
  307. package/dist/ui/toast-registry.d.ts +8 -0
  308. package/dist/ui/toast-registry.d.ts.map +1 -0
  309. package/dist/ui/toast-registry.js +13 -0
  310. package/dist/ui/toast-registry.js.map +1 -0
  311. package/dist/ui/toast.d.ts.map +1 -1
  312. package/dist/ui/toast.js +141 -136
  313. package/dist/ui/toast.js.map +1 -0
  314. package/dist/ui/toaster.d.ts.map +1 -1
  315. package/dist/ui/toaster.js +15 -14
  316. package/dist/ui/toaster.js.map +1 -0
  317. package/dist/ui/toggle-group.d.ts +2 -0
  318. package/dist/ui/toggle-group.d.ts.map +1 -1
  319. package/dist/ui/toggle-group.js +23 -16
  320. package/dist/ui/toggle-group.js.map +1 -0
  321. package/dist/ui/toggle.d.ts +2 -0
  322. package/dist/ui/toggle.d.ts.map +1 -1
  323. package/dist/ui/toggle.js +14 -6
  324. package/dist/ui/toggle.js.map +1 -0
  325. package/dist/ui/tooltip.js.map +1 -0
  326. package/dist/ui/visually-hidden.js.map +1 -0
  327. package/docs/components/_header.md +85 -85
  328. package/docs/components/composed/activity-feed.md +62 -62
  329. package/docs/components/composed/avatar-group.md +65 -65
  330. package/docs/components/composed/bulk-action-bar.md +40 -40
  331. package/docs/components/composed/command-palette.md +40 -40
  332. package/docs/components/composed/confirm-dialog.md +46 -46
  333. package/docs/components/composed/content-card.md +36 -36
  334. package/docs/components/composed/date-picker.md +130 -130
  335. package/docs/components/composed/deadline-indicator.md +27 -27
  336. package/docs/components/composed/emoji-picker.md +52 -52
  337. package/docs/components/composed/empty-state.md +53 -53
  338. package/docs/components/composed/error-boundary.md +29 -29
  339. package/docs/components/composed/file-preview.md +40 -40
  340. package/docs/components/composed/filter-bar.md +57 -57
  341. package/docs/components/composed/form-section.md +31 -31
  342. package/docs/components/composed/global-loading.md +27 -27
  343. package/docs/components/composed/inline-edit.md +35 -35
  344. package/docs/components/composed/loading-skeleton.md +51 -51
  345. package/docs/components/composed/markdown-viewer.md +27 -27
  346. package/docs/components/composed/master-detail.md +48 -48
  347. package/docs/components/composed/member-picker.md +35 -35
  348. package/docs/components/composed/multi-select-popover.md +62 -62
  349. package/docs/components/composed/page-header.md +41 -41
  350. package/docs/components/composed/page-skeletons.md +32 -32
  351. package/docs/components/composed/priority-indicator.md +32 -32
  352. package/docs/components/composed/responsive-overlay.md +34 -34
  353. package/docs/components/composed/rich-text-editor.md +82 -82
  354. package/docs/components/composed/schedule-view.md +39 -39
  355. package/docs/components/composed/simple-tooltip.md +33 -33
  356. package/docs/components/composed/status-badge.md +55 -55
  357. package/docs/components/shell/app-command-palette.md +44 -44
  358. package/docs/components/shell/bottom-navbar.md +52 -52
  359. package/docs/components/shell/command-registry.md +48 -48
  360. package/docs/components/shell/link-context.md +41 -41
  361. package/docs/components/shell/notification-center.md +63 -63
  362. package/docs/components/shell/notification-preferences.md +42 -42
  363. package/docs/components/shell/sidebar.md +92 -92
  364. package/docs/components/shell/top-bar.md +143 -143
  365. package/docs/components/ui/accordion.md +51 -51
  366. package/docs/components/ui/alert-dialog.md +61 -61
  367. package/docs/components/ui/alert.md +46 -46
  368. package/docs/components/ui/aspect-ratio.md +25 -25
  369. package/docs/components/ui/autocomplete.md +48 -48
  370. package/docs/components/ui/avatar.md +56 -56
  371. package/docs/components/ui/badge.md +83 -82
  372. package/docs/components/ui/banner.md +42 -42
  373. package/docs/components/ui/breadcrumb.md +37 -37
  374. package/docs/components/ui/button-group.md +41 -41
  375. package/docs/components/ui/button.md +94 -93
  376. package/docs/components/ui/card.md +52 -52
  377. package/docs/components/ui/charts.md +43 -43
  378. package/docs/components/ui/checkbox.md +36 -36
  379. package/docs/components/ui/chip.md +47 -47
  380. package/docs/components/ui/code.md +28 -28
  381. package/docs/components/ui/collapsible.md +40 -40
  382. package/docs/components/ui/color-input.md +91 -91
  383. package/docs/components/ui/color-swatch.md +25 -25
  384. package/docs/components/ui/combobox.md +54 -54
  385. package/docs/components/ui/container.md +26 -26
  386. package/docs/components/ui/context-menu.md +43 -43
  387. package/docs/components/ui/data-table-body.md +1 -1
  388. package/docs/components/ui/data-table-bulk-actions.md +1 -1
  389. package/docs/components/ui/data-table-card.md +1 -1
  390. package/docs/components/ui/data-table-context.md +1 -1
  391. package/docs/components/ui/data-table-header.md +1 -1
  392. package/docs/components/ui/data-table-pagination.md +1 -1
  393. package/docs/components/ui/data-table-toolbar.md +44 -44
  394. package/docs/components/ui/data-table.md +94 -94
  395. package/docs/components/ui/dialog.md +54 -54
  396. package/docs/components/ui/dropdown-menu.md +48 -48
  397. package/docs/components/ui/file-upload.md +41 -41
  398. package/docs/components/ui/form.md +51 -51
  399. package/docs/components/ui/hover-card.md +32 -32
  400. package/docs/components/ui/icon-button.md +40 -40
  401. package/docs/components/ui/input-otp.md +44 -44
  402. package/docs/components/ui/input.md +74 -74
  403. package/docs/components/ui/label.md +25 -25
  404. package/docs/components/ui/link.md +29 -29
  405. package/docs/components/ui/menubar.md +44 -44
  406. package/docs/components/ui/navigation-menu.md +46 -46
  407. package/docs/components/ui/number-input.md +44 -44
  408. package/docs/components/ui/pagination.md +48 -48
  409. package/docs/components/ui/popover.md +30 -30
  410. package/docs/components/ui/progress-ring.md +41 -41
  411. package/docs/components/ui/progress.md +34 -34
  412. package/docs/components/ui/radio.md +34 -34
  413. package/docs/components/ui/search-input.md +43 -43
  414. package/docs/components/ui/segmented-control.md +50 -50
  415. package/docs/components/ui/select.md +53 -53
  416. package/docs/components/ui/separator.md +32 -32
  417. package/docs/components/ui/sheet.md +47 -47
  418. package/docs/components/ui/sidebar.md +72 -72
  419. package/docs/components/ui/skeleton.md +77 -77
  420. package/docs/components/ui/slider.md +29 -29
  421. package/docs/components/ui/spinner.md +54 -54
  422. package/docs/components/ui/stack.md +39 -39
  423. package/docs/components/ui/stat-card.md +61 -61
  424. package/docs/components/ui/status-dot.md +26 -26
  425. package/docs/components/ui/stepper.md +49 -49
  426. package/docs/components/ui/switch.md +47 -47
  427. package/docs/components/ui/table.md +47 -47
  428. package/docs/components/ui/tabs.md +60 -60
  429. package/docs/components/ui/text.md +37 -37
  430. package/docs/components/ui/textarea.md +39 -39
  431. package/docs/components/ui/toast.md +65 -65
  432. package/docs/components/ui/toaster.md +47 -47
  433. package/docs/components/ui/toggle-group.md +43 -43
  434. package/docs/components/ui/toggle.md +37 -37
  435. package/docs/components/ui/tooltip.md +38 -38
  436. package/docs/components/ui/tree-view.md +65 -65
  437. package/docs/components/ui/visually-hidden.md +21 -21
  438. package/llms-full.txt +5266 -5264
  439. package/llms.txt +624 -580
  440. package/package.json +7 -8
package/llms.txt CHANGED
@@ -1,580 +1,624 @@
1
- # @devalok/shilp-sutra
2
-
3
- > Radix UI + Tailwind CSS + CVA design system for Devalok apps.
4
- > Built on the same primitives as shadcn/ui but with key API differences.
5
- > Read this file BEFORE writing any UI code. Do NOT guess from shadcn/ui knowledge.
6
-
7
- ## BREAKING CHANGES (v0.33.x — Tailwind 4 + Toolchain)
8
-
9
- - **Tailwind CSS 3 4:** `outline-none` `outline-hidden`, `rounded-sm` `rounded-xs`, `backdrop-blur-sm` `backdrop-blur-xs`, `!prefix` `suffix!` important syntax. Consumers using our preset: add `@import "tailwindcss"` + `@config` to your CSS, replace `darkMode: 'class'` with `@variant dark (&:is(.dark *))` in CSS. Peer dep accepts both `^3.4.0 || ^4.0.0`.
10
- - **tailwind-merge 3.0 3.5:** Required for TW4 class recognition.
11
- - **TypeScript 5.7 6.0.2:** `types` defaults to `[]` in TS6. Add explicit `"types": ["node"]` to tsconfig if needed.
12
- - **ESLint 9 10:** Config file lookup starts from linted file directory (not CWD). Verify monorepo configs.
13
- - **react-zoom-pan-pinch 3 4:** `onTransformed` renamed to `onTransform`. Peer dep `^3.0.0 || ^4.0.0`.
14
-
15
- ## CHANGES (v0.33.1 / v0.33.2)
16
-
17
- - Bumped: React 19.2.5, Storybook 10.3.5, Vitest 4.1.4, framer-motion 12.38, @floating-ui/dom 1.7.6, @tabler/icons-react 3.41.1, esbuild 0.28, jsdom 29, Playwright 1.59.1, PostCSS 8.5.9, Prettier 3.8.2, vite-plugin-dts 4.5.4.
18
-
19
- ## BREAKING CHANGES (v0.33.0)
20
-
21
- - **EmojiSuggestion:** Named export removed. Use `createEmojiSuggestion(set?)` factory. Default: `createEmojiSuggestion()` (native set).
22
- - **Emoji HTML output:** Non-native `emojiSet` renders emoji as `<span data-emoji-id="..." data-emoji-set="..." role="img">native</span>` nodes, not raw Unicode. `plainText` still returns Unicode.
23
-
24
- ## CHANGES (v0.33.0)
25
-
26
- - **RichChatInput v2** Complete rewrite. Structured output (`html`, `plainText`, `attachments?`, `voiceNote?`). Zone architecture. 4 variants: `compact` (default), `expanded`, `minimal`, `inline`. Props: `onSubmit`, `onSchedule?(msg, date)`, `mentions?`, `slashCommands?`, `onFileUpload?`, `onImageUpload?`, `onVoiceRecord?`, `onTranscribe?`, `replyTo?`, `toolbar?`, `emojiSet?`, `actionButton?`, `enterBehavior?`, `maxLength?`, `isStreaming?`, `disclaimer?`, `sendOptions?`, `leadingSlot?`, `trailingSlot?`.
27
- - **Custom EmojiNode** TipTap inline atom node. Renders emoji via spritesheet images for consistent Apple/Google/Twitter/Facebook art styles. `emojiSet` prop on `EmojiPicker`, `EmojiPickerPopover`, `RichChatInput`, `RichTextEditor`. Sets: `native` (default), `apple`, `google`, `twitter`, `facebook`.
28
- - **SplitButton** (`ui/`) — `[Action | ▼]` button with dropdown. Props: `variant(solid|soft|outline)`, `color`, `size`, `triggerSide(left|right)`, `triggerWidth`, `placement` (Floating UI), `dropdownContent`. Proper ARIA: `role="group"`, `aria-haspopup`, `aria-expanded`.
29
- - **Schedule Send** `onSchedule?(msg, date)` on RichChatInput. Smart presets (time-of-day aware) + DateTimePicker. Banner shows scheduled time. Send button morphs to SplitButton.
30
- - **ButtonGroup rebuild** Compound component pattern. Button reads position from context, applies radius inline. New props: `disabled` (propagates), `attached` (true/false), `fullWidth`. Tonal dividers for solid/soft/ghost variants. Focus z-index isolation.
31
- - **TipTap v2v3** `useEditorState`, `immediatelyRender: false` (SSR-safe), `ListKit`. Fixes React 19 `removeChild` crash.
32
- - **Composable toolbar** — Exported: `ToolbarButton`, `ToolbarDivider`, `ToolbarGroup`, `BoldButton`, `ItalicButton`, `UnderlineButton`, `StrikeButton`, `HighlightButton`, `CodeButton`, `BulletListButton`, `OrderedListButton`, `BlockquoteButton`, `LinkButton`, `EmojiButton`.
33
- - **Button `disabled`** Now inherited from ButtonGroup context.
34
-
35
- ## BREAKING CHANGES (v0.32.0)
36
-
37
- - **Button:** `variant="default"` removed (use `"solid"`), `variant="destructive"` removed (use `variant="solid" color="error"`), `color="default"` removed (use `"accent"`).
38
- - **Chip:** Removed. Use `Badge` instead.
39
- - **SegmentedControl:** Rewritten. `variant="filled"` `"accent"`, `variant="tonal"` → `"default"`. `SegmentedControlItem` no longer exported. Legacy sizes `small`/`medium`/`big` removed.
40
- - **TopBar:** Now renders as `<header>` (was `<div>`).
41
- - **Sidebar:** Now renders as `<aside>` (was `<div>`).
42
- - **InfoBlock:** `role="status"` (was `role="alert"`).
43
- - **Border tokens:** One step darker system-wide.
44
- - **Dark mode button text:** Pure white `neutral-0` (#fff) on brand-colored buttons.
45
- - **BottomNavbar:** Bottom padding is now `pb-safe` (safe-area-inset).
46
- - **ResponsiveOverlay:** Deprecated. Use Dialog or Sheet directly.
47
- - **iOS inputs:** Forced to `font-size: max(16px, 1em)` on mobile via preset.
48
-
49
- ## CHANGES (v0.32.0)
50
-
51
- - **Mobile Responsiveness:**
52
- - Dialog auto-fullScreens on mobile (<768px). Opt out: `<DialogContent responsive={false}>`.
53
- - Sheet auto-bottom with swipe-to-dismiss on mobile. Drag handle, 30% threshold. Opt out: `<SheetContent responsive={false}>`.
54
- - Popover renders as bottom drawer on mobile automatically.
55
- - `.touch-target` utility 44px invisible hit area for Apple HIG compliance.
56
- - `.pt-safe`, `.pb-safe`, `.pl-safe`, `.pr-safe`, `.p-safe` — safe area inset utilities.
57
- - `useTouchDevice()` — detects touch capability (vs viewport width).
58
- - `useViewportHeight()` — dynamic viewport height via Visual Viewport API.
59
- - Sidebar has swipe-to-close on mobile.
60
- - **DataTable `mobileView="card"`** — Rows render as stacked cards below 640px. First column = card title, rest = label-value pairs.
61
- - **DataTable `aria-sort`** — Sortable column headers include `aria-sort`.
62
- - **Charts `ariaLabel` prop** — Configurable screen reader label on all chart components.
63
- - **SegmentedControl** Redesigned: `variant="default"` (white pill + shadow-sm) | `variant="accent"` (brand pill). Inset radius, snappy spring animation.
64
- - **`--shadow-kbd` token** Keyboard shortcut badge shadow. Use `shadow-kbd` utility.
65
- - **Checkbox/Radio `size` prop** — `sm | md (default) | lg`.
66
-
67
- ## CHANGES (v0.31.0)
68
- - **Alert `size` prop** — `sm | md (default) | lg`. Scales padding, gap, icon, text.
69
- - **Card `color` prop** — `default | accent | error | success | warning | info | neutral`. Semantic border color.
70
- - **Card `size` prop** — `sm | md (default) | lg`. Propagated to sub-components via context.
71
- - **Select `variant` prop** — `default | outline | ghost` on SelectTrigger.
72
- - **Select `color` prop** — `default | error | success | warning` on SelectTrigger. Sets `aria-invalid` when error.
73
- - **Tabs `color` prop** — `accent (default) | neutral`. Affects line variant indicator.
74
- - **Tabs `size` prop** `sm | md (default) | lg`. Scales height and padding.
75
- - **Badge `truncate` prop** Enables ellipsis truncation. Combine with fixed width or `maxWidth`.
76
- - **New subpath exports** — `./ui/icon`, `./ui/icon-context`, `./ui/icon-group`, `./ui/badge-group`, `./ui/badge-indicator`, `./ui/devalok-grain`, `./ai/types`.
77
- - **Server-safe fix** — `empty-state`, `priority-indicator`, `status-badge` now correctly get `"use client"` (were incorrectly omitted).
78
- - **Server-safe detection** — Hardcoded allowlist replaced with `// @server-safe` source annotations.
79
-
80
- ## CHANGES (v0.30.0)
81
- - **RichTextEditor `toolbar` prop** `toolbar?: ToolbarItem[]` whitelist of toolbar items to display. Omit to show all (default). `ToolbarItem` type exported.
82
- - **`@devalok/shilp-sutra-karm` removed** Domain components moved to Karm app repo. npm package deprecated.
83
- - **Warning dark mode fixed** `warning-*` tokens now have proper dark mode values (higher chroma than category amber).
84
- - **tailwind-merge fix** — All `text-ds-*` sizes now correctly registered. `cn('text-ds-lg', 'text-accent-11')` no longer strips the color.
85
- - **AvatarGroup fixes** Overflow badge text matches avatar size, indicator dots scale with size, aria-labels added.
86
-
87
- ## BREAKING CHANGES (v0.27.0 Externalized Dependencies)
88
-
89
- FilePreview and MarkdownViewer dependencies are now **external** (not bundled).
90
- Install them if you use these components:
91
-
92
- ```bash
93
- pnpm add react-pdf react-zoom-pan-pinch react-syntax-highlighter
94
- ```
95
-
96
- These are optional peerDependencies consumers who don't use FilePreview or MarkdownViewer are unaffected.
97
-
98
- **Next.js optimization:** Add to your `next.config.js`:
99
- ```js
100
- optimizePackageImports: ['@devalok/shilp-sutra']
101
- ```
102
-
103
- ## BREAKING CHANGES (v0.23.0 Semantic Surface & Shadow Tokens)
104
-
105
- **Surface tokens renamed:** Numeric `surface-1..4` replaced with semantic names.
106
- | Old | New | Usage |
107
- |-----|-----|-------|
108
- | `bg-surface-1` | `bg-surface-base` | Page background |
109
- | `bg-surface-1` | `bg-surface-sunken` | Shell chrome (sidebar, topbar), board columns |
110
- | `bg-surface-1` | `bg-surface-overlay` | Dialogs, popovers, dropdowns, inputs |
111
- | `bg-surface-2` | `bg-surface-raised` | Cards, widgets, panels |
112
- | `bg-surface-3` | `bg-surface-raised-hover` | Hover states on raised elements |
113
- | `bg-surface-4` | `bg-surface-raised-active` | Active/pressed states |
114
-
115
- Same pattern for `border-surface-*`, `text-surface-*`, `ring-surface-*`.
116
-
117
- **Shadow tokens renamed:** Numeric `shadow-01..05` replaced with semantic names.
118
- | Old | New |
119
- |-----|-----|
120
- | `shadow-01` | `shadow-raised` |
121
- | `shadow-02` | `shadow-raised-hover` |
122
- | `shadow-03` | `shadow-floating` |
123
- | `shadow-04` | `shadow-overlay` |
124
- | `shadow-05` | (removed — was unused) |
125
-
126
- **New surface tokens:**
127
- - `bg-surface-sunken`recessed areas (sidebar, board columns, segmented track)
128
- - `bg-surface-overlay` — floating elements (dialogs, popovers, inputs). Diverges from base in dark mode.
129
- - `bg-surface-inverted` / `text-surface-inverted-fg`tooltips, inverted badges
130
- - `bg-surface-disabled` / `text-surface-fg-disabled` — disabled elements
131
- - `border-surface-border-subtle` hairline dividers
132
- - `bg-backdrop` dialog/sheet backdrop overlay
133
-
134
- **New shadow tokens:**
135
- - `shadow-glow` — selection/focus accent glow
136
- - `shadow-inset` — toggle/segmented track deboss
137
- - `shadow-ring` / `shadow-ring-sm` — focus ring / subtle separator
138
-
139
- **Hard rule: never combine explicit border + shadow.** Shadows include a 1px ring layer. Adding a CSS border creates a 2px edge. Use shadow OR border, never both.
140
-
141
- **Breaking:** Old numeric aliases (`--color-surface-1..4`, `--shadow-01..05`, Tailwind `bg-surface-1..4`, `shadow-01..05`) have been removed. Use the semantic names listed above.
142
-
143
- **Component Decision Matrix:**
144
- | Building... | Surface | Shadow |
145
- |-------------|---------|--------|
146
- | Page/layout | `surface-base` | none |
147
- | Shell (sidebar/topbar) | `surface-sunken` | `shadow-raised` |
148
- | Card/widget/panel | `surface-raised` | `shadow-raised` |
149
- | Card hover | `surface-raised` | `shadow-raised-hover` |
150
- | Board column/well | `surface-sunken` | none |
151
- | Popover/menu/dropdown | `surface-overlay` | `shadow-floating` |
152
- | Dialog/modal/sheet | `surface-overlay` | `shadow-overlay` |
153
- | Tooltip | `surface-inverted` | `shadow-floating` |
154
- | Toast | `surface-overlay` | `shadow-floating` |
155
- | Input (rest) | `surface-overlay` | none |
156
- | Input (focus) | `surface-overlay` | `shadow-ring` |
157
- | Button (solid) | accent colors | `shadow-raised` |
158
- | Button (disabled) | `surface-disabled` | none |
159
- | Segmented track | `surface-sunken` | `shadow-inset` |
160
- | Selected item | current surface | `shadow-glow` |
161
-
162
- ## BREAKING CHANGES (v0.18.0 — Framer Motion + OKLCH)
163
-
164
- **New runtime dependency:** `framer-motion@^12.36.0` (bundled). Karm consumers must install `framer-motion@^12.0.0` as peer dep.
165
-
166
- **Transitions removed:** `Fade`, `Collapse`, `Grow`, `Slide` from `./ui/transitions` no longer exist. Use `MotionFade`, `MotionCollapse`, `MotionSlide` from `@devalok/shilp-sutra/motion/primitives`.
167
-
168
- **CSS keyframe animations removed:** 18 keyframes (`fade-in`, `fade-out`, `slide-up`, `scale-in`, etc.) and their `animate-*` utilities removed from Tailwind preset. Use motion primitives instead.
169
-
170
- **`useReducedMotion()` removed:** Use `<MotionProvider reducedMotion="user">` at app root.
171
-
172
- **New motion system:**
173
- - `import { MotionProvider, springs, tweens } from '@devalok/shilp-sutra/motion'`
174
- - `import { MotionFade, MotionCollapse, MotionSlide, MotionPop, MotionScale, MotionStagger } from '@devalok/shilp-sutra/motion/primitives'`
175
- - Springs: `springs.snappy`, `springs.smooth`, `springs.bouncy`, `springs.gentle`
176
- - Tweens: `tweens.fade`, `tweens.colorShift`
177
-
178
- **Spinner v2:** New props `state?: 'spinning' | 'success' | 'error'`, `variant?: 'filled' | 'bare'`, `delay?: number`, `onComplete?: () => void`
179
-
180
- **Button `onClickAsync`:** New prop `onClickAsync?: (e) => Promise<void>` — auto-manages loading → success/error → idle states. `asyncFeedbackDuration?: number` (default 1500ms).
181
-
182
- **Server safety changes:** EmptyState, StatusBadge, PriorityIndicator, Spinner are NOT server-safe (they use Framer Motion). Do NOT import from RSC.
183
-
184
- **Build:** `framer-motion` and `sonner` moved from `dependencies` to `devDependencies` (bundled at build time — no consumer install needed for core).
185
-
186
- **New APIs in v0.18.0:**
187
- - Combobox: `accessibleLabel?: string` — custom aria-label for trigger (falls back to placeholder)
188
- - Slider: multi-thumb support — pass array `defaultValue={[25, 75]}` for range sliders
189
-
190
- ## CHANGES (v0.16.0)
191
- - **DataTable server-side features**: `onSort` callback (manual sorting), `pagination` prop (server-side pagination with page/total/onPageChange), `selectedIds` + `selectableFilter` (controlled selection), `loading` shimmer, `emptyState` ReactNode, `singleExpand`, `stickyHeader`, `onRowClick`, `bulkActions` floating bar
192
- - **DataTable display**: `density?: 'compact' | 'standard' | 'comfortable'` (compact=4px padding, standard=16px, comfortable=32px). `toolbar?: boolean` (column visibility + density + export controls). Column `meta: { align: 'right' }` for numeric columns (auto-applies text-right tabular-nums). Column `meta: { hideBelow: 'md' }` for responsive column hiding (hidden below breakpoint). `selectableFilter?: (row) => boolean` to disable selection on certain rows (e.g. only PENDING rows selectable).
193
- - **ActivityFeed**: New composed component — `@devalok/shilp-sutra/composed/activity-feed` — vertical timeline with colored dots, actor avatars, expandable detail, compact mode, load more
194
- - EmptyState: `iconSize?: 'sm' | 'md' | 'lg'` prop for icon dimension control
195
- - BottomNavbar: `badge?: number` on BottomNavItem for notification counts (99+ cap)
196
- - AppSidebar: `preFooterClassName?: string` for scrollable preFooterSlot
197
-
198
- ## CHANGES (v0.15.0)
199
- - **Input font standardization**: All input sizes (sm, md, lg) now use text-ds-md (14px). Previously lg used text-ds-lg (18px). Affects Input, Select, SearchInput, Textarea.
200
- - CommandPalette: Staggered slide-up animations for items, fade-in for groups, scale-in search icon, active item color transitions
201
-
202
- ## CHANGES (v0.14.0)
203
- - **BREAKING z-index**: Select, Combobox, Autocomplete, DropdownMenu, ContextMenu, Menubar, HoverCard promoted from z-dropdown (1000) to z-popover (1400). Fixes dropdowns rendering behind Sheet/Dialog. If you had custom z-index overrides (e.g. `[data-radix-popper-content-wrapper] { z-index: 1400 !important }`) you can now remove them.
204
- - TabsTrigger: Added gap-ds-02 (4px) between icon and label
205
- - AppSidebar: footer.version now accepts string | { label, href } for clickable version links
206
-
207
- ## CHANGES (v0.13.0)
208
- - EmptyState: icon prop now accepts ComponentType (e.g. Tabler icon references) in addition to ReactNode
209
- - NotificationCenter: Notification.actions?: NotificationAction[] — inline action buttons (Approve/Deny) per notification
210
- - NotificationCenter: Tier dot now doubles as read/unread marker; separate unread dot removed
211
- - AppSidebar: footer.promo?: SidebarPromo — dismissable promo banner with icon, text, action button
212
- - AppSidebar: Footer links + version render on same line with · dividers
213
- - Collapsible: Now uses height-based expand/collapse animation (animate-collapsible-down/up)
214
- - Tailwind preset: 4 new keyframes + utilities — accordion-down, accordion-up, collapsible-down, collapsible-up
215
-
216
- ## CHANGES (v0.12.0)
217
- - Input: Softer resting border (border-subtle instead of border), subtler focus ring (ring-1 ring-focus/50 instead of ring-2 ring-focus)
218
- - Tailwind preset: 9 animation keyframes + utilities (fade-in, fade-out, slide-up, slide-right, scale-in, scale-out, glow-pulse, scale-bounce, lift)
219
- - Tailwind preset: Stagger plugins — .delay-stagger (30ms × --stagger-index), .delay-stagger-50 (50ms × --stagger-index)
220
-
221
- ## BREAKING CHANGES (v0.11.0 — dark mode)
222
- - Dark mode interactive colors shifted: --color-interactive pink-400→pink-500, --color-interactive-hover pink-300pink-600, --color-interactive-active pink-200pink-700, --color-interactive-subtle pink-950→pink-1000
223
- - Dark mode text status colors shifted: --color-text-error red-200→red-300, --color-text-success green-200→green-300, --color-text-warning yellow-200→yellow-300, --color-text-link blue-200→blue-300, --color-text-brand pink-300→pink-400
224
- - New primitive token: --pink-1000 (#150208) near-black
225
-
226
- ## BREAKING CHANGES (v0.8.0)
227
- - Combobox: Now uses discriminated union. Single: `multiple?: false, value: string, onValueChange: (v: string) => void`. Multiple: `multiple: true, value: string[], onValueChange: (v: string[]) => void`. No more `v as string[]` casts.
228
- - StatusBadge: Pass either `status` OR `color`, not both (discriminated union).
229
- - Input/Textarea: Now auto-inherit state, aria-describedby, aria-required from FormField context. Explicit props override.
230
-
231
- ## BREAKING CHANGES (v0.18.0 — OKLCH token migration, continued)
232
- - All color primitives migrated from hex (50-950 shades) to OKLCH (12 functional steps)
233
- - Old shade numbers: --pink-50..950. New step numbers: --pink-1..12 (OKLCH values)
234
- - Step purposes: 1=app-bg, 2=subtle-bg, 3=component-bg, 4=hover, 5=active, 6=border-subtle, 7=border, 8=border-strong, 9=solid/accent, 10=solid-hover, 11=lo-contrast-text, 12=hi-contrast-text
235
- - New semantic tokens: --color-accent-{1-12}, --color-secondary-{1-12}, --color-surface-{base,raised,raised-hover,raised-active,sunken,overlay,inverted,disabled}, --color-surface-fg/fg-muted/fg-subtle/border/border-subtle
236
- - Status tokens: --color-error-{3,7,9,11,fg}, --color-success-{3,7,9,11,fg}, --color-warning-{3,7,9,11,fg}, --color-info-{3,7,9,11,fg}
237
- - New Tailwind utilities: accent-1..12, secondary-1..12, surface-base/raised/sunken/overlay/inverted/disabled, status/category step utilities
238
- - Backward compat: ALL old semantic token names preserved as aliases. --color-interactive still works → maps to --color-accent-9
239
- - Consumer rebranding: override --color-accent-1..12 CSS vars OR use generateScale() utility with a seed color
240
- - Dark mode: algorithmically derived (OKLCH curves), NOT hex overrides. Surfaces lighten with elevation.
241
- - If you reference --pink-500 etc directly, migrate: 50→1, 100→2, 200→3, 300→4, 400→5, 500→7, 600→8, 700→9, 800→10, 900→11, 950→12
242
-
243
- ## v0.22.0 — UI Polish & Micro-Refinement
244
-
245
- **Shadows**: All shadow tokens now use 3-layer stacks. Visual change only same token names. Shadow tokens renamed in v0.23.0 (see breaking changes above).
246
-
247
- **Transitions**: All CSS transitions use `ease-productive-standard` easing. Tween presets aligned: `tweens.fade` = 0.11s, `tweens.colorShift` = 0.07s.
248
-
249
- **New Tailwind utilities**:
250
- - `.focus-ring` double-ring (2px surface + 2px accent), use on custom interactive elements (buttons, cards)
251
- - `.focus-ring-inset` inset ring, use on buttons over solid backgrounds
252
- - `.focus-ring-sm` 1px subtle ring, use on inputs and small controls
253
- - `.tabular-nums`aligned numbers via `font-variant-numeric: tabular-nums`
254
-
255
- **Category color utilities** (standalone, not tied to Badge/Chip):
256
- - 7 colors: teal, amber, slate, indigo, cyan, orange, emerald
257
- - 4 steps each: bg-category-{color}-{3|7|9|11}, text-category-{color}-{3|7|9|11}, border-category-{color}-{3|7|9|11}
258
- - Use for: board column accents, status indicators, tag colors, category chips
259
-
260
- **Dense size variant (xs)** added to Input, Select, SearchInput, Button, Textarea:
261
- - xs = 28px height (h-ds-xs-plus), 12px text (text-ds-sm), compact padding
262
- - Designed for filter bars, toolbar controls, and dense UI contexts
263
- - Button also gets icon-xs (28×28) for compact icon buttons
264
- - Size matrix: xs=28px | sm=32px | md=40px (default) | lg=48px
265
-
266
- **Separator**: New `variant` prop — `"gradient" | "gradient-left" | "gradient-right"`. Default unchanged.
267
-
268
- **Checkbox**: Path-draw animation (stroke draws progressively). Uncontrolled usage now works.
269
-
270
- **Tooltip**: Auto-wraps with `<TooltipProvider>` no manual provider needed. Text color fixed for dark mode.
271
-
272
- **Avatar fallback**: Now respects `shape` prop (was always circle). Font size auto-scales with avatar size (v0.22.3).
273
-
274
- **AvatarGroup renderAvatar**: Wrapper is positioning-only pass `size` directly to your Avatar, do NOT use `className="h-full w-full"` (v0.22.3).
275
-
276
- **New hover states**: Checkbox, Radio, Switch track, Select items, DropdownMenu items, Combobox trigger.
277
-
278
- ## AI Command System (v0.25.0+)
279
-
280
- New `@devalok/shilp-sutra/ai` module composable AI command interface.
281
-
282
- **CommandBar** Unified input (hero/inline/floating variants):
283
- ```tsx
284
- <CommandBar
285
- variant="hero"
286
- onSubmit={(query) => sendToAI(query)} // AI submission
287
- groups={commandGroups} // optional command palette filtering
288
- state="idle" // idle | typing | processing | responded
289
- greeting="Good morning, Mudit."
290
- hints={['Add member...', 'Check status...']}
291
- agentName="Devadoot"
292
- agentIcon={<DevadootIcon state={iconState} />}
293
- >
294
- <AIConversation messages={messages} isProcessing={loading} />
295
- </CommandBar>
296
- ```
297
-
298
- **BlockRenderer** Renders AI response JSON as DS components:
299
- ```tsx
300
- <BlockRenderer blocks={response.blocks} onAction={handleAction} customBlocks={myBlocks} />
301
- ```
302
-
303
- Block types: `text`, `table`, `confirm`, `success`, `error`, `info`, `loading`, `divider`, `stat_row`.
304
-
305
- **AICommandProvider** Optional context wrapper:
306
- ```tsx
307
- <AICommandProvider customBlocks={karmBlocks} onAction={handle} agent={{ name: 'Devadoot' }}>
308
- {/* CommandBar + AIConversation auto-wire from context */}
309
- </AICommandProvider>
310
- ```
311
-
312
- **DevadootIcon**Animated Devalok chakra with gradient state animations:
313
- ```tsx
314
- <DevadootIcon state="processing" size={20} /> // idle | processing | responded | error
315
- ```
316
-
317
- ## Install & Setup
318
-
319
- pnpm add @devalok/shilp-sutra
320
-
321
- ### Next.js Setup (Required for Next.js + pnpm)
322
-
323
- Add to next.config.js:
324
- ```js
325
- transpilePackages: ["@devalok/shilp-sutra", "@devalok/shilp-sutra-brand"]
326
- ```
327
-
328
- // Import components (barrel):
329
- import { Button, Card, Dialog } from '@devalok/shilp-sutra'
330
-
331
- // Import per-component (recommended for Server Components):
332
- import { Button } from '@devalok/shilp-sutra/ui/button'
333
- import { PageHeader } from '@devalok/shilp-sutra/composed/page-header'
334
- import { TopBar } from '@devalok/shilp-sutra/shell/top-bar'
335
-
336
- // Chat primitives (v0.29.0+):
337
- import { MessageList, Message, SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator } from '@devalok/shilp-sutra/ui/chat'
338
-
339
- // AI command system (v0.25.0+):
340
- import { CommandBar, AIConversation, BlockRenderer, AICommandProvider, DevadootIcon } from '@devalok/shilp-sutra/ai'
341
-
342
- // Toast (imperative, no hook needed):
343
- import { toast } from '@devalok/shilp-sutra/ui/toast'
344
-
345
- // Hooks:
346
- import { useColorMode } from '@devalok/shilp-sutra/hooks/use-color-mode'
347
-
348
- // CSS tokens (import once at app root):
349
- import '@devalok/shilp-sutra/tokens'
350
-
351
- // Tailwind preset (in tailwind.config):
352
- import shilpSutra from '@devalok/shilp-sutra/tailwind'
353
-
354
- ## CRITICAL: Differences from shadcn/ui
355
-
356
- If you have shadcn/ui knowledge, these are the differences that WILL trip you up:
357
-
358
- | shadcn/ui pattern | shilp-sutra equivalent | Notes |
359
- |---|---|---|
360
- | variant="destructive" | color="error" | Two-axis system: variant=shape, color=intent |
361
- | size="default" | size="md" | All sizes: sm, md, lg (never "default") |
362
- | <Select size="lg"> | <SelectTrigger size="lg"> | Size goes on trigger, NOT root |
363
- | <Chip> | <Badge onClick={...}> | Chip is deprecated, use Badge with onClick |
364
- | useToast() + toast({ variant }) | toast.success('msg') | Imperative API, no hook needed |
365
- | Badge variant="destructive" | Badge variant="solid" color="error" | Two-axis: variant + color |
366
- | Alert + AlertTitle + AlertDescription | <Alert title="..." color="error"> | Single component, not compound |
367
- | Form + FormField + FormItem + FormLabel + FormControl + FormDescription + FormMessage | FormField + Label + Input + FormHelperText + useFormField() | Simpler API, hook-based a11y wiring |
368
- | Pagination | PaginationRoot | Root component name differs |
369
-
370
- ### The Two-Axis Variant System
371
-
372
- Many components use TWO props where shadcn uses one:
373
- - `variant` controls SHAPE/SURFACE: solid, outline, ghost, subtle, filled, etc.
374
- - `color` controls INTENT/SEMANTICS: default, error, success, warning, info, etc.
375
-
376
- Examples:
377
- <Button variant="solid" color="error">Delete</Button> // red solid button
378
- <Button variant="soft" color="warning">Pending</Button> // amber tinted button
379
- <Button variant="outline" color="success">Approve</Button> // green outline button
380
- <Badge variant="solid" color="success">Active</Badge> // green solid badge
381
- <Alert variant="filled" color="warning">Warning!</Alert> // amber filled alert
382
-
383
- Components with two-axis system: Button, Badge, Alert, Banner, Progress, StatusBadge
384
-
385
- ## Component Quick Reference
386
-
387
- ### Inputs & Controls
388
- - Button: variant(solid|soft|outline|ghost|link) color(accent|error|success|warning|neutral) size(xs|sm|md|lg|compact-xs|compact-sm|compact-md|icon-xs|icon-sm|icon-md|icon-lg) shape(default|pill) weight(semibold|normal) + loading, startIcon, endIcon, asChild, processing?('ambient'|'working'|'urgent'|boolean — marching ants SVG border, forces soft variant), processingColor?('accent'|'error'|'success'|'warning'|'neutral'), processingDisabled?(boolean, default true — set false for cancel-by-click). onClickAsync auto-activates processing='working' during loading phase. Layout animation always on. Deprecated aliases still work: variant="default"→solid, variant="destructive"→solid+error, color="default"→accent
389
- - IconButton: icon(ReactNode, required) shape(square|circle) size(sm|md|lg) + aria-label required
390
- - SplitButton: [Action | ▼] button with dropdown. Props: variant(solid|soft|outline), color, size(xs|sm|md|icon-xs|icon-sm|icon-md), triggerSide(left|right, default right), triggerWidth?(number|string), placement?(Floating UI Placement, default top-end), dropdownContent(ReactNode), open?, onOpenChange?, dropdownLabel?, dropdownIcon?. ARIA: role="group", aria-haspopup="menu", aria-expanded.
391
- - ButtonGroup: Visually merges adjacent Buttons. Props: variant, color, size, disabled (propagates), orientation(horizontal|vertical), attached(true|false, default true), fullWidth. Compound pattern: Button reads position from context, applies radius + border-removal inline. Tonal dividers for solid/soft/ghost. Focus z-index isolation.
392
- - Icon: `<Icon icon={IconPlus} />` — context-aware wrapper for Tabler icons. Size tiers: xs(14px) sm(16px) md(18px) lg(20px) xl(24px) 2xl(32px). Default: md. Stroke: light(1.5) regular(2) bold(2.5). Default: regular. Scales per size tier. Reads size from parent Button/IconGroup via IconContext. Explicit props override. Accessibility: aria-hidden by default. Pass label="Add item" for accessible icons. Animation: animate="spin|pulse|bounce|draw". `draw` renders SVG path-draw animation (check/X icons draw progressively via pathLength; other icons fall back to static). State machine: state="idle|loading|success|error". Button integration: startIcon={<Icon icon={IconPlus} />} (NOT raw <IconPlus />). IconGroup: <IconGroup size="sm" gap="tight"> for toolbar patterns.
393
- - Input: size(xs|sm|md|lg) state(InputState) + startSection(ReactNode), endSection(ReactNode), startSectionClickable(bool), endSectionClickable(bool), startSectionType('icon'|'label'), endSectionType('icon'|'label'), wrapperClassName(string). Container-level focus ring wraps input + sections as one unit. Sections are pointer-events-none by default; use *SectionClickable for interactive content (clear buttons, toggles). Section type auto-inferred: strings→'label' (tinted bg + border separator), React elements→'icon' (fixed-width centered). Override with *SectionType. Flexbox section layout. Icons auto-size via IconProvider per input size. className targets <input>, wrapperClassName targets wrapper div. Deprecated aliases: startIcon→startSection, endIcon→endSection, inputVariants→inputWrapperVariants. Type: InputState = 'default' | 'error' | 'warning' | 'success'
394
- - SearchInput: size(xs|sm|md|lg) + loading, onClear. Delegates to Input v2 sections internally.
395
- - NumberInput: value + onValueChange, min, max, step (controlled only)
396
- - Textarea: size(xs|sm|md|lg) state(default|error|warning|success)
397
- - ColorInput: value(hex string) onChange(value) presets({hex,label}[]|string[]|false, default: 10 named colors) variant('default'|'inline') showPicker(boolean, default:true) defaultFormat('hex'|'rgb'|'hsl') align('start'|'center'|'end') disabled. Popover trigger opens interactive picker (react-colorful) + format switcher + preset swatches + undo/reset. Inline variant renders entire trigger as the color with contrast-aware text.
398
- - Checkbox: checked, onCheckedChange, error(boolean), indeterminate(boolean)
399
- - Switch: checked, onCheckedChange, error(boolean), size(sm|md|lg), color(accent|success|warning), thumbIcon(ReactNode)
400
- - RadioGroup > RadioGroupItem(value)
401
- - Select > SelectTrigger(size: xs|sm|md|lg) > SelectValue; SelectContent > SelectItem(value)
402
- - Toggle: variant(default|outline) size(sm|md|lg)
403
- - ToggleGroup > ToggleGroupItem (variant/size propagate from root)
404
- - SegmentedControl > SegmentedControlItem: variant(filled|tonal) size(sm|md|lg). Types: SegmentedControlOption = { id, text, icon? }, SegmentedControlSize = 'sm' | 'md' | 'lg', SegmentedControlVariant = 'filled' | 'tonal'
405
- - Slider: standard Radix slider
406
-
407
- ### Feedback & Notifications
408
- - Alert: variant(subtle|filled|outline) color(info|success|warning|error|neutral) + title, onDismiss
409
- - Banner: color(info|success|warning|error|neutral) + actions?(ReactNode), onDismiss. `action` (singular) deprecated, use `actions`. Mobile flex-wrap for multiple buttons.
410
- - Toast: imperative API via toast.success/error/warning/info/loading/message/undo/promise/upload/custom REQUIRES <Toaster> at layout root
411
- - Spinner: size(sm|md|lg) — renders with role="status"
412
- - Progress: track size(sm|md|lg), indicator color(default|success|warning|error), autoColor(boolean, auto-shifts color by value: 0-59=default, 60-84=warning, 85-100=success, >100=error)
413
-
414
- NOTIFICATION SELECTION GUIDE:
415
- - Alert: inline contextual feedback within a form or page section
416
- - Banner: persistent page-level notification above content
417
- - Toast: transient notification triggered by user action (needs <Toaster>, then call toast.success() etc.)
418
-
419
- ### Data Display
420
- - Badge: variant(subtle|solid|outline|soft) color(default|accent|error|success|warning|info|neutral + 7 category colors + custom) size(xs|sm|md|lg) + onClick, onDismiss, selected, disabled, dot, startIcon, endIcon, maxWidth, circle, asChild. Compound: Badge.Indicator(count, max, dot, color, invisible, showZero, placement, children), Badge.Group(max, gap, size, onOverflowClick, children). Custom colors: color="custom" + style={{'--badge-color':'#hex'}}. Grain-ready (has relative/overflow-hidden/isolate).
421
- - Chip: DEPRECATED — Use `<Badge onClick={...}>` instead. Chip wrapper maps label prop to children for backward compat.
422
- - Avatar: size(xs|sm|md|lg|xl) shape(circle|square|rounded) status?(AvatarStatus) ring?('lead'|'admin'|'client') badge?(number|'dot'|ReactNode) loading?(boolean) > AvatarImage + AvatarFallback(colorSeed?). Types: AvatarStatus = 'online'|'offline'|'busy'|'away', AvatarRing = 'none'|'lead'|'admin'|'client'. Fallback colors are deterministic from name hash (8 categorical). Online dot pulses. Badge pops in with MotionPop.
423
- - Card: variant(default|elevated|outline|flat) interactive(boolean) accent?(left|top|right|bottom) accentColor?(default|secondary|error|success|warning|info) > CardHeader > CardTitle, CardDescription; CardContent; CardFooter
424
- - Table > TableHeader > TableRow > TableHead; TableBody > TableRow > TableCell; TableFooter; TableCaption
425
- - Text: variant(TextVariant) as(element). Type: TextVariant = 'heading-2xl' | 'heading-xl' | 'heading-lg' | 'heading-md' | 'heading-sm' | 'heading-xs' | 'body-lg' | 'body-md' | 'body-sm' | 'body-xs' | 'label-lg' | 'label-md' | 'label-sm' | 'label-xs' | 'caption' | 'overline'
426
- - Code: variant(inline|block)
427
- - Skeleton: variant(rectangle|circle|text) animation(pulse|shimmer|none)
428
- - StatCard: title/label, value, delta, icon, prefix, suffix, comparisonLabel, secondaryLabel, progress, sparkline, onClick, href, accent(default|success|warning|error|info), footer
429
- - ColorSwatch: color(CSS string) size(sm|md|lg) shape(circle|square|rounded) ring(boolean) — for dynamic runtime colors
430
- - StatusDot: status(healthy|warning|critical|neutral|inactive) size(sm|md|lg) pulse?(boolean, default true for healthy) label?(string)
431
- - ProgressRing: value(number) max?(100) size(sm|md|lg) color(default|success|warning|error|info) showValue?(boolean) label?(string). Also: MultiProgressRing for concentric Activity Ring style
432
- - DevalokGrain: Brand texture overlay drop inside any element with `relative overflow-hidden isolate`. Props: intensity('subtle'|'medium'|'heavy'), surface('solid'|'soft'), sheen(boolean, inner highlight), animated(boolean, fade-in on mount), hoverIntensify(boolean, parent needs `group` class), tint(CSS color string for directional gradient). No gradient rendered without tint.
433
-
434
- ### Chat Primitives (ui/chat/)
435
- Import: `@devalok/shilp-sutra/ui/chat`
436
- - MessageList: children, autoScroll?(true), newMessageCount?(number, shows floating "N new" pill), onScrollToBottom?(), onLoadMore?(), isLoadingMore?(boolean), emptySlot?(ReactNode), headerSlot?(ReactNode). role="log" aria-live="polite".
437
- - Message: COMPOUND variant('flat'|'bubble') placement('start'|'end') highlight?('mention'|'internal') grouped?(boolean) deleted?(boolean) deletedText?(string). Sub-parts: Message.Avatar(src?, fallback?, icon?, size?('sm'|'md')), Message.Content, Message.Author(name, badge?, timestamp?, formattedTimestamp?, timestampFormat?), Message.Body, Message.EditableBody(content, onSave, onCancel?, canEdit?, renderContent?), Message.Reactions(reactions[{emoji,count,reacted}], onReact), Message.Actions(children, delay?), Message.Action(icon, label, onClick, variant?('default'|'danger'))
438
- - SystemMessage: variant('event'|'alert') icon?(ReactNode) timestamp?(string) children
439
- - MessageInput: onSubmit(text=>void), placeholder?, disabled?, isStreaming?(boolean, shows stop button), onCancel?(), leadingSlot?, trailingSlot?, disclaimer?(string), sendIcon?(ReactNode). Enter to send, Shift+Enter for newline.
440
- - DateSeparator: date(Date|string), format?((date)=>string). Shows "Today", "Yesterday", or "Mar 15".
441
- - UnreadSeparator: label?('NEW'), count?(number). Accent-colored horizontal rule.
442
- - TypingIndicator: users({name, image?}[]). Shows animated bouncing dots + "Alice is typing..." / "Alice and Bob are typing..." / "Several people are typing..."
443
-
444
- ### Overlays
445
- - Dialog > DialogTrigger; DialogContent > DialogHeader > DialogTitle, DialogDescription; [content]; DialogFooter
446
- - AlertDialog > AlertDialogTrigger; AlertDialogContent > AlertDialogHeader > AlertDialogTitle; AlertDialogFooter > AlertDialogCancel, AlertDialogAction
447
- - Sheet: side(top|bottom|left|right) > SheetTrigger; SheetContent > SheetHeader > SheetTitle; [content]; SheetFooter
448
- - Popover > PopoverTrigger; PopoverContent
449
- - Tooltip: auto-wraps with <TooltipProvider> (no manual provider needed) > Tooltip > TooltipTrigger; TooltipContent
450
- - HoverCard > HoverCardTrigger; HoverCardContent
451
- - Collapsible > CollapsibleTrigger; CollapsibleContent
452
-
453
- ### Navigation
454
- - Tabs > TabsList(variant: line|contained) > TabsTrigger(value); TabsContent(value)variant propagates via context
455
- - Accordion(type: single|multiple) > AccordionItem(value) > AccordionTrigger(chevronPosition?: 'left'|'right', default 'right'); AccordionContent
456
- - Breadcrumb > BreadcrumbList > BreadcrumbItem > BreadcrumbLink | BreadcrumbPage; BreadcrumbSeparator
457
- - PaginationRoot > PaginationContent > PaginationItem > PaginationLink(isActive) | PaginationPrevious | PaginationNext | PaginationEllipsis
458
- - DropdownMenu > DropdownMenuTrigger; DropdownMenuContent > DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuRadioGroup > DropdownMenuRadioItem
459
- - ContextMenu > ContextMenuTrigger (right-click); ContextMenuContent > same sub-components as DropdownMenu
460
- - Menubar > MenubarMenu > MenubarTrigger; MenubarContent > same sub-components
461
- - NavigationMenu > NavigationMenuList > NavigationMenuItem > NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink
462
-
463
- ### Layout
464
- - Stack: direction(vertical|horizontal) gap(SpacingToken|number) align, justify, wrap
465
- - Container: maxWidth(default|body|full)
466
- - Separator: orientation(horizontal|vertical)
467
- - Sidebar: complex see llms-full.txt for complete tree
468
-
469
- ### Form Pattern
470
- - FormField: state(FormHelperState) > Label + Input + FormHelperText. Type: FormHelperState = 'helper' | 'error' | 'warning' | 'success'
471
- - useFormField() hook returns { state, helperTextId, required } from FormField context
472
- - Wire accessibility: const { state, helperTextId } = useFormField(); then aria-describedby={helperTextId}, aria-invalid={state === 'error'}
473
- - Input/Textarea auto-wire from FormField context (no manual hookup needed). Explicit props override.
474
-
475
- ### Composed Components
476
- - ConfirmDialog: open, onOpenChange, title, description, onConfirm + confirmText, cancelText, color(default|error), loading
477
- - PageHeader: title, subtitle, breadcrumbs[], actions(ReactNode)
478
- - AvatarGroup: users(AvatarUser[]), max?(number), size?(xs|sm|md|lg|xl), showTooltip?, borderColor?('surface-base'|'surface-raised'), onOverflowClick?(), renderAvatar?((user,index)=>ReactNode), expandDirection?('left'|'right'), expandAmount?('compact'|'default'|'wide'). Type: AvatarUser = { name, image?, ring?, indicator?('lead'|'admin'|ReactNode) }. GPU-composited hover expand via translateX. Use expandDirection="left" for right-aligned groups. indicator renders a small dot on avatar: 'lead'=warning-9, 'admin'=accent-9, or custom ReactNode.
479
- - StatusBadge: DISCRIMINATED UNION — pass status OR color, not both. status(active|pending|approved|rejected|completed|blocked|in-progress|review|cancelled|draft) color(success|warning|error|info|neutral) size(sm|md) onClick?(() => void, renders as button with auto chevron-down icon) icon?(ReactNode, custom trailing icon)
480
- - ContentCard: variant(default|outline|ghost) padding(default|compact|spacious|none)
481
- - EmptyState: icon(ReactNode or ComponentType), title(required), description, action(ReactNode), compact
482
- - PriorityIndicator: priority(Priority) display(compact|full). Type: Priority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' | 'low' | 'medium' | 'high' | 'urgent'
483
- - SimpleTooltip: wraps Tooltip compound into single component
484
- - DatePicker, DateRangePicker, DateTimePicker
485
- - TimePicker: standalone time selector — value(Date|null), onChange, format('12h'|'24h'), minuteStep, showSeconds, disabled
486
- - CalendarGrid: low-level calendar widget currentMonth, selected, rangeStart/End, onSelect, onMonthChange, events(CalendarEvent[])
487
- - YearPicker: decade year grid — currentYear, selectedYear, onYearSelect, minDate, maxDate
488
- - MonthPicker: month grid — currentYear, selectedMonth(0-11), onMonthSelect, minDate, maxDate
489
- - Presets: date range quick-select buttons presets(PresetKey[]), onSelect(start, end). Keys: today, yesterday, last7days, last30days, thisMonth, lastMonth, thisYear
490
- - useCalendar: hook for calendar month state returns currentMonth, goToPreviousMonth, goToNextMonth, goToMonth, goToYear
491
- - (UploadProgress REMOVED upload tracking is now built into toast.upload())
492
- - RichTextEditor: Tiptap editor — bold/italic/underline/strike/highlight, headings, blockquote, lists (bullet/ordered/task), code, links, images (paste/drop/upload), file attachments, @mentions, emoji picker + :shortcode:, text alignment, HR. Props: onImageUpload?, onFileUpload?, mentions?, onMentionSearch?, onMentionSelect?(item: MentionItem), emojiSet?(native|apple|google|twitter|facebook)
493
- - RichTextViewer: read-only renderer for RichTextEditor HTML content (renders all above content types)
494
- - RichChatInput: compact rich text chat input for AI/messaging. Output: RichChatInputMessage { html, plainText, attachments?, voiceNote? }. Variants: compact(default), expanded, minimal, inline. Key props: onSubmit(msg), onSchedule?(msg,date), emojiSet?, mentions?, slashCommands?, onFileUpload?, onImageUpload?, onVoiceRecord?, replyTo?, toolbar?(bool|items[]|ReactNode), actionButton?(ReactNode|false), enterBehavior?(send|newline), maxLength?, isStreaming?, onCancel?, disclaimer?, sendOptions?, leadingSlot?, trailingSlot?. Composable toolbar primitives exported: ToolbarButton, ToolbarDivider, ToolbarGroup, BoldButton, ItalicButton, etc.
495
- - ActivityFeed: items(ActivityItem[]), onLoadMore, loading, hasMore, emptyState, compact, maxInitialItems, groupBy?('time'|'none'), groupLabels?({ today, yesterday, thisWeek, older }), renderItem?((item, index) => ReactNode|undefined, custom renderer per item — return ReactNode for custom, undefined for default). Type: ActivityItem = { id, actor?, action, timestamp, icon?, color?, detail? }. Utility: groupItemsByTime(items, labels) exported.
496
- - CommandPalette: open, defaultOpen, onOpenChange (controlled/uncontrolled), keybinding(string|string[]|false), maxHeight, emptyState(ReactNode), footerHints(FooterHint[]|false). CommandItem: label(string|ReactNode), description(string|ReactNode), renderLabel(query=>ReactNode), filterValue(string), shortcut(rendered as keycap badges). Keyboard shortcuts rendered per-key with platform-aware Cmd/Ctrl. Reduced-motion support via MotionProvider.
497
- - MemberPicker: thin wrapper around MultiSelectPopover with Avatar rendering
498
- - MultiSelectPopover: items/groups, value, onValueChange, searchPlaceholder, onSearch?(async), renderItem?, emptyMessage, maxSelections. Generic multi-select popover with search + checkmarks.
499
- - FilterBar: searchValue, onSearchChange, onClearAll, size(xs|sm|md). Children: FilterSelect(label, value, onValueChange, options), FilterMultiSelect(label, value, onValueChange, options). Size propagates via context.
500
- - InlineEdit: value, onSave(string=>void|Promise), placeholder, textClassName, inputSize(xs|sm|md), multiline, readOnly, maxLength, saving. Click-to-edit text → input transition.
501
- - FormSection: title, description?, collapsible?, defaultOpen?. Titled form section with separator, optional collapse.
502
- - BulkActionBar: show, count, onClearSelection, actions[{label,icon?,onClick,color?,disabled?}]. Fixed bottom floating bar for multi-select contexts.
503
- - DeadlineIndicator: deadline(Date|string), warningThreshold?(1440min), criticalThreshold?(240min), format(relative|absolute), showIcon. Color transitions: green→yellow→red→overdue.
504
- - MasterDetail: selected, onBack, masterWidth, breakpoint(sm|md|lg). Compound: MasterDetail.List, MasterDetail.Detail, MasterDetail.ListItem(active). Desktop=grid, mobile=stacked with back button.
505
- - ResponsiveOverlay: open, onOpenChange, title, description, breakpoint(sm|md). Dialog on desktop, bottom Sheet on mobile.
506
- - MarkdownViewer: content(string), compact?, allowHtml?(false), linkTarget?('_blank'). Renders markdown with design system tokens.
507
- - EmojiPicker: onSelect(emoji), set?(native|apple|google|twitter|facebook), theme(auto|light|dark). EmojiPickerPopover wraps in Popover. Lazy-loads emoji-mart with set-specific data.
508
- - EmojiNode: TipTap inline atom node for spritesheet emoji rendering. Attrs: id, native, set, x, y. Use createEmojiSuggestion(set) to wire :shortcode: autocomplete. Export: EmojiNode, EmojiNodeAttrs, createEmojiSuggestion.
509
- - FilePreview: url, type?(image|pdf|video|audio|embed), mimeType?, alt?. Auto-detects type. Image zoom, PDF iframe, native video/audio, embed for Figma/YouTube/Loom.
510
- - ErrorDisplay, GlobalLoading
511
- - Loading skeletons: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton
512
- - Page skeletons: DashboardSkeleton, ProjectListSkeleton, TaskDetailSkeleton (no props, server-safe)
513
-
514
- ### Shell Components (app-level layout)
515
- - TopBar: Composition-based. Subcomponents: TopBar.Left, TopBar.Center (optional, triggers grid), TopBar.Right, TopBar.Section(gap: tight|default|loose), TopBar.IconButton(icon, tooltip), TopBar.Title, TopBar.UserMenu(user, onNavigate?, onLogout?, userMenuItems?). Types: TopBarUser = { name, email?, image? }, UserMenuItem = { label, icon?, href?, onClick?, separator?, color?, badge?, disabled? }
516
- - AppSidebar: navigation tree with NavItem[], NavGroup[]. Types: NavItem = { title, href, icon, exact?, badge?, children?, defaultOpen? }, NavSubItem = { title, href, icon?, exact? }, NavGroup = { label, items, action? }, SidebarUser = { name, email?, image?, designation?, role? }
517
-
518
- ### AppSidebar (v0.10.0 additions)
519
- - NavItem.children?: NavSubItem[] — collapsible sub-list with chevron toggle
520
- - NavItem.defaultOpen?: boolean control initial collapsed state
521
- - NavItem.badge?: string | number — badge on nav item (99+ cap for numbers)
522
- - NavGroup.action?: ReactNode action button next to group label
523
- - footer?: SidebarFooterConfigstructured footer with links, version, slot, promo (replaces footerLinks)
524
- - headerSlot?: ReactNode — content between user info and navigation
525
- - preFooterSlot?: ReactNode content between navigation and footer
526
- - renderItem?: (item, defaultRender) => ReactNode | null custom item rendering
527
-
528
- - BottomNavbar: mobile navigation, user is optional. Types: BottomNavItem = { title, href, icon, exact?, badge? }, BottomNavbarUser = { name, role? }
529
- - NotificationCenter: notifications[], onMarkRead, onMarkAllRead, onNavigate, getNotificationRoute?, footerSlot?, emptyState?, headerActions?, popoverClassName?, onDismiss?(id). Types: Notification = { id, title, body?, tier, isRead, createdAt, entityType?, entityId?, projectId?, project?, actions? }, NotificationAction = { label, variant?, onClick }
530
- - NotificationPreferences: preferences[], projects[], onSave, onToggleMute, onUpdateTier, onDelete. Types: NotificationPreference = { id, userId?, projectId, channel, minTier, muted }, NotificationProject = { id, title }
531
- - AppCommandPalette: user, isAdmin, onNavigate, onSearch, searchResults, searchResultGroups(SearchResultGroup[]), isSearching, onSearchResultSelect (when provided, consumer owns routing no internal URL computation), searchResultsLabel(string|((count)=>string)), open, defaultOpen, onOpenChange, keybinding, maxHeight, emptyState, footerHints. Types: SearchResult = { id, title, snippet?, entityType, projectId?, metadata?, icon?(ReactNode), rank?(number), shortcut?(string) }, SearchResultGroup = { label, results: SearchResult[] }, AppCommandPaletteUser = { name, role? }
532
- - LinkProvider: wraps app with router-agnostic Link component component(ForwardRefComponent), children. useLink() hook returns the Link component.
533
-
534
- ### Motion System (Framer Motion)
535
- - Setup: Wrap app root with `<MotionProvider>` from `@devalok/shilp-sutra/motion`. Handles reduced-motion detection globally.
536
- - Import presets: `import { springs, tweens, stagger } from '@devalok/shilp-sutra/motion'`
537
- - Import primitives: `import { MotionFade, MotionScale, MotionPop, MotionSlide, MotionCollapse, MotionStagger, MotionStaggerItem } from '@devalok/shilp-sutra/motion/primitives'`
538
- - Spring presets (spatial: position, scale, size): snappy (buttons/hover), smooth (dialogs/panels), bouncy (toasts/pop-ins), gentle (collapse/expand)
539
- - Tween presets (non-spatial: opacity, color): fade (opacity enter/exit), colorShift (hover color/bg)
540
- - All primitives take `show: boolean` to control mount/unmount via AnimatePresence
541
- - MotionSlide: additional `direction` prop (up|down|left|right)
542
- - MotionStagger + MotionStaggerItem: orchestrated stagger with configurable `delay` (default 0.04s)
543
- - All primitives support `layout`, `layoutId`, `whileInView`, `viewportOnce`, `preset` props
544
- - useMotion() hook returns { springs, tweens, reducedMotion: boolean }
545
- - Old Fade/Collapse/Grow/Slide from @devalok/shilp-sutra/ui/transitions are REMOVED use Motion* equivalents
546
-
547
- ### Hooks
548
- - toast: imperative API import { toast } from '@devalok/shilp-sutra/ui/toast'. Methods: toast.success/error/warning/info/loading/message/undo/promise/upload/custom/dismiss. useToast() is deprecated.
549
- - useColorMode(): returns { colorMode, setColorMode, toggleColorMode }
550
- - useMobile(): returns boolean (true if viewport < 768px)
551
- - useLink(): returns router-agnostic Link component from LinkProvider context (shell/link-context)
552
-
553
- ## Server-Safe Components (no "use client")
554
-
555
- These can be imported directly in Next.js Server Components:
556
- - UI: Text, Skeleton, Stack, Container, Table (and sub-components), Code, VisuallyHidden
557
- - Composed: ContentCard, PageHeader, LoadingSkeleton, PageSkeletons, PriorityIndicator
558
-
559
- Use per-component imports for server components:
560
- import { Text } from '@devalok/shilp-sutra/ui/text'
561
- import { PageHeader } from '@devalok/shilp-sutra/composed/page-header'
562
-
563
- DO NOT use barrel imports in Server Components they include "use client" components.
564
-
565
- ## Common Mistakes -- DO NOT
566
-
567
- - DO NOT use variant="destructive" use color="error"
568
- - DO NOT use size="default" use size="md" (or sm, lg)
569
- - DO NOT put size on <Select> put it on <SelectTrigger size="md">
570
- - DO NOT use <Chip> Chip is deprecated. Use <Badge onClick={...}> instead
571
- - DO NOT use useToast() hook — use import { toast } from '@devalok/shilp-sutra/ui/toast' (imperative)
572
- - DO NOT use toast({ title, color }) object syntax use toast.success('message'), toast.error('message'), etc.
573
- - DO NOT call toast() without <Toaster /> mounted at your layout root
574
- - DO NOT use <Alert><AlertTitle>...</AlertTitle></Alert> use <Alert title="..." />
575
- - DO NOT import from barrel in Next.js Server Componentsuse per-component imports
576
- - DO NOT use variant="secondary" on Buttonuse variant="outline" or variant="ghost"
577
- - DO NOT use variant="default" on Button — use variant="solid" (deprecated alias, still works)
578
- - DO NOT use variant="destructive" on Button — use variant="solid" color="error" (deprecated alias, still works)
579
- - DO NOT use color="default" on Button use color="accent" (deprecated alias, still works)
580
- - DO NOT put variant on individual TabsTrigger put it on TabsList (propagates via context)
1
+ # @devalok/shilp-sutra
2
+
3
+ > Radix UI + Tailwind CSS + CVA design system for Devalok apps.
4
+ > Built on the same primitives as shadcn/ui but with key API differences.
5
+ > Read this file BEFORE writing any UI code. Do NOT guess from shadcn/ui knowledge.
6
+
7
+ ## NEW (v0.36.0)
8
+
9
+ - **Forced-colors (Windows high-contrast) support.** Every semantic color token remaps to system keywords (`Canvas`, `CanvasText`, `Highlight`, `HighlightText`, `LinkText`, `GrayText`, `Mark`, `ButtonText`, `VisitedText`) under `@media (forced-colors: active)`. Focus ring forced via `outline: 2px solid Highlight`, interactive elements get visible borders, decorative grain + skeleton shimmer suppressed. Zero runtime impact when inactive.
10
+ - **FormField auto-wires Label Input via context.** `<FormField>` now publishes an `inputId`; `<Label>` reads `htmlFor` and `<Input>` reads `id` from context unless either is explicit on the child. Drops the need to hand-generate matching ids.
11
+ - **Toast error assertive a11y.** `toast.error()` renders `role="alert"` + `aria-live="assertive"` + `aria-atomic="true"` so screen readers interrupt speech. Other types remain `role="status"` + polite.
12
+ - **Dev-mode missing-`<Toaster />` warning.** `toast()` called without a mounted `Toaster` logs a one-time console warning in dev. Production-silent.
13
+ - **Design default:** prefer `variant="soft"` over `variant="outline"` for non-primary Button actions. Captured in this file's Component Quick Reference and CLAUDE.md. Outline remains valid on colored bg, toolbars, primary-adjacent hierarchy.
14
+
15
+ ## FIXES (v0.36.0)
16
+
17
+ - **Alert solid body text illegible.** Was forcing `text-surface-fg-muted` (grey) on top of step-9 saturated bgs and using `text-accent-fg` for warning (white-on-amber failed contrast). Now per-color `text-{info|success|warning|error}-fg` on the root + drops the muted override on solid/filled variants.
18
+ - **Button processing ants drifting outside the button.** Overlay SVG now sized to measured `btnEl.offsetWidth/offsetHeight` with a `ResizeObserver` — no more `calc(100% - 2px)` against the wrapper diverging from the button during width transitions / async-feedback icon swaps.
19
+ - **Per-color `-fg` tokens on non-accent status backgrounds.** Button async success/error, BottomNavbar + TopBar error badges now use `text-error-fg` / `text-success-fg` (not `text-accent-fg`) — brand-swap safe.
20
+ - **Documentation truth fixes.** 6 `data-table-*.md` shipped literal bash template headers (`# $(echo $f | sed ...)`) in `llms-full.txt`; fixed. Button Props block had fake `variant="default"` / `"destructive"` alias claims (removed in 0.32.0); stripped. Badge `truncate` prop added to Props block. `packages/core/CHANGELOG.md` reconstructed from 0.33.x → 0.35.0. README component counts + tech stack updated.
21
+
22
+ ## BREAKING CHANGES (v0.35.0 World-Class Audit)
23
+
24
+ - **Dark mode colors:** Solid variant backgrounds darkened for WCAG AA. Step-9 L=0.63→0.54. Warning amber L=0.72→0.57. All solid buttons/badges are noticeably darker in dark mode.
25
+ - **Responsive typography:** Heading sizes 3xl–6xl use `clamp()` for fluid scaling. Headings shrink on mobile.
26
+ - **Body letter spacing:** body-lg (-0.01em), body-md (0em), body-sm (+0.01em), body-xs (+0.02em). Was all -0.02em.
27
+ - **surface-fg-subtle:** Darkened from neutral-8 to neutral-9 in light mode. Tertiary text is more visible.
28
+ - **MessageList:** `isLoadingMore` renamed to `loadingMore`.
29
+ - **AppCommandPalette:** Default Karm routes removed. Use `CommandRegistryProvider` for page registration. `SearchResult` type adds optional `href` field.
30
+ - **NumberInput:** Shape changed from pill to rounded rectangle.
31
+ - **Alert:** `variant="filled"` deprecated use `"solid"` (alias still works).
32
+ - **SegmentedControl:** `variant="accent"` deprecated use `"solid"` (alias still works).
33
+ - **Dependencies:** `@floating-ui/dom`, `@tiptap/*`, `prosemirror-state` moved to devDeps (bundled; consumers no longer install them).
34
+
35
+ ## NEW (v0.35.0)
36
+
37
+ - **Size props:** Combobox (xs/sm/md/lg), NumberInput (xs/sm/md/lg + state), Slider (sm/md/lg + color), InputOTP (sm/md/lg + state).
38
+ - **Toggle color:** `color` prop on Toggle/ToggleGroup (accent/error/success/neutral).
39
+ - **Tabs vertical:** `orientation="vertical"` for side-nav layout.
40
+ - **Stepper clickable:** `onStepClick` callback for navigating to completed steps.
41
+ - **AlertDialog responsive:** `responsive` prop for mobile bottom-sheet.
42
+ - **Typography:** `code`, `label-plain-lg/md/sm` variants. Tailwind composite utilities: `text-heading-xl`, `text-body-md`, `text-code`, etc.
43
+ - **Layout spacing:** `--spacing-page-x` (responsive 16→24→40px), `--spacing-section-gap`, `--spacing-card-gap`.
44
+ - **Link colors:** `--color-link`, `--color-link-hover`, `--color-link-visited` tokens.
45
+ - **useFormField:** Now wired into Select, Combobox, Autocomplete, Checkbox, Radio, Switch, Slider, InputOTP.
46
+ - **Chart a11y:** Keyboard tooltip access on BarChart/LineChart. `ariaDescription` on ChartContainer.
47
+ - **Dev warnings:** Token-missing CSS detection + MotionProvider hint (dev mode only).
48
+
49
+ ## BREAKING CHANGES (v0.33.x — Tailwind 4 + Toolchain)
50
+
51
+ - **Tailwind CSS 3 → 4:** `outline-none` → `outline-hidden`, `rounded-sm` → `rounded-xs`, `backdrop-blur-sm` → `backdrop-blur-xs`, `!prefix` → `suffix!` important syntax. Consumers using our preset: add `@import "tailwindcss"` + `@config` to your CSS, replace `darkMode: 'class'` with `@variant dark (&:is(.dark *))` in CSS. Peer dep accepts both `^3.4.0 || ^4.0.0`.
52
+ - **tailwind-merge 3.0 3.5:** Required for TW4 class recognition.
53
+ - **TypeScript 5.7 6.0.2:** `types` defaults to `[]` in TS6. Add explicit `"types": ["node"]` to tsconfig if needed.
54
+ - **ESLint 9 10:** Config file lookup starts from linted file directory (not CWD). Verify monorepo configs.
55
+ - **react-zoom-pan-pinch 3 4:** `onTransformed` renamed to `onTransform`. Peer dep `^3.0.0 || ^4.0.0`.
56
+
57
+ ## CHANGES (v0.33.1 / v0.33.2)
58
+
59
+ - Bumped: React 19.2.5, Storybook 10.3.5, Vitest 4.1.4, framer-motion 12.38, @floating-ui/dom 1.7.6, @tabler/icons-react 3.41.1, esbuild 0.28, jsdom 29, Playwright 1.59.1, PostCSS 8.5.9, Prettier 3.8.2, vite-plugin-dts 4.5.4.
60
+
61
+ ## BREAKING CHANGES (v0.33.0)
62
+
63
+ - **EmojiSuggestion:** Named export removed. Use `createEmojiSuggestion(set?)` factory. Default: `createEmojiSuggestion()` (native set).
64
+ - **Emoji HTML output:** Non-native `emojiSet` renders emoji as `<span data-emoji-id="..." data-emoji-set="..." role="img">native</span>` nodes, not raw Unicode. `plainText` still returns Unicode.
65
+
66
+ ## CHANGES (v0.33.0)
67
+
68
+ - **RichChatInput v2** — Complete rewrite. Structured output (`html`, `plainText`, `attachments?`, `voiceNote?`). Zone architecture. 4 variants: `compact` (default), `expanded`, `minimal`, `inline`. Props: `onSubmit`, `onSchedule?(msg, date)`, `mentions?`, `slashCommands?`, `onFileUpload?`, `onImageUpload?`, `onVoiceRecord?`, `onTranscribe?`, `replyTo?`, `toolbar?`, `emojiSet?`, `actionButton?`, `enterBehavior?`, `maxLength?`, `isStreaming?`, `disclaimer?`, `sendOptions?`, `leadingSlot?`, `trailingSlot?`.
69
+ - **Custom EmojiNode** — TipTap inline atom node. Renders emoji via spritesheet images for consistent Apple/Google/Twitter/Facebook art styles. `emojiSet` prop on `EmojiPicker`, `EmojiPickerPopover`, `RichChatInput`, `RichTextEditor`. Sets: `native` (default), `apple`, `google`, `twitter`, `facebook`.
70
+ - **SplitButton** (`ui/`) — `[Action | ▼]` button with dropdown. Props: `variant(solid|soft|outline)`, `color`, `size`, `triggerSide(left|right)`, `triggerWidth`, `placement` (Floating UI), `dropdownContent`. Proper ARIA: `role="group"`, `aria-haspopup`, `aria-expanded`.
71
+ - **Schedule Send** — `onSchedule?(msg, date)` on RichChatInput. Smart presets (time-of-day aware) + DateTimePicker. Banner shows scheduled time. Send button morphs to SplitButton.
72
+ - **ButtonGroup rebuild** — Compound component pattern. Button reads position from context, applies radius inline. New props: `disabled` (propagates), `attached` (true/false), `fullWidth`. Tonal dividers for solid/soft/ghost variants. Focus z-index isolation.
73
+ - **TipTap v2 → v3** — `useEditorState`, `immediatelyRender: false` (SSR-safe), `ListKit`. Fixes React 19 `removeChild` crash.
74
+ - **Composable toolbar** — Exported: `ToolbarButton`, `ToolbarDivider`, `ToolbarGroup`, `BoldButton`, `ItalicButton`, `UnderlineButton`, `StrikeButton`, `HighlightButton`, `CodeButton`, `BulletListButton`, `OrderedListButton`, `BlockquoteButton`, `LinkButton`, `EmojiButton`.
75
+ - **Button `disabled`**Now inherited from ButtonGroup context.
76
+
77
+ ## BREAKING CHANGES (v0.32.0)
78
+
79
+ - **Button:** `variant="default"` removed (use `"solid"`), `variant="destructive"` removed (use `variant="solid" color="error"`), `color="default"` removed (use `"accent"`).
80
+ - **Chip:** Removed. Use `Badge` instead.
81
+ - **SegmentedControl:** Rewritten. `variant="filled"` `"accent"`, `variant="tonal"` `"default"`. `SegmentedControlItem` no longer exported. Legacy sizes `small`/`medium`/`big` removed.
82
+ - **TopBar:** Now renders as `<header>` (was `<div>`).
83
+ - **Sidebar:** Now renders as `<aside>` (was `<div>`).
84
+ - **InfoBlock:** `role="status"` (was `role="alert"`).
85
+ - **Border tokens:** One step darker system-wide.
86
+ - **Dark mode button text:** Pure white `neutral-0` (#fff) on brand-colored buttons.
87
+ - **BottomNavbar:** Bottom padding is now `pb-safe` (safe-area-inset).
88
+ - **ResponsiveOverlay:** Deprecated. Use Dialog or Sheet directly.
89
+ - **iOS inputs:** Forced to `font-size: max(16px, 1em)` on mobile via preset.
90
+
91
+ ## CHANGES (v0.32.0)
92
+
93
+ - **Mobile Responsiveness:**
94
+ - Dialog auto-fullScreens on mobile (<768px). Opt out: `<DialogContent responsive={false}>`.
95
+ - Sheet auto-bottom with swipe-to-dismiss on mobile. Drag handle, 30% threshold. Opt out: `<SheetContent responsive={false}>`.
96
+ - Popover renders as bottom drawer on mobile automatically.
97
+ - `.touch-target` utility — 44px invisible hit area for Apple HIG compliance.
98
+ - `.pt-safe`, `.pb-safe`, `.pl-safe`, `.pr-safe`, `.p-safe` — safe area inset utilities.
99
+ - `useTouchDevice()` — detects touch capability (vs viewport width).
100
+ - `useViewportHeight()` — dynamic viewport height via Visual Viewport API.
101
+ - Sidebar has swipe-to-close on mobile.
102
+ - **DataTable `mobileView="card"`** — Rows render as stacked cards below 640px. First column = card title, rest = label-value pairs.
103
+ - **DataTable `aria-sort`**Sortable column headers include `aria-sort`.
104
+ - **Charts `ariaLabel` prop** — Configurable screen reader label on all chart components.
105
+ - **SegmentedControl** Redesigned: `variant="default"` (white pill + shadow-sm) | `variant="accent"` (brand pill). Inset radius, snappy spring animation.
106
+ - **`--shadow-kbd` token** Keyboard shortcut badge shadow. Use `shadow-kbd` utility.
107
+ - **Checkbox/Radio `size` prop** — `sm | md (default) | lg`.
108
+
109
+ ## CHANGES (v0.31.0)
110
+ - **Alert `size` prop** `sm | md (default) | lg`. Scales padding, gap, icon, text.
111
+ - **Card `color` prop** `default | accent | error | success | warning | info | neutral`. Semantic border color.
112
+ - **Card `size` prop** `sm | md (default) | lg`. Propagated to sub-components via context.
113
+ - **Select `variant` prop** `default | outline | ghost` on SelectTrigger.
114
+ - **Select `color` prop** — `default | error | success | warning` on SelectTrigger. Sets `aria-invalid` when error.
115
+ - **Tabs `color` prop** — `accent (default) | neutral`. Affects line variant indicator.
116
+ - **Tabs `size` prop** — `sm | md (default) | lg`. Scales height and padding.
117
+ - **Badge `truncate` prop** Enables ellipsis truncation. Combine with fixed width or `maxWidth`.
118
+ - **New subpath exports** — `./ui/icon`, `./ui/icon-context`, `./ui/icon-group`, `./ui/badge-group`, `./ui/badge-indicator`, `./ui/devalok-grain`, `./ai/types`.
119
+ - **Server-safe fix** — `empty-state`, `priority-indicator`, `status-badge` now correctly get `"use client"` (were incorrectly omitted).
120
+ - **Server-safe detection** — Hardcoded allowlist replaced with `// @server-safe` source annotations.
121
+
122
+ ## CHANGES (v0.30.0)
123
+ - **RichTextEditor `toolbar` prop** `toolbar?: ToolbarItem[]` whitelist of toolbar items to display. Omit to show all (default). `ToolbarItem` type exported.
124
+ - **`@devalok/shilp-sutra-karm` removed**Domain components moved to Karm app repo. npm package deprecated.
125
+ - **Warning dark mode fixed** — `warning-*` tokens now have proper dark mode values (higher chroma than category amber).
126
+ - **tailwind-merge fix** — All `text-ds-*` sizes now correctly registered. `cn('text-ds-lg', 'text-accent-11')` no longer strips the color.
127
+ - **AvatarGroup fixes** Overflow badge text matches avatar size, indicator dots scale with size, aria-labels added.
128
+
129
+ ## BREAKING CHANGES (v0.27.0Externalized Dependencies)
130
+
131
+ FilePreview and MarkdownViewer dependencies are now **external** (not bundled).
132
+ Install them if you use these components:
133
+
134
+ ```bash
135
+ pnpm add react-pdf react-zoom-pan-pinch react-syntax-highlighter
136
+ ```
137
+
138
+ These are optional peerDependencies — consumers who don't use FilePreview or MarkdownViewer are unaffected.
139
+
140
+ **Next.js optimization:** Add to your `next.config.js`:
141
+ ```js
142
+ optimizePackageImports: ['@devalok/shilp-sutra']
143
+ ```
144
+
145
+ ## BREAKING CHANGES (v0.23.0 — Semantic Surface & Shadow Tokens)
146
+
147
+ **Surface tokens renamed:** Numeric `surface-1..4` replaced with semantic names.
148
+ | Old | New | Usage |
149
+ |-----|-----|-------|
150
+ | `bg-surface-1` | `bg-surface-base` | Page background |
151
+ | `bg-surface-1` | `bg-surface-sunken` | Shell chrome (sidebar, topbar), board columns |
152
+ | `bg-surface-1` | `bg-surface-overlay` | Dialogs, popovers, dropdowns, inputs |
153
+ | `bg-surface-2` | `bg-surface-raised` | Cards, widgets, panels |
154
+ | `bg-surface-3` | `bg-surface-raised-hover` | Hover states on raised elements |
155
+ | `bg-surface-4` | `bg-surface-raised-active` | Active/pressed states |
156
+
157
+ Same pattern for `border-surface-*`, `text-surface-*`, `ring-surface-*`.
158
+
159
+ **Shadow tokens renamed:** Numeric `shadow-01..05` replaced with semantic names.
160
+ | Old | New |
161
+ |-----|-----|
162
+ | `shadow-01` | `shadow-raised` |
163
+ | `shadow-02` | `shadow-raised-hover` |
164
+ | `shadow-03` | `shadow-floating` |
165
+ | `shadow-04` | `shadow-overlay` |
166
+ | `shadow-05` | (removed was unused) |
167
+
168
+ **New surface tokens:**
169
+ - `bg-surface-sunken` — recessed areas (sidebar, board columns, segmented track)
170
+ - `bg-surface-overlay` — floating elements (dialogs, popovers, inputs). Diverges from base in dark mode.
171
+ - `bg-surface-inverted` / `text-surface-inverted-fg` — tooltips, inverted badges
172
+ - `bg-surface-disabled` / `text-surface-fg-disabled` — disabled elements
173
+ - `border-surface-border-subtle` hairline dividers
174
+ - `bg-backdrop` dialog/sheet backdrop overlay
175
+
176
+ **New shadow tokens:**
177
+ - `shadow-glow` — selection/focus accent glow
178
+ - `shadow-inset` toggle/segmented track deboss
179
+ - `shadow-ring` / `shadow-ring-sm` — focus ring / subtle separator
180
+
181
+ **Hard rule: never combine explicit border + shadow.** Shadows include a 1px ring layer. Adding a CSS border creates a 2px edge. Use shadow OR border, never both.
182
+
183
+ **Breaking:** Old numeric aliases (`--color-surface-1..4`, `--shadow-01..05`, Tailwind `bg-surface-1..4`, `shadow-01..05`) have been removed. Use the semantic names listed above.
184
+
185
+ **Component Decision Matrix:**
186
+ | Building... | Surface | Shadow |
187
+ |-------------|---------|--------|
188
+ | Page/layout | `surface-base` | none |
189
+ | Shell (sidebar/topbar) | `surface-sunken` | `shadow-raised` |
190
+ | Card/widget/panel | `surface-raised` | `shadow-raised` |
191
+ | Card hover | `surface-raised` | `shadow-raised-hover` |
192
+ | Board column/well | `surface-sunken` | none |
193
+ | Popover/menu/dropdown | `surface-overlay` | `shadow-floating` |
194
+ | Dialog/modal/sheet | `surface-overlay` | `shadow-overlay` |
195
+ | Tooltip | `surface-inverted` | `shadow-floating` |
196
+ | Toast | `surface-overlay` | `shadow-floating` |
197
+ | Input (rest) | `surface-overlay` | none |
198
+ | Input (focus) | `surface-overlay` | `shadow-ring` |
199
+ | Button (solid) | accent colors | `shadow-raised` |
200
+ | Button (disabled) | `surface-disabled` | none |
201
+ | Segmented track | `surface-sunken` | `shadow-inset` |
202
+ | Selected item | current surface | `shadow-glow` |
203
+
204
+ ## BREAKING CHANGES (v0.18.0 Framer Motion + OKLCH)
205
+
206
+ **New runtime dependency:** `framer-motion@^12.36.0` (bundled). Karm consumers must install `framer-motion@^12.0.0` as peer dep.
207
+
208
+ **Transitions removed:** `Fade`, `Collapse`, `Grow`, `Slide` from `./ui/transitions` no longer exist. Use `MotionFade`, `MotionCollapse`, `MotionSlide` from `@devalok/shilp-sutra/motion/primitives`.
209
+
210
+ **CSS keyframe animations removed:** 18 keyframes (`fade-in`, `fade-out`, `slide-up`, `scale-in`, etc.) and their `animate-*` utilities removed from Tailwind preset. Use motion primitives instead.
211
+
212
+ **`useReducedMotion()` removed:** Use `<MotionProvider reducedMotion="user">` at app root.
213
+
214
+ **New motion system:**
215
+ - `import { MotionProvider, springs, tweens } from '@devalok/shilp-sutra/motion'`
216
+ - `import { MotionFade, MotionCollapse, MotionSlide, MotionPop, MotionScale, MotionStagger } from '@devalok/shilp-sutra/motion/primitives'`
217
+ - Springs: `springs.snappy`, `springs.smooth`, `springs.bouncy`, `springs.gentle`
218
+ - Tweens: `tweens.fade`, `tweens.colorShift`
219
+
220
+ **Spinner v2:** New props `state?: 'spinning' | 'success' | 'error'`, `variant?: 'filled' | 'bare'`, `delay?: number`, `onComplete?: () => void`
221
+
222
+ **Button `onClickAsync`:** New prop `onClickAsync?: (e) => Promise<void>` — auto-manages loading success/erroridle states. `asyncFeedbackDuration?: number` (default 1500ms).
223
+
224
+ **Server safety changes:** EmptyState, StatusBadge, PriorityIndicator, Spinner are NOT server-safe (they use Framer Motion). Do NOT import from RSC.
225
+
226
+ **Build:** `framer-motion` and `sonner` moved from `dependencies` to `devDependencies` (bundled at build time — no consumer install needed for core).
227
+
228
+ **New APIs in v0.18.0:**
229
+ - Combobox: `accessibleLabel?: string` custom aria-label for trigger (falls back to placeholder)
230
+ - Slider: multi-thumb support — pass array `defaultValue={[25, 75]}` for range sliders
231
+
232
+ ## CHANGES (v0.16.0)
233
+ - **DataTable server-side features**: `onSort` callback (manual sorting), `pagination` prop (server-side pagination with page/total/onPageChange), `selectedIds` + `selectableFilter` (controlled selection), `loading` shimmer, `emptyState` ReactNode, `singleExpand`, `stickyHeader`, `onRowClick`, `bulkActions` floating bar
234
+ - **DataTable display**: `density?: 'compact' | 'standard' | 'comfortable'` (compact=4px padding, standard=16px, comfortable=32px). `toolbar?: boolean` (column visibility + density + export controls). Column `meta: { align: 'right' }` for numeric columns (auto-applies text-right tabular-nums). Column `meta: { hideBelow: 'md' }` for responsive column hiding (hidden below breakpoint). `selectableFilter?: (row) => boolean` to disable selection on certain rows (e.g. only PENDING rows selectable).
235
+ - **ActivityFeed**: New composed component — `@devalok/shilp-sutra/composed/activity-feed` — vertical timeline with colored dots, actor avatars, expandable detail, compact mode, load more
236
+ - EmptyState: `iconSize?: 'sm' | 'md' | 'lg'` prop for icon dimension control
237
+ - BottomNavbar: `badge?: number` on BottomNavItem for notification counts (99+ cap)
238
+ - AppSidebar: `preFooterClassName?: string` for scrollable preFooterSlot
239
+
240
+ ## CHANGES (v0.15.0)
241
+ - **Input font standardization**: All input sizes (sm, md, lg) now use text-ds-md (14px). Previously lg used text-ds-lg (18px). Affects Input, Select, SearchInput, Textarea.
242
+ - CommandPalette: Staggered slide-up animations for items, fade-in for groups, scale-in search icon, active item color transitions
243
+
244
+ ## CHANGES (v0.14.0)
245
+ - **BREAKING z-index**: Select, Combobox, Autocomplete, DropdownMenu, ContextMenu, Menubar, HoverCard promoted from z-dropdown (1000) to z-popover (1400). Fixes dropdowns rendering behind Sheet/Dialog. If you had custom z-index overrides (e.g. `[data-radix-popper-content-wrapper] { z-index: 1400 !important }`) you can now remove them.
246
+ - TabsTrigger: Added gap-ds-02 (4px) between icon and label
247
+ - AppSidebar: footer.version now accepts string | { label, href } for clickable version links
248
+
249
+ ## CHANGES (v0.13.0)
250
+ - EmptyState: icon prop now accepts ComponentType (e.g. Tabler icon references) in addition to ReactNode
251
+ - NotificationCenter: Notification.actions?: NotificationAction[] inline action buttons (Approve/Deny) per notification
252
+ - NotificationCenter: Tier dot now doubles as read/unread marker; separate unread dot removed
253
+ - AppSidebar: footer.promo?: SidebarPromo dismissable promo banner with icon, text, action button
254
+ - AppSidebar: Footer links + version render on same line with · dividers
255
+ - Collapsible: Now uses height-based expand/collapse animation (animate-collapsible-down/up)
256
+ - Tailwind preset: 4 new keyframes + utilities — accordion-down, accordion-up, collapsible-down, collapsible-up
257
+
258
+ ## CHANGES (v0.12.0)
259
+ - Input: Softer resting border (border-subtle instead of border), subtler focus ring (ring-1 ring-focus/50 instead of ring-2 ring-focus)
260
+ - Tailwind preset: 9 animation keyframes + utilities (fade-in, fade-out, slide-up, slide-right, scale-in, scale-out, glow-pulse, scale-bounce, lift)
261
+ - Tailwind preset: Stagger plugins — .delay-stagger (30ms × --stagger-index), .delay-stagger-50 (50ms × --stagger-index)
262
+
263
+ ## BREAKING CHANGES (v0.11.0 dark mode)
264
+ - Dark mode interactive colors shifted: --color-interactive pink-400→pink-500, --color-interactive-hover pink-300→pink-600, --color-interactive-active pink-200→pink-700, --color-interactive-subtle pink-950→pink-1000
265
+ - Dark mode text status colors shifted: --color-text-error red-200→red-300, --color-text-success green-200→green-300, --color-text-warning yellow-200→yellow-300, --color-text-link blue-200→blue-300, --color-text-brand pink-300→pink-400
266
+ - New primitive token: --pink-1000 (#150208) near-black
267
+
268
+ ## BREAKING CHANGES (v0.8.0)
269
+ - Combobox: Now uses discriminated union. Single: `multiple?: false, value: string, onValueChange: (v: string) => void`. Multiple: `multiple: true, value: string[], onValueChange: (v: string[]) => void`. No more `v as string[]` casts.
270
+ - StatusBadge: Pass either `status` OR `color`, not both (discriminated union).
271
+ - Input/Textarea: Now auto-inherit state, aria-describedby, aria-required from FormField context. Explicit props override.
272
+
273
+ ## BREAKING CHANGES (v0.18.0 — OKLCH token migration, continued)
274
+ - All color primitives migrated from hex (50-950 shades) to OKLCH (12 functional steps)
275
+ - Old shade numbers: --pink-50..950. New step numbers: --pink-1..12 (OKLCH values)
276
+ - Step purposes: 1=app-bg, 2=subtle-bg, 3=component-bg, 4=hover, 5=active, 6=border-subtle, 7=border, 8=border-strong, 9=solid/accent, 10=solid-hover, 11=lo-contrast-text, 12=hi-contrast-text
277
+ - New semantic tokens: --color-accent-{1-12}, --color-secondary-{1-12}, --color-surface-{base,raised,raised-hover,raised-active,sunken,overlay,inverted,disabled}, --color-surface-fg/fg-muted/fg-subtle/border/border-subtle
278
+ - Status tokens: --color-error-{3,7,9,11,fg}, --color-success-{3,7,9,11,fg}, --color-warning-{3,7,9,11,fg}, --color-info-{3,7,9,11,fg}
279
+ - New Tailwind utilities: accent-1..12, secondary-1..12, surface-base/raised/sunken/overlay/inverted/disabled, status/category step utilities
280
+ - Backward compat: ALL old semantic token names preserved as aliases. --color-interactive still works maps to --color-accent-9
281
+ - Consumer rebranding: override --color-accent-1..12 CSS vars OR use generateScale() utility with a seed color
282
+ - Dark mode: algorithmically derived (OKLCH curves), NOT hex overrides. Surfaces lighten with elevation.
283
+ - If you reference --pink-500 etc directly, migrate: 50→1, 100→2, 200→3, 300→4, 400→5, 500→7, 600→8, 700→9, 800→10, 900→11, 950→12
284
+
285
+ ## v0.22.0 — UI Polish & Micro-Refinement
286
+
287
+ **Shadows**: All shadow tokens now use 3-layer stacks. Visual change only — same token names. Shadow tokens renamed in v0.23.0 (see breaking changes above).
288
+
289
+ **Transitions**: All CSS transitions use `ease-productive-standard` easing. Tween presets aligned: `tweens.fade` = 0.11s, `tweens.colorShift` = 0.07s.
290
+
291
+ **New Tailwind utilities**:
292
+ - `.focus-ring` — double-ring (2px surface + 2px accent), use on custom interactive elements (buttons, cards)
293
+ - `.focus-ring-inset` — inset ring, use on buttons over solid backgrounds
294
+ - `.focus-ring-sm` 1px subtle ring, use on inputs and small controls
295
+ - `.tabular-nums` — aligned numbers via `font-variant-numeric: tabular-nums`
296
+
297
+ **Category color utilities** (standalone, not tied to Badge/Chip):
298
+ - 7 colors: teal, amber, slate, indigo, cyan, orange, emerald
299
+ - 4 steps each: bg-category-{color}-{3|7|9|11}, text-category-{color}-{3|7|9|11}, border-category-{color}-{3|7|9|11}
300
+ - Use for: board column accents, status indicators, tag colors, category chips
301
+
302
+ **Dense size variant (xs)** added to Input, Select, SearchInput, Button, Textarea:
303
+ - xs = 28px height (h-ds-xs-plus), 12px text (text-ds-sm), compact padding
304
+ - Designed for filter bars, toolbar controls, and dense UI contexts
305
+ - Button also gets icon-xs (28×28) for compact icon buttons
306
+ - Size matrix: xs=28px | sm=32px | md=40px (default) | lg=48px
307
+
308
+ **Separator**: New `variant` prop — `"gradient" | "gradient-left" | "gradient-right"`. Default unchanged.
309
+
310
+ **Checkbox**: Path-draw animation (stroke draws progressively). Uncontrolled usage now works.
311
+
312
+ **Tooltip**: Auto-wraps with `<TooltipProvider>` no manual provider needed. Text color fixed for dark mode.
313
+
314
+ **Avatar fallback**: Now respects `shape` prop (was always circle). Font size auto-scales with avatar size (v0.22.3).
315
+
316
+ **AvatarGroup renderAvatar**: Wrapper is positioning-only — pass `size` directly to your Avatar, do NOT use `className="h-full w-full"` (v0.22.3).
317
+
318
+ **New hover states**: Checkbox, Radio, Switch track, Select items, DropdownMenu items, Combobox trigger.
319
+
320
+ ## AI Command System (v0.25.0+)
321
+
322
+ New `@devalok/shilp-sutra/ai` module — composable AI command interface.
323
+
324
+ **CommandBar** — Unified input (hero/inline/floating variants):
325
+ ```tsx
326
+ <CommandBar
327
+ variant="hero"
328
+ onSubmit={(query) => sendToAI(query)} // AI submission
329
+ groups={commandGroups} // optional command palette filtering
330
+ state="idle" // idle | typing | processing | responded
331
+ greeting="Good morning, Mudit."
332
+ hints={['Add member...', 'Check status...']}
333
+ agentName="Devadoot"
334
+ agentIcon={<DevadootIcon state={iconState} />}
335
+ >
336
+ <AIConversation messages={messages} isProcessing={loading} />
337
+ </CommandBar>
338
+ ```
339
+
340
+ **BlockRenderer** Renders AI response JSON as DS components:
341
+ ```tsx
342
+ <BlockRenderer blocks={response.blocks} onAction={handleAction} customBlocks={myBlocks} />
343
+ ```
344
+
345
+ Block types: `text`, `table`, `confirm`, `success`, `error`, `info`, `loading`, `divider`, `stat_row`.
346
+
347
+ **AICommandProvider** — Optional context wrapper:
348
+ ```tsx
349
+ <AICommandProvider customBlocks={karmBlocks} onAction={handle} agent={{ name: 'Devadoot' }}>
350
+ {/* CommandBar + AIConversation auto-wire from context */}
351
+ </AICommandProvider>
352
+ ```
353
+
354
+ **DevadootIcon** Animated Devalok chakra with gradient state animations:
355
+ ```tsx
356
+ <DevadootIcon state="processing" size={20} /> // idle | processing | responded | error
357
+ ```
358
+
359
+ ## Install & Setup
360
+
361
+ pnpm add @devalok/shilp-sutra
362
+
363
+ ### Next.js Setup (Required for Next.js + pnpm)
364
+
365
+ Add to next.config.js:
366
+ ```js
367
+ transpilePackages: ["@devalok/shilp-sutra", "@devalok/shilp-sutra-brand"]
368
+ ```
369
+
370
+ // Import components (barrel):
371
+ import { Button, Card, Dialog } from '@devalok/shilp-sutra'
372
+
373
+ // Import per-component (recommended for Server Components):
374
+ import { Button } from '@devalok/shilp-sutra/ui/button'
375
+ import { PageHeader } from '@devalok/shilp-sutra/composed/page-header'
376
+ import { TopBar } from '@devalok/shilp-sutra/shell/top-bar'
377
+
378
+ // Chat primitives (v0.29.0+):
379
+ import { MessageList, Message, SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator } from '@devalok/shilp-sutra/ui/chat'
380
+
381
+ // AI command system (v0.25.0+):
382
+ import { CommandBar, AIConversation, BlockRenderer, AICommandProvider, DevadootIcon } from '@devalok/shilp-sutra/ai'
383
+
384
+ // Toast (imperative, no hook needed):
385
+ import { toast } from '@devalok/shilp-sutra/ui/toast'
386
+
387
+ // Hooks:
388
+ import { useColorMode } from '@devalok/shilp-sutra/hooks/use-color-mode'
389
+
390
+ // CSS tokens (import once at app root):
391
+ import '@devalok/shilp-sutra/tokens'
392
+
393
+ // Tailwind preset (in tailwind.config):
394
+ import shilpSutra from '@devalok/shilp-sutra/tailwind'
395
+
396
+ ## CRITICAL: Differences from shadcn/ui
397
+
398
+ If you have shadcn/ui knowledge, these are the differences that WILL trip you up:
399
+
400
+ | shadcn/ui pattern | shilp-sutra equivalent | Notes |
401
+ |---|---|---|
402
+ | variant="destructive" | color="error" | Two-axis system: variant=shape, color=intent |
403
+ | size="default" | size="md" | All sizes: sm, md, lg (never "default") |
404
+ | <Select size="lg"> | <SelectTrigger size="lg"> | Size goes on trigger, NOT root |
405
+ | <Chip> | <Badge onClick={...}> | Chip is deprecated, use Badge with onClick |
406
+ | useToast() + toast({ variant }) | toast.success('msg') | Imperative API, no hook needed |
407
+ | Badge variant="destructive" | Badge variant="solid" color="error" | Two-axis: variant + color |
408
+ | Alert + AlertTitle + AlertDescription | <Alert title="..." color="error"> | Single component, not compound |
409
+ | Form + FormField + FormItem + FormLabel + FormControl + FormDescription + FormMessage | FormField + Label + Input + FormHelperText + useFormField() | Simpler API, hook-based a11y wiring |
410
+ | Pagination | PaginationRoot | Root component name differs |
411
+
412
+ ### The Two-Axis Variant System
413
+
414
+ Many components use TWO props where shadcn uses one:
415
+ - `variant` controls SHAPE/SURFACE: solid, outline, ghost, subtle, filled, etc.
416
+ - `color` controls INTENT/SEMANTICS: default, error, success, warning, info, etc.
417
+
418
+ Examples:
419
+ <Button variant="solid" color="error">Delete</Button> // red solid button
420
+ <Button variant="soft" color="warning">Pending</Button> // amber tinted button
421
+ <Button variant="soft" color="accent">Cancel</Button> // preferred for secondary actions
422
+ <Badge variant="solid" color="success">Active</Badge> // green solid badge
423
+ <Alert variant="solid" color="warning">Warning!</Alert> // amber filled alert
424
+
425
+ **Design preference (Devalok default):** for **secondary** Button actions, reach for `variant="soft"` before `variant="outline"`. Soft feels warmer, brand-consistent, and reads better in data-dense UIs. Use `outline` only when soft's tint would disappear (colored bg, surface-raised), in toolbar/icon-dense contexts, or when you need outline's stronger hierarchy next to a primary action.
426
+
427
+ Components with two-axis system: Button, Badge, Alert, Banner, Progress, StatusBadge
428
+
429
+ ## Component Quick Reference
430
+
431
+ ### Inputs & Controls
432
+ - Button: variant(solid|soft|outline|ghost|link) color(accent|error|success|warning|neutral) size(xs|sm|md|lg|compact-xs|compact-sm|compact-md|icon-xs|icon-sm|icon-md|icon-lg) shape(default|pill) weight(semibold|normal) + loading, startIcon, endIcon, asChild, processing?('ambient'|'working'|'urgent'|boolean — marching ants SVG border, forces soft variant), processingColor?('accent'|'error'|'success'|'warning'|'neutral'), processingDisabled?(boolean, default true set false for cancel-by-click). onClickAsync auto-activates processing='working' during loading phase. Layout animation always on. Deprecated aliases still work: variant="default"→solid, variant="destructive"→solid+error, color="default"→accent
433
+ - IconButton: icon(ReactNode, required) shape(square|circle) size(sm|md|lg) + aria-label required
434
+ - SplitButton: [Action | ▼] button with dropdown. Props: variant(solid|soft|outline), color, size(xs|sm|md|icon-xs|icon-sm|icon-md), triggerSide(left|right, default right), triggerWidth?(number|string), placement?(Floating UI Placement, default top-end), dropdownContent(ReactNode), open?, onOpenChange?, dropdownLabel?, dropdownIcon?. ARIA: role="group", aria-haspopup="menu", aria-expanded.
435
+ - ButtonGroup: Visually merges adjacent Buttons. Props: variant, color, size, disabled (propagates), orientation(horizontal|vertical), attached(true|false, default true), fullWidth. Compound pattern: Button reads position from context, applies radius + border-removal inline. Tonal dividers for solid/soft/ghost. Focus z-index isolation.
436
+ - Icon: `<Icon icon={IconPlus} />` — context-aware wrapper for Tabler icons. Size tiers: xs(14px) sm(16px) md(18px) lg(20px) xl(24px) 2xl(32px). Default: md. Stroke: light(1.5) regular(2) bold(2.5). Default: regular. Scales per size tier. Reads size from parent Button/IconGroup via IconContext. Explicit props override. Accessibility: aria-hidden by default. Pass label="Add item" for accessible icons. Animation: animate="spin|pulse|bounce|draw". `draw` renders SVG path-draw animation (check/X icons draw progressively via pathLength; other icons fall back to static). State machine: state="idle|loading|success|error". Button integration: startIcon={<Icon icon={IconPlus} />} (NOT raw <IconPlus />). IconGroup: <IconGroup size="sm" gap="tight"> for toolbar patterns.
437
+ - Input: size(xs|sm|md|lg) state(InputState) + startSection(ReactNode), endSection(ReactNode), startSectionClickable(bool), endSectionClickable(bool), startSectionType('icon'|'label'), endSectionType('icon'|'label'), wrapperClassName(string). Container-level focus ring wraps input + sections as one unit. Sections are pointer-events-none by default; use *SectionClickable for interactive content (clear buttons, toggles). Section type auto-inferred: strings→'label' (tinted bg + border separator), React elements→'icon' (fixed-width centered). Override with *SectionType. Flexbox section layout. Icons auto-size via IconProvider per input size. className targets <input>, wrapperClassName targets wrapper div. Deprecated aliases: startIcon→startSection, endIcon→endSection, inputVariants→inputWrapperVariants. Type: InputState = 'default' | 'error' | 'warning' | 'success'
438
+ - SearchInput: size(xs|sm|md|lg) + loading, onClear. Delegates to Input v2 sections internally.
439
+ - NumberInput: value + onValueChange, min, max, step (controlled only)
440
+ - Textarea: size(xs|sm|md|lg) state(default|error|warning|success)
441
+ - ColorInput: value(hex string) onChange(value) presets({hex,label}[]|string[]|false, default: 10 named colors) variant('default'|'inline') showPicker(boolean, default:true) defaultFormat('hex'|'rgb'|'hsl') align('start'|'center'|'end') disabled. Popover trigger opens interactive picker (react-colorful) + format switcher + preset swatches + undo/reset. Inline variant renders entire trigger as the color with contrast-aware text.
442
+ - Checkbox: checked, onCheckedChange, error(boolean), indeterminate(boolean)
443
+ - Switch: checked, onCheckedChange, error(boolean), size(sm|md|lg), color(accent|success|warning), thumbIcon(ReactNode)
444
+ - RadioGroup > RadioGroupItem(value)
445
+ - Select > SelectTrigger(size: xs|sm|md|lg) > SelectValue; SelectContent > SelectItem(value)
446
+ - Toggle: variant(default|outline) size(sm|md|lg)
447
+ - ToggleGroup > ToggleGroupItem (variant/size propagate from root)
448
+ - SegmentedControl > SegmentedControlItem: variant(filled|tonal) size(sm|md|lg). Types: SegmentedControlOption = { id, text, icon? }, SegmentedControlSize = 'sm' | 'md' | 'lg', SegmentedControlVariant = 'filled' | 'tonal'
449
+ - Slider: standard Radix slider
450
+
451
+ ### Feedback & Notifications
452
+ - Alert: variant(subtle|filled|outline) color(info|success|warning|error|neutral) + title, onDismiss
453
+ - Banner: color(info|success|warning|error|neutral) + actions?(ReactNode), onDismiss. `action` (singular) deprecated, use `actions`. Mobile flex-wrap for multiple buttons.
454
+ - Toast: imperative API via toast.success/error/warning/info/loading/message/undo/promise/upload/customREQUIRES <Toaster> at layout root
455
+ - Spinner: size(sm|md|lg) renders with role="status"
456
+ - Progress: track size(sm|md|lg), indicator color(default|success|warning|error), autoColor(boolean, auto-shifts color by value: 0-59=default, 60-84=warning, 85-100=success, >100=error)
457
+
458
+ NOTIFICATION SELECTION GUIDE:
459
+ - Alert: inline contextual feedback within a form or page section
460
+ - Banner: persistent page-level notification above content
461
+ - Toast: transient notification triggered by user action (needs <Toaster>, then call toast.success() etc.)
462
+
463
+ ### Data Display
464
+ - Badge: variant(subtle|solid|outline|soft) color(default|accent|error|success|warning|info|neutral + 7 category colors + custom) size(xs|sm|md|lg) + onClick, onDismiss, selected, disabled, dot, startIcon, endIcon, maxWidth, circle, asChild. Compound: Badge.Indicator(count, max, dot, color, invisible, showZero, placement, children), Badge.Group(max, gap, size, onOverflowClick, children). Custom colors: color="custom" + style={{'--badge-color':'#hex'}}. Grain-ready (has relative/overflow-hidden/isolate).
465
+ - Chip: DEPRECATED — Use `<Badge onClick={...}>` instead. Chip wrapper maps label prop to children for backward compat.
466
+ - Avatar: size(xs|sm|md|lg|xl) shape(circle|square|rounded) status?(AvatarStatus) ring?('lead'|'admin'|'client') badge?(number|'dot'|ReactNode) loading?(boolean) > AvatarImage + AvatarFallback(colorSeed?). Types: AvatarStatus = 'online'|'offline'|'busy'|'away', AvatarRing = 'none'|'lead'|'admin'|'client'. Fallback colors are deterministic from name hash (8 categorical). Online dot pulses. Badge pops in with MotionPop.
467
+ - Card: variant(default|elevated|outline|flat) interactive(boolean) accent?(left|top|right|bottom) accentColor?(default|secondary|error|success|warning|info) > CardHeader > CardTitle, CardDescription; CardContent; CardFooter
468
+ - Table > TableHeader > TableRow > TableHead; TableBody > TableRow > TableCell; TableFooter; TableCaption
469
+ - Text: variant(TextVariant) as(element). Type: TextVariant = 'heading-2xl' | 'heading-xl' | 'heading-lg' | 'heading-md' | 'heading-sm' | 'heading-xs' | 'body-lg' | 'body-md' | 'body-sm' | 'body-xs' | 'label-lg' | 'label-md' | 'label-sm' | 'label-xs' | 'caption' | 'overline'
470
+ - Code: variant(inline|block)
471
+ - Skeleton: variant(rectangle|circle|text) animation(pulse|shimmer|none)
472
+ - StatCard: title/label, value, delta, icon, prefix, suffix, comparisonLabel, secondaryLabel, progress, sparkline, onClick, href, accent(default|success|warning|error|info), footer
473
+ - ColorSwatch: color(CSS string) size(sm|md|lg) shape(circle|square|rounded) ring(boolean) for dynamic runtime colors
474
+ - StatusDot: status(healthy|warning|critical|neutral|inactive) size(sm|md|lg) pulse?(boolean, default true for healthy) label?(string)
475
+ - ProgressRing: value(number) max?(100) size(sm|md|lg) color(default|success|warning|error|info) showValue?(boolean) label?(string). Also: MultiProgressRing for concentric Activity Ring style
476
+ - DevalokGrain: Brand texture overlay — drop inside any element with `relative overflow-hidden isolate`. Props: intensity('subtle'|'medium'|'heavy'), surface('solid'|'soft'), sheen(boolean, inner highlight), animated(boolean, fade-in on mount), hoverIntensify(boolean, parent needs `group` class), tint(CSS color string for directional gradient). No gradient rendered without tint.
477
+
478
+ ### Chat Primitives (ui/chat/)
479
+ Import: `@devalok/shilp-sutra/ui/chat`
480
+ - MessageList: children, autoScroll?(true), newMessageCount?(number, shows floating "N new" pill), onScrollToBottom?(), onLoadMore?(), isLoadingMore?(boolean), emptySlot?(ReactNode), headerSlot?(ReactNode). role="log" aria-live="polite".
481
+ - Message: COMPOUND — variant('flat'|'bubble') placement('start'|'end') highlight?('mention'|'internal') grouped?(boolean) deleted?(boolean) deletedText?(string). Sub-parts: Message.Avatar(src?, fallback?, icon?, size?('sm'|'md')), Message.Content, Message.Author(name, badge?, timestamp?, formattedTimestamp?, timestampFormat?), Message.Body, Message.EditableBody(content, onSave, onCancel?, canEdit?, renderContent?), Message.Reactions(reactions[{emoji,count,reacted}], onReact), Message.Actions(children, delay?), Message.Action(icon, label, onClick, variant?('default'|'danger'))
482
+ - SystemMessage: variant('event'|'alert') icon?(ReactNode) timestamp?(string) children
483
+ - MessageInput: onSubmit(text=>void), placeholder?, disabled?, isStreaming?(boolean, shows stop button), onCancel?(), leadingSlot?, trailingSlot?, disclaimer?(string), sendIcon?(ReactNode). Enter to send, Shift+Enter for newline.
484
+ - DateSeparator: date(Date|string), format?((date)=>string). Shows "Today", "Yesterday", or "Mar 15".
485
+ - UnreadSeparator: label?('NEW'), count?(number). Accent-colored horizontal rule.
486
+ - TypingIndicator: users({name, image?}[]). Shows animated bouncing dots + "Alice is typing..." / "Alice and Bob are typing..." / "Several people are typing..."
487
+
488
+ ### Overlays
489
+ - Dialog > DialogTrigger; DialogContent > DialogHeader > DialogTitle, DialogDescription; [content]; DialogFooter
490
+ - AlertDialog > AlertDialogTrigger; AlertDialogContent > AlertDialogHeader > AlertDialogTitle; AlertDialogFooter > AlertDialogCancel, AlertDialogAction
491
+ - Sheet: side(top|bottom|left|right) > SheetTrigger; SheetContent > SheetHeader > SheetTitle; [content]; SheetFooter
492
+ - Popover > PopoverTrigger; PopoverContent
493
+ - Tooltip: auto-wraps with <TooltipProvider> (no manual provider needed) > Tooltip > TooltipTrigger; TooltipContent
494
+ - HoverCard > HoverCardTrigger; HoverCardContent
495
+ - Collapsible > CollapsibleTrigger; CollapsibleContent
496
+
497
+ ### Navigation
498
+ - Tabs > TabsList(variant: line|contained) > TabsTrigger(value); TabsContent(value) variant propagates via context
499
+ - Accordion(type: single|multiple) > AccordionItem(value) > AccordionTrigger(chevronPosition?: 'left'|'right', default 'right'); AccordionContent
500
+ - Breadcrumb > BreadcrumbList > BreadcrumbItem > BreadcrumbLink | BreadcrumbPage; BreadcrumbSeparator
501
+ - PaginationRoot > PaginationContent > PaginationItem > PaginationLink(isActive) | PaginationPrevious | PaginationNext | PaginationEllipsis
502
+ - DropdownMenu > DropdownMenuTrigger; DropdownMenuContent > DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuRadioGroup > DropdownMenuRadioItem
503
+ - ContextMenu > ContextMenuTrigger (right-click); ContextMenuContent > same sub-components as DropdownMenu
504
+ - Menubar > MenubarMenu > MenubarTrigger; MenubarContent > same sub-components
505
+ - NavigationMenu > NavigationMenuList > NavigationMenuItem > NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink
506
+
507
+ ### Layout
508
+ - Stack: direction(vertical|horizontal) gap(SpacingToken|number) align, justify, wrap
509
+ - Container: maxWidth(default|body|full)
510
+ - Separator: orientation(horizontal|vertical)
511
+ - Sidebar: complex see llms-full.txt for complete tree
512
+
513
+ ### Form Pattern
514
+ - FormField: state(FormHelperState) > Label + Input + FormHelperText. Type: FormHelperState = 'helper' | 'error' | 'warning' | 'success'
515
+ - useFormField() hook returns { state, helperTextId, required } from FormField context
516
+ - Wire accessibility: const { state, helperTextId } = useFormField(); then aria-describedby={helperTextId}, aria-invalid={state === 'error'}
517
+ - Input/Textarea auto-wire from FormField context (no manual hookup needed). Explicit props override.
518
+
519
+ ### Composed Components
520
+ - ConfirmDialog: open, onOpenChange, title, description, onConfirm + confirmText, cancelText, color(default|error), loading
521
+ - PageHeader: title, subtitle, breadcrumbs[], actions(ReactNode)
522
+ - AvatarGroup: users(AvatarUser[]), max?(number), size?(xs|sm|md|lg|xl), showTooltip?, borderColor?('surface-base'|'surface-raised'), onOverflowClick?(), renderAvatar?((user,index)=>ReactNode), expandDirection?('left'|'right'), expandAmount?('compact'|'default'|'wide'). Type: AvatarUser = { name, image?, ring?, indicator?('lead'|'admin'|ReactNode) }. GPU-composited hover expand via translateX. Use expandDirection="left" for right-aligned groups. indicator renders a small dot on avatar: 'lead'=warning-9, 'admin'=accent-9, or custom ReactNode.
523
+ - StatusBadge: DISCRIMINATED UNION pass status OR color, not both. status(active|pending|approved|rejected|completed|blocked|in-progress|review|cancelled|draft) color(success|warning|error|info|neutral) size(sm|md) onClick?(() => void, renders as button with auto chevron-down icon) icon?(ReactNode, custom trailing icon)
524
+ - ContentCard: variant(default|outline|ghost) padding(default|compact|spacious|none)
525
+ - EmptyState: icon(ReactNode or ComponentType), title(required), description, action(ReactNode), compact
526
+ - PriorityIndicator: priority(Priority) display(compact|full). Type: Priority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' | 'low' | 'medium' | 'high' | 'urgent'
527
+ - SimpleTooltip: wraps Tooltip compound into single component
528
+ - DatePicker, DateRangePicker, DateTimePicker
529
+ - TimePicker: standalone time selector value(Date|null), onChange, format('12h'|'24h'), minuteStep, showSeconds, disabled
530
+ - CalendarGrid: low-level calendar widget currentMonth, selected, rangeStart/End, onSelect, onMonthChange, events(CalendarEvent[])
531
+ - YearPicker: decade year gridcurrentYear, selectedYear, onYearSelect, minDate, maxDate
532
+ - MonthPicker: month gridcurrentYear, selectedMonth(0-11), onMonthSelect, minDate, maxDate
533
+ - Presets: date range quick-select buttons — presets(PresetKey[]), onSelect(start, end). Keys: today, yesterday, last7days, last30days, thisMonth, lastMonth, thisYear
534
+ - useCalendar: hook for calendar month state — returns currentMonth, goToPreviousMonth, goToNextMonth, goToMonth, goToYear
535
+ - (UploadProgress REMOVED upload tracking is now built into toast.upload())
536
+ - RichTextEditor: Tiptap editor — bold/italic/underline/strike/highlight, headings, blockquote, lists (bullet/ordered/task), code, links, images (paste/drop/upload), file attachments, @mentions, emoji picker + :shortcode:, text alignment, HR. Props: onImageUpload?, onFileUpload?, mentions?, onMentionSearch?, onMentionSelect?(item: MentionItem), emojiSet?(native|apple|google|twitter|facebook)
537
+ - RichTextViewer: read-only renderer for RichTextEditor HTML content (renders all above content types)
538
+ - RichChatInput: compact rich text chat input for AI/messaging. Output: RichChatInputMessage { html, plainText, attachments?, voiceNote? }. Variants: compact(default), expanded, minimal, inline. Key props: onSubmit(msg), onSchedule?(msg,date), emojiSet?, mentions?, slashCommands?, onFileUpload?, onImageUpload?, onVoiceRecord?, replyTo?, toolbar?(bool|items[]|ReactNode), actionButton?(ReactNode|false), enterBehavior?(send|newline), maxLength?, isStreaming?, onCancel?, disclaimer?, sendOptions?, leadingSlot?, trailingSlot?. Composable toolbar primitives exported: ToolbarButton, ToolbarDivider, ToolbarGroup, BoldButton, ItalicButton, etc.
539
+ - ActivityFeed: items(ActivityItem[]), onLoadMore, loading, hasMore, emptyState, compact, maxInitialItems, groupBy?('time'|'none'), groupLabels?({ today, yesterday, thisWeek, older }), renderItem?((item, index) => ReactNode|undefined, custom renderer per item — return ReactNode for custom, undefined for default). Type: ActivityItem = { id, actor?, action, timestamp, icon?, color?, detail? }. Utility: groupItemsByTime(items, labels) exported.
540
+ - CommandPalette: open, defaultOpen, onOpenChange (controlled/uncontrolled), keybinding(string|string[]|false), maxHeight, emptyState(ReactNode), footerHints(FooterHint[]|false). CommandItem: label(string|ReactNode), description(string|ReactNode), renderLabel(query=>ReactNode), filterValue(string), shortcut(rendered as keycap badges). Keyboard shortcuts rendered per-key with platform-aware Cmd/Ctrl. Reduced-motion support via MotionProvider.
541
+ - MemberPicker: thin wrapper around MultiSelectPopover with Avatar rendering
542
+ - MultiSelectPopover: items/groups, value, onValueChange, searchPlaceholder, onSearch?(async), renderItem?, emptyMessage, maxSelections. Generic multi-select popover with search + checkmarks.
543
+ - FilterBar: searchValue, onSearchChange, onClearAll, size(xs|sm|md). Children: FilterSelect(label, value, onValueChange, options), FilterMultiSelect(label, value, onValueChange, options). Size propagates via context.
544
+ - InlineEdit: value, onSave(string=>void|Promise), placeholder, textClassName, inputSize(xs|sm|md), multiline, readOnly, maxLength, saving. Click-to-edit text → input transition.
545
+ - FormSection: title, description?, collapsible?, defaultOpen?. Titled form section with separator, optional collapse.
546
+ - BulkActionBar: show, count, onClearSelection, actions[{label,icon?,onClick,color?,disabled?}]. Fixed bottom floating bar for multi-select contexts.
547
+ - DeadlineIndicator: deadline(Date|string), warningThreshold?(1440min), criticalThreshold?(240min), format(relative|absolute), showIcon. Color transitions: green→yellow→red→overdue.
548
+ - MasterDetail: selected, onBack, masterWidth, breakpoint(sm|md|lg). Compound: MasterDetail.List, MasterDetail.Detail, MasterDetail.ListItem(active). Desktop=grid, mobile=stacked with back button.
549
+ - ResponsiveOverlay: open, onOpenChange, title, description, breakpoint(sm|md). Dialog on desktop, bottom Sheet on mobile.
550
+ - MarkdownViewer: content(string), compact?, allowHtml?(false), linkTarget?('_blank'). Renders markdown with design system tokens.
551
+ - EmojiPicker: onSelect(emoji), set?(native|apple|google|twitter|facebook), theme(auto|light|dark). EmojiPickerPopover wraps in Popover. Lazy-loads emoji-mart with set-specific data.
552
+ - EmojiNode: TipTap inline atom node for spritesheet emoji rendering. Attrs: id, native, set, x, y. Use createEmojiSuggestion(set) to wire :shortcode: autocomplete. Export: EmojiNode, EmojiNodeAttrs, createEmojiSuggestion.
553
+ - FilePreview: url, type?(image|pdf|video|audio|embed), mimeType?, alt?. Auto-detects type. Image zoom, PDF iframe, native video/audio, embed for Figma/YouTube/Loom.
554
+ - ErrorDisplay, GlobalLoading
555
+ - Loading skeletons: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton
556
+ - Page skeletons: DashboardSkeleton, ProjectListSkeleton, TaskDetailSkeleton (no props, server-safe)
557
+
558
+ ### Shell Components (app-level layout)
559
+ - TopBar: Composition-based. Subcomponents: TopBar.Left, TopBar.Center (optional, triggers grid), TopBar.Right, TopBar.Section(gap: tight|default|loose), TopBar.IconButton(icon, tooltip), TopBar.Title, TopBar.UserMenu(user, onNavigate?, onLogout?, userMenuItems?). Types: TopBarUser = { name, email?, image? }, UserMenuItem = { label, icon?, href?, onClick?, separator?, color?, badge?, disabled? }
560
+ - AppSidebar: navigation tree with NavItem[], NavGroup[]. Types: NavItem = { title, href, icon, exact?, badge?, children?, defaultOpen? }, NavSubItem = { title, href, icon?, exact? }, NavGroup = { label, items, action? }, SidebarUser = { name, email?, image?, designation?, role? }
561
+
562
+ ### AppSidebar (v0.10.0 additions)
563
+ - NavItem.children?: NavSubItem[]collapsible sub-list with chevron toggle
564
+ - NavItem.defaultOpen?: boolean — control initial collapsed state
565
+ - NavItem.badge?: string | number — badge on nav item (99+ cap for numbers)
566
+ - NavGroup.action?: ReactNode — action button next to group label
567
+ - footer?: SidebarFooterConfig structured footer with links, version, slot, promo (replaces footerLinks)
568
+ - headerSlot?: ReactNode content between user info and navigation
569
+ - preFooterSlot?: ReactNodecontent between navigation and footer
570
+ - renderItem?: (item, defaultRender) => ReactNode | null custom item rendering
571
+
572
+ - BottomNavbar: mobile navigation, user is optional. Types: BottomNavItem = { title, href, icon, exact?, badge? }, BottomNavbarUser = { name, role? }
573
+ - NotificationCenter: notifications[], onMarkRead, onMarkAllRead, onNavigate, getNotificationRoute?, footerSlot?, emptyState?, headerActions?, popoverClassName?, onDismiss?(id). Types: Notification = { id, title, body?, tier, isRead, createdAt, entityType?, entityId?, projectId?, project?, actions? }, NotificationAction = { label, variant?, onClick }
574
+ - NotificationPreferences: preferences[], projects[], onSave, onToggleMute, onUpdateTier, onDelete. Types: NotificationPreference = { id, userId?, projectId, channel, minTier, muted }, NotificationProject = { id, title }
575
+ - AppCommandPalette: user, isAdmin, onNavigate, onSearch, searchResults, searchResultGroups(SearchResultGroup[]), isSearching, onSearchResultSelect (when provided, consumer owns routing no internal URL computation), searchResultsLabel(string|((count)=>string)), open, defaultOpen, onOpenChange, keybinding, maxHeight, emptyState, footerHints. Types: SearchResult = { id, title, snippet?, entityType, projectId?, metadata?, icon?(ReactNode), rank?(number), shortcut?(string) }, SearchResultGroup = { label, results: SearchResult[] }, AppCommandPaletteUser = { name, role? }
576
+ - LinkProvider: wraps app with router-agnostic Link component component(ForwardRefComponent), children. useLink() hook returns the Link component.
577
+
578
+ ### Motion System (Framer Motion)
579
+ - Setup: Wrap app root with `<MotionProvider>` from `@devalok/shilp-sutra/motion`. Handles reduced-motion detection globally.
580
+ - Import presets: `import { springs, tweens, stagger } from '@devalok/shilp-sutra/motion'`
581
+ - Import primitives: `import { MotionFade, MotionScale, MotionPop, MotionSlide, MotionCollapse, MotionStagger, MotionStaggerItem } from '@devalok/shilp-sutra/motion/primitives'`
582
+ - Spring presets (spatial: position, scale, size): snappy (buttons/hover), smooth (dialogs/panels), bouncy (toasts/pop-ins), gentle (collapse/expand)
583
+ - Tween presets (non-spatial: opacity, color): fade (opacity enter/exit), colorShift (hover color/bg)
584
+ - All primitives take `show: boolean` to control mount/unmount via AnimatePresence
585
+ - MotionSlide: additional `direction` prop (up|down|left|right)
586
+ - MotionStagger + MotionStaggerItem: orchestrated stagger with configurable `delay` (default 0.04s)
587
+ - All primitives support `layout`, `layoutId`, `whileInView`, `viewportOnce`, `preset` props
588
+ - useMotion() hook returns { springs, tweens, reducedMotion: boolean }
589
+ - Old Fade/Collapse/Grow/Slide from @devalok/shilp-sutra/ui/transitions are REMOVED — use Motion* equivalents
590
+
591
+ ### Hooks
592
+ - toast: imperative API — import { toast } from '@devalok/shilp-sutra/ui/toast'. Methods: toast.success/error/warning/info/loading/message/undo/promise/upload/custom/dismiss. useToast() is deprecated.
593
+ - useColorMode(): returns { colorMode, setColorMode, toggleColorMode }
594
+ - useMobile(): returns boolean (true if viewport < 768px)
595
+ - useLink(): returns router-agnostic Link component from LinkProvider context (shell/link-context)
596
+
597
+ ## Server-Safe Components (no "use client")
598
+
599
+ These can be imported directly in Next.js Server Components:
600
+ - UI: Text, Skeleton, Stack, Container, Table (and sub-components), Code, VisuallyHidden
601
+ - Composed: ContentCard, PageHeader, LoadingSkeleton, PageSkeletons, PriorityIndicator
602
+
603
+ Use per-component imports for server components:
604
+ import { Text } from '@devalok/shilp-sutra/ui/text'
605
+ import { PageHeader } from '@devalok/shilp-sutra/composed/page-header'
606
+
607
+ DO NOT use barrel imports in Server Components — they include "use client" components.
608
+
609
+ ## Common Mistakes -- DO NOT
610
+
611
+ - DO NOT use variant="destructive" — use color="error"
612
+ - DO NOT use size="default" — use size="md" (or sm, lg)
613
+ - DO NOT put size on <Select> — put it on <SelectTrigger size="md">
614
+ - DO NOT use <Chip> — Chip is deprecated. Use <Badge onClick={...}> instead
615
+ - DO NOT use useToast() hook — use import { toast } from '@devalok/shilp-sutra/ui/toast' (imperative)
616
+ - DO NOT use toast({ title, color }) object syntax — use toast.success('message'), toast.error('message'), etc.
617
+ - DO NOT call toast() without <Toaster /> mounted at your layout root
618
+ - DO NOT use <Alert><AlertTitle>...</AlertTitle></Alert> — use <Alert title="..." />
619
+ - DO NOT import from barrel in Next.js Server Components — use per-component imports
620
+ - DO NOT use variant="secondary" on Button — use variant="outline" or variant="ghost"
621
+ - DO NOT use variant="default" on Button — use variant="solid" (deprecated alias, still works)
622
+ - DO NOT use variant="destructive" on Button — use variant="solid" color="error" (deprecated alias, still works)
623
+ - DO NOT use color="default" on Button — use color="accent" (deprecated alias, still works)
624
+ - DO NOT put variant on individual TabsTrigger — put it on TabsList (propagates via context)