@devalok/shilp-sutra 0.48.0 → 0.49.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 (261) hide show
  1. package/BREAKING.json +32 -0
  2. package/MIGRATION.md +891 -881
  3. package/dist/_chunks/badge-group.js +52 -65
  4. package/dist/_chunks/badge-group.js.map +1 -1
  5. package/dist/_chunks/block-shell.js +1 -1
  6. package/dist/_chunks/chart-container.js +1 -1
  7. package/dist/_chunks/chat.js +4 -4
  8. package/dist/_chunks/chat.js.map +1 -1
  9. package/dist/_chunks/colors.js +2 -2
  10. package/dist/_chunks/document-preview.js +4 -4
  11. package/dist/_chunks/emoji-suggestion.js +5 -5
  12. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  13. package/dist/_chunks/emoji.js +1 -1
  14. package/dist/_chunks/field-state.js +8 -0
  15. package/dist/_chunks/field-state.js.map +1 -0
  16. package/dist/_chunks/grid-lines.js +1 -1
  17. package/dist/_chunks/image-preview.js +7 -7
  18. package/dist/_chunks/keybinding.js +1 -1
  19. package/dist/_chunks/link-context.js +1 -1
  20. package/dist/_chunks/mention-suggestion.js +2 -2
  21. package/dist/_chunks/mention.js +1 -1
  22. package/dist/_chunks/motion-provider.js +1 -1
  23. package/dist/_chunks/normalize-icon.js +1 -1
  24. package/dist/_chunks/oauth-button.js +2 -2
  25. package/dist/_chunks/popover.js +55 -52
  26. package/dist/_chunks/popover.js.map +1 -1
  27. package/dist/_chunks/primitives.js +155 -155
  28. package/dist/_chunks/primitives.js.map +1 -1
  29. package/dist/_chunks/shared.js +5 -5
  30. package/dist/_chunks/success.js +4 -4
  31. package/dist/_chunks/tiptap.js +8 -8
  32. package/dist/_chunks/tooltip.js +1 -1
  33. package/dist/_chunks/tree-view.js +2 -2
  34. package/dist/_chunks/use-calendar.js +2 -2
  35. package/dist/_chunks/use-calendar.js.map +1 -1
  36. package/dist/_chunks/use-controllable-open.js +15 -0
  37. package/dist/_chunks/use-controllable-open.js.map +1 -0
  38. package/dist/_chunks/vendor-client.js +1 -1
  39. package/dist/_chunks/vendor-utils.js +1 -1
  40. package/dist/ai/block-renderer.js +7 -7
  41. package/dist/ai/blocks/error.js +1 -1
  42. package/dist/ai/blocks/index.js +2 -2
  43. package/dist/ai/blocks/text.js +1 -1
  44. package/dist/ai/command-bar.js +6 -6
  45. package/dist/ai/conversation.js +2 -2
  46. package/dist/ai/index.js +3 -3
  47. package/dist/composed/avatar-group.js +1 -1
  48. package/dist/composed/bulk-action-bar.js +1 -1
  49. package/dist/composed/command-palette.js +9 -9
  50. package/dist/composed/command-palette.js.map +1 -1
  51. package/dist/composed/confirm-dialog.js +3 -3
  52. package/dist/composed/confirm-dialog.js.map +1 -1
  53. package/dist/composed/content-card.js +1 -1
  54. package/dist/composed/date-picker/index.js +13 -13
  55. package/dist/composed/date-picker/index.js.map +1 -1
  56. package/dist/composed/emoji-picker.js +4 -4
  57. package/dist/composed/empty-state.js +1 -1
  58. package/dist/composed/error-boundary.js +1 -1
  59. package/dist/composed/error-boundary.js.map +1 -1
  60. package/dist/composed/extensions/emoji-node.js +1 -1
  61. package/dist/composed/extensions/emoji-suggestion.js +1 -1
  62. package/dist/composed/file-preview.js +14 -14
  63. package/dist/composed/filter-bar.js +1 -1
  64. package/dist/composed/index.d.ts +3 -1
  65. package/dist/composed/index.d.ts.map +1 -1
  66. package/dist/composed/index.js +4 -3
  67. package/dist/composed/loading-skeleton.js +15 -15
  68. package/dist/composed/loading-skeleton.js.map +1 -1
  69. package/dist/composed/multi-select-popover.js +3 -3
  70. package/dist/composed/page-header.d.ts.map +1 -1
  71. package/dist/composed/page-header.js +32 -45
  72. package/dist/composed/page-header.js.map +1 -1
  73. package/dist/composed/page-skeletons.js +19 -19
  74. package/dist/composed/page-skeletons.js.map +1 -1
  75. package/dist/composed/priority-indicator.js +1 -1
  76. package/dist/composed/responsive-modal.d.ts +39 -0
  77. package/dist/composed/responsive-modal.d.ts.map +1 -0
  78. package/dist/composed/responsive-modal.js +212 -0
  79. package/dist/composed/responsive-modal.js.map +1 -0
  80. package/dist/composed/rich-chat-input.js +445 -445
  81. package/dist/composed/rich-chat-input.js.map +1 -1
  82. package/dist/composed/rich-text-editor.js +29 -29
  83. package/dist/composed/rich-text-editor.js.map +1 -1
  84. package/dist/composed/schedule-view.d.ts +1 -1
  85. package/dist/composed/schedule-view.d.ts.map +1 -1
  86. package/dist/composed/schedule-view.js +48 -54
  87. package/dist/composed/schedule-view.js.map +1 -1
  88. package/dist/composed/status-badge.d.ts +13 -11
  89. package/dist/composed/status-badge.d.ts.map +1 -1
  90. package/dist/composed/status-badge.js +54 -130
  91. package/dist/composed/status-badge.js.map +1 -1
  92. package/dist/motion/index.js +2 -2
  93. package/dist/shell/bottom-navbar.js +3 -3
  94. package/dist/shell/bottom-navbar.js.map +1 -1
  95. package/dist/shell/index.js +2 -2
  96. package/dist/shell/link-context.js +2 -2
  97. package/dist/shell/notification-center.js +3 -3
  98. package/dist/shell/sidebar.js +2 -2
  99. package/dist/shell/top-bar.js +2 -2
  100. package/dist/shell/top-bar.js.map +1 -1
  101. package/dist/tokens/semantic.css +8 -1
  102. package/dist/ui/accordion.js +11 -11
  103. package/dist/ui/alert-dialog.js +34 -34
  104. package/dist/ui/alert.js +1 -1
  105. package/dist/ui/aspect-ratio.js +1 -1
  106. package/dist/ui/autocomplete.js +7 -7
  107. package/dist/ui/avatar.d.ts.map +1 -1
  108. package/dist/ui/avatar.js +84 -79
  109. package/dist/ui/avatar.js.map +1 -1
  110. package/dist/ui/badge-group.js +1 -1
  111. package/dist/ui/badge.d.ts.map +1 -1
  112. package/dist/ui/badge.js +1 -1
  113. package/dist/ui/banner.js +1 -1
  114. package/dist/ui/breadcrumb.d.ts +0 -1
  115. package/dist/ui/breadcrumb.d.ts.map +1 -1
  116. package/dist/ui/breadcrumb.js +58 -35
  117. package/dist/ui/breadcrumb.js.map +1 -1
  118. package/dist/ui/button.js +3 -3
  119. package/dist/ui/card.js +1 -1
  120. package/dist/ui/charts/area-chart.js +6 -6
  121. package/dist/ui/charts/bar-chart.js +6 -6
  122. package/dist/ui/charts/chart-container.js +1 -1
  123. package/dist/ui/charts/gauge-chart.js +2 -2
  124. package/dist/ui/charts/index.js +2 -2
  125. package/dist/ui/charts/line-chart.js +6 -6
  126. package/dist/ui/charts/pie-chart.js +5 -5
  127. package/dist/ui/charts/radar-chart.js +5 -5
  128. package/dist/ui/charts/sparkline.js +2 -2
  129. package/dist/ui/chat/index.js +2 -2
  130. package/dist/ui/checkbox.d.ts +4 -2
  131. package/dist/ui/checkbox.d.ts.map +1 -1
  132. package/dist/ui/checkbox.js +33 -28
  133. package/dist/ui/checkbox.js.map +1 -1
  134. package/dist/ui/collapsible.js +5 -5
  135. package/dist/ui/color-input.js +4 -4
  136. package/dist/ui/combobox.d.ts +3 -0
  137. package/dist/ui/combobox.d.ts.map +1 -1
  138. package/dist/ui/combobox.js +137 -132
  139. package/dist/ui/combobox.js.map +1 -1
  140. package/dist/ui/context-menu.js +32 -32
  141. package/dist/ui/dialog.d.ts.map +1 -1
  142. package/dist/ui/dialog.js +49 -46
  143. package/dist/ui/dialog.js.map +1 -1
  144. package/dist/ui/dot.d.ts +38 -0
  145. package/dist/ui/dot.d.ts.map +1 -0
  146. package/dist/ui/dot.js +92 -0
  147. package/dist/ui/dot.js.map +1 -0
  148. package/dist/ui/dropdown-menu.d.ts.map +1 -1
  149. package/dist/ui/dropdown-menu.js +81 -76
  150. package/dist/ui/dropdown-menu.js.map +1 -1
  151. package/dist/ui/hover-card.js +6 -6
  152. package/dist/ui/icon-button.js +1 -1
  153. package/dist/ui/index.d.ts +3 -2
  154. package/dist/ui/index.d.ts.map +1 -1
  155. package/dist/ui/index.js +67 -67
  156. package/dist/ui/index.js.map +1 -1
  157. package/dist/ui/input-otp.js +1 -1
  158. package/dist/ui/input-otp.js.map +1 -1
  159. package/dist/ui/input.d.ts +4 -2
  160. package/dist/ui/input.d.ts.map +1 -1
  161. package/dist/ui/input.js +39 -38
  162. package/dist/ui/input.js.map +1 -1
  163. package/dist/ui/label.js +1 -1
  164. package/dist/ui/lib/field-state.d.ts +21 -0
  165. package/dist/ui/lib/field-state.d.ts.map +1 -0
  166. package/dist/ui/lib/use-controllable-open.d.ts +32 -0
  167. package/dist/ui/lib/use-controllable-open.d.ts.map +1 -0
  168. package/dist/ui/lib/utils.js +4 -4
  169. package/dist/ui/link.js +1 -1
  170. package/dist/ui/menubar.js +53 -53
  171. package/dist/ui/navigation-menu.js +27 -27
  172. package/dist/ui/number-input.d.ts +4 -2
  173. package/dist/ui/number-input.d.ts.map +1 -1
  174. package/dist/ui/number-input.js +52 -51
  175. package/dist/ui/number-input.js.map +1 -1
  176. package/dist/ui/oauth-button/index.js +2 -2
  177. package/dist/ui/pagination.js +1 -1
  178. package/dist/ui/popover.d.ts.map +1 -1
  179. package/dist/ui/popover.js +2 -2
  180. package/dist/ui/progress.d.ts +66 -42
  181. package/dist/ui/progress.d.ts.map +1 -1
  182. package/dist/ui/progress.js +144 -40
  183. package/dist/ui/progress.js.map +1 -1
  184. package/dist/ui/radio.d.ts +6 -2
  185. package/dist/ui/radio.d.ts.map +1 -1
  186. package/dist/ui/radio.js +44 -33
  187. package/dist/ui/radio.js.map +1 -1
  188. package/dist/ui/segmented-control.js +1 -1
  189. package/dist/ui/select.d.ts +1 -1
  190. package/dist/ui/select.d.ts.map +1 -1
  191. package/dist/ui/select.js +56 -55
  192. package/dist/ui/select.js.map +1 -1
  193. package/dist/ui/separator.js +2 -2
  194. package/dist/ui/separator.js.map +1 -1
  195. package/dist/ui/sheet.d.ts.map +1 -1
  196. package/dist/ui/sheet.js +56 -53
  197. package/dist/ui/sheet.js.map +1 -1
  198. package/dist/ui/sidebar.js +6 -6
  199. package/dist/ui/sidebar.js.map +1 -1
  200. package/dist/ui/skeleton.js +1 -1
  201. package/dist/ui/slider.js +8 -8
  202. package/dist/ui/slider.js.map +1 -1
  203. package/dist/ui/split-button.js +3 -3
  204. package/dist/ui/stat-card.d.ts.map +1 -1
  205. package/dist/ui/stat-card.js +123 -126
  206. package/dist/ui/stat-card.js.map +1 -1
  207. package/dist/ui/stat-flash.js +1 -1
  208. package/dist/ui/stepper.js +1 -1
  209. package/dist/ui/surface.js +2 -2
  210. package/dist/ui/switch.d.ts +3 -1
  211. package/dist/ui/switch.d.ts.map +1 -1
  212. package/dist/ui/switch.js +32 -27
  213. package/dist/ui/switch.js.map +1 -1
  214. package/dist/ui/table-row-link.js +1 -1
  215. package/dist/ui/tabs.js +13 -13
  216. package/dist/ui/text.js +1 -1
  217. package/dist/ui/textarea.d.ts +3 -3
  218. package/dist/ui/textarea.d.ts.map +1 -1
  219. package/dist/ui/textarea.js +19 -18
  220. package/dist/ui/textarea.js.map +1 -1
  221. package/dist/ui/toast.js +2 -2
  222. package/dist/ui/toast.js.map +1 -1
  223. package/dist/ui/toggle-group.js +1 -1
  224. package/dist/ui/toggle.js +2 -2
  225. package/dist/ui/tooltip.d.ts.map +1 -1
  226. package/dist/ui/tooltip.js +37 -34
  227. package/dist/ui/tooltip.js.map +1 -1
  228. package/dist/ui/tree-view/index.js +2 -2
  229. package/docs/components/ai/ai-command-provider.md +46 -0
  230. package/docs/components/ai/block-renderer.md +59 -0
  231. package/docs/components/ai/command-bar.md +78 -0
  232. package/docs/components/ai/conversation.md +59 -0
  233. package/docs/components/ai/devadoot-icon.md +41 -0
  234. package/docs/components/composed/page-header.md +1 -1
  235. package/docs/components/composed/responsive-modal.md +66 -0
  236. package/docs/components/composed/schedule-view.md +6 -2
  237. package/docs/components/ui/breadcrumb.md +1 -1
  238. package/docs/components/ui/checkbox.md +4 -1
  239. package/docs/components/ui/combobox.md +4 -0
  240. package/docs/components/ui/dot.md +61 -0
  241. package/docs/components/ui/progress.md +54 -16
  242. package/docs/components/ui/radio.md +6 -2
  243. package/docs/components/ui/select.md +9 -5
  244. package/docs/components/ui/switch.md +4 -1
  245. package/docs/components/ui/table.md +2 -1
  246. package/llms.txt +11 -3
  247. package/make-kit/components/form.md +2 -2
  248. package/make-kit/components/icon.md +2 -2
  249. package/make-kit/components/overview.md +2 -2
  250. package/make-kit/components/select.md +1 -1
  251. package/make-kit/components/table.md +1 -1
  252. package/mcp-manifest.json +2656 -1068
  253. package/mcp-manifest.schema.json +18 -0
  254. package/package.json +11 -6
  255. package/skill/SKILL.md +1 -1
  256. package/skill/references/components.md +11 -3
  257. package/dist/ui/status-dot.d.ts +0 -27
  258. package/dist/ui/status-dot.d.ts.map +0 -1
  259. package/dist/ui/status-dot.js +0 -68
  260. package/dist/ui/status-dot.js.map +0 -1
  261. package/docs/components/ui/status-dot.md +0 -35
package/mcp-manifest.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./mcp-manifest.schema.json",
3
- "manifestVersion": "1.1.0",
3
+ "manifestVersion": "1.2.0",
4
4
  "package": "@devalok/shilp-sutra",
5
- "packageVersion": "0.48.0",
5
+ "packageVersion": "0.49.1",
6
6
  "components": {
7
7
  "accordion": {
8
8
  "displayName": "Accordion",
@@ -1106,7 +1106,7 @@
1106
1106
  "displayName": "Breadcrumb",
1107
1107
  "tier": "ui",
1108
1108
  "import": "@devalok/shilp-sutra/ui/breadcrumb",
1109
- "serverSafe": false,
1109
+ "serverSafe": true,
1110
1110
  "description": "",
1111
1111
  "props": {},
1112
1112
  "composition": {
@@ -1617,28 +1617,6 @@
1617
1617
  },
1618
1618
  "required": false,
1619
1619
  "description": "enables hover shadow lift + pointer cursor"
1620
- },
1621
- "placement": {
1622
- "type": {
1623
- "name": "union",
1624
- "raw": "\"top-right\" (default) | \"top-left\" | \"bottom-right\" | \"bottom-left\""
1625
- },
1626
- "required": false
1627
- },
1628
- "tuck": {
1629
- "type": {
1630
- "name": "boolean"
1631
- },
1632
- "required": false,
1633
- "description": "pull a step toward the corner so an icon button's glyph aligns to the content edge"
1634
- },
1635
- "side": {
1636
- "type": {
1637
- "name": "union",
1638
- "raw": "\"x\" (default) | \"top\" | \"bottom\" | \"y\" | \"all\""
1639
- },
1640
- "required": false,
1641
- "description": "which card padding to negate; top/bottom/y for direct children — inherit the card radius; x/all for content inside a slot"
1642
1620
  }
1643
1621
  },
1644
1622
  "composition": {
@@ -1702,6 +1680,38 @@
1702
1680
  "size": "md",
1703
1681
  "orientation": "vertical"
1704
1682
  },
1683
+ "subComponents": {
1684
+ "CardAction": {
1685
+ "props": {
1686
+ "placement": {
1687
+ "type": {
1688
+ "name": "union",
1689
+ "raw": "\"top-right\" (default) | \"top-left\" | \"bottom-right\" | \"bottom-left\""
1690
+ },
1691
+ "required": false
1692
+ },
1693
+ "tuck": {
1694
+ "type": {
1695
+ "name": "boolean"
1696
+ },
1697
+ "required": false,
1698
+ "description": "pull a step toward the corner so an icon button's glyph aligns to the content edge"
1699
+ }
1700
+ }
1701
+ },
1702
+ "CardBleed": {
1703
+ "props": {
1704
+ "side": {
1705
+ "type": {
1706
+ "name": "union",
1707
+ "raw": "\"x\" (default) | \"top\" | \"bottom\" | \"y\" | \"all\""
1708
+ },
1709
+ "required": false,
1710
+ "description": "which card padding to negate; top/bottom/y for direct children — inherit the card radius; x/all for content inside a slot"
1711
+ }
1712
+ }
1713
+ }
1714
+ },
1705
1715
  "examples": [
1706
1716
  "<Card variant=\"elevated\" interactive onClick={() => navigate(url)}>\n <CardHeader>\n <CardTitle>Project</CardTitle>\n <CardDescription>Last updated 2h ago</CardDescription>\n </CardHeader>\n <CardContent><p>Content here</p></CardContent>\n</Card>"
1707
1717
  ],
@@ -1857,12 +1867,18 @@
1857
1867
  "required": false,
1858
1868
  "defaultValue": "md"
1859
1869
  },
1860
- "error": {
1870
+ "state": {
1861
1871
  "type": {
1862
- "name": "boolean"
1872
+ "name": "enum",
1873
+ "value": [
1874
+ "default",
1875
+ "error",
1876
+ "warning",
1877
+ "success"
1878
+ ]
1863
1879
  },
1864
1880
  "required": false,
1865
- "description": "shows red border"
1881
+ "description": "validation border/bg tint; error sets aria-invalid. Inherited from FormField when omitted"
1866
1882
  },
1867
1883
  "indeterminate": {
1868
1884
  "type": {
@@ -1898,6 +1914,10 @@
1898
1914
  "WCAG 2.5.8 minimum target size met at md (24px); sm (20px) may fail if not paired with enough label hit area"
1899
1915
  ],
1900
1916
  "changes": [
1917
+ {
1918
+ "version": "0.49.0",
1919
+ "summary": "**BREAKING** Removed the `error: boolean` prop; use `state` (`FieldState = \"default\" | \"error\" | \"warning\" | \"success\"`). Migrate `<Checkbox error />` → `<Checkbox state=\"error\" />`. Gains `warning`/`success` tints and now inherits state from `FormField`."
1920
+ },
1901
1921
  {
1902
1922
  "version": "0.22.0",
1903
1923
  "summary": "**Changed** Check indicator animation from scale-bounce to path-draw (stroke draws progressively). Indeterminate dash also draws in."
@@ -2273,6 +2293,19 @@
2273
2293
  "description": "trigger height",
2274
2294
  "defaultValue": "md"
2275
2295
  },
2296
+ "state": {
2297
+ "type": {
2298
+ "name": "enum",
2299
+ "value": [
2300
+ "default",
2301
+ "error",
2302
+ "warning",
2303
+ "success"
2304
+ ]
2305
+ },
2306
+ "required": false,
2307
+ "description": "validation border tint; error sets aria-invalid. Inherited from FormField when omitted"
2308
+ },
2276
2309
  "Multiple": {
2277
2310
  "type": {
2278
2311
  "name": "function",
@@ -2372,6 +2405,10 @@
2372
2405
  "Dropdown content is portalled to document.body — parent styles like `overflow: hidden` don't clip it, and container-scoped test queries won't find it"
2373
2406
  ],
2374
2407
  "changes": [
2408
+ {
2409
+ "version": "0.49.0",
2410
+ "summary": "**Added** `state` prop (`FieldState = \"default\" | \"error\" | \"warning\" | \"success\"`) — unified field-state API. Renders a validation border tint + sets `aria-invalid`; inherits from `FormField` when omitted. (Additive — Combobox had no prior validation prop.)"
2411
+ },
2375
2412
  {
2376
2413
  "version": "0.18.0",
2377
2414
  "summary": "**Added** `accessibleLabel` prop — custom aria-label for trigger, falls back to placeholder"
@@ -3171,6 +3208,130 @@
3171
3208
  }
3172
3209
  ]
3173
3210
  },
3211
+ "dot": {
3212
+ "displayName": "Dot",
3213
+ "tier": "ui",
3214
+ "import": "@devalok/shilp-sutra/ui/dot",
3215
+ "serverSafe": false,
3216
+ "description": "A small semantic status/indicator dot — the low-level primitive behind status pills, presence indicators, legend swatches, and `StatusDot`. Intent-coloured, sized, optionally pulsing, filled or ring.",
3217
+ "props": {
3218
+ "color": {
3219
+ "type": {
3220
+ "name": "enum",
3221
+ "value": [
3222
+ "accent",
3223
+ "success",
3224
+ "warning",
3225
+ "error",
3226
+ "info",
3227
+ "neutral",
3228
+ "current"
3229
+ ]
3230
+ },
3231
+ "required": false,
3232
+ "description": "intent colour; `current` inherits text colour"
3233
+ },
3234
+ "size": {
3235
+ "type": {
3236
+ "name": "enum",
3237
+ "value": [
3238
+ "xs",
3239
+ "sm",
3240
+ "md",
3241
+ "lg"
3242
+ ]
3243
+ },
3244
+ "required": false
3245
+ },
3246
+ "variant": {
3247
+ "type": {
3248
+ "name": "enum",
3249
+ "value": [
3250
+ "filled",
3251
+ "ring",
3252
+ "off"
3253
+ ]
3254
+ },
3255
+ "required": false,
3256
+ "description": "`off` = faint fill + light border, i.e. inactive"
3257
+ },
3258
+ "withBorder": {
3259
+ "type": {
3260
+ "name": "boolean"
3261
+ },
3262
+ "required": false,
3263
+ "description": "contrast ring so the dot stays visible on busy/coloured backgrounds"
3264
+ },
3265
+ "pulse": {
3266
+ "type": {
3267
+ "name": "boolean"
3268
+ },
3269
+ "required": false,
3270
+ "description": "animate a pulsing ripple; ignored for `off`"
3271
+ },
3272
+ "pulseSpeed": {
3273
+ "type": {
3274
+ "name": "enum",
3275
+ "value": [
3276
+ "slow",
3277
+ "normal",
3278
+ "fast"
3279
+ ]
3280
+ },
3281
+ "required": false,
3282
+ "description": "pulse tempo"
3283
+ },
3284
+ "label": {
3285
+ "type": {
3286
+ "name": "ReactNode"
3287
+ },
3288
+ "required": false,
3289
+ "description": "inline text; makes the dot an announced status"
3290
+ },
3291
+ "labelPosition": {
3292
+ "type": {
3293
+ "name": "enum",
3294
+ "value": [
3295
+ "start",
3296
+ "end"
3297
+ ]
3298
+ },
3299
+ "required": false,
3300
+ "description": "which side the label sits on"
3301
+ },
3302
+ "labelClassName": {
3303
+ "type": {
3304
+ "name": "string"
3305
+ },
3306
+ "required": false
3307
+ }
3308
+ },
3309
+ "composition": {
3310
+ "notes": [
3311
+ "**Decorative vs announced.** A bare `<Dot>` is `aria-hidden` (the surrounding element carries meaning — e.g. a Badge's text). Pass a `label` (or `aria-label`) to make it a `role=\"status\"` announced indicator.",
3312
+ "**Intent colour, shared vocabulary.** `color` uses the same intent names as the rest of the system (`accent/success/warning/error/info/neutral`), so a Dot next to a Badge/Button of the same intent matches.",
3313
+ "**`pulse` = \"live\".** Off by default (static status). Turn it on for active/attention states (recording, live, connecting) — a pulsing dot reads as \"happening now\", so leave it off for settled statuses.",
3314
+ "**Powers the higher-level pieces.** `StatusBadge` composes `<Badge>` + `<Dot>`; use `Dot` directly anywhere you need a coloured indicator without a pill.",
3315
+ "**Three treatments:** `filled` (active), `ring` (hollow outline), `off` (faint same-tone fill + light border — present but inactive/disabled).",
3316
+ "**`withBorder`** adds a contrast ring (`ring-2 ring-surface-raised`) so the dot reads on avatars, images, or coloured fills — the pattern Avatar's status dot uses.",
3317
+ "**`pulseSpeed`** (slow/normal/fast) tunes the pulse tempo — fast for urgent (recording), slow for ambient (syncing)."
3318
+ ]
3319
+ },
3320
+ "docPath": "docs/components/ui/dot.md",
3321
+ "examples": [
3322
+ "<Dot color=\"success\" /> {/* bare, decorative */}\n<Dot color=\"error\" pulse pulseSpeed=\"fast\" label=\"Recording\" /> {/* pulsing + announced */}\n<Dot color=\"neutral\" variant=\"off\" label=\"Offline\" /> {/* inactive: faint fill + light border */}\n<Dot color=\"success\" withBorder /> {/* contrast ring for busy backgrounds */}\n<Dot color=\"accent\" label=\"3 online\" labelPosition=\"start\" /> {/* label before the dot */}\n<Dot color=\"neutral\" variant=\"ring\" size=\"lg\" /> {/* hollow ring */}\n\n// As leading content in a pill:\n<Badge variant=\"soft\" color=\"warning\" startIcon={<Dot color=\"warning\" size=\"sm\" />}>\n Pending\n</Badge>"
3323
+ ],
3324
+ "gotchas": [
3325
+ "A bare dot is decorative by design — if a dot is the *only* signal (no adjacent text), give it a `label` or `aria-label` so it's announced.",
3326
+ "`pulse` respects `prefers-reduced-motion` (the ripple is disabled)."
3327
+ ],
3328
+ "changes": [
3329
+ {
3330
+ "version": "0.49.0",
3331
+ "summary": "**Added** Initial release. Extracted as the shared primitive behind `StatusDot`, `StatusBadge`, and `Badge`'s dot. Colours `accent/success/warning/error/info/neutral/current`; sizes `xs–lg`; variants `filled/ring/off`; `withBorder` contrast ring; `pulse` + `pulseSpeed`; `label` + `labelPosition`."
3332
+ }
3333
+ ]
3334
+ },
3174
3335
  "dropdown-menu": {
3175
3336
  "displayName": "DropdownMenu",
3176
3337
  "tier": "ui",
@@ -3372,7 +3533,7 @@
3372
3533
  ]
3373
3534
  },
3374
3535
  "required": false,
3375
- "description": "inherits from FormField context"
3536
+ "defaultValue": "helper"
3376
3537
  },
3377
3538
  "helperTextId": {
3378
3539
  "type": {
@@ -3396,6 +3557,25 @@
3396
3557
  ]
3397
3558
  },
3398
3559
  "docPath": "docs/components/ui/form.md",
3560
+ "subComponents": {
3561
+ "FormHelperText": {
3562
+ "props": {
3563
+ "state": {
3564
+ "type": {
3565
+ "name": "enum",
3566
+ "value": [
3567
+ "helper",
3568
+ "error",
3569
+ "warning",
3570
+ "success"
3571
+ ]
3572
+ },
3573
+ "required": false,
3574
+ "description": "inherits from FormField context"
3575
+ }
3576
+ }
3577
+ }
3578
+ },
3399
3579
  "examples": [
3400
3580
  "<FormField state=\"error\">\n <Label htmlFor=\"email\">Email</Label>\n <Input id=\"email\" state=\"error\" />\n <FormHelperText>Please enter a valid email.</FormHelperText>\n</FormField>"
3401
3581
  ],
@@ -3991,13 +4171,6 @@
3991
4171
  },
3992
4172
  "required": false,
3993
4173
  "description": "on the outer group container — separate from inner input's className"
3994
- },
3995
- "index": {
3996
- "type": {
3997
- "name": "object",
3998
- "raw": "number (REQUIRED, 0-based) — which position this slot renders"
3999
- },
4000
- "required": false
4001
4174
  }
4002
4175
  },
4003
4176
  "composition": {
@@ -4030,6 +4203,19 @@
4030
4203
  "size": "md",
4031
4204
  "state": "default"
4032
4205
  },
4206
+ "subComponents": {
4207
+ "InputOTPSlot": {
4208
+ "props": {
4209
+ "index": {
4210
+ "type": {
4211
+ "name": "object",
4212
+ "raw": "number (REQUIRED, 0-based) — which position this slot renders"
4213
+ },
4214
+ "required": false
4215
+ }
4216
+ }
4217
+ }
4218
+ },
4033
4219
  "examples": [
4034
4220
  "<InputOTP maxLength={6} onComplete={verifyCode}>\n <InputOTPGroup>\n <InputOTPSlot index={0} />\n <InputOTPSlot index={1} />\n <InputOTPSlot index={2} />\n </InputOTPGroup>\n <InputOTPSeparator />\n <InputOTPGroup>\n <InputOTPSlot index={3} />\n <InputOTPSlot index={4} />\n <InputOTPSlot index={5} />\n </InputOTPGroup>\n</InputOTP>"
4035
4221
  ],
@@ -4555,15 +4741,22 @@
4555
4741
  "tier": "ui",
4556
4742
  "import": "@devalok/shilp-sutra/ui/progress",
4557
4743
  "serverSafe": false,
4558
- "description": "",
4744
+ "description": "A linear progress bar. Use the smart all-in-one `<Progress value={70} />` for the common cases, or the compound parts (`Progress.Root` / `Track` / `Indicator` / `Segment` / `Label` / `Value`) for full layout control and multi-segment bars.",
4559
4745
  "props": {
4560
4746
  "value": {
4561
4747
  "type": {
4562
- "name": "object",
4563
- "raw": "number (0-100) — omit for indeterminate"
4748
+ "name": "union",
4749
+ "raw": "number | null (0–max) — omit or null for an indeterminate bar"
4564
4750
  },
4565
4751
  "required": false
4566
4752
  },
4753
+ "max": {
4754
+ "type": {
4755
+ "name": "number"
4756
+ },
4757
+ "required": false,
4758
+ "description": "scale maximum, default 100"
4759
+ },
4567
4760
  "size": {
4568
4761
  "type": {
4569
4762
  "name": "enum",
@@ -4580,7 +4773,7 @@
4580
4773
  "type": {
4581
4774
  "name": "enum",
4582
4775
  "value": [
4583
- "default",
4776
+ "accent",
4584
4777
  "success",
4585
4778
  "warning",
4586
4779
  "error"
@@ -4594,43 +4787,103 @@
4594
4787
  "name": "boolean"
4595
4788
  },
4596
4789
  "required": false,
4597
- "description": "auto-shifts color by value: 0-59=default, 60-84=warning, 85-100=success, >100=error"
4790
+ "description": "auto-shift color by value: 0-59=accent, 60-84=warning, 85-100=success, >100=error"
4791
+ },
4792
+ "label": {
4793
+ "type": {
4794
+ "name": "ReactNode"
4795
+ },
4796
+ "required": false,
4797
+ "description": "descriptive label rendered before the bar; names the bar for a11y"
4598
4798
  },
4599
- "showLabel": {
4799
+ "showValue": {
4600
4800
  "type": {
4601
4801
  "name": "boolean"
4602
4802
  },
4603
4803
  "required": false,
4604
- "description": "shows percentage text"
4804
+ "description": "shows the \"{n}%\" readout after the bar"
4805
+ },
4806
+ "segments": {
4807
+ "type": {
4808
+ "name": "union",
4809
+ "raw": "{ value: number; color?: \"accent\" | \"success\" | \"warning\" | \"error\" }[]"
4810
+ },
4811
+ "required": false,
4812
+ "description": "multi-segment bar; overrides the single indicator"
4813
+ },
4814
+ "trackClassName": {
4815
+ "type": {
4816
+ "name": "string"
4817
+ },
4818
+ "required": false,
4819
+ "description": "class for the Track element"
4605
4820
  },
4606
4821
  "indicatorClassName": {
4607
4822
  "type": {
4608
4823
  "name": "string"
4609
4824
  },
4610
- "required": false
4825
+ "required": false,
4826
+ "description": "class for the single Indicator; ignored when segments set"
4611
4827
  }
4612
4828
  },
4613
4829
  "composition": {
4614
4830
  "notes": [
4615
- "**Radix Progress** underneath `value` (determinate) or absent (indeterminate). Standard ARIA: role=progressbar, aria-valuenow/min/max.",
4616
- "**autoColor semantic signal:** Maps value thresholds to color so consumers don't have to manually compute: 0–59=default, 60–84=warning, 85–100=success, >100=error. Useful for storage meters, budget trackers, goal progress.",
4617
- "**Indeterminate:** Omit `value` to get a continuous animated indeterminate bar. Use for unknown-duration loads.",
4618
- "**Progress vs ProgressRing:** Progress is a linear bar (horizontal). ProgressRing is circular. ProgressRing offers multi-ring stacked variants; Progress doesn't.",
4619
- "**Inside Card/StatCard:** StatCard has a `progress` prop that renders a thin inline version use that inside StatCards instead of a separate Progress."
4831
+ "**Two APIs, one component.** The smart `<Progress>` composes the parts for you; reach for the compound parts when you need a custom layout (label above the bar, value inside, multiple bars) or multi-segment fills. Structure follows Ark UI / Chakra; `Progress.Segment` follows Mantine.",
4832
+ "**`Progress.Track` is the accessible progressbar** (role=progressbar, aria-valuenow/min/max from `Root`'s value). Give it a name via `aria-label`, or a `Progress.Label` + matching `aria-labelledby`. The smart form wires this from the `label` prop / a passed `aria-label` automatically.",
4833
+ "**autoColor semantic signal:** maps value thresholds to color (0–59 accent · 60–84 warning · 85–100 success · >100 error) — storage meters, budget trackers, goal progress. Pass an explicit `color` to opt out.",
4834
+ "**Segments** render side-by-side, each `value` as a % of `max`; the Track's aria value still reflects `Root`'s `value`.",
4835
+ "**Indeterminate:** omit `value` (or pass `null`) for the continuous sweep. Motion-reduced users get a static bar.",
4836
+ "**Progress vs ProgressRing:** Progress is linear; `ProgressRing` is circular (with multi-ring stacked variants)."
4837
+ ],
4838
+ "parts": [
4839
+ {
4840
+ "name": "Progress",
4841
+ "description": "smart all-in-one — value/size/color/label/showValue/autoColor/segments"
4842
+ },
4843
+ {
4844
+ "name": "Progress.Root",
4845
+ "description": "layout container + context; owns value/max/size"
4846
+ },
4847
+ {
4848
+ "name": "Progress.Label",
4849
+ "description": "descriptive label; give it id + point Track's aria-labelledby at it"
4850
+ },
4851
+ {
4852
+ "name": "Progress.Track",
4853
+ "description": "the aria progressbar + track visual; holds Indicator or Segments"
4854
+ },
4855
+ {
4856
+ "name": "Progress.Indicator",
4857
+ "description": "single fill; color, or auto-color by value"
4858
+ },
4859
+ {
4860
+ "name": "Progress.Segment",
4861
+ "description": "one slice of a multi-segment bar — value + color"
4862
+ },
4863
+ {
4864
+ "name": "Progress.Value",
4865
+ "description": "the \"{n}%\" readout; custom via children or a `format` fn"
4866
+ }
4620
4867
  ]
4621
4868
  },
4622
4869
  "docPath": "docs/components/ui/progress.md",
4623
4870
  "examples": [
4624
- "<Progress value={75} color=\"success\" showLabel />\n<Progress size=\"sm\" /> {/* indeterminate */}"
4871
+ "// Simple:\n<Progress value={75} color=\"success\" showValue />\n<Progress size=\"sm\" /> {/* indeterminate */}\n<Progress value={80} autoColor showValue /> {/* color follows value */}\n\n// Multi-segment (Mantine-style):\n<Progress segments={[{ value: 40, color: 'success' }, { value: 30, color: 'warning' }]} />\n\n// Compound — full control:\n<Progress.Root value={62} size=\"lg\">\n <Progress.Label id=\"storage-lbl\">Storage</Progress.Label>\n <Progress.Track aria-labelledby=\"storage-lbl\">\n <Progress.Indicator color=\"warning\" />\n </Progress.Track>\n <Progress.Value format={(pct) => `${pct}% of 50 GB`} />\n</Progress.Root>"
4625
4872
  ],
4626
4873
  "gotchas": [
4627
- "Omit value (or pass undefined) for indeterminate animation",
4628
- "`autoColor` overrides `color` when `value` is set — do not pass both unless you want autoColor to win"
4874
+ "Omit `value` (or pass `null`) for indeterminate.",
4875
+ "Pass an explicit `color` to override `autoColor`.",
4876
+ "Compound `Progress.Track` needs a name — an `aria-label`, or a `Progress.Label` whose `id` the Track's `aria-labelledby` points to. A Track with neither is an unnamed progressbar (axe will flag it).",
4877
+ "`Progress.Indicator` / `Segment` / `Value` throw if rendered outside `Progress.Root`."
4629
4878
  ],
4630
4879
  "changes": [
4880
+ {
4881
+ "version": "0.49.0",
4882
+ "summary": "**BREAKING** Progress redesigned as a compound component. Renamed `showLabel` → `showValue`. The `color` neutral value `\"default\"` → `\"accent\"` (the type is now `\"accent\" | \"success\" | \"warning\" | \"error\"`). Added compound parts (`Progress.Root/Track/Indicator/Segment/Label/Value`), a `label` prop, a `max` prop, a `segments` prop (multi-segment bars), and `trackClassName`. Migrate `showLabel` → `showValue` and `color=\"default\"` → `color=\"accent\"` (or drop it — accent is the default)."
4883
+ },
4631
4884
  {
4632
4885
  "version": "0.29.0",
4633
- "summary": "**Added** `autoColor` prop — automatically shifts indicator color based on value thresholds (0-59 default, 60-84 warning, 85-100 success, >100 error)"
4886
+ "summary": "**Added** `autoColor` prop — automatically shifts indicator color based on value thresholds"
4634
4887
  },
4635
4888
  {
4636
4889
  "version": "0.1.0",
@@ -4700,13 +4953,6 @@
4700
4953
  },
4701
4954
  "required": false,
4702
4955
  "description": "accessible label — falls back to \"{n}% progress\""
4703
- },
4704
- "rings": {
4705
- "type": {
4706
- "name": "union",
4707
- "raw": "Array<{ value: number; max?: number; color?: \"default\" | \"success\" | \"warning\" | \"error\" | \"info\"; label?: string }>"
4708
- },
4709
- "required": false
4710
4956
  }
4711
4957
  },
4712
4958
  "composition": {
@@ -4725,6 +4971,30 @@
4725
4971
  "color": "default",
4726
4972
  "showValue": "{false}"
4727
4973
  },
4974
+ "subComponents": {
4975
+ "MultiProgressRing": {
4976
+ "props": {
4977
+ "rings": {
4978
+ "type": {
4979
+ "name": "union",
4980
+ "raw": "Array<{ value: number; max?: number; color?: \"default\" | \"success\" | \"warning\" | \"error\" | \"info\"; label?: string }>"
4981
+ },
4982
+ "required": false
4983
+ },
4984
+ "size": {
4985
+ "type": {
4986
+ "name": "enum",
4987
+ "value": [
4988
+ "sm",
4989
+ "md",
4990
+ "lg"
4991
+ ]
4992
+ },
4993
+ "required": false
4994
+ }
4995
+ }
4996
+ }
4997
+ },
4728
4998
  "examples": [
4729
4999
  "<ProgressRing value={75} />\n<ProgressRing value={3} max={12} size=\"lg\" color=\"warning\" showValue />\n\n<MultiProgressRing\n rings={[\n { value: 80, color: 'error', label: 'Move' },\n { value: 60, color: 'success', label: 'Exercise' },\n ]}\n size=\"lg\"\n/>"
4730
5000
  ],
@@ -4746,7 +5016,7 @@
4746
5016
  "name": "string"
4747
5017
  },
4748
5018
  "required": false,
4749
- "description": "REQUIRED — what's selected when this item is checked"
5019
+ "description": "controlled"
4750
5020
  },
4751
5021
  "onValueChange": {
4752
5022
  "type": {
@@ -4766,7 +5036,7 @@
4766
5036
  "name": "boolean"
4767
5037
  },
4768
5038
  "required": false,
4769
- "description": "item-level override"
5039
+ "description": "propagates to all items"
4770
5040
  },
4771
5041
  "orientation": {
4772
5042
  "type": {
@@ -4785,17 +5055,18 @@
4785
5055
  "required": false,
4786
5056
  "description": "form name for all items"
4787
5057
  },
4788
- "size": {
5058
+ "state": {
4789
5059
  "type": {
4790
5060
  "name": "enum",
4791
5061
  "value": [
4792
- "sm",
4793
- "md",
4794
- "lg"
5062
+ "default",
5063
+ "error",
5064
+ "warning",
5065
+ "success"
4795
5066
  ]
4796
5067
  },
4797
5068
  "required": false,
4798
- "defaultValue": "md"
5069
+ "description": "validation; sets aria-invalid on the group + tints item borders. Inherited from FormField when omitted"
4799
5070
  }
4800
5071
  },
4801
5072
  "composition": {
@@ -4804,7 +5075,7 @@
4804
5075
  "**RadioGroup propagates** `disabled` to every RadioGroupItem; items can opt back in with `disabled={false}` for granular control (rare).",
4805
5076
  "**Labels:** RadioGroupItem has no intrinsic label — pair each with `<Label htmlFor=\"x\" />` + `<RadioGroupItem id=\"x\" value=\"...\" />`. Screen readers announce the group label (from FormField or aria-labelledby on RadioGroup) plus each item's label.",
4806
5077
  "**Form libraries:** RadioGroup works with react-hook-form via Controller (onValueChange maps to field.onChange). The `name` prop puts a hidden form input per item for native form serialization.",
4807
- "**FormField integration:** RadioGroup does NOT auto-consume FormField error state. For error visuals, style the RadioGroup surround (e.g. via aria-invalid on a wrapping fieldset) individual radios don't show red borders the way Inputs do."
5078
+ "**FormField integration:** RadioGroup now consumes FormField state (or set `state` explicitly). It sets `aria-invalid` on the group and tints each item's border to matchunified with the other form controls via the shared `FieldState` type. An explicit `state` prop wins over FormField context."
4808
5079
  ],
4809
5080
  "parts": [
4810
5081
  {
@@ -4821,15 +5092,50 @@
4821
5092
  "defaults": {
4822
5093
  "size": "md"
4823
5094
  },
5095
+ "subComponents": {
5096
+ "RadioGroupItem": {
5097
+ "props": {
5098
+ "value": {
5099
+ "type": {
5100
+ "name": "string"
5101
+ },
5102
+ "required": false,
5103
+ "description": "REQUIRED — what's selected when this item is checked"
5104
+ },
5105
+ "size": {
5106
+ "type": {
5107
+ "name": "enum",
5108
+ "value": [
5109
+ "sm",
5110
+ "md",
5111
+ "lg"
5112
+ ]
5113
+ },
5114
+ "required": false
5115
+ },
5116
+ "disabled": {
5117
+ "type": {
5118
+ "name": "boolean"
5119
+ },
5120
+ "required": false,
5121
+ "description": "item-level override"
5122
+ }
5123
+ }
5124
+ }
5125
+ },
4824
5126
  "examples": [
4825
5127
  "<RadioGroup defaultValue=\"option-1\" onValueChange={setValue}>\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"option-1\" id=\"r1\" />\n <Label htmlFor=\"r1\">Option 1</Label>\n </div>\n <div className=\"flex items-center gap-2\">\n <RadioGroupItem value=\"option-2\" id=\"r2\" />\n <Label htmlFor=\"r2\">Option 2</Label>\n </div>\n</RadioGroup>"
4826
5128
  ],
4827
5129
  "gotchas": [
4828
5130
  "Each RadioGroupItem needs a unique `value` prop",
4829
5131
  "Pair each item with a Label for accessibility",
4830
- "RadioGroup does NOT auto-inherit FormField error state handle error styling at the group level"
5132
+ "RadioGroup inherits FormField state; pass `state` explicitly to override"
4831
5133
  ],
4832
5134
  "changes": [
5135
+ {
5136
+ "version": "0.49.0",
5137
+ "summary": "**Added** `state` prop on RadioGroup (`FieldState = \"default\" | \"error\" | \"warning\" | \"success\"`) — unified field-state API. Sets `aria-invalid` + tints item borders, and now inherits from `FormField` context."
5138
+ },
4833
5139
  {
4834
5140
  "version": "0.4.2",
4835
5141
  "summary": "**Added** `RadioGroupProps`, `RadioGroupItemProps` type exports"
@@ -5024,65 +5330,25 @@
5024
5330
  "import": "@devalok/shilp-sutra/ui/select",
5025
5331
  "serverSafe": false,
5026
5332
  "description": "",
5027
- "props": {
5028
- "variant": {
5029
- "type": {
5030
- "name": "enum",
5031
- "value": [
5032
- "default",
5033
- "outline",
5034
- "ghost"
5035
- ]
5036
- },
5037
- "required": false,
5038
- "defaultValue": "default"
5039
- },
5040
- "color": {
5041
- "type": {
5042
- "name": "enum",
5043
- "value": [
5044
- "default",
5045
- "error",
5046
- "success",
5047
- "warning"
5048
- ]
5049
- },
5050
- "required": false,
5051
- "description": "sets aria-invalid when error",
5052
- "defaultValue": "default"
5053
- },
5054
- "size": {
5055
- "type": {
5056
- "name": "enum",
5057
- "value": [
5058
- "xs",
5059
- "sm",
5060
- "md",
5061
- "lg"
5062
- ]
5063
- },
5064
- "required": false,
5065
- "defaultValue": "md"
5066
- }
5067
- },
5068
- "composition": {
5069
- "notes": [
5070
- "**Radix Select** underneath — `value`/`onValueChange`/`defaultValue`/`open`/`onOpenChange` standard state.",
5071
- "**Styling props live on SelectTrigger, not Select root.** The Select root owns value/state; the Trigger owns appearance (variant/color/size). Setting `<Select size=\"lg\">` silently does nothing — TypeScript won't catch it.",
5072
- "**SelectItem requires `value`** — unique within the Select. Labels are the children of SelectItem.",
5073
- "**SelectGroup + SelectLabel:** Organize options into sections with a non-interactive section heading.",
5074
- "**FormField integration:** Set `color=\"error\"` on SelectTrigger for error visuals. Not auto-consumed from FormField (same as Checkbox/Radio — form-library convention for select controls).",
5075
- "**Portal + z-popover (1400):** content portals to body, stacks above Dialog/Sheet/other overlays.",
5076
- "**Select vs Combobox vs Autocomplete:** Select = short fixed list, click-to-open, no typeahead. Combobox = searchable, forced selection. Autocomplete = searchable, free text. Pick by list size and search need."
5077
- ],
5078
- "parts": [
5079
- {
5080
- "name": "Select",
5081
- "description": "root — value, onValueChange, defaultValue"
5333
+ "props": {},
5334
+ "composition": {
5335
+ "notes": [
5336
+ "**Radix Select** underneath — `value`/`onValueChange`/`defaultValue`/`open`/`onOpenChange` standard state.",
5337
+ "**Styling props live on SelectTrigger, not Select root.** The Select root owns value/state; the Trigger owns appearance (variant/state/size). Setting `<Select size=\"lg\">` silently does nothing — TypeScript won't catch it.",
5338
+ "**SelectItem requires `value`** — unique within the Select. Labels are the children of SelectItem.",
5339
+ "**SelectGroup + SelectLabel:** Organize options into sections with a non-interactive section heading.",
5340
+ "**FormField integration:** Set `state=\"error\"` on SelectTrigger for error visuals, or omit it inside a `<FormField state=\"error\">` — SelectTrigger now inherits the field state from context (explicit `state` prop wins). Unified with Input/Textarea/Checkbox/Radio/Switch/Combobox via the shared `FieldState` type.",
5341
+ "**Portal + z-popover (1400):** content portals to body, stacks above Dialog/Sheet/other overlays.",
5342
+ "**Select vs Combobox vs Autocomplete:** Select = short fixed list, click-to-open, no typeahead. Combobox = searchable, forced selection. Autocomplete = searchable, free text. Pick by list size and search need."
5343
+ ],
5344
+ "parts": [
5345
+ {
5346
+ "name": "Select",
5347
+ "description": "root — value, onValueChange, defaultValue"
5082
5348
  },
5083
5349
  {
5084
5350
  "name": "SelectTrigger",
5085
- "description": "variant/color/size go HERE, not on Select root"
5351
+ "description": "variant/state/size go HERE, not on Select root"
5086
5352
  },
5087
5353
  {
5088
5354
  "name": "SelectValue",
@@ -5111,9 +5377,51 @@
5111
5377
  "docPath": "docs/components/ui/select.md",
5112
5378
  "defaults": {
5113
5379
  "variant": "default",
5114
- "color": "default",
5380
+ "state": "default",
5115
5381
  "size": "md"
5116
5382
  },
5383
+ "subComponents": {
5384
+ "SelectTrigger": {
5385
+ "props": {
5386
+ "variant": {
5387
+ "type": {
5388
+ "name": "enum",
5389
+ "value": [
5390
+ "default",
5391
+ "outline",
5392
+ "ghost"
5393
+ ]
5394
+ },
5395
+ "required": false
5396
+ },
5397
+ "state": {
5398
+ "type": {
5399
+ "name": "enum",
5400
+ "value": [
5401
+ "default",
5402
+ "error",
5403
+ "warning",
5404
+ "success"
5405
+ ]
5406
+ },
5407
+ "required": false,
5408
+ "description": "validation; sets aria-invalid when error. Inherited from FormField when omitted"
5409
+ },
5410
+ "size": {
5411
+ "type": {
5412
+ "name": "enum",
5413
+ "value": [
5414
+ "xs",
5415
+ "sm",
5416
+ "md",
5417
+ "lg"
5418
+ ]
5419
+ },
5420
+ "required": false
5421
+ }
5422
+ }
5423
+ }
5424
+ },
5117
5425
  "examples": [
5118
5426
  "<Select onValueChange={setValue}>\n <SelectTrigger size=\"lg\">\n <SelectValue placeholder=\"Choose...\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"a\">Option A</SelectItem>\n <SelectItem value=\"b\">Option B</SelectItem>\n </SelectContent>\n</Select>"
5119
5427
  ],
@@ -5122,6 +5430,10 @@
5122
5430
  "`<Select size=\"lg\">` is silently ignored (no TypeScript error)"
5123
5431
  ],
5124
5432
  "changes": [
5433
+ {
5434
+ "version": "0.49.0",
5435
+ "summary": "**BREAKING** Renamed the SelectTrigger `color` prop → `state` (unified field-state API across all form controls; type `FieldState = \"default\" | \"error\" | \"warning\" | \"success\"`). Migrate `<SelectTrigger color=\"error\">` → `<SelectTrigger state=\"error\">`."
5436
+ },
5125
5437
  {
5126
5438
  "version": "0.31.0",
5127
5439
  "summary": "**Added** `variant` prop on SelectTrigger: `default | outline | ghost`"
@@ -5204,21 +5516,7 @@
5204
5516
  "import": "@devalok/shilp-sutra/ui/sheet",
5205
5517
  "serverSafe": false,
5206
5518
  "description": "",
5207
- "props": {
5208
- "side": {
5209
- "type": {
5210
- "name": "enum",
5211
- "value": [
5212
- "top",
5213
- "bottom",
5214
- "left",
5215
- "right"
5216
- ]
5217
- },
5218
- "required": false,
5219
- "defaultValue": "right"
5220
- }
5221
- },
5519
+ "props": {},
5222
5520
  "composition": {
5223
5521
  "notes": [
5224
5522
  "Same primitives as Dialog — open/onOpenChange/defaultOpen, trigger asChild, portal rendering, focus trap.",
@@ -5259,6 +5557,24 @@
5259
5557
  "defaults": {
5260
5558
  "side": "right"
5261
5559
  },
5560
+ "subComponents": {
5561
+ "SheetContent": {
5562
+ "props": {
5563
+ "side": {
5564
+ "type": {
5565
+ "name": "enum",
5566
+ "value": [
5567
+ "top",
5568
+ "bottom",
5569
+ "left",
5570
+ "right"
5571
+ ]
5572
+ },
5573
+ "required": false
5574
+ }
5575
+ }
5576
+ }
5577
+ },
5262
5578
  "examples": [
5263
5579
  "<Sheet>\n <SheetTrigger asChild><Button>Open</Button></SheetTrigger>\n <SheetContent side=\"right\">\n <SheetHeader>\n <SheetTitle>Settings</SheetTitle>\n </SheetHeader>\n <div>Content</div>\n </SheetContent>\n</Sheet>"
5264
5580
  ],
@@ -5451,77 +5767,6 @@
5451
5767
  },
5452
5768
  "required": false,
5453
5769
  "defaultValue": "pulse"
5454
- },
5455
- "size": {
5456
- "type": {
5457
- "name": "enum",
5458
- "value": [
5459
- "sm",
5460
- "md",
5461
- "lg"
5462
- ]
5463
- },
5464
- "required": false,
5465
- "defaultValue": "md"
5466
- },
5467
- "lines": {
5468
- "type": {
5469
- "name": "number"
5470
- },
5471
- "required": false,
5472
- "defaultValue": 3
5473
- },
5474
- "lastLineWidth": {
5475
- "type": {
5476
- "name": "enum",
5477
- "value": [
5478
- "full",
5479
- "three-quarter",
5480
- "half"
5481
- ]
5482
- },
5483
- "required": false,
5484
- "defaultValue": "three-quarter"
5485
- },
5486
- "spacing": {
5487
- "type": {
5488
- "name": "enum",
5489
- "value": [
5490
- "sm",
5491
- "md"
5492
- ]
5493
- },
5494
- "required": false,
5495
- "defaultValue": "md"
5496
- },
5497
- "width": {
5498
- "type": {
5499
- "name": "string"
5500
- },
5501
- "required": false,
5502
- "defaultValue": "w-full"
5503
- },
5504
- "bars": {
5505
- "type": {
5506
- "name": "number"
5507
- },
5508
- "required": false,
5509
- "defaultValue": 7
5510
- },
5511
- "height": {
5512
- "type": {
5513
- "name": "string"
5514
- },
5515
- "required": false,
5516
- "defaultValue": "h-40"
5517
- },
5518
- "label": {
5519
- "type": {
5520
- "name": "object",
5521
- "raw": "string (default: \"Loading\") — accessible label for the loading state"
5522
- },
5523
- "required": false,
5524
- "defaultValue": "Loading"
5525
5770
  }
5526
5771
  },
5527
5772
  "composition": {
@@ -5546,6 +5791,212 @@
5546
5791
  "height": "h-40",
5547
5792
  "label": "Loading"
5548
5793
  },
5794
+ "subComponents": {
5795
+ "SkeletonAvatar": {
5796
+ "props": {
5797
+ "size": {
5798
+ "type": {
5799
+ "name": "enum",
5800
+ "value": [
5801
+ "sm",
5802
+ "md",
5803
+ "lg",
5804
+ "xl"
5805
+ ]
5806
+ },
5807
+ "required": false
5808
+ },
5809
+ "animation": {
5810
+ "type": {
5811
+ "name": "enum",
5812
+ "value": [
5813
+ "pulse",
5814
+ "shimmer",
5815
+ "none"
5816
+ ]
5817
+ },
5818
+ "required": false
5819
+ }
5820
+ }
5821
+ },
5822
+ "SkeletonText": {
5823
+ "props": {
5824
+ "lines": {
5825
+ "type": {
5826
+ "name": "number"
5827
+ },
5828
+ "required": false,
5829
+ "defaultValue": 3
5830
+ },
5831
+ "lastLineWidth": {
5832
+ "type": {
5833
+ "name": "enum",
5834
+ "value": [
5835
+ "full",
5836
+ "three-quarter",
5837
+ "half"
5838
+ ]
5839
+ },
5840
+ "required": false,
5841
+ "defaultValue": "three-quarter"
5842
+ },
5843
+ "spacing": {
5844
+ "type": {
5845
+ "name": "enum",
5846
+ "value": [
5847
+ "sm",
5848
+ "md"
5849
+ ]
5850
+ },
5851
+ "required": false,
5852
+ "defaultValue": "md"
5853
+ },
5854
+ "animation": {
5855
+ "type": {
5856
+ "name": "enum",
5857
+ "value": [
5858
+ "pulse",
5859
+ "shimmer",
5860
+ "none"
5861
+ ]
5862
+ },
5863
+ "required": false
5864
+ }
5865
+ }
5866
+ },
5867
+ "SkeletonButton": {
5868
+ "props": {
5869
+ "size": {
5870
+ "type": {
5871
+ "name": "enum",
5872
+ "value": [
5873
+ "sm",
5874
+ "md",
5875
+ "lg"
5876
+ ]
5877
+ },
5878
+ "required": false
5879
+ },
5880
+ "width": {
5881
+ "type": {
5882
+ "name": "enum",
5883
+ "value": [
5884
+ "auto",
5885
+ "full",
5886
+ "icon"
5887
+ ]
5888
+ },
5889
+ "required": false
5890
+ },
5891
+ "animation": {
5892
+ "type": {
5893
+ "name": "enum",
5894
+ "value": [
5895
+ "pulse",
5896
+ "shimmer",
5897
+ "none"
5898
+ ]
5899
+ },
5900
+ "required": false
5901
+ }
5902
+ }
5903
+ },
5904
+ "SkeletonInput": {
5905
+ "props": {
5906
+ "size": {
5907
+ "type": {
5908
+ "name": "enum",
5909
+ "value": [
5910
+ "sm",
5911
+ "md",
5912
+ "lg"
5913
+ ]
5914
+ },
5915
+ "required": false
5916
+ },
5917
+ "animation": {
5918
+ "type": {
5919
+ "name": "enum",
5920
+ "value": [
5921
+ "pulse",
5922
+ "shimmer",
5923
+ "none"
5924
+ ]
5925
+ },
5926
+ "required": false
5927
+ }
5928
+ }
5929
+ },
5930
+ "SkeletonChart": {
5931
+ "props": {
5932
+ "bars": {
5933
+ "type": {
5934
+ "name": "number"
5935
+ },
5936
+ "required": false,
5937
+ "defaultValue": 7
5938
+ },
5939
+ "height": {
5940
+ "type": {
5941
+ "name": "string"
5942
+ },
5943
+ "required": false,
5944
+ "defaultValue": "h-40"
5945
+ },
5946
+ "animation": {
5947
+ "type": {
5948
+ "name": "enum",
5949
+ "value": [
5950
+ "pulse",
5951
+ "shimmer",
5952
+ "none"
5953
+ ]
5954
+ },
5955
+ "required": false
5956
+ }
5957
+ }
5958
+ },
5959
+ "SkeletonImage": {
5960
+ "props": {
5961
+ "width": {
5962
+ "type": {
5963
+ "name": "string"
5964
+ },
5965
+ "required": false,
5966
+ "defaultValue": "w-full"
5967
+ },
5968
+ "height": {
5969
+ "type": {
5970
+ "name": "string"
5971
+ },
5972
+ "required": false,
5973
+ "defaultValue": "h-40"
5974
+ },
5975
+ "animation": {
5976
+ "type": {
5977
+ "name": "enum",
5978
+ "value": [
5979
+ "pulse",
5980
+ "shimmer",
5981
+ "none"
5982
+ ]
5983
+ },
5984
+ "required": false
5985
+ }
5986
+ }
5987
+ },
5988
+ "SkeletonGroup": {
5989
+ "props": {
5990
+ "label": {
5991
+ "type": {
5992
+ "name": "object",
5993
+ "raw": "string (default: \"Loading\") — accessible label for the loading state"
5994
+ },
5995
+ "required": false
5996
+ }
5997
+ }
5998
+ }
5999
+ },
5549
6000
  "examples": [
5550
6001
  "<Skeleton variant=\"text\" className=\"w-3/4\" />\n<Skeleton variant=\"circle\" className=\"h-12 w-12\" />\n<Skeleton variant=\"rectangle\" animation=\"shimmer\" className=\"h-48 w-full\" />\n\n<SkeletonGroup label=\"Loading user profile\">\n <SkeletonAvatar size=\"lg\" />\n <SkeletonText lines={2} />\n <SkeletonButton />\n</SkeletonGroup>\n\n<SkeletonChart bars={5} height=\"h-32\" />\n<SkeletonImage height=\"h-64\" />"
5551
6002
  ],
@@ -6217,82 +6668,6 @@
6217
6668
  }
6218
6669
  ]
6219
6670
  },
6220
- "status-dot": {
6221
- "displayName": "StatusDot",
6222
- "tier": "ui",
6223
- "import": "@devalok/shilp-sutra/ui/status-dot",
6224
- "serverSafe": true,
6225
- "description": "",
6226
- "props": {
6227
- "status": {
6228
- "type": {
6229
- "name": "enum",
6230
- "value": [
6231
- "healthy",
6232
- "warning",
6233
- "critical",
6234
- "neutral",
6235
- "inactive"
6236
- ]
6237
- },
6238
- "required": false
6239
- },
6240
- "size": {
6241
- "type": {
6242
- "name": "enum",
6243
- "value": [
6244
- "sm",
6245
- "md",
6246
- "lg"
6247
- ]
6248
- },
6249
- "required": false,
6250
- "defaultValue": "md"
6251
- },
6252
- "pulse": {
6253
- "type": {
6254
- "name": "boolean"
6255
- },
6256
- "required": false,
6257
- "description": "ping animation; defaults to true for \"healthy\", false for others",
6258
- "defaultValue": "{status ==="
6259
- },
6260
- "label": {
6261
- "type": {
6262
- "name": "string"
6263
- },
6264
- "required": false,
6265
- "description": "inline text rendered after the dot"
6266
- },
6267
- "labelClassName": {
6268
- "type": {
6269
- "name": "string"
6270
- },
6271
- "required": false,
6272
- "description": "extra classes on the label span"
6273
- }
6274
- },
6275
- "composition": {
6276
- "notes": [
6277
- "**Server-safe presentational dot** — simple status indicator, pairs with inline text.",
6278
- "**Status semantics map to color:** healthy=success, warning=warning, critical=error, neutral=muted surface, inactive=dimmed. The pulse animation calls attention to \"healthy\" by default (active presence); you can flip it for other statuses by setting pulse explicitly.",
6279
- "**StatusDot vs BadgeIndicator vs StatusBadge:** - StatusDot = tiny presence/status indicator with optional inline label (e.g. \"Service online\") - BadgeIndicator = overlay on another element (notification dot on a bell icon) - StatusBadge (composed) = full pill-style badge with colored bg and label text (e.g. ticket status)",
6280
- "**Label composability:** If you pass `label`, it renders inline after the dot. Use `labelClassName` for custom typography (e.g. font-mono for status codes)."
6281
- ]
6282
- },
6283
- "docPath": "docs/components/ui/status-dot.md",
6284
- "defaults": {
6285
- "size": "md",
6286
- "pulse": "{status ==="
6287
- },
6288
- "examples": [
6289
- "<StatusDot status=\"healthy\" />\n<StatusDot status=\"critical\" label=\"Service down\" pulse />\n<StatusDot status=\"warning\" size=\"lg\" label=\"Elevated load\" />"
6290
- ],
6291
- "gotchas": [
6292
- "The `pulse` prop auto-enables for \"healthy\" status — pass `pulse={false}` to suppress",
6293
- "Status type is exported as `StatusDotStatus` if you need it in consumer code"
6294
- ]
6295
- },
6296
6671
  "stepper": {
6297
6672
  "displayName": "Stepper / Step",
6298
6673
  "tier": "ui",
@@ -6323,25 +6698,6 @@
6323
6698
  "raw": "<Step> elements"
6324
6699
  },
6325
6700
  "required": false
6326
- },
6327
- "label": {
6328
- "type": {
6329
- "name": "string"
6330
- },
6331
- "required": true
6332
- },
6333
- "description": {
6334
- "type": {
6335
- "name": "string"
6336
- },
6337
- "required": false
6338
- },
6339
- "icon": {
6340
- "type": {
6341
- "name": "ReactNode"
6342
- },
6343
- "required": false,
6344
- "description": "overrides default number/checkmark"
6345
6701
  }
6346
6702
  },
6347
6703
  "composition": {
@@ -6368,6 +6724,31 @@
6368
6724
  ]
6369
6725
  },
6370
6726
  "docPath": "docs/components/ui/stepper.md",
6727
+ "subComponents": {
6728
+ "Step": {
6729
+ "props": {
6730
+ "label": {
6731
+ "type": {
6732
+ "name": "string"
6733
+ },
6734
+ "required": true
6735
+ },
6736
+ "description": {
6737
+ "type": {
6738
+ "name": "string"
6739
+ },
6740
+ "required": false
6741
+ },
6742
+ "icon": {
6743
+ "type": {
6744
+ "name": "ReactNode"
6745
+ },
6746
+ "required": false,
6747
+ "description": "overrides default number/checkmark"
6748
+ }
6749
+ }
6750
+ }
6751
+ },
6371
6752
  "examples": [
6372
6753
  "<Stepper activeStep={1}>\n <Step label=\"Account\" description=\"Create credentials\" />\n <Step label=\"Profile\" description=\"Add details\" />\n <Step label=\"Review\" />\n</Stepper>"
6373
6754
  ],
@@ -6495,12 +6876,18 @@
6495
6876
  },
6496
6877
  "required": false
6497
6878
  },
6498
- "error": {
6879
+ "state": {
6499
6880
  "type": {
6500
- "name": "boolean"
6881
+ "name": "enum",
6882
+ "value": [
6883
+ "default",
6884
+ "error",
6885
+ "warning",
6886
+ "success"
6887
+ ]
6501
6888
  },
6502
6889
  "required": false,
6503
- "description": "shows red border/bg"
6890
+ "description": "validation border/checked-track tint; error sets aria-invalid. Inherited from FormField when omitted. Distinct from `color`, the ON-track tint"
6504
6891
  },
6505
6892
  "disabled": {
6506
6893
  "type": {
@@ -6563,6 +6950,10 @@
6563
6950
  "Switch does NOT auto-consume FormField — pass `error` explicitly inside a FormField"
6564
6951
  ],
6565
6952
  "changes": [
6953
+ {
6954
+ "version": "0.49.0",
6955
+ "summary": "**BREAKING** Removed the `error: boolean` prop; use `state` (`FieldState = \"default\" | \"error\" | \"warning\" | \"success\"`). Migrate `<Switch error />` → `<Switch state=\"error\" />`. Gains `warning`/`success` and inherits from `FormField`. (`color` is unchanged — it's the ON-track tint, not validation.)"
6956
+ },
6566
6957
  {
6567
6958
  "version": "0.29.0",
6568
6959
  "summary": "**Added** `size` prop: `\"sm\"` (18px track) | `\"md\"` (24px, default) | `\"lg\"` (28px track)"
@@ -6605,28 +6996,6 @@
6605
6996
  },
6606
6997
  "required": false,
6607
6998
  "description": "opt-in zebra — even body rows get the faintest surface step; hairline separators remain the default row cue"
6608
- },
6609
- "numeric": {
6610
- "type": {
6611
- "name": "boolean"
6612
- },
6613
- "required": false,
6614
- "description": "right-align + tabular figures; header follows the column. Identifier-numbers — dates, phones, IDs — stay left"
6615
- },
6616
- "persist": {
6617
- "type": {
6618
- "name": "boolean"
6619
- },
6620
- "required": false,
6621
- "description": "always show instead of hover/focus reveal"
6622
- },
6623
- "href": {
6624
- "type": {
6625
- "name": "object",
6626
- "raw": "string (required); stretch: boolean"
6627
- },
6628
- "required": false,
6629
- "description": "default true"
6630
6999
  }
6631
7000
  },
6632
7001
  "composition": {
@@ -6677,6 +7046,59 @@
6677
7046
  ]
6678
7047
  },
6679
7048
  "docPath": "docs/components/ui/table.md",
7049
+ "subComponents": {
7050
+ "TableCell": {
7051
+ "props": {
7052
+ "numeric": {
7053
+ "type": {
7054
+ "name": "boolean"
7055
+ },
7056
+ "required": false,
7057
+ "description": "right-align + tabular figures; header follows the column. Identifier-numbers — dates, phones, IDs — stay left"
7058
+ }
7059
+ }
7060
+ },
7061
+ "TableHead": {
7062
+ "props": {
7063
+ "numeric": {
7064
+ "type": {
7065
+ "name": "boolean"
7066
+ },
7067
+ "required": false,
7068
+ "description": "right-align + tabular figures; header follows the column. Identifier-numbers — dates, phones, IDs — stay left"
7069
+ }
7070
+ }
7071
+ },
7072
+ "TableRowActions": {
7073
+ "props": {
7074
+ "persist": {
7075
+ "type": {
7076
+ "name": "boolean"
7077
+ },
7078
+ "required": false,
7079
+ "description": "always show instead of hover/focus reveal"
7080
+ }
7081
+ }
7082
+ },
7083
+ "TableRowLink": {
7084
+ "props": {
7085
+ "href": {
7086
+ "type": {
7087
+ "name": "string"
7088
+ },
7089
+ "required": true
7090
+ },
7091
+ "stretch": {
7092
+ "type": {
7093
+ "name": "boolean"
7094
+ },
7095
+ "required": false,
7096
+ "defaultValue": true
7097
+ }
7098
+ },
7099
+ "note": "separate import: ui/table-row-link — client component"
7100
+ }
7101
+ },
6680
7102
  "examples": [
6681
7103
  "<Table>\n <TableHeader>\n <TableRow>\n <TableHead>Name</TableHead>\n <TableHead>Status</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell>Project Alpha</TableCell>\n <TableCell><Badge color=\"success\">Active</Badge></TableCell>\n </TableRow>\n </TableBody>\n</Table>"
6682
7104
  ],
@@ -6770,7 +7192,7 @@
6770
7192
  "type": {
6771
7193
  "name": "string"
6772
7194
  },
6773
- "required": true
7195
+ "required": false
6774
7196
  },
6775
7197
  "onValueChange": {
6776
7198
  "type": {
@@ -6778,37 +7200,6 @@
6778
7200
  "raw": "(value: string) => void"
6779
7201
  },
6780
7202
  "required": false
6781
- },
6782
- "variant": {
6783
- "type": {
6784
- "name": "object",
6785
- "raw": "(inherits from TabsList)"
6786
- },
6787
- "required": false,
6788
- "defaultValue": "line"
6789
- },
6790
- "size": {
6791
- "type": {
6792
- "name": "enum",
6793
- "value": [
6794
- "sm",
6795
- "md",
6796
- "lg"
6797
- ]
6798
- },
6799
- "required": false,
6800
- "defaultValue": "md"
6801
- },
6802
- "orientation": {
6803
- "type": {
6804
- "name": "enum",
6805
- "value": [
6806
- "horizontal",
6807
- "vertical"
6808
- ]
6809
- },
6810
- "required": false,
6811
- "defaultValue": "horizontal"
6812
7203
  }
6813
7204
  },
6814
7205
  "composition": {
@@ -6843,6 +7234,70 @@
6843
7234
  "size": "md",
6844
7235
  "orientation": "horizontal"
6845
7236
  },
7237
+ "subComponents": {
7238
+ "TabsList": {
7239
+ "props": {
7240
+ "variant": {
7241
+ "type": {
7242
+ "name": "enum",
7243
+ "value": [
7244
+ "line",
7245
+ "contained"
7246
+ ]
7247
+ },
7248
+ "required": false
7249
+ },
7250
+ "size": {
7251
+ "type": {
7252
+ "name": "enum",
7253
+ "value": [
7254
+ "sm",
7255
+ "md",
7256
+ "lg"
7257
+ ]
7258
+ },
7259
+ "required": false
7260
+ },
7261
+ "orientation": {
7262
+ "type": {
7263
+ "name": "enum",
7264
+ "value": [
7265
+ "horizontal",
7266
+ "vertical"
7267
+ ]
7268
+ },
7269
+ "required": false
7270
+ }
7271
+ }
7272
+ },
7273
+ "TabsTrigger": {
7274
+ "props": {
7275
+ "value": {
7276
+ "type": {
7277
+ "name": "string"
7278
+ },
7279
+ "required": true
7280
+ },
7281
+ "variant": {
7282
+ "type": {
7283
+ "name": "object",
7284
+ "raw": "(inherits from TabsList)"
7285
+ },
7286
+ "required": false
7287
+ }
7288
+ }
7289
+ },
7290
+ "TabsContent": {
7291
+ "props": {
7292
+ "value": {
7293
+ "type": {
7294
+ "name": "string"
7295
+ },
7296
+ "required": true
7297
+ }
7298
+ }
7299
+ }
7300
+ },
6846
7301
  "examples": [
6847
7302
  "<Tabs defaultValue=\"overview\">\n <TabsList variant=\"contained\">\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"activity\">Activity</TabsTrigger>\n </TabsList>\n <TabsContent value=\"overview\">Overview content</TabsContent>\n <TabsContent value=\"activity\">Activity content</TabsContent>\n</Tabs>"
6848
7303
  ],
@@ -7293,7 +7748,8 @@
7293
7748
  },
7294
7749
  "value": {
7295
7750
  "type": {
7296
- "name": "string"
7751
+ "name": "union",
7752
+ "raw": "string | string[]"
7297
7753
  },
7298
7754
  "required": false
7299
7755
  },
@@ -7327,6 +7783,18 @@
7327
7783
  "variant": "default",
7328
7784
  "size": "md"
7329
7785
  },
7786
+ "subComponents": {
7787
+ "ToggleGroupItem": {
7788
+ "props": {
7789
+ "value": {
7790
+ "type": {
7791
+ "name": "string"
7792
+ },
7793
+ "required": false
7794
+ }
7795
+ }
7796
+ }
7797
+ },
7330
7798
  "examples": [
7331
7799
  "<ToggleGroup type=\"single\" variant=\"outline\" size=\"sm\" value={alignment} onValueChange={setAlignment}>\n <ToggleGroupItem value=\"left\"><IconAlignLeft /></ToggleGroupItem>\n <ToggleGroupItem value=\"center\"><IconAlignCenter /></ToggleGroupItem>\n <ToggleGroupItem value=\"right\"><IconAlignRight /></ToggleGroupItem>\n</ToggleGroup>"
7332
7800
  ],
@@ -7466,49 +7934,7 @@
7466
7934
  "name": "ReactNode"
7467
7935
  },
7468
7936
  "required": false,
7469
- "description": "nested TreeItems"
7470
- },
7471
- "itemId": {
7472
- "type": {
7473
- "name": "string"
7474
- },
7475
- "required": true
7476
- },
7477
- "label": {
7478
- "type": {
7479
- "name": "ReactNode"
7480
- },
7481
- "required": false
7482
- },
7483
- "secondaryLabel": {
7484
- "type": {
7485
- "name": "ReactNode"
7486
- },
7487
- "required": false
7488
- },
7489
- "icon": {
7490
- "type": {
7491
- "name": "ReactNode"
7492
- },
7493
- "required": false
7494
- },
7495
- "actions": {
7496
- "type": {
7497
- "name": "ReactNode"
7498
- },
7499
- "required": false
7500
- },
7501
- "disabled": {
7502
- "type": {
7503
- "name": "boolean"
7504
- },
7505
- "required": false
7506
- },
7507
- "depth": {
7508
- "type": {
7509
- "name": "number"
7510
- },
7511
- "required": false
7937
+ "description": "declarative mode"
7512
7938
  }
7513
7939
  },
7514
7940
  "composition": {
@@ -7521,6 +7947,61 @@
7521
7947
  ]
7522
7948
  },
7523
7949
  "docPath": "docs/components/ui/tree-view.md",
7950
+ "subComponents": {
7951
+ "TreeItem": {
7952
+ "props": {
7953
+ "itemId": {
7954
+ "type": {
7955
+ "name": "string"
7956
+ },
7957
+ "required": true
7958
+ },
7959
+ "label": {
7960
+ "type": {
7961
+ "name": "ReactNode"
7962
+ },
7963
+ "required": false
7964
+ },
7965
+ "secondaryLabel": {
7966
+ "type": {
7967
+ "name": "ReactNode"
7968
+ },
7969
+ "required": false
7970
+ },
7971
+ "icon": {
7972
+ "type": {
7973
+ "name": "ReactNode"
7974
+ },
7975
+ "required": false
7976
+ },
7977
+ "actions": {
7978
+ "type": {
7979
+ "name": "ReactNode"
7980
+ },
7981
+ "required": false
7982
+ },
7983
+ "disabled": {
7984
+ "type": {
7985
+ "name": "boolean"
7986
+ },
7987
+ "required": false
7988
+ },
7989
+ "depth": {
7990
+ "type": {
7991
+ "name": "number"
7992
+ },
7993
+ "required": false
7994
+ },
7995
+ "children": {
7996
+ "type": {
7997
+ "name": "ReactNode"
7998
+ },
7999
+ "required": false,
8000
+ "description": "nested TreeItems"
8001
+ }
8002
+ }
8003
+ }
8004
+ },
7524
8005
  "gotchas": [
7525
8006
  "Supports both data-driven (items prop) and declarative (children) modes",
7526
8007
  "Don't mix data-driven and declarative in the same TreeView — pick one",
@@ -7971,43 +8452,6 @@
7971
8452
  "name": "string"
7972
8453
  },
7973
8454
  "required": false
7974
- },
7975
- "label": {
7976
- "type": {
7977
- "name": "string"
7978
- },
7979
- "required": false
7980
- },
7981
- "icon": {
7982
- "type": {
7983
- "name": "object",
7984
- "raw": "ComponentType<{ className?: string }>"
7985
- },
7986
- "required": false,
7987
- "description": "optional icon component"
7988
- },
7989
- "onClick": {
7990
- "type": {
7991
- "name": "function",
7992
- "raw": "() => void"
7993
- },
7994
- "required": false
7995
- },
7996
- "color": {
7997
- "type": {
7998
- "name": "enum",
7999
- "value": [
8000
- "default",
8001
- "error"
8002
- ]
8003
- },
8004
- "required": false
8005
- },
8006
- "disabled": {
8007
- "type": {
8008
- "name": "boolean"
8009
- },
8010
- "required": false
8011
8455
  }
8012
8456
  },
8013
8457
  "composition": {
@@ -8019,6 +8463,49 @@
8019
8463
  ]
8020
8464
  },
8021
8465
  "docPath": "docs/components/composed/bulk-action-bar.md",
8466
+ "subComponents": {
8467
+ "BulkActionBarAction": {
8468
+ "props": {
8469
+ "label": {
8470
+ "type": {
8471
+ "name": "string"
8472
+ },
8473
+ "required": false
8474
+ },
8475
+ "icon": {
8476
+ "type": {
8477
+ "name": "object",
8478
+ "raw": "ComponentType<{ className?: string }>"
8479
+ },
8480
+ "required": false,
8481
+ "description": "optional icon component"
8482
+ },
8483
+ "onClick": {
8484
+ "type": {
8485
+ "name": "function",
8486
+ "raw": "() => void"
8487
+ },
8488
+ "required": false
8489
+ },
8490
+ "color": {
8491
+ "type": {
8492
+ "name": "enum",
8493
+ "value": [
8494
+ "default",
8495
+ "error"
8496
+ ]
8497
+ },
8498
+ "required": false
8499
+ },
8500
+ "disabled": {
8501
+ "type": {
8502
+ "name": "boolean"
8503
+ },
8504
+ "required": false
8505
+ }
8506
+ }
8507
+ }
8508
+ },
8022
8509
  "examples": [
8023
8510
  "<BulkActionBar\n show={selected.length > 0}\n count={selected.length}\n onClearSelection={() => setSelected([])}\n actions={[\n { label: 'Archive', icon: IconArchive, onClick: archiveSelected },\n { label: 'Delete', icon: IconTrash, onClick: deleteSelected, color: 'error' },\n ]}\n/>"
8024
8511
  ],
@@ -8321,13 +8808,12 @@
8321
8808
  "name": "union",
8322
8809
  "raw": "Date | null"
8323
8810
  },
8324
- "required": false,
8325
- "description": "time stored as a Date object"
8811
+ "required": false
8326
8812
  },
8327
8813
  "onChange": {
8328
8814
  "type": {
8329
8815
  "name": "function",
8330
- "raw": "(date: Date) => void"
8816
+ "raw": "(date: Date | null) => void"
8331
8817
  },
8332
8818
  "required": false
8333
8819
  },
@@ -8336,7 +8822,7 @@
8336
8822
  "name": "string"
8337
8823
  },
8338
8824
  "required": false,
8339
- "defaultValue": "Pick a time"
8825
+ "defaultValue": "Pick a date"
8340
8826
  },
8341
8827
  "formatStr": {
8342
8828
  "type": {
@@ -8371,292 +8857,524 @@
8371
8857
  "name": "string"
8372
8858
  },
8373
8859
  "required": false
8860
+ }
8861
+ },
8862
+ "composition": {
8863
+ "notes": [
8864
+ "**7 sub-components in one kit:** DatePicker, DateRangePicker, DateTimePicker, TimePicker, CalendarGrid, MonthPicker, YearPicker, Presets. Built on Popover (trigger + calendar content) + date-fns.",
8865
+ "**Layered abstractions:** - High-level: DatePicker / DateRangePicker / DateTimePicker / TimePicker (use these 95% of the time — Popover-wrapped, single-field pickers with formatted value display). - Low-level: CalendarGrid / MonthPicker / YearPicker (use for custom picker layouts, inline calendars, dashboards with embedded date selection).",
8866
+ "**useCalendar hook** manages month navigation state — use it when building custom picker UI (e.g. inline calendar with custom header).",
8867
+ "**Presets component** is standalone — drop it next to a DateRangePicker's calendar for quick-select sidebars (Today / Last 7 days / This month / etc.).",
8868
+ "**Events on calendar:** CalendarGrid accepts `events: { date, color, label }[]` — renders up to 3 colored dots per day cell. Useful for availability / booked-days highlights.",
8869
+ "**min/max/disabledDates** are shared contract across the whole family — pass the same bounds config to any date picker variant."
8870
+ ]
8871
+ },
8872
+ "docPath": "docs/components/composed/date-picker.md",
8873
+ "defaults": {
8874
+ "placeholder": "Pick a date range",
8875
+ "formatStr": "MMM d",
8876
+ "numberOfMonths": 1,
8877
+ "format": "12h",
8878
+ "minuteStep": 1,
8879
+ "secondStep": 1,
8880
+ "showSeconds": false
8881
+ },
8882
+ "subComponents": {
8883
+ "DateRangePicker": {
8884
+ "props": {
8885
+ "startDate": {
8886
+ "type": {
8887
+ "name": "union",
8888
+ "raw": "Date | null"
8889
+ },
8890
+ "required": false
8891
+ },
8892
+ "endDate": {
8893
+ "type": {
8894
+ "name": "union",
8895
+ "raw": "Date | null"
8896
+ },
8897
+ "required": false
8898
+ },
8899
+ "onChange": {
8900
+ "type": {
8901
+ "name": "function",
8902
+ "raw": "(range: { start: Date | null, end: Date | null }) => void"
8903
+ },
8904
+ "required": false
8905
+ },
8906
+ "placeholder": {
8907
+ "type": {
8908
+ "name": "string"
8909
+ },
8910
+ "required": false,
8911
+ "defaultValue": "Pick a date range"
8912
+ },
8913
+ "formatStr": {
8914
+ "type": {
8915
+ "name": "string"
8916
+ },
8917
+ "required": false,
8918
+ "defaultValue": "MMM d, yyyy"
8919
+ },
8920
+ "minDate": {
8921
+ "type": {
8922
+ "name": "object",
8923
+ "raw": "Date"
8924
+ },
8925
+ "required": false
8926
+ },
8927
+ "maxDate": {
8928
+ "type": {
8929
+ "name": "object",
8930
+ "raw": "Date"
8931
+ },
8932
+ "required": false
8933
+ },
8934
+ "disabledDates": {
8935
+ "type": {
8936
+ "name": "function",
8937
+ "raw": "(date: Date) => boolean"
8938
+ },
8939
+ "required": false
8940
+ },
8941
+ "presets": {
8942
+ "type": {
8943
+ "name": "object",
8944
+ "raw": "PresetKey[]"
8945
+ },
8946
+ "required": false,
8947
+ "description": "shows quick-select sidebar"
8948
+ },
8949
+ "numberOfMonths": {
8950
+ "type": {
8951
+ "name": "number"
8952
+ },
8953
+ "required": false,
8954
+ "defaultValue": 1
8955
+ }
8956
+ }
8374
8957
  },
8375
- "startDate": {
8376
- "type": {
8377
- "name": "union",
8378
- "raw": "Date | null"
8379
- },
8380
- "required": false
8958
+ "DateTimePicker": {
8959
+ "props": {
8960
+ "value": {
8961
+ "type": {
8962
+ "name": "union",
8963
+ "raw": "Date | null"
8964
+ },
8965
+ "required": false
8966
+ },
8967
+ "onChange": {
8968
+ "type": {
8969
+ "name": "function",
8970
+ "raw": "(date: Date | null) => void"
8971
+ },
8972
+ "required": false
8973
+ },
8974
+ "minDate": {
8975
+ "type": {
8976
+ "name": "object",
8977
+ "raw": "Date"
8978
+ },
8979
+ "required": false
8980
+ },
8981
+ "maxDate": {
8982
+ "type": {
8983
+ "name": "object",
8984
+ "raw": "Date"
8985
+ },
8986
+ "required": false
8987
+ },
8988
+ "disabledDates": {
8989
+ "type": {
8990
+ "name": "function",
8991
+ "raw": "(date: Date) => boolean"
8992
+ },
8993
+ "required": false
8994
+ },
8995
+ "timeFormat": {
8996
+ "type": {
8997
+ "name": "enum",
8998
+ "value": [
8999
+ "12h",
9000
+ "24h"
9001
+ ]
9002
+ },
9003
+ "required": false
9004
+ },
9005
+ "minuteStep": {
9006
+ "type": {
9007
+ "name": "number"
9008
+ },
9009
+ "required": false
9010
+ },
9011
+ "placeholder": {
9012
+ "type": {
9013
+ "name": "string"
9014
+ },
9015
+ "required": false
9016
+ },
9017
+ "className": {
9018
+ "type": {
9019
+ "name": "string"
9020
+ },
9021
+ "required": false
9022
+ }
9023
+ }
8381
9024
  },
8382
- "endDate": {
8383
- "type": {
8384
- "name": "union",
8385
- "raw": "Date | null"
8386
- },
8387
- "required": false
9025
+ "TimePicker": {
9026
+ "props": {
9027
+ "value": {
9028
+ "type": {
9029
+ "name": "union",
9030
+ "raw": "Date | null"
9031
+ },
9032
+ "required": false,
9033
+ "description": "time stored as a Date object"
9034
+ },
9035
+ "onChange": {
9036
+ "type": {
9037
+ "name": "function",
9038
+ "raw": "(date: Date) => void"
9039
+ },
9040
+ "required": false
9041
+ },
9042
+ "format": {
9043
+ "type": {
9044
+ "name": "enum",
9045
+ "value": [
9046
+ "12h",
9047
+ "24h"
9048
+ ]
9049
+ },
9050
+ "required": false,
9051
+ "defaultValue": "12h"
9052
+ },
9053
+ "minuteStep": {
9054
+ "type": {
9055
+ "name": "number"
9056
+ },
9057
+ "required": false,
9058
+ "defaultValue": 1
9059
+ },
9060
+ "secondStep": {
9061
+ "type": {
9062
+ "name": "number"
9063
+ },
9064
+ "required": false,
9065
+ "defaultValue": 1
9066
+ },
9067
+ "showSeconds": {
9068
+ "type": {
9069
+ "name": "boolean"
9070
+ },
9071
+ "required": false,
9072
+ "defaultValue": false
9073
+ },
9074
+ "placeholder": {
9075
+ "type": {
9076
+ "name": "string"
9077
+ },
9078
+ "required": false,
9079
+ "defaultValue": "Pick a time"
9080
+ },
9081
+ "disabled": {
9082
+ "type": {
9083
+ "name": "boolean"
9084
+ },
9085
+ "required": false,
9086
+ "defaultValue": false
9087
+ },
9088
+ "className": {
9089
+ "type": {
9090
+ "name": "string"
9091
+ },
9092
+ "required": false
9093
+ }
9094
+ }
8388
9095
  },
8389
- "presets": {
8390
- "type": {
8391
- "name": "object",
8392
- "raw": "PresetKey[]"
8393
- },
8394
- "required": true
9096
+ "CalendarGrid": {
9097
+ "props": {
9098
+ "currentMonth": {
9099
+ "type": {
9100
+ "name": "object",
9101
+ "raw": "Date"
9102
+ },
9103
+ "required": true
9104
+ },
9105
+ "selected": {
9106
+ "type": {
9107
+ "name": "union",
9108
+ "raw": "Date | null"
9109
+ },
9110
+ "required": false
9111
+ },
9112
+ "rangeStart": {
9113
+ "type": {
9114
+ "name": "union",
9115
+ "raw": "Date | null"
9116
+ },
9117
+ "required": false
9118
+ },
9119
+ "rangeEnd": {
9120
+ "type": {
9121
+ "name": "union",
9122
+ "raw": "Date | null"
9123
+ },
9124
+ "required": false
9125
+ },
9126
+ "hoverDate": {
9127
+ "type": {
9128
+ "name": "union",
9129
+ "raw": "Date | null"
9130
+ },
9131
+ "required": false
9132
+ },
9133
+ "onSelect": {
9134
+ "type": {
9135
+ "name": "function",
9136
+ "raw": "(date: Date) => void (REQUIRED)"
9137
+ },
9138
+ "required": false
9139
+ },
9140
+ "onHover": {
9141
+ "type": {
9142
+ "name": "function",
9143
+ "raw": "(date: Date | null) => void"
9144
+ },
9145
+ "required": false
9146
+ },
9147
+ "onMonthChange": {
9148
+ "type": {
9149
+ "name": "function",
9150
+ "raw": "(date: Date) => void (REQUIRED)"
9151
+ },
9152
+ "required": false
9153
+ },
9154
+ "onHeaderClick": {
9155
+ "type": {
9156
+ "name": "function",
9157
+ "raw": "() => void"
9158
+ },
9159
+ "required": false
9160
+ },
9161
+ "disabledDates": {
9162
+ "type": {
9163
+ "name": "function",
9164
+ "raw": "(date: Date) => boolean"
9165
+ },
9166
+ "required": false
9167
+ },
9168
+ "minDate": {
9169
+ "type": {
9170
+ "name": "object",
9171
+ "raw": "Date"
9172
+ },
9173
+ "required": false
9174
+ },
9175
+ "maxDate": {
9176
+ "type": {
9177
+ "name": "object",
9178
+ "raw": "Date"
9179
+ },
9180
+ "required": false
9181
+ },
9182
+ "hidePrevNav": {
9183
+ "type": {
9184
+ "name": "boolean"
9185
+ },
9186
+ "required": false
9187
+ },
9188
+ "hideNextNav": {
9189
+ "type": {
9190
+ "name": "boolean"
9191
+ },
9192
+ "required": false
9193
+ },
9194
+ "events": {
9195
+ "type": {
9196
+ "name": "object",
9197
+ "raw": "CalendarEvent[] — { date: Date, color?: string, label?: string }"
9198
+ },
9199
+ "required": false
9200
+ }
9201
+ }
9202
+ },
9203
+ "YearPicker": {
9204
+ "props": {
9205
+ "currentYear": {
9206
+ "type": {
9207
+ "name": "number"
9208
+ },
9209
+ "required": true
9210
+ },
9211
+ "selectedYear": {
9212
+ "type": {
9213
+ "name": "number"
9214
+ },
9215
+ "required": false
9216
+ },
9217
+ "onYearSelect": {
9218
+ "type": {
9219
+ "name": "function",
9220
+ "raw": "(year: number) => void (REQUIRED)"
9221
+ },
9222
+ "required": false
9223
+ },
9224
+ "minDate": {
9225
+ "type": {
9226
+ "name": "object",
9227
+ "raw": "Date"
9228
+ },
9229
+ "required": false
9230
+ },
9231
+ "maxDate": {
9232
+ "type": {
9233
+ "name": "object",
9234
+ "raw": "Date"
9235
+ },
9236
+ "required": false
9237
+ }
9238
+ }
9239
+ },
9240
+ "MonthPicker": {
9241
+ "props": {
9242
+ "currentYear": {
9243
+ "type": {
9244
+ "name": "number"
9245
+ },
9246
+ "required": true
9247
+ },
9248
+ "selectedMonth": {
9249
+ "type": {
9250
+ "name": "number"
9251
+ },
9252
+ "required": false,
9253
+ "description": "0-11"
9254
+ },
9255
+ "onMonthSelect": {
9256
+ "type": {
9257
+ "name": "function",
9258
+ "raw": "(month: number) => void (REQUIRED)"
9259
+ },
9260
+ "required": false
9261
+ },
9262
+ "minDate": {
9263
+ "type": {
9264
+ "name": "object",
9265
+ "raw": "Date"
9266
+ },
9267
+ "required": false
9268
+ },
9269
+ "maxDate": {
9270
+ "type": {
9271
+ "name": "object",
9272
+ "raw": "Date"
9273
+ },
9274
+ "required": false
9275
+ }
9276
+ }
9277
+ },
9278
+ "Presets": {
9279
+ "props": {
9280
+ "presets": {
9281
+ "type": {
9282
+ "name": "object",
9283
+ "raw": "PresetKey[]"
9284
+ },
9285
+ "required": true
9286
+ },
9287
+ "onSelect": {
9288
+ "type": {
9289
+ "name": "function",
9290
+ "raw": "(start: Date, end: Date) => void (REQUIRED)"
9291
+ },
9292
+ "required": false
9293
+ },
9294
+ "className": {
9295
+ "type": {
9296
+ "name": "string"
9297
+ },
9298
+ "required": false
9299
+ }
9300
+ }
9301
+ },
9302
+ "useCalendar hook": {
9303
+ "props": {}
9304
+ }
9305
+ },
9306
+ "examples": [
9307
+ "<DatePicker value={date} onChange={setDate} placeholder=\"Select date\" />\n\n<DateRangePicker\n startDate={start}\n endDate={end}\n onChange={({ start, end }) => { setStart(start); setEnd(end); }}\n/>\n\n<DateTimePicker value={dateTime} onChange={setDateTime} timeFormat=\"12h\" minuteStep={15} />\n\n<TimePicker value={time} onChange={setTime} format=\"24h\" minuteStep={15} />"
9308
+ ],
9309
+ "gotchas": [
9310
+ "TimePicker stores time inside a Date object — only hours/minutes/seconds are meaningful",
9311
+ "CalendarGrid is a low-level building block — prefer DatePicker/DateRangePicker for most use cases",
9312
+ "MonthPicker month values are 0-indexed (Jan=0, Dec=11) — same as JavaScript `Date.getMonth()`",
9313
+ "YearPicker displays a 12-year grid based on the decade of `currentYear`",
9314
+ "CalendarGrid supports up to 3 event dots per day cell",
9315
+ "useCalendar is a convenience hook for managing calendar month state"
9316
+ ],
9317
+ "changes": [
9318
+ {
9319
+ "version": "0.18.0",
9320
+ "summary": "**Fixed** Added `aria-label` to DatePicker/DateRangePicker trigger buttons"
9321
+ },
9322
+ {
9323
+ "version": "0.4.2",
9324
+ "summary": "**Changed** DateRangePicker default `formatStr` from `'MMM d'` to `'MMM d, yyyy'`"
8395
9325
  },
8396
- "numberOfMonths": {
9326
+ {
9327
+ "version": "0.1.0",
9328
+ "summary": "**Added** Initial release"
9329
+ }
9330
+ ],
9331
+ "peers": [
9332
+ "date-fns"
9333
+ ]
9334
+ },
9335
+ "deadline-indicator": {
9336
+ "displayName": "DeadlineIndicator",
9337
+ "tier": "composed",
9338
+ "import": "@devalok/shilp-sutra/composed/deadline-indicator",
9339
+ "serverSafe": true,
9340
+ "description": "",
9341
+ "props": {
9342
+ "deadline": {
8397
9343
  "type": {
8398
- "name": "number"
9344
+ "name": "union",
9345
+ "raw": "Date | string"
8399
9346
  },
8400
9347
  "required": false,
8401
- "defaultValue": 1
9348
+ "description": "deadline timestamp"
8402
9349
  },
8403
- "timeFormat": {
9350
+ "warningThreshold": {
8404
9351
  "type": {
8405
- "name": "enum",
8406
- "value": [
8407
- "12h",
8408
- "24h"
8409
- ]
9352
+ "name": "number"
8410
9353
  },
8411
- "required": false
9354
+ "required": false,
9355
+ "description": "minutes before deadline to show warning color",
9356
+ "defaultValue": "{1440} (24h)"
8412
9357
  },
8413
- "minuteStep": {
9358
+ "criticalThreshold": {
8414
9359
  "type": {
8415
9360
  "name": "number"
8416
9361
  },
8417
9362
  "required": false,
8418
- "defaultValue": 1
9363
+ "description": "minutes before deadline to show critical/error color",
9364
+ "defaultValue": "{240} (4h)"
8419
9365
  },
8420
9366
  "format": {
8421
9367
  "type": {
8422
9368
  "name": "enum",
8423
9369
  "value": [
8424
- "12h",
8425
- "24h"
9370
+ "relative",
9371
+ "absolute"
8426
9372
  ]
8427
9373
  },
8428
9374
  "required": false,
8429
- "defaultValue": "12h"
8430
- },
8431
- "secondStep": {
8432
- "type": {
8433
- "name": "number"
8434
- },
8435
- "required": false,
8436
- "defaultValue": 1
8437
- },
8438
- "showSeconds": {
8439
- "type": {
8440
- "name": "boolean"
8441
- },
8442
- "required": false,
8443
- "defaultValue": false
9375
+ "defaultValue": "relative"
8444
9376
  },
8445
- "disabled": {
8446
- "type": {
8447
- "name": "boolean"
8448
- },
8449
- "required": false,
8450
- "defaultValue": false
8451
- },
8452
- "currentMonth": {
8453
- "type": {
8454
- "name": "object",
8455
- "raw": "Date"
8456
- },
8457
- "required": true
8458
- },
8459
- "selected": {
8460
- "type": {
8461
- "name": "union",
8462
- "raw": "Date | null"
8463
- },
8464
- "required": false
8465
- },
8466
- "rangeStart": {
8467
- "type": {
8468
- "name": "union",
8469
- "raw": "Date | null"
8470
- },
8471
- "required": false
8472
- },
8473
- "rangeEnd": {
8474
- "type": {
8475
- "name": "union",
8476
- "raw": "Date | null"
8477
- },
8478
- "required": false
8479
- },
8480
- "hoverDate": {
8481
- "type": {
8482
- "name": "union",
8483
- "raw": "Date | null"
8484
- },
8485
- "required": false
8486
- },
8487
- "onSelect": {
8488
- "type": {
8489
- "name": "function",
8490
- "raw": "(start: Date, end: Date) => void (REQUIRED)"
8491
- },
8492
- "required": false
8493
- },
8494
- "onHover": {
8495
- "type": {
8496
- "name": "function",
8497
- "raw": "(date: Date | null) => void"
8498
- },
8499
- "required": false
8500
- },
8501
- "onMonthChange": {
8502
- "type": {
8503
- "name": "function",
8504
- "raw": "(date: Date) => void (REQUIRED)"
8505
- },
8506
- "required": false
8507
- },
8508
- "onHeaderClick": {
8509
- "type": {
8510
- "name": "function",
8511
- "raw": "() => void"
8512
- },
8513
- "required": false
8514
- },
8515
- "hidePrevNav": {
8516
- "type": {
8517
- "name": "boolean"
8518
- },
8519
- "required": false
8520
- },
8521
- "hideNextNav": {
8522
- "type": {
8523
- "name": "boolean"
8524
- },
8525
- "required": false
8526
- },
8527
- "events": {
8528
- "type": {
8529
- "name": "object",
8530
- "raw": "CalendarEvent[] — { date: Date, color?: string, label?: string }"
8531
- },
8532
- "required": false
8533
- },
8534
- "currentYear": {
8535
- "type": {
8536
- "name": "number"
8537
- },
8538
- "required": true
8539
- },
8540
- "selectedYear": {
8541
- "type": {
8542
- "name": "number"
8543
- },
8544
- "required": false
8545
- },
8546
- "onYearSelect": {
8547
- "type": {
8548
- "name": "function",
8549
- "raw": "(year: number) => void (REQUIRED)"
8550
- },
8551
- "required": false
8552
- },
8553
- "selectedMonth": {
8554
- "type": {
8555
- "name": "number"
8556
- },
8557
- "required": false,
8558
- "description": "0-11"
8559
- },
8560
- "onMonthSelect": {
8561
- "type": {
8562
- "name": "function",
8563
- "raw": "(month: number) => void (REQUIRED)"
8564
- },
8565
- "required": false
8566
- }
8567
- },
8568
- "composition": {
8569
- "notes": [
8570
- "**7 sub-components in one kit:** DatePicker, DateRangePicker, DateTimePicker, TimePicker, CalendarGrid, MonthPicker, YearPicker, Presets. Built on Popover (trigger + calendar content) + date-fns.",
8571
- "**Layered abstractions:** - High-level: DatePicker / DateRangePicker / DateTimePicker / TimePicker (use these 95% of the time — Popover-wrapped, single-field pickers with formatted value display). - Low-level: CalendarGrid / MonthPicker / YearPicker (use for custom picker layouts, inline calendars, dashboards with embedded date selection).",
8572
- "**useCalendar hook** manages month navigation state — use it when building custom picker UI (e.g. inline calendar with custom header).",
8573
- "**Presets component** is standalone — drop it next to a DateRangePicker's calendar for quick-select sidebars (Today / Last 7 days / This month / etc.).",
8574
- "**Events on calendar:** CalendarGrid accepts `events: { date, color, label }[]` — renders up to 3 colored dots per day cell. Useful for availability / booked-days highlights.",
8575
- "**min/max/disabledDates** are shared contract across the whole family — pass the same bounds config to any date picker variant."
8576
- ]
8577
- },
8578
- "docPath": "docs/components/composed/date-picker.md",
8579
- "defaults": {
8580
- "placeholder": "Pick a date range",
8581
- "formatStr": "MMM d",
8582
- "numberOfMonths": 1,
8583
- "format": "12h",
8584
- "minuteStep": 1,
8585
- "secondStep": 1,
8586
- "showSeconds": false
8587
- },
8588
- "examples": [
8589
- "<DatePicker value={date} onChange={setDate} placeholder=\"Select date\" />\n\n<DateRangePicker\n startDate={start}\n endDate={end}\n onChange={({ start, end }) => { setStart(start); setEnd(end); }}\n/>\n\n<DateTimePicker value={dateTime} onChange={setDateTime} timeFormat=\"12h\" minuteStep={15} />\n\n<TimePicker value={time} onChange={setTime} format=\"24h\" minuteStep={15} />"
8590
- ],
8591
- "gotchas": [
8592
- "TimePicker stores time inside a Date object — only hours/minutes/seconds are meaningful",
8593
- "CalendarGrid is a low-level building block — prefer DatePicker/DateRangePicker for most use cases",
8594
- "MonthPicker month values are 0-indexed (Jan=0, Dec=11) — same as JavaScript `Date.getMonth()`",
8595
- "YearPicker displays a 12-year grid based on the decade of `currentYear`",
8596
- "CalendarGrid supports up to 3 event dots per day cell",
8597
- "useCalendar is a convenience hook for managing calendar month state"
8598
- ],
8599
- "changes": [
8600
- {
8601
- "version": "0.18.0",
8602
- "summary": "**Fixed** Added `aria-label` to DatePicker/DateRangePicker trigger buttons"
8603
- },
8604
- {
8605
- "version": "0.4.2",
8606
- "summary": "**Changed** DateRangePicker default `formatStr` from `'MMM d'` to `'MMM d, yyyy'`"
8607
- },
8608
- {
8609
- "version": "0.1.0",
8610
- "summary": "**Added** Initial release"
8611
- }
8612
- ],
8613
- "peers": [
8614
- "date-fns"
8615
- ]
8616
- },
8617
- "deadline-indicator": {
8618
- "displayName": "DeadlineIndicator",
8619
- "tier": "composed",
8620
- "import": "@devalok/shilp-sutra/composed/deadline-indicator",
8621
- "serverSafe": true,
8622
- "description": "",
8623
- "props": {
8624
- "deadline": {
8625
- "type": {
8626
- "name": "union",
8627
- "raw": "Date | string"
8628
- },
8629
- "required": false,
8630
- "description": "deadline timestamp"
8631
- },
8632
- "warningThreshold": {
8633
- "type": {
8634
- "name": "number"
8635
- },
8636
- "required": false,
8637
- "description": "minutes before deadline to show warning color",
8638
- "defaultValue": "{1440} (24h)"
8639
- },
8640
- "criticalThreshold": {
8641
- "type": {
8642
- "name": "number"
8643
- },
8644
- "required": false,
8645
- "description": "minutes before deadline to show critical/error color",
8646
- "defaultValue": "{240} (4h)"
8647
- },
8648
- "format": {
8649
- "type": {
8650
- "name": "enum",
8651
- "value": [
8652
- "relative",
8653
- "absolute"
8654
- ]
8655
- },
8656
- "required": false,
8657
- "defaultValue": "relative"
8658
- },
8659
- "showIcon": {
9377
+ "showIcon": {
8660
9378
  "type": {
8661
9379
  "name": "boolean"
8662
9380
  },
@@ -8716,44 +9434,6 @@
8716
9434
  "name": "string"
8717
9435
  },
8718
9436
  "required": false
8719
- },
8720
- "children": {
8721
- "type": {
8722
- "name": "ReactNode"
8723
- },
8724
- "required": false,
8725
- "description": "trigger element"
8726
- },
8727
- "align": {
8728
- "type": {
8729
- "name": "enum",
8730
- "value": [
8731
- "start",
8732
- "center",
8733
- "end"
8734
- ]
8735
- },
8736
- "required": false,
8737
- "defaultValue": "start"
8738
- },
8739
- "id": {
8740
- "type": {
8741
- "name": "string"
8742
- },
8743
- "required": false
8744
- },
8745
- "native": {
8746
- "type": {
8747
- "name": "string"
8748
- },
8749
- "required": false,
8750
- "description": "the emoji character"
8751
- },
8752
- "shortcodes": {
8753
- "type": {
8754
- "name": "string"
8755
- },
8756
- "required": false
8757
9437
  }
8758
9438
  },
8759
9439
  "composition": {
@@ -8771,6 +9451,54 @@
8771
9451
  "defaults": {
8772
9452
  "align": "start"
8773
9453
  },
9454
+ "subComponents": {
9455
+ "EmojiPickerPopover": {
9456
+ "props": {
9457
+ "children": {
9458
+ "type": {
9459
+ "name": "ReactNode"
9460
+ },
9461
+ "required": false,
9462
+ "description": "trigger element"
9463
+ },
9464
+ "align": {
9465
+ "type": {
9466
+ "name": "enum",
9467
+ "value": [
9468
+ "start",
9469
+ "center",
9470
+ "end"
9471
+ ]
9472
+ },
9473
+ "required": false
9474
+ }
9475
+ },
9476
+ "note": "extends EmojiPicker props"
9477
+ },
9478
+ "EmojiData": {
9479
+ "props": {
9480
+ "id": {
9481
+ "type": {
9482
+ "name": "string"
9483
+ },
9484
+ "required": false
9485
+ },
9486
+ "native": {
9487
+ "type": {
9488
+ "name": "string"
9489
+ },
9490
+ "required": false,
9491
+ "description": "the emoji character"
9492
+ },
9493
+ "shortcodes": {
9494
+ "type": {
9495
+ "name": "string"
9496
+ },
9497
+ "required": false
9498
+ }
9499
+ }
9500
+ }
9501
+ },
8774
9502
  "examples": [
8775
9503
  "<EmojiPickerPopover onSelect={(emoji) => insertEmoji(emoji.native)}>\n <Button variant=\"ghost\" size=\"icon-sm\">😀</Button>\n</EmojiPickerPopover>\n\n<EmojiPicker onSelect={handleEmoji} />"
8776
9504
  ],
@@ -9090,41 +9818,6 @@
9090
9818
  },
9091
9819
  "required": false,
9092
9820
  "description": "FilterSelect / FilterMultiSelect controls"
9093
- },
9094
- "label": {
9095
- "type": {
9096
- "name": "string"
9097
- },
9098
- "required": false
9099
- },
9100
- "value": {
9101
- "type": {
9102
- "name": "object",
9103
- "raw": "string[]"
9104
- },
9105
- "required": false
9106
- },
9107
- "onValueChange": {
9108
- "type": {
9109
- "name": "function",
9110
- "raw": "(values: string[]) => void"
9111
- },
9112
- "required": false
9113
- },
9114
- "options": {
9115
- "type": {
9116
- "name": "object",
9117
- "raw": "{ value: string; label: string }[]"
9118
- },
9119
- "required": false
9120
- },
9121
- "allLabel": {
9122
- "type": {
9123
- "name": "string"
9124
- },
9125
- "required": false,
9126
- "description": "label for the \"all\" option",
9127
- "defaultValue": "All"
9128
9821
  }
9129
9822
  },
9130
9823
  "composition": {
@@ -9143,6 +9836,76 @@
9143
9836
  "searchPlaceholder": "Search...",
9144
9837
  "allLabel": "All"
9145
9838
  },
9839
+ "subComponents": {
9840
+ "FilterSelect": {
9841
+ "props": {
9842
+ "label": {
9843
+ "type": {
9844
+ "name": "string"
9845
+ },
9846
+ "required": false
9847
+ },
9848
+ "value": {
9849
+ "type": {
9850
+ "name": "string"
9851
+ },
9852
+ "required": false
9853
+ },
9854
+ "onValueChange": {
9855
+ "type": {
9856
+ "name": "function",
9857
+ "raw": "(value: string) => void"
9858
+ },
9859
+ "required": false
9860
+ },
9861
+ "options": {
9862
+ "type": {
9863
+ "name": "object",
9864
+ "raw": "{ value: string; label: string }[]"
9865
+ },
9866
+ "required": false
9867
+ },
9868
+ "allLabel": {
9869
+ "type": {
9870
+ "name": "string"
9871
+ },
9872
+ "required": false,
9873
+ "description": "label for the \"all\" option"
9874
+ }
9875
+ }
9876
+ },
9877
+ "FilterMultiSelect": {
9878
+ "props": {
9879
+ "label": {
9880
+ "type": {
9881
+ "name": "string"
9882
+ },
9883
+ "required": false
9884
+ },
9885
+ "value": {
9886
+ "type": {
9887
+ "name": "object",
9888
+ "raw": "string[]"
9889
+ },
9890
+ "required": false
9891
+ },
9892
+ "onValueChange": {
9893
+ "type": {
9894
+ "name": "function",
9895
+ "raw": "(values: string[]) => void"
9896
+ },
9897
+ "required": false
9898
+ },
9899
+ "options": {
9900
+ "type": {
9901
+ "name": "object",
9902
+ "raw": "{ value: string; label: string }[]"
9903
+ },
9904
+ "required": false
9905
+ }
9906
+ }
9907
+ }
9908
+ },
9146
9909
  "examples": [
9147
9910
  "<FilterBar searchValue={search} onSearchChange={setSearch} onClearAll={clearFilters}>\n <FilterSelect\n label=\"Status\"\n value={status}\n onValueChange={setStatus}\n options={[{ value: 'active', label: 'Active' }, { value: 'done', label: 'Done' }]}\n />\n <FilterMultiSelect\n label=\"Assignees\"\n value={assignees}\n onValueChange={setAssignees}\n options={memberOptions}\n />\n</FilterBar>"
9148
9911
  ],
@@ -9351,42 +10114,7 @@
9351
10114
  "import": "@devalok/shilp-sutra/composed/loading-skeleton",
9352
10115
  "serverSafe": true,
9353
10116
  "description": "Exports: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton",
9354
- "props": {
9355
- "className": {
9356
- "type": {
9357
- "name": "string"
9358
- },
9359
- "required": false
9360
- },
9361
- "rows": {
9362
- "type": {
9363
- "name": "number"
9364
- },
9365
- "required": false,
9366
- "defaultValue": 6
9367
- },
9368
- "columns": {
9369
- "type": {
9370
- "name": "number"
9371
- },
9372
- "required": false,
9373
- "defaultValue": 4
9374
- },
9375
- "cardsPerColumn": {
9376
- "type": {
9377
- "name": "number"
9378
- },
9379
- "required": false,
9380
- "defaultValue": 3
9381
- },
9382
- "showAvatar": {
9383
- "type": {
9384
- "name": "boolean"
9385
- },
9386
- "required": false,
9387
- "defaultValue": true
9388
- }
9389
- },
10117
+ "props": {},
9390
10118
  "composition": {
9391
10119
  "notes": [
9392
10120
  "**Pre-composed skeleton layouts** — CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton. Each mimics the shape of a common DS layout so users see meaningful loading placeholders.",
@@ -9403,6 +10131,90 @@
9403
10131
  "cardsPerColumn": 3,
9404
10132
  "showAvatar": true
9405
10133
  },
10134
+ "subComponents": {
10135
+ "CardSkeleton": {
10136
+ "props": {
10137
+ "className": {
10138
+ "type": {
10139
+ "name": "string"
10140
+ },
10141
+ "required": false
10142
+ }
10143
+ }
10144
+ },
10145
+ "TableSkeleton": {
10146
+ "props": {
10147
+ "rows": {
10148
+ "type": {
10149
+ "name": "number"
10150
+ },
10151
+ "required": false,
10152
+ "defaultValue": 5
10153
+ },
10154
+ "columns": {
10155
+ "type": {
10156
+ "name": "number"
10157
+ },
10158
+ "required": false,
10159
+ "defaultValue": 4
10160
+ },
10161
+ "className": {
10162
+ "type": {
10163
+ "name": "string"
10164
+ },
10165
+ "required": false
10166
+ }
10167
+ }
10168
+ },
10169
+ "BoardSkeleton": {
10170
+ "props": {
10171
+ "columns": {
10172
+ "type": {
10173
+ "name": "number"
10174
+ },
10175
+ "required": false,
10176
+ "defaultValue": 4
10177
+ },
10178
+ "cardsPerColumn": {
10179
+ "type": {
10180
+ "name": "number"
10181
+ },
10182
+ "required": false,
10183
+ "defaultValue": 3
10184
+ },
10185
+ "className": {
10186
+ "type": {
10187
+ "name": "string"
10188
+ },
10189
+ "required": false
10190
+ }
10191
+ }
10192
+ },
10193
+ "ListSkeleton": {
10194
+ "props": {
10195
+ "rows": {
10196
+ "type": {
10197
+ "name": "number"
10198
+ },
10199
+ "required": false,
10200
+ "defaultValue": 6
10201
+ },
10202
+ "showAvatar": {
10203
+ "type": {
10204
+ "name": "boolean"
10205
+ },
10206
+ "required": false,
10207
+ "defaultValue": true
10208
+ },
10209
+ "className": {
10210
+ "type": {
10211
+ "name": "string"
10212
+ },
10213
+ "required": false
10214
+ }
10215
+ }
10216
+ }
10217
+ },
9406
10218
  "examples": [
9407
10219
  "<CardSkeleton />\n<TableSkeleton rows={8} columns={5} />\n<BoardSkeleton columns={3} cardsPerColumn={4} />\n<ListSkeleton rows={10} showAvatar={false} />"
9408
10220
  ],
@@ -9535,13 +10347,6 @@
9535
10347
  "required": false,
9536
10348
  "description": "below this, stacked mobile mode activates",
9537
10349
  "defaultValue": "md"
9538
- },
9539
- "active": {
9540
- "type": {
9541
- "name": "boolean"
9542
- },
9543
- "required": false,
9544
- "description": "highlights the item"
9545
10350
  }
9546
10351
  },
9547
10352
  "composition": {
@@ -9559,6 +10364,19 @@
9559
10364
  "masterWidth": "280px",
9560
10365
  "breakpoint": "md"
9561
10366
  },
10367
+ "subComponents": {
10368
+ "MasterDetail.ListItem": {
10369
+ "props": {
10370
+ "active": {
10371
+ "type": {
10372
+ "name": "boolean"
10373
+ },
10374
+ "required": false,
10375
+ "description": "highlights the item"
10376
+ }
10377
+ }
10378
+ }
10379
+ },
9562
10380
  "examples": [
9563
10381
  "<MasterDetail selected={selectedId} onBack={() => setSelectedId(null)}>\n <MasterDetail.List>\n {items.map((item) => (\n <MasterDetail.ListItem\n key={item.id}\n active={item.id === selectedId}\n onClick={() => setSelectedId(item.id)}\n >\n {item.name}\n </MasterDetail.ListItem>\n ))}\n </MasterDetail.List>\n <MasterDetail.Detail>\n {selectedId ? <ItemDetail id={selectedId} /> : <EmptyState />}\n </MasterDetail.Detail>\n</MasterDetail>"
9564
10382
  ],
@@ -9663,7 +10481,8 @@
9663
10481
  "name": "object",
9664
10482
  "raw": "MultiSelectItem[]"
9665
10483
  },
9666
- "required": false
10484
+ "required": false,
10485
+ "description": "flat list — use `groups` for grouped rendering"
9667
10486
  },
9668
10487
  "groups": {
9669
10488
  "type": {
@@ -9759,36 +10578,6 @@
9759
10578
  },
9760
10579
  "required": false,
9761
10580
  "description": "trigger element"
9762
- },
9763
- "id": {
9764
- "type": {
9765
- "name": "string"
9766
- },
9767
- "required": false
9768
- },
9769
- "label": {
9770
- "type": {
9771
- "name": "string"
9772
- },
9773
- "required": false
9774
- },
9775
- "image": {
9776
- "type": {
9777
- "name": "string"
9778
- },
9779
- "required": false
9780
- },
9781
- "description": {
9782
- "type": {
9783
- "name": "string"
9784
- },
9785
- "required": false
9786
- },
9787
- "disabled": {
9788
- "type": {
9789
- "name": "boolean"
9790
- },
9791
- "required": false
9792
10581
  }
9793
10582
  },
9794
10583
  "composition": {
@@ -9809,6 +10598,59 @@
9809
10598
  "align": "start",
9810
10599
  "width": "{240}"
9811
10600
  },
10601
+ "subComponents": {
10602
+ "MultiSelectItem": {
10603
+ "props": {
10604
+ "id": {
10605
+ "type": {
10606
+ "name": "string"
10607
+ },
10608
+ "required": false
10609
+ },
10610
+ "label": {
10611
+ "type": {
10612
+ "name": "string"
10613
+ },
10614
+ "required": false
10615
+ },
10616
+ "image": {
10617
+ "type": {
10618
+ "name": "string"
10619
+ },
10620
+ "required": false
10621
+ },
10622
+ "description": {
10623
+ "type": {
10624
+ "name": "string"
10625
+ },
10626
+ "required": false
10627
+ },
10628
+ "disabled": {
10629
+ "type": {
10630
+ "name": "boolean"
10631
+ },
10632
+ "required": false
10633
+ }
10634
+ }
10635
+ },
10636
+ "MultiSelectGroup": {
10637
+ "props": {
10638
+ "label": {
10639
+ "type": {
10640
+ "name": "string"
10641
+ },
10642
+ "required": false
10643
+ },
10644
+ "items": {
10645
+ "type": {
10646
+ "name": "object",
10647
+ "raw": "MultiSelectItem[]"
10648
+ },
10649
+ "required": false
10650
+ }
10651
+ }
10652
+ }
10653
+ },
9812
10654
  "examples": [
9813
10655
  "<MultiSelectPopover\n items={[\n { id: '1', label: 'Alice', image: '/alice.jpg' },\n { id: '2', label: 'Bob' },\n ]}\n value={selected}\n onValueChange={setSelected}\n>\n <Button>Assign members</Button>\n</MultiSelectPopover>"
9814
10656
  ],
@@ -9875,7 +10717,7 @@
9875
10717
  "**Server-safe page-top header** with title + subtitle + breadcrumbs + actions slot. Renders Breadcrumb internally from the `breadcrumbs` array.",
9876
10718
  "**Auto-derived title:** If `title` is omitted, the last breadcrumb's `label` becomes the h1. Saves duplication when the page title matches the breadcrumb leaf.",
9877
10719
  "**Breadcrumb contract:** Last item should NOT have an `href` (it's the current page — renders as BreadcrumbPage, not a link). Items with `href` render as BreadcrumbLink.",
9878
- "**actions slot:** Typically one to three buttons (Save, Cancel, More). For larger action groups, use ButtonGroup or a toolbar.",
10720
+ "**actions slot:** Typically one to three buttons (Save, Cancel, More). The slot wraps onto its own line under the title on narrow viewports instead of forcing horizontal overflow, so multiple/wide buttons are mobile-safe. For larger action groups, use ButtonGroup or a toolbar.",
9879
10721
  "**Not for tabs / sub-navigation** — pair with Tabs rendered below PageHeader for that."
9880
10722
  ]
9881
10723
  },
@@ -10001,168 +10843,159 @@
10001
10843
  }
10002
10844
  ]
10003
10845
  },
10004
- "rich-chat-input": {
10005
- "displayName": "RichChatInput",
10846
+ "responsive-modal": {
10847
+ "displayName": "ResponsiveModal",
10006
10848
  "tier": "composed",
10007
- "import": "@devalok/shilp-sutra/composed/rich-chat-input",
10849
+ "import": "@devalok/shilp-sutra/composed/responsive-modal",
10008
10850
  "serverSafe": false,
10009
- "description": "Compact rich text chat input for unified human+AI workspaces. Built on TipTap.",
10851
+ "description": "",
10010
10852
  "props": {
10011
- "onSubmit": {
10012
- "type": {
10013
- "name": "function",
10014
- "raw": "(html: string, plainText: string) => void (REQUIRED)"
10015
- },
10016
- "required": false
10017
- },
10018
- "placeholder": {
10019
- "type": {
10020
- "name": "string"
10021
- },
10022
- "required": false,
10023
- "defaultValue": "Type a message..."
10024
- },
10025
- "disabled": {
10853
+ "open": {
10026
10854
  "type": {
10027
10855
  "name": "boolean"
10028
10856
  },
10029
10857
  "required": false,
10030
- "defaultValue": false
10031
- },
10032
- "variant": {
10033
- "type": {
10034
- "name": "enum",
10035
- "value": [
10036
- "compact",
10037
- "expanded",
10038
- "minimal"
10039
- ]
10040
- },
10041
- "required": false,
10042
- "defaultValue": "compact"
10043
- },
10044
- "maxRows": {
10045
- "type": {
10046
- "name": "number"
10047
- },
10048
- "required": false
10858
+ "description": "controlled open state"
10049
10859
  },
10050
- "enterBehavior": {
10860
+ "defaultOpen": {
10051
10861
  "type": {
10052
- "name": "enum",
10053
- "value": [
10054
- "send",
10055
- "newline"
10056
- ]
10862
+ "name": "boolean"
10057
10863
  },
10058
10864
  "required": false,
10059
- "defaultValue": "send"
10060
- },
10061
- "maxLength": {
10062
- "type": {
10063
- "name": "object",
10064
- "raw": "number — enables character counter"
10065
- },
10066
- "required": false
10067
- },
10068
- "mentions": {
10069
- "type": {
10070
- "name": "object",
10071
- "raw": "MentionItem[] — static list for @mention autocomplete"
10072
- },
10073
- "required": false
10865
+ "description": "uncontrolled initial state"
10074
10866
  },
10075
- "onMentionSearch": {
10076
- "type": {
10077
- "name": "function",
10078
- "raw": "(query: string) => Promise<MentionItem[]> — async search"
10079
- },
10080
- "required": false
10081
- },
10082
- "onMentionSelect": {
10867
+ "onOpenChange": {
10083
10868
  "type": {
10084
10869
  "name": "function",
10085
- "raw": "(item: MentionItem) => void"
10870
+ "raw": "(open: boolean) => void"
10086
10871
  },
10087
10872
  "required": false
10088
10873
  },
10089
- "onFileUpload": {
10874
+ "dismissable": {
10090
10875
  "type": {
10091
- "name": "function",
10092
- "raw": "(file: File) => Promise<{ url: string; name: string; size: number }>"
10876
+ "name": "boolean"
10093
10877
  },
10094
- "required": false
10095
- },
10096
- "onImageUpload": {
10097
- "type": {
10098
- "name": "function",
10099
- "raw": "(file: File) => Promise<string>"
10878
+ "required": false,
10879
+ "defaultValue": "true — when false, Escape / outside-click / drag cannot close; only an explicit Close or onOpenChange does"
10880
+ }
10881
+ },
10882
+ "composition": {
10883
+ "parts": [
10884
+ {
10885
+ "name": "ResponsiveModal",
10886
+ "required": true,
10887
+ "description": "root; owns open/close state and the desktop/mobile switch"
10100
10888
  },
10101
- "required": false
10102
- },
10103
- "slashCommands": {
10104
- "type": {
10105
- "name": "object",
10106
- "raw": "SlashCommandGroup[] — enables / command palette"
10889
+ {
10890
+ "name": "ResponsiveModalTrigger",
10891
+ "description": "opens the modal; use `asChild` to wrap your own button"
10107
10892
  },
10108
- "required": false
10109
- },
10110
- "onTyping": {
10111
- "type": {
10112
- "name": "function",
10113
- "raw": "(isTyping: boolean) => void — typing indicator callback"
10893
+ {
10894
+ "name": "ResponsiveModalContent",
10895
+ "description": "the switching panel: centered Dialog at md+, bottom sheet below"
10114
10896
  },
10115
- "required": false
10116
- },
10117
- "onEmpty": {
10118
- "type": {
10119
- "name": "function",
10120
- "raw": "(isEmpty: boolean) => void"
10897
+ {
10898
+ "name": "ResponsiveModalBackground",
10899
+ "slot": "behind",
10900
+ "description": "optional full-bleed layer painted at `-z-10`, clipped to the panel radius"
10121
10901
  },
10122
- "required": false
10123
- },
10124
- "isStreaming": {
10125
- "type": {
10126
- "name": "object",
10127
- "raw": "boolean (default: false) — shows stop button instead of send"
10902
+ {
10903
+ "name": "ResponsiveModalHeader",
10904
+ "slot": "top",
10905
+ "description": "pinned; stays put while the body scrolls"
10128
10906
  },
10129
- "required": false
10130
- },
10131
- "onCancel": {
10132
- "type": {
10133
- "name": "function",
10134
- "raw": "() => void — called when stop button is clicked"
10907
+ {
10908
+ "name": "ResponsiveModalTitle",
10909
+ "required": true,
10910
+ "description": "labels the dialog for accessibility"
10135
10911
  },
10136
- "required": false
10137
- },
10138
- "leadingSlot": {
10139
- "type": {
10140
- "name": "ReactNode"
10912
+ {
10913
+ "name": "ResponsiveModalDescription",
10914
+ "description": "optional subtitle"
10141
10915
  },
10142
- "required": false
10143
- },
10144
- "trailingSlot": {
10145
- "type": {
10146
- "name": "ReactNode"
10916
+ {
10917
+ "name": "ResponsiveModalBody",
10918
+ "description": "internal scroll region (min-h-0 flex-1 overflow-y-auto), capped 85dvh desktop / 90dvh mobile"
10147
10919
  },
10148
- "required": false
10149
- },
10150
- "disclaimer": {
10151
- "type": {
10152
- "name": "object",
10153
- "raw": "string — small text below the input"
10920
+ {
10921
+ "name": "ResponsiveModalFooter",
10922
+ "slot": "bottom",
10923
+ "description": "pinned action row; stacks on mobile, right-aligned inline on desktop"
10154
10924
  },
10155
- "required": false
10156
- },
10157
- "toolbar": {
10158
- "type": {
10159
- "name": "union",
10160
- "raw": "boolean | ChatToolbarItem[]"
10925
+ {
10926
+ "name": "ResponsiveModalClose",
10927
+ "description": "manual close (Content already renders a built-in close button when dismissable)"
10928
+ }
10929
+ ],
10930
+ "composesWith": [
10931
+ {
10932
+ "component": "dialog",
10933
+ "relation": "alternative-to",
10934
+ "description": "use Dialog directly when you always want a centered modal"
10161
10935
  },
10162
- "required": false,
10163
- "defaultValue": true
10936
+ {
10937
+ "component": "sheet",
10938
+ "relation": "alternative-to",
10939
+ "description": "use Sheet directly when you always want an edge panel"
10940
+ }
10941
+ ],
10942
+ "contexts": [
10943
+ {
10944
+ "name": "ResponsiveModal",
10945
+ "effect": "provides open / isMobile / dismissable / onClose to its parts via context"
10946
+ }
10947
+ ]
10948
+ },
10949
+ "docPath": "docs/components/composed/responsive-modal.md",
10950
+ "defaults": {
10951
+ "dismissable": true
10952
+ },
10953
+ "subComponents": {
10954
+ "ResponsiveModalContent": {
10955
+ "props": {
10956
+ "snapPoints": {
10957
+ "type": {
10958
+ "name": "object",
10959
+ "raw": "number[]"
10960
+ },
10961
+ "required": false,
10962
+ "description": "mobile only; ascending viewport-height fractions like [0.4, 0.9] the sheet rests at. Omit for a content-height sheet. Ignored on desktop"
10963
+ },
10964
+ "defaultSnapPoint": {
10965
+ "type": {
10966
+ "name": "number"
10967
+ },
10968
+ "required": false,
10969
+ "description": "mobile only; index into snapPoints the sheet opens at. Defaults to the last/tallest"
10970
+ }
10971
+ }
10164
10972
  }
10165
10973
  },
10974
+ "examples": [
10975
+ "<ResponsiveModal>\n <ResponsiveModalTrigger asChild><Button>Edit profile</Button></ResponsiveModalTrigger>\n <ResponsiveModalContent snapPoints={[0.5, 0.9]}>\n <ResponsiveModalBackground className=\"bg-linear-to-br from-accent-3 to-accent-6 opacity-40\" />\n <ResponsiveModalHeader>\n <ResponsiveModalTitle>Edit profile</ResponsiveModalTitle>\n <ResponsiveModalDescription>Changes save when you apply.</ResponsiveModalDescription>\n </ResponsiveModalHeader>\n <ResponsiveModalBody>{/* form fields — scrolls internally */}</ResponsiveModalBody>\n <ResponsiveModalFooter>\n <ResponsiveModalClose asChild><Button variant=\"soft\">Cancel</Button></ResponsiveModalClose>\n <Button>Apply</Button>\n </ResponsiveModalFooter>\n </ResponsiveModalContent>\n</ResponsiveModal>"
10976
+ ],
10977
+ "gotchas": [
10978
+ "Built on the same dialog primitive as Dialog and Sheet — focus trap, Escape, scroll lock, and portal are handled. Not server-safe (uses hooks); import in a client component.",
10979
+ "Put a `ResponsiveModalTitle` inside every modal — it sets the ARIA label. Omitting it triggers an accessibility warning.",
10980
+ "The built-in close button sits at `z-10` above `ResponsiveModalBackground` (`-z-10`); keep Header/Body/Footer in normal flow (no `relative z-*` wrapper) or a positioned wrapper will paint over the close button and eat the tap.",
10981
+ "`snapPoints` and `defaultSnapPoint` are mobile-only — they are ignored at md+ (always a centered Dialog).",
10982
+ "Height caps live on the panel (85dvh desktop / 90dvh mobile); do not add your own `max-h` to `ResponsiveModalBody` — it already scrolls.",
10983
+ "Prefer this over `DialogContent responsive` when the mobile form should be a partial bottom sheet; `responsive` collapses to a full-screen takeover that leaves dead space under short content."
10984
+ ],
10985
+ "changes": [
10986
+ {
10987
+ "version": "0.49.0",
10988
+ "summary": "Added — new component. Dialog (md+) / bottom-sheet (mobile) responsive modal with pinned header/footer, internal scroll body, optional full-bleed background slot, drag-to-dismiss, and optional mobile snap points."
10989
+ }
10990
+ ]
10991
+ },
10992
+ "rich-chat-input": {
10993
+ "displayName": "RichChatInput",
10994
+ "tier": "composed",
10995
+ "import": "@devalok/shilp-sutra/composed/rich-chat-input",
10996
+ "serverSafe": false,
10997
+ "description": "Compact rich text chat input for unified human+AI workspaces. Built on TipTap.",
10998
+ "props": {},
10166
10999
  "composition": {
10167
11000
  "notes": [
10168
11001
  "**Chat-specific TipTap editor** — purpose-built for AI + human messaging. Built on RichTextEditor primitives but pre-configured for the chat UX (auto-resize, Enter-to-send, inline toolbar).",
@@ -10175,6 +11008,166 @@
10175
11008
  ]
10176
11009
  },
10177
11010
  "docPath": "docs/components/composed/rich-chat-input.md",
11011
+ "subComponents": {
11012
+ "RichChatInputProps": {
11013
+ "props": {
11014
+ "onSubmit": {
11015
+ "type": {
11016
+ "name": "function",
11017
+ "raw": "(html: string, plainText: string) => void (REQUIRED)"
11018
+ },
11019
+ "required": false
11020
+ },
11021
+ "placeholder": {
11022
+ "type": {
11023
+ "name": "string"
11024
+ },
11025
+ "required": false,
11026
+ "defaultValue": "Type a message..."
11027
+ },
11028
+ "disabled": {
11029
+ "type": {
11030
+ "name": "boolean"
11031
+ },
11032
+ "required": false,
11033
+ "defaultValue": false
11034
+ },
11035
+ "variant": {
11036
+ "type": {
11037
+ "name": "enum",
11038
+ "value": [
11039
+ "compact",
11040
+ "expanded",
11041
+ "minimal"
11042
+ ]
11043
+ },
11044
+ "required": false,
11045
+ "defaultValue": "compact"
11046
+ },
11047
+ "maxRows": {
11048
+ "type": {
11049
+ "name": "number"
11050
+ },
11051
+ "required": false
11052
+ },
11053
+ "enterBehavior": {
11054
+ "type": {
11055
+ "name": "enum",
11056
+ "value": [
11057
+ "send",
11058
+ "newline"
11059
+ ]
11060
+ },
11061
+ "required": false,
11062
+ "defaultValue": "send"
11063
+ },
11064
+ "maxLength": {
11065
+ "type": {
11066
+ "name": "object",
11067
+ "raw": "number — enables character counter"
11068
+ },
11069
+ "required": false
11070
+ },
11071
+ "mentions": {
11072
+ "type": {
11073
+ "name": "object",
11074
+ "raw": "MentionItem[] — static list for @mention autocomplete"
11075
+ },
11076
+ "required": false
11077
+ },
11078
+ "onMentionSearch": {
11079
+ "type": {
11080
+ "name": "function",
11081
+ "raw": "(query: string) => Promise<MentionItem[]> — async search"
11082
+ },
11083
+ "required": false
11084
+ },
11085
+ "onMentionSelect": {
11086
+ "type": {
11087
+ "name": "function",
11088
+ "raw": "(item: MentionItem) => void"
11089
+ },
11090
+ "required": false
11091
+ },
11092
+ "onFileUpload": {
11093
+ "type": {
11094
+ "name": "function",
11095
+ "raw": "(file: File) => Promise<{ url: string; name: string; size: number }>"
11096
+ },
11097
+ "required": false
11098
+ },
11099
+ "onImageUpload": {
11100
+ "type": {
11101
+ "name": "function",
11102
+ "raw": "(file: File) => Promise<string>"
11103
+ },
11104
+ "required": false
11105
+ },
11106
+ "slashCommands": {
11107
+ "type": {
11108
+ "name": "object",
11109
+ "raw": "SlashCommandGroup[] — enables / command palette"
11110
+ },
11111
+ "required": false
11112
+ },
11113
+ "onTyping": {
11114
+ "type": {
11115
+ "name": "function",
11116
+ "raw": "(isTyping: boolean) => void — typing indicator callback"
11117
+ },
11118
+ "required": false
11119
+ },
11120
+ "onEmpty": {
11121
+ "type": {
11122
+ "name": "function",
11123
+ "raw": "(isEmpty: boolean) => void"
11124
+ },
11125
+ "required": false
11126
+ },
11127
+ "isStreaming": {
11128
+ "type": {
11129
+ "name": "object",
11130
+ "raw": "boolean (default: false) — shows stop button instead of send"
11131
+ },
11132
+ "required": false
11133
+ },
11134
+ "onCancel": {
11135
+ "type": {
11136
+ "name": "function",
11137
+ "raw": "() => void — called when stop button is clicked"
11138
+ },
11139
+ "required": false
11140
+ },
11141
+ "leadingSlot": {
11142
+ "type": {
11143
+ "name": "ReactNode"
11144
+ },
11145
+ "required": false
11146
+ },
11147
+ "trailingSlot": {
11148
+ "type": {
11149
+ "name": "ReactNode"
11150
+ },
11151
+ "required": false
11152
+ },
11153
+ "disclaimer": {
11154
+ "type": {
11155
+ "name": "object",
11156
+ "raw": "string — small text below the input"
11157
+ },
11158
+ "required": false
11159
+ },
11160
+ "toolbar": {
11161
+ "type": {
11162
+ "name": "union",
11163
+ "raw": "boolean | ChatToolbarItem[]"
11164
+ },
11165
+ "required": false,
11166
+ "defaultValue": true
11167
+ }
11168
+ }
11169
+ }
11170
+ },
10178
11171
  "examples": [
10179
11172
  "<RichChatInput\n onSubmit={(html, text) => sendMessage(html)}\n mentions={teamMembers}\n onFileUpload={uploadFile}\n slashCommands={[{ label: 'Actions', commands: [...] }]}\n/>\n\n<RichChatInput\n variant=\"expanded\"\n onSubmit={handleSubmit}\n maxLength={2000}\n disclaimer=\"AI-generated content may be inaccurate.\"\n/>\n\n<RichChatInput\n variant=\"minimal\"\n enterBehavior=\"newline\"\n onSubmit={handleReply}\n/>"
10180
11173
  ],
@@ -10209,7 +11202,7 @@
10209
11202
  "name": "string"
10210
11203
  },
10211
11204
  "required": false,
10212
- "description": "REQUIRED, HTML string"
11205
+ "description": "HTML string"
10213
11206
  },
10214
11207
  "placeholder": {
10215
11208
  "type": {
@@ -10297,6 +11290,25 @@
10297
11290
  "placeholder": "Start writing...",
10298
11291
  "editable": true
10299
11292
  },
11293
+ "subComponents": {
11294
+ "RichTextViewer": {
11295
+ "props": {
11296
+ "content": {
11297
+ "type": {
11298
+ "name": "string"
11299
+ },
11300
+ "required": false,
11301
+ "description": "REQUIRED, HTML string"
11302
+ },
11303
+ "className": {
11304
+ "type": {
11305
+ "name": "string"
11306
+ },
11307
+ "required": false
11308
+ }
11309
+ }
11310
+ }
11311
+ },
10300
11312
  "examples": [
10301
11313
  "<RichTextEditor content={html} onChange={setHtml} placeholder=\"Write your message...\" />\n\n<RichTextEditor\n content={html}\n onChange={setHtml}\n mentions={[{ id: '1', label: 'Aarav' }]}\n onImageUpload={async (file) => uploadAndReturnUrl(file)}\n onFileUpload={async (file) => ({ url: uploadUrl, name: file.name, size: file.size })}\n/>\n\n<RichTextViewer content={savedHtml} />"
10302
11314
  ],
@@ -10412,7 +11424,7 @@
10412
11424
  "**Day / Week calendar view** for time-block display (meetings, shifts, availability). Not a full calendar app — no month view, no drag-to-create.",
10413
11425
  "**Event data is consumer-owned:** You pass `events` as an array; ScheduleView doesn't fetch, doesn't cache, doesn't expand recurring events. All scheduling logic lives in your app.",
10414
11426
  "**Event click + slot click** — `onEventClick` for existing events; `onSlotClick` for creating new events (fires with start/end of the empty slot).",
10415
- "**Color vocabulary matches the DS** — `primary/success/warning/error/info/neutral`. Map your event types to these at the data layer.",
11427
+ "**Color vocabulary matches the DS** — `accent/success/warning/error/info/neutral`. Map your event types to these at the data layer.",
10416
11428
  "**endHour is exclusive:** `endHour=18` means the last visible slot starts at 17:30 (with 30min slots). Match your UX expectation: 9-5 typically means `startHour=9, endHour=18`.",
10417
11429
  "**Pairs with date-picker/composed** — use DatePicker or DateRangePicker to choose which date to show; pass that as ScheduleView's `date`."
10418
11430
  ]
@@ -10432,6 +11444,10 @@
10432
11444
  "Events that span outside `startHour`/`endHour` may be clipped"
10433
11445
  ],
10434
11446
  "changes": [
11447
+ {
11448
+ "version": "0.49.0",
11449
+ "summary": "**BREAKING** `ScheduleEvent.color` value `\"primary\"` renamed `\"accent\"` (DS colour vocabulary). It was the default, so untyped events are unaffected."
11450
+ },
10435
11451
  {
10436
11452
  "version": "0.1.0",
10437
11453
  "summary": "**Added** Initial release"
@@ -10846,28 +11862,7 @@
10846
11862
  "import": "@devalok/shilp-sutra/shell/command-registry",
10847
11863
  "serverSafe": false,
10848
11864
  "description": "Exports: CommandRegistryProvider, useCommandRegistry",
10849
- "props": {
10850
- "children": {
10851
- "type": {
10852
- "name": "ReactNode"
10853
- },
10854
- "required": false
10855
- },
10856
- "registry": {
10857
- "type": {
10858
- "name": "object",
10859
- "raw": "CommandRegistry"
10860
- },
10861
- "required": true
10862
- },
10863
- "Returns": {
10864
- "type": {
10865
- "name": "union",
10866
- "raw": "CommandRegistry | null"
10867
- },
10868
- "required": false
10869
- }
10870
- },
11865
+ "props": {},
10871
11866
  "composition": {
10872
11867
  "notes": [
10873
11868
  "**Context provider for AppCommandPalette.** Registers page-level navigation items that the command palette surfaces as commands.",
@@ -10878,6 +11873,36 @@
10878
11873
  ]
10879
11874
  },
10880
11875
  "docPath": "docs/components/shell/command-registry.md",
11876
+ "subComponents": {
11877
+ "CommandRegistryProvider": {
11878
+ "props": {
11879
+ "children": {
11880
+ "type": {
11881
+ "name": "ReactNode"
11882
+ },
11883
+ "required": false
11884
+ },
11885
+ "registry": {
11886
+ "type": {
11887
+ "name": "object",
11888
+ "raw": "CommandRegistry"
11889
+ },
11890
+ "required": true
11891
+ }
11892
+ }
11893
+ },
11894
+ "useCommandRegistry hook": {
11895
+ "props": {
11896
+ "Returns": {
11897
+ "type": {
11898
+ "name": "union",
11899
+ "raw": "CommandRegistry | null"
11900
+ },
11901
+ "required": false
11902
+ }
11903
+ }
11904
+ }
11905
+ },
10881
11906
  "examples": [
10882
11907
  "<CommandRegistryProvider\n registry={{\n pages: [\n { id: 'dashboard', label: 'Dashboard', icon: <IconHome />, path: '/dashboard' },\n { id: 'projects', label: 'Projects', icon: <IconFolder />, path: '/projects' },\n ],\n adminPages: [\n { id: 'users', label: 'Manage Users', icon: <IconUsers />, path: '/admin/users' },\n ],\n }}\n>\n <App />\n</CommandRegistryProvider>"
10883
11908
  ],
@@ -10913,13 +11938,6 @@
10913
11938
  "name": "ReactNode"
10914
11939
  },
10915
11940
  "required": false
10916
- },
10917
- "Returns": {
10918
- "type": {
10919
- "name": "object",
10920
- "raw": "LinkComponent"
10921
- },
10922
- "required": false
10923
11941
  }
10924
11942
  },
10925
11943
  "composition": {
@@ -10933,6 +11951,19 @@
10933
11951
  ]
10934
11952
  },
10935
11953
  "docPath": "docs/components/shell/link-context.md",
11954
+ "subComponents": {
11955
+ "useLink hook": {
11956
+ "props": {
11957
+ "Returns": {
11958
+ "type": {
11959
+ "name": "object",
11960
+ "raw": "LinkComponent"
11961
+ },
11962
+ "required": false
11963
+ }
11964
+ }
11965
+ }
11966
+ },
10936
11967
  "examples": [
10937
11968
  "import Link from 'next/link'\n\n<LinkProvider component={Link}>\n <AppSidebar ... />\n <BottomNavbar ... />\n</LinkProvider>"
10938
11969
  ],
@@ -11209,102 +12240,655 @@
11209
12240
  "name": "string"
11210
12241
  },
11211
12242
  "required": false
12243
+ }
12244
+ },
12245
+ "composition": {
12246
+ "notes": [
12247
+ "**Composition-based, NOT data-driven.** Use dot-notation subcomponents (`TopBar.Left`, `TopBar.Center`, `TopBar.Right`, `TopBar.Section`, `TopBar.IconButton`, `TopBar.Title`, `TopBar.UserMenu`) to assemble. No \"props config\" — explicit JSX.",
12248
+ "**Two-zone vs three-zone layout** — adding `TopBar.Center` flips the root from `flex` to CSS grid (`1fr auto 1fr`) for true centering. Standard apps are two-zone (Left + Right); dashboards with prominent search are three-zone.",
12249
+ "**Required providers:** - `SidebarProvider` — for SidebarTrigger inside `TopBar.Left` to work - `LinkProvider` — for TopBar.UserMenu's menu items that use `href`",
12250
+ "**NotificationCenter lives inside TopBar.Right** — it's a complete bell+popover component. Drop it in a TopBar.Section next to other icon buttons.",
12251
+ "**UserMenu is composable:** `userMenuItems` inserts custom items between the built-in Profile and the color-mode toggle. Each item can navigate (href), run an action (onClick), or show a separator/badge/color decoration.",
12252
+ "**Responsive hiding:** Actions that shouldn't appear on mobile use `className=\"hidden md:flex\"` on the IconButton — the component doesn't enforce mobile hiding; that's layout responsibility.",
12253
+ "**Pairs with AppSidebar** — desktop app shell is typically `<TopBar>` + `<AppSidebar>` + main content region."
12254
+ ]
12255
+ },
12256
+ "docPath": "docs/components/shell/top-bar.md",
12257
+ "subComponents": {
12258
+ "TopBar.Left": {
12259
+ "props": {
12260
+ "children": {
12261
+ "type": {
12262
+ "name": "ReactNode"
12263
+ },
12264
+ "required": false
12265
+ },
12266
+ "className": {
12267
+ "type": {
12268
+ "name": "string"
12269
+ },
12270
+ "required": false
12271
+ }
12272
+ }
11212
12273
  },
11213
- "gap": {
12274
+ "TopBar.Center": {
12275
+ "props": {
12276
+ "children": {
12277
+ "type": {
12278
+ "name": "ReactNode"
12279
+ },
12280
+ "required": false
12281
+ },
12282
+ "className": {
12283
+ "type": {
12284
+ "name": "string"
12285
+ },
12286
+ "required": false
12287
+ }
12288
+ }
12289
+ },
12290
+ "TopBar.Right": {
12291
+ "props": {
12292
+ "children": {
12293
+ "type": {
12294
+ "name": "ReactNode"
12295
+ },
12296
+ "required": false
12297
+ },
12298
+ "className": {
12299
+ "type": {
12300
+ "name": "string"
12301
+ },
12302
+ "required": false
12303
+ }
12304
+ }
12305
+ },
12306
+ "TopBar.Section": {
12307
+ "props": {
12308
+ "gap": {
12309
+ "type": {
12310
+ "name": "enum",
12311
+ "value": [
12312
+ "tight",
12313
+ "default",
12314
+ "loose"
12315
+ ]
12316
+ },
12317
+ "required": false,
12318
+ "defaultValue": "default"
12319
+ },
12320
+ "children": {
12321
+ "type": {
12322
+ "name": "ReactNode"
12323
+ },
12324
+ "required": false
12325
+ },
12326
+ "className": {
12327
+ "type": {
12328
+ "name": "string"
12329
+ },
12330
+ "required": false
12331
+ }
12332
+ }
12333
+ },
12334
+ "TopBar.IconButton": {
12335
+ "props": {
12336
+ "icon": {
12337
+ "type": {
12338
+ "name": "ReactNode"
12339
+ },
12340
+ "required": false
12341
+ },
12342
+ "tooltip": {
12343
+ "type": {
12344
+ "name": "string"
12345
+ },
12346
+ "required": false
12347
+ }
12348
+ }
12349
+ },
12350
+ "TopBar.Title": {
12351
+ "props": {
12352
+ "children": {
12353
+ "type": {
12354
+ "name": "ReactNode"
12355
+ },
12356
+ "required": false
12357
+ },
12358
+ "className": {
12359
+ "type": {
12360
+ "name": "string"
12361
+ },
12362
+ "required": false
12363
+ }
12364
+ }
12365
+ },
12366
+ "TopBar.UserMenu": {
12367
+ "props": {
12368
+ "user": {
12369
+ "type": {
12370
+ "name": "object",
12371
+ "raw": "TopBarUser — { name, email?, image? }"
12372
+ },
12373
+ "required": false
12374
+ },
12375
+ "onNavigate": {
12376
+ "type": {
12377
+ "name": "function",
12378
+ "raw": "(path: string) => void"
12379
+ },
12380
+ "required": false
12381
+ },
12382
+ "onLogout": {
12383
+ "type": {
12384
+ "name": "function",
12385
+ "raw": "() => void"
12386
+ },
12387
+ "required": false
12388
+ },
12389
+ "userMenuItems": {
12390
+ "type": {
12391
+ "name": "object",
12392
+ "raw": "UserMenuItem[]"
12393
+ },
12394
+ "required": false
12395
+ },
12396
+ "className": {
12397
+ "type": {
12398
+ "name": "string"
12399
+ },
12400
+ "required": false
12401
+ }
12402
+ }
12403
+ }
12404
+ },
12405
+ "examples": [
12406
+ "<TopBar>\n <TopBar.Left>\n <SidebarTrigger />\n <TopBar.Title>Dashboard</TopBar.Title>\n </TopBar.Left>\n <TopBar.Right>\n <TopBar.Section gap=\"tight\">\n <TopBar.IconButton icon={<IconSearch />} tooltip=\"Search (Ctrl+K)\" onClick={openSearch} />\n <NotificationCenter notifications={notifications} />\n <TopBar.IconButton icon={<IconSparkles />} tooltip=\"AI Chat\" onClick={openAI} />\n </TopBar.Section>\n <TopBar.UserMenu\n user={{ name: 'John', email: 'john@example.com' }}\n onNavigate={(p) => router.push(p)}\n onLogout={handleLogout}\n userMenuItems={[\n { label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },\n ]}\n />\n </TopBar.Right>\n</TopBar>",
12407
+ "<TopBar>\n <TopBar.Left>\n <SidebarTrigger />\n <TopBar.Title>Dashboard</TopBar.Title>\n </TopBar.Left>\n <TopBar.Center>\n <SearchBarTrigger />\n </TopBar.Center>\n <TopBar.Right>\n <TopBar.Section gap=\"tight\">\n <TopBar.IconButton icon={<IconBell />} tooltip=\"Notifications\" onClick={fn} />\n </TopBar.Section>\n <TopBar.UserMenu user={user} onLogout={logout} />\n </TopBar.Right>\n</TopBar>"
12408
+ ],
12409
+ "gotchas": [
12410
+ "Without `TopBar.Center`, layout is flex (two-zone). With it, layout switches to CSS grid `1fr auto 1fr` for true centering.",
12411
+ "`TopBar.IconButton` renders any number of action buttons — no artificial limit. Use responsive hiding (`className=\"hidden md:flex\"`) for mobile.",
12412
+ "`TopBar.UserMenu` includes Profile link, color mode toggle, and logout automatically. `userMenuItems` are inserted between Profile and the toggle.",
12413
+ "Requires SidebarProvider wrapper for SidebarTrigger to work."
12414
+ ],
12415
+ "changes": [
12416
+ {
12417
+ "version": "0.19.0",
12418
+ "summary": "**BREAKING** Rewritten as composition API. Old props-based API removed (`pageTitle`, `onSearchClick`, `onAiChatClick`, `notificationSlot`, `mobileLogo` props)."
12419
+ },
12420
+ {
12421
+ "version": "0.27.2",
12422
+ "summary": "**Fixed** UserMenu email truncation — long emails now truncate instead of overflowing the dropdown"
12423
+ },
12424
+ {
12425
+ "version": "0.7.0",
12426
+ "summary": "**Added** `userMenuItems` prop for custom dropdown items"
12427
+ },
12428
+ {
12429
+ "version": "0.1.1",
12430
+ "summary": "**Changed** Decoupled from Next.js via LinkProvider"
12431
+ },
12432
+ {
12433
+ "version": "0.1.0",
12434
+ "summary": "**Added** Initial release"
12435
+ }
12436
+ ]
12437
+ },
12438
+ "ai-command-provider": {
12439
+ "displayName": "AICommandProvider",
12440
+ "tier": "ai",
12441
+ "import": "@devalok/shilp-sutra/ai/ai-command-provider",
12442
+ "serverSafe": false,
12443
+ "description": "Context provider for the AI command system. Supplies custom block renderers, the action handler, and the agent identity to `AIConversation` / `BlockRenderer` below it, so you configure them once instead of threading props through every message. Ships a `useAICommand()` hook to read the context.",
12444
+ "props": {
12445
+ "children": {
11214
12446
  "type": {
11215
- "name": "enum",
11216
- "value": [
11217
- "tight",
11218
- "default",
11219
- "loose"
11220
- ]
12447
+ "name": "ReactNode"
11221
12448
  },
11222
- "required": false,
11223
- "defaultValue": "default"
12449
+ "required": true
11224
12450
  },
11225
- "icon": {
12451
+ "customBlocks": {
11226
12452
  "type": {
11227
- "name": "ReactNode"
12453
+ "name": "object",
12454
+ "raw": "Record<string, ComponentType<BlockComponentProps>> — custom block-type renderers available to all descendants"
11228
12455
  },
11229
12456
  "required": false
11230
12457
  },
11231
- "tooltip": {
12458
+ "onAction": {
11232
12459
  "type": {
11233
- "name": "string"
12460
+ "name": "function",
12461
+ "raw": "(actionId: string, type: \"confirm\" | \"cancel\" | \"undo\") => void — default action handler for descendant blocks"
11234
12462
  },
11235
12463
  "required": false
11236
12464
  },
11237
- "user": {
12465
+ "agent": {
12466
+ "type": {
12467
+ "name": "object",
12468
+ "raw": "{ name: string, icon?: IconInput } — default agent identity for assistant messages"
12469
+ },
12470
+ "required": false
12471
+ }
12472
+ },
12473
+ "composition": {
12474
+ "notes": [
12475
+ "**Configure once** — set `customBlocks`, `onAction`, and `agent` here; `AIConversation` and `BlockRenderer` read them via context. Per-component props still win over the context (prop overrides provider).",
12476
+ "**`useAICommand()`** — returns the context (`{ customBlocks, onAction, agent }`) or `null` when no provider is mounted. Custom blocks can use it to reach the shared action handler.",
12477
+ "**Optional** — `AIConversation`/`BlockRenderer` work without a provider if you pass their props directly; the provider is a convenience for app-wide config."
12478
+ ]
12479
+ },
12480
+ "docPath": "docs/components/ai/ai-command-provider.md",
12481
+ "examples": [
12482
+ "<AICommandProvider\n agent={{ name: 'Devadoot', icon: <IconSparkles /> }}\n customBlocks={{ chart: ChartBlock }}\n onAction={(id, type) => handleAction(id, type)}\n>\n <AIConversation messages={messages} />\n</AICommandProvider>\n\n// Read the context in a descendant:\nfunction MyBlock() {\n const ctx = useAICommand() // { customBlocks, onAction, agent } | null\n // ...\n}"
12483
+ ],
12484
+ "gotchas": [
12485
+ "Client component — mount inside a client boundary.",
12486
+ "`useAICommand()` returns `null` (not a throw) when there's no provider — guard for it in custom blocks."
12487
+ ],
12488
+ "changes": [
12489
+ {
12490
+ "version": "0.49.0",
12491
+ "summary": "**Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP)."
12492
+ }
12493
+ ]
12494
+ },
12495
+ "block-renderer": {
12496
+ "displayName": "BlockRenderer",
12497
+ "tier": "ai",
12498
+ "import": "@devalok/shilp-sutra/ai/block-renderer",
12499
+ "serverSafe": false,
12500
+ "description": "Renders an ordered list of typed AI \"blocks\" — the structured chunks an assistant/ server emits instead of plain text. A registry maps each block's `type` to a React component; consumers can register their own types. This doc also covers the block system and how to author a custom block.",
12501
+ "props": {
12502
+ "blocks": {
11238
12503
  "type": {
11239
12504
  "name": "object",
11240
- "raw": "TopBarUser{ name, email?, image? }"
12505
+ "raw": "Block[] (required) ordered blocks to render"
11241
12506
  },
11242
12507
  "required": false
11243
12508
  },
11244
- "onNavigate": {
12509
+ "onAction": {
11245
12510
  "type": {
11246
12511
  "name": "function",
11247
- "raw": "(path: string) => void"
12512
+ "raw": "(actionId: string, type: \"confirm\" | \"cancel\" | \"undo\") => void — fired by interactive blocks (e.g. confirm)"
12513
+ },
12514
+ "required": false
12515
+ },
12516
+ "customBlocks": {
12517
+ "type": {
12518
+ "name": "object",
12519
+ "raw": "Record<string, ComponentType<BlockComponentProps>> — extra type→component renderers, merged OVER the built-ins"
12520
+ },
12521
+ "required": false,
12522
+ "description": "prop wins over context"
12523
+ },
12524
+ "staggerDelay": {
12525
+ "type": {
12526
+ "name": "object",
12527
+ "raw": "number — ms between each block's entrance animation"
12528
+ },
12529
+ "required": false,
12530
+ "description": "default 50"
12531
+ },
12532
+ "className": {
12533
+ "type": {
12534
+ "name": "string"
12535
+ },
12536
+ "required": false
12537
+ }
12538
+ },
12539
+ "composition": {
12540
+ "notes": [
12541
+ "**The block system** — the AI conversation renders assistant output as a `Block[]`. Each block has a `type` (string) and a `data` payload. `BlockRenderer` looks up the type in its registry and renders the matching component; an unknown type falls back to an `Alert` showing the raw JSON (so a new server-emitted type degrades gracefully instead of crashing).",
12542
+ "**Built-in block types** (9): `text` (Markdown prose), `table` (tabular data), `confirm` (action confirmation — confirm/cancel buttons + a \"Why this action?\" rationale drawer), `success` / `error` / `info` (status messages), `loading` (pending indicator), `divider` (separator), `stat_row` (a row of metric cards, composes `StatCard`).",
12543
+ "**Confidence** — every block may carry `confidence: \"high\" | \"medium\" | \"low\"`. Low-confidence blocks get a faint warning wash + a \"Low confidence\" chip (owned by the shared `BlockShell` wrapper, so the treatment is consistent across all block types). This is an AI-native affordance: the UI signals how sure the model is.",
12544
+ "**Writing a custom block** — a block component receives `BlockComponentProps<T>` (`data`, `confidence`, `onAction`, `blockId`). Wrap your content in `BlockShell` to inherit the confidence treatment. Register it via `customBlocks` (on `BlockRenderer` or `AICommandProvider`) keyed by the `type` string your server emits.",
12545
+ "**Two public block subpaths** — `text` and `error` import `react-markdown` + `remark-gfm` (a Markdown peer dependency). They were split out of the `ai/blocks` barrel in 0.40.0 so consumers don't pull those peers unless they render Markdown. Import them directly when needed: `@devalok/shilp-sutra/ai/blocks/text`, `@devalok/shilp-sutra/ai/blocks/error`.",
12546
+ "**Provider merge** — `customBlocks` from `AICommandProvider` (context) are merged with the `customBlocks` prop; the prop wins on key collision. Same for `onAction`."
12547
+ ]
12548
+ },
12549
+ "docPath": "docs/components/ai/block-renderer.md",
12550
+ "examples": [
12551
+ "// Render server-emitted blocks:\n<BlockRenderer\n blocks={message.blocks}\n onAction={(id, type) => handleAction(id, type)}\n/>\n\n// Register a custom block type:\nfunction ChartBlock({ data }) {\n return <MyChart series={data.series} />\n}\n<BlockRenderer\n blocks={message.blocks}\n customBlocks={{ chart: ChartBlock }}\n/>"
12552
+ ],
12553
+ "gotchas": [
12554
+ "Client component — mount inside a client boundary.",
12555
+ "Requires a mounted `MotionProvider` (block entrances respect reduced-motion).",
12556
+ "Rendering `text`/`error` blocks requires the `react-markdown` + `remark-gfm` peer dependencies — install them if your blocks include Markdown.",
12557
+ "The `ai/blocks/*` components are an implementation detail of the registry; consume blocks via `BlockRenderer`/`AIConversation`, not by importing each block (except the two documented Markdown subpaths)."
12558
+ ],
12559
+ "changes": [
12560
+ {
12561
+ "version": "0.49.0",
12562
+ "summary": "**Added** Component + block-system documentation (the AI layer is now covered by the docs gate + hosted MCP)."
12563
+ }
12564
+ ]
12565
+ },
12566
+ "command-bar": {
12567
+ "displayName": "CommandBar",
12568
+ "tier": "ai",
12569
+ "import": "@devalok/shilp-sutra/ai/command-bar",
12570
+ "serverSafe": false,
12571
+ "description": "A unified AI command input with three layout variants. Supports natural-language submission (`onSubmit`) and, optionally, command-palette filtering (`groups`) in the same bar. Shows an animated brand-gradient border while processing.",
12572
+ "props": {
12573
+ "onSubmit": {
12574
+ "type": {
12575
+ "name": "function",
12576
+ "raw": "(query: string) => void — called on Enter (natural-language submission)"
11248
12577
  },
11249
12578
  "required": false
11250
12579
  },
11251
- "onLogout": {
12580
+ "state": {
12581
+ "type": {
12582
+ "name": "union",
12583
+ "raw": "\"idle\" | \"typing\" | \"processing\" | \"responded\" — drives visual feedback"
12584
+ },
12585
+ "required": false,
12586
+ "description": "gradient border, placeholder"
12587
+ },
12588
+ "groups": {
12589
+ "type": {
12590
+ "name": "object",
12591
+ "raw": "CommandGroup[] — when provided, enables command-palette filtering alongside AI submission"
12592
+ },
12593
+ "required": false
12594
+ },
12595
+ "onSearch": {
11252
12596
  "type": {
11253
12597
  "name": "function",
11254
- "raw": "() => void"
12598
+ "raw": "(query: string) => void — fired as the query changes (palette mode)"
12599
+ },
12600
+ "required": false
12601
+ },
12602
+ "emptyMessage": {
12603
+ "type": {
12604
+ "name": "object",
12605
+ "raw": "string — text when a palette search yields nothing"
12606
+ },
12607
+ "required": false
12608
+ },
12609
+ "emptyState": {
12610
+ "type": {
12611
+ "name": "ReactNode"
12612
+ },
12613
+ "required": false
12614
+ },
12615
+ "variant": {
12616
+ "type": {
12617
+ "name": "union",
12618
+ "raw": "\"hero\" | \"inline\" | \"floating\" — layout"
12619
+ },
12620
+ "required": false,
12621
+ "description": "default \"hero\""
12622
+ },
12623
+ "placeholder": {
12624
+ "type": {
12625
+ "name": "union",
12626
+ "raw": "string | string[] — static text, or an array that rotates on an interval"
11255
12627
  },
11256
12628
  "required": false
11257
12629
  },
11258
- "userMenuItems": {
12630
+ "placeholderInterval": {
12631
+ "type": {
12632
+ "name": "object",
12633
+ "raw": "number — rotation interval in ms when placeholder is an array"
12634
+ },
12635
+ "required": false,
12636
+ "description": "default 4000"
12637
+ },
12638
+ "greeting": {
12639
+ "type": {
12640
+ "name": "object",
12641
+ "raw": "string — text above the input"
12642
+ },
12643
+ "required": false,
12644
+ "description": "hero variant"
12645
+ },
12646
+ "hints": {
11259
12647
  "type": {
11260
12648
  "name": "object",
11261
- "raw": "UserMenuItem[]"
12649
+ "raw": "string[] — hint strings below the input"
12650
+ },
12651
+ "required": false,
12652
+ "description": "hero variant"
12653
+ },
12654
+ "agentName": {
12655
+ "type": {
12656
+ "name": "string"
12657
+ },
12658
+ "required": false
12659
+ },
12660
+ "agentIcon": {
12661
+ "type": {
12662
+ "name": "ReactNode"
12663
+ },
12664
+ "required": false
12665
+ },
12666
+ "open": {
12667
+ "type": {
12668
+ "name": "object",
12669
+ "raw": "boolean — controlled open state"
12670
+ },
12671
+ "required": false,
12672
+ "description": "floating variant"
12673
+ },
12674
+ "defaultOpen": {
12675
+ "type": {
12676
+ "name": "object",
12677
+ "raw": "boolean — uncontrolled initial open"
12678
+ },
12679
+ "required": false,
12680
+ "description": "floating variant"
12681
+ },
12682
+ "onOpenChange": {
12683
+ "type": {
12684
+ "name": "function",
12685
+ "raw": "(open: boolean) => void — floating variant"
12686
+ },
12687
+ "required": false
12688
+ },
12689
+ "keybinding": {
12690
+ "type": {
12691
+ "name": "union",
12692
+ "raw": "string | string[] | false — global toggle for the floating bar"
12693
+ },
12694
+ "required": false,
12695
+ "description": "default \"mod+j\""
12696
+ },
12697
+ "disabled": {
12698
+ "type": {
12699
+ "name": "boolean"
12700
+ },
12701
+ "required": false
12702
+ },
12703
+ "maxHeight": {
12704
+ "type": {
12705
+ "name": "union",
12706
+ "raw": "string | number — cap on the results/scroll region"
12707
+ },
12708
+ "required": false,
12709
+ "description": "default \"320px\""
12710
+ },
12711
+ "children": {
12712
+ "type": {
12713
+ "name": "ReactNode"
11262
12714
  },
11263
12715
  "required": false
11264
12716
  }
11265
12717
  },
11266
12718
  "composition": {
11267
12719
  "notes": [
11268
- "**Composition-based, NOT data-driven.** Use dot-notation subcomponents (`TopBar.Left`, `TopBar.Center`, `TopBar.Right`, `TopBar.Section`, `TopBar.IconButton`, `TopBar.Title`, `TopBar.UserMenu`) to assemble. No \"props config\" explicit JSX.",
11269
- "**Two-zone vs three-zone layout** — adding `TopBar.Center` flips the root from `flex` to CSS grid (`1fr auto 1fr`) for true centering. Standard apps are two-zone (Left + Right); dashboards with prominent search are three-zone.",
11270
- "**Required providers:** - `SidebarProvider` for SidebarTrigger inside `TopBar.Left` to work - `LinkProvider` for TopBar.UserMenu's menu items that use `href`",
11271
- "**NotificationCenter lives inside TopBar.Right** — it's a complete bell+popover component. Drop it in a TopBar.Section next to other icon buttons.",
11272
- "**UserMenu is composable:** `userMenuItems` inserts custom items between the built-in Profile and the color-mode toggle. Each item can navigate (href), run an action (onClick), or show a separator/badge/color decoration.",
11273
- "**Responsive hiding:** Actions that shouldn't appear on mobile use `className=\"hidden md:flex\"` on the IconButton — the component doesn't enforce mobile hiding; that's layout responsibility.",
11274
- "**Pairs with AppSidebar** — desktop app shell is typically `<TopBar>` + `<AppSidebar>` + main content region."
12720
+ "**Two modes in one bar** pass `onSubmit` for natural-language AI; add `groups` to also get command-palette filtering (arrow-key navigation, grouped items). Reuses `CommandGroup`/`CommandItem` from composed/command-palette.",
12721
+ "**`floating` reuses the Dialog primitive** (`DialogContentRaw`) with a global keybinding same overlay pattern as CommandPalette, so focus-trap/Escape/scroll-lock come for free.",
12722
+ "**State-driven feedback** set `state=\"processing\"` to show the animated brand-gradient border; `\"responded\"` to settle it. Wire `state` to your agent's lifecycle.",
12723
+ "**Placeholder rotation** — pass an array to `placeholder` for the rotating-prompt effect (paused while typing; respects reduced-motion).",
12724
+ "**Pairs with `AIConversation`** CommandBar is the input; AIConversation renders the response thread."
11275
12725
  ]
11276
12726
  },
11277
- "docPath": "docs/components/shell/top-bar.md",
12727
+ "docPath": "docs/components/ai/command-bar.md",
11278
12728
  "examples": [
11279
- "<TopBar>\n <TopBar.Left>\n <SidebarTrigger />\n <TopBar.Title>Dashboard</TopBar.Title>\n </TopBar.Left>\n <TopBar.Right>\n <TopBar.Section gap=\"tight\">\n <TopBar.IconButton icon={<IconSearch />} tooltip=\"Search (Ctrl+K)\" onClick={openSearch} />\n <NotificationCenter notifications={notifications} />\n <TopBar.IconButton icon={<IconSparkles />} tooltip=\"AI Chat\" onClick={openAI} />\n </TopBar.Section>\n <TopBar.UserMenu\n user={{ name: 'John', email: 'john@example.com' }}\n onNavigate={(p) => router.push(p)}\n onLogout={handleLogout}\n userMenuItems={[\n { label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },\n ]}\n />\n </TopBar.Right>\n</TopBar>",
11280
- "<TopBar>\n <TopBar.Left>\n <SidebarTrigger />\n <TopBar.Title>Dashboard</TopBar.Title>\n </TopBar.Left>\n <TopBar.Center>\n <SearchBarTrigger />\n </TopBar.Center>\n <TopBar.Right>\n <TopBar.Section gap=\"tight\">\n <TopBar.IconButton icon={<IconBell />} tooltip=\"Notifications\" onClick={fn} />\n </TopBar.Section>\n <TopBar.UserMenu user={user} onLogout={logout} />\n </TopBar.Right>\n</TopBar>"
12729
+ "// Hero variant — the primary AI entry point on a dashboard:\n<CommandBar\n variant=\"hero\"\n greeting=\"What can I help with?\"\n placeholder={['Summarize this project…', 'Draft a status update…', 'Find overdue tasks…']}\n hints={['⌘J to open anywhere', 'Ask in plain English']}\n state={aiState}\n onSubmit={(q) => runAgent(q)}\n/>\n\n// Floating variant global ⌘J overlay, palette + AI in one:\n<CommandBar\n variant=\"floating\"\n keybinding=\"mod+j\"\n groups={commandGroups}\n onSearch={setQuery}\n onSubmit={(q) => runAgent(q)}\n/>"
11281
12730
  ],
11282
12731
  "gotchas": [
11283
- "Without `TopBar.Center`, layout is flex (two-zone). With it, layout switches to CSS grid `1fr auto 1fr` for true centering.",
11284
- "`TopBar.IconButton` renders any number of action buttons — no artificial limit. Use responsive hiding (`className=\"hidden md:flex\"`) for mobile.",
11285
- "`TopBar.UserMenu` includes Profile link, color mode toggle, and logout automatically. `userMenuItems` are inserted between Profile and the toggle.",
11286
- "Requires SidebarProvider wrapper for SidebarTrigger to work."
12732
+ "Client component mount inside a client boundary.",
12733
+ "Requires a mounted `MotionProvider`.",
12734
+ "`keybinding` only applies to the `floating` variant; pass `false` to disable the global shortcut.",
12735
+ "Largest component in the AI layer (3 variants share one implementation) — prefer `inline`/`hero` for embedded bars, `floating` for the app-wide launcher."
11287
12736
  ],
11288
12737
  "changes": [
11289
12738
  {
11290
- "version": "0.19.0",
11291
- "summary": "**BREAKING** Rewritten as composition API. Old props-based API removed (`pageTitle`, `onSearchClick`, `onAiChatClick`, `notificationSlot`, `mobileLogo` props)."
12739
+ "version": "0.49.0",
12740
+ "summary": "**Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP)."
12741
+ }
12742
+ ]
12743
+ },
12744
+ "conversation": {
12745
+ "displayName": "AIConversation",
12746
+ "tier": "ai",
12747
+ "import": "@devalok/shilp-sutra/ai/conversation",
12748
+ "serverSafe": false,
12749
+ "description": "A scrollable AI conversation thread: user + assistant turns, streaming processing steps, an agent header, and structured content blocks (rendered via BlockRenderer) with confirm/cancel/undo action support.",
12750
+ "props": {
12751
+ "messages": {
12752
+ "type": {
12753
+ "name": "object",
12754
+ "raw": "ConversationMessage[] (required) — ordered user + assistant turns"
12755
+ },
12756
+ "required": false
11292
12757
  },
11293
- {
11294
- "version": "0.27.2",
11295
- "summary": "**Fixed** UserMenu email truncation — long emails now truncate instead of overflowing the dropdown"
12758
+ "isProcessing": {
12759
+ "type": {
12760
+ "name": "object",
12761
+ "raw": "boolean — shows a live processing indicator below the last message"
12762
+ },
12763
+ "required": false
11296
12764
  },
11297
- {
11298
- "version": "0.7.0",
11299
- "summary": "**Added** `userMenuItems` prop for custom dropdown items"
12765
+ "processingSteps": {
12766
+ "type": {
12767
+ "name": "object",
12768
+ "raw": "ProcessingStep[] — granular steps shown during processing"
12769
+ },
12770
+ "required": false,
12771
+ "description": "status: pending | active | done | error"
12772
+ },
12773
+ "agent": {
12774
+ "type": {
12775
+ "name": "object",
12776
+ "raw": "{ name: string, icon?: IconInput } — agent identity shown as a header on assistant messages"
12777
+ },
12778
+ "required": false
11300
12779
  },
12780
+ "onAction": {
12781
+ "type": {
12782
+ "name": "function",
12783
+ "raw": "(actionId: string, type: \"confirm\" | \"cancel\" | \"undo\") => void — fired by action blocks"
12784
+ },
12785
+ "required": false
12786
+ },
12787
+ "customBlocks": {
12788
+ "type": {
12789
+ "name": "object",
12790
+ "raw": "Record<string, ComponentType<BlockComponentProps>> — extra block-type renderers merged over the built-ins"
12791
+ },
12792
+ "required": false
12793
+ },
12794
+ "maxHeight": {
12795
+ "type": {
12796
+ "name": "union",
12797
+ "raw": "string | number — max height of the container"
12798
+ },
12799
+ "required": false,
12800
+ "description": "enables scrolling"
12801
+ },
12802
+ "autoScroll": {
12803
+ "type": {
12804
+ "name": "object",
12805
+ "raw": "boolean — auto-scroll to bottom on new messages"
12806
+ },
12807
+ "required": false,
12808
+ "description": "default true"
12809
+ },
12810
+ "className": {
12811
+ "type": {
12812
+ "name": "string"
12813
+ },
12814
+ "required": false
12815
+ }
12816
+ },
12817
+ "composition": {
12818
+ "notes": [
12819
+ "**Renders blocks, not raw text** — each assistant turn is a list of typed `Block`s rendered by `BlockRenderer`. See the block-renderer doc for the block system and how to register custom block types.",
12820
+ "**Pairs with `AICommandProvider`** — the provider supplies `customBlocks`, `onAction`, and `agent` via context so you don't thread them through every message. Props on `AIConversation` win over context.",
12821
+ "**Pairs with `CommandBar`** — CommandBar is the input surface (natural-language submission); AIConversation is the output thread. Common layout: CommandBar on top/bottom, AIConversation as the scroll region.",
12822
+ "**Streaming** — set `isProcessing` + feed `processingSteps` to show step-by-step progress (Reading → Drafting → …) while the model works.",
12823
+ "**Actions** — action blocks (e.g. `confirm`) call `onAction(actionId, type)`; wire it to your confirm/cancel/undo handlers."
12824
+ ]
12825
+ },
12826
+ "docPath": "docs/components/ai/conversation.md",
12827
+ "examples": [
12828
+ "<AICommandProvider agent={{ name: 'Devadoot' }} onAction={handleAction}>\n <AIConversation\n messages={messages}\n isProcessing={isThinking}\n processingSteps={[\n { label: 'Reading project', status: 'done' },\n { label: 'Drafting reply', status: 'active' },\n ]}\n agent={{ name: 'Devadoot', icon: <IconSparkles /> }}\n onAction={(id, type) => handleAction(id, type)}\n maxHeight=\"60vh\"\n />\n</AICommandProvider>"
12829
+ ],
12830
+ "gotchas": [
12831
+ "Client component — mount inside a client boundary.",
12832
+ "Requires a mounted `MotionProvider` (respects reduced-motion for the step spinner and block entrances).",
12833
+ "`agent` set here labels assistant messages; `AICommandProvider`'s `agent` is the fallback when not passed per-conversation."
12834
+ ],
12835
+ "changes": [
11301
12836
  {
11302
- "version": "0.1.1",
11303
- "summary": "**Changed** Decoupled from Next.js via LinkProvider"
12837
+ "version": "0.49.0",
12838
+ "summary": "**Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP)."
12839
+ }
12840
+ ]
12841
+ },
12842
+ "devadoot-icon": {
12843
+ "displayName": "DevadootIcon",
12844
+ "tier": "ai",
12845
+ "import": "@devalok/shilp-sutra/ai",
12846
+ "serverSafe": false,
12847
+ "description": "The animated Devalok chakra glyph — the visual identity for the AI command system. Uses fill-first animation (the gradient color *is* the animation, Gemini-style), with a distinct state for idle, processing, responded, and error.",
12848
+ "props": {
12849
+ "state": {
12850
+ "type": {
12851
+ "name": "union",
12852
+ "raw": "\"idle\" | \"processing\" | \"responded\" | \"error\" — animation mode"
12853
+ },
12854
+ "required": false,
12855
+ "description": "default \"idle\""
11304
12856
  },
12857
+ "size": {
12858
+ "type": {
12859
+ "name": "object",
12860
+ "raw": "number — pixel size"
12861
+ },
12862
+ "required": false,
12863
+ "description": "default 20"
12864
+ },
12865
+ "className": {
12866
+ "type": {
12867
+ "name": "string"
12868
+ },
12869
+ "required": false
12870
+ }
12871
+ },
12872
+ "composition": {
12873
+ "notes": [
12874
+ "**State-as-identity** — `idle` breathes pink↔rose slowly; `processing` sweeps a pink→purple→magenta gradient + glow; `responded` flashes bright then settles + a scale pop; `error` turns red with a glow pulse. Wire `state` to your agent's status.",
12875
+ "**Pairs with `CommandBar` / `AIConversation`** — commonly placed in the CommandBar (hero/floating) or as the agent header avatar in the conversation.",
12876
+ "**Exported from the `ai` barrel** — `import { DevadootIcon } from '@devalok/shilp-sutra/ai'` (no dedicated subpath)."
12877
+ ]
12878
+ },
12879
+ "docPath": "docs/components/ai/devadoot-icon.md",
12880
+ "examples": [
12881
+ "// Drive the icon from the agent lifecycle:\n<DevadootIcon state={isThinking ? 'processing' : hasReplied ? 'responded' : 'idle'} size={24} />\n\n// Error state:\n<DevadootIcon state=\"error\" />"
12882
+ ],
12883
+ "gotchas": [
12884
+ "Client component — mount inside a client boundary.",
12885
+ "Requires a mounted `MotionProvider`; renders a static chakra when reduced-motion is set.",
12886
+ "Brand-locked colors (Devalok pink↔purple palette) — it's a brand asset, not a generic spinner. Use `Spinner` for neutral loading."
12887
+ ],
12888
+ "changes": [
11305
12889
  {
11306
- "version": "0.1.0",
11307
- "summary": "**Added** Initial release"
12890
+ "version": "0.49.0",
12891
+ "summary": "**Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP)."
11308
12892
  }
11309
12893
  ]
11310
12894
  }
@@ -11503,6 +13087,10 @@
11503
13087
  "name": "--color-surface-raised-active",
11504
13088
  "value": "Canvas"
11505
13089
  },
13090
+ {
13091
+ "name": "--color-surface-chrome",
13092
+ "value": "Canvas"
13093
+ },
11506
13094
  {
11507
13095
  "name": "--color-surface-inverted",
11508
13096
  "value": "CanvasText"