@devalok/shilp-sutra 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/BREAKING.json +32 -0
  2. package/MIGRATION.md +891 -881
  3. package/dist/_chunks/badge-group.js +50 -63
  4. package/dist/_chunks/badge-group.js.map +1 -1
  5. package/dist/_chunks/chat.js +1 -1
  6. package/dist/_chunks/chat.js.map +1 -1
  7. package/dist/_chunks/field-state.js +8 -0
  8. package/dist/_chunks/field-state.js.map +1 -0
  9. package/dist/_chunks/popover.js +50 -47
  10. package/dist/_chunks/popover.js.map +1 -1
  11. package/dist/_chunks/primitives.js +155 -155
  12. package/dist/_chunks/primitives.js.map +1 -1
  13. package/dist/_chunks/shared.js +4 -4
  14. package/dist/_chunks/tiptap.js +10 -10
  15. package/dist/_chunks/use-calendar.js +1 -1
  16. package/dist/_chunks/use-calendar.js.map +1 -1
  17. package/dist/_chunks/use-controllable-open.js +15 -0
  18. package/dist/_chunks/use-controllable-open.js.map +1 -0
  19. package/dist/composed/command-palette.js +3 -3
  20. package/dist/composed/command-palette.js.map +1 -1
  21. package/dist/composed/confirm-dialog.js +3 -3
  22. package/dist/composed/confirm-dialog.js.map +1 -1
  23. package/dist/composed/date-picker/index.js +3 -3
  24. package/dist/composed/date-picker/index.js.map +1 -1
  25. package/dist/composed/error-boundary.js +1 -1
  26. package/dist/composed/error-boundary.js.map +1 -1
  27. package/dist/composed/index.d.ts +3 -1
  28. package/dist/composed/index.d.ts.map +1 -1
  29. package/dist/composed/index.js +4 -3
  30. package/dist/composed/loading-skeleton.js +15 -15
  31. package/dist/composed/loading-skeleton.js.map +1 -1
  32. package/dist/composed/page-header.d.ts.map +1 -1
  33. package/dist/composed/page-header.js +32 -45
  34. package/dist/composed/page-header.js.map +1 -1
  35. package/dist/composed/page-skeletons.js +19 -19
  36. package/dist/composed/page-skeletons.js.map +1 -1
  37. package/dist/composed/responsive-modal.d.ts +39 -0
  38. package/dist/composed/responsive-modal.d.ts.map +1 -0
  39. package/dist/composed/responsive-modal.js +212 -0
  40. package/dist/composed/responsive-modal.js.map +1 -0
  41. package/dist/composed/rich-chat-input.js +4 -4
  42. package/dist/composed/rich-text-editor.js +1 -1
  43. package/dist/composed/rich-text-editor.js.map +1 -1
  44. package/dist/composed/schedule-view.d.ts +1 -1
  45. package/dist/composed/schedule-view.d.ts.map +1 -1
  46. package/dist/composed/schedule-view.js +48 -54
  47. package/dist/composed/schedule-view.js.map +1 -1
  48. package/dist/composed/status-badge.d.ts +13 -11
  49. package/dist/composed/status-badge.d.ts.map +1 -1
  50. package/dist/composed/status-badge.js +54 -130
  51. package/dist/composed/status-badge.js.map +1 -1
  52. package/dist/shell/bottom-navbar.js +1 -1
  53. package/dist/shell/bottom-navbar.js.map +1 -1
  54. package/dist/shell/top-bar.js +1 -1
  55. package/dist/shell/top-bar.js.map +1 -1
  56. package/dist/tokens/semantic.css +8 -1
  57. package/dist/ui/accordion.js +9 -9
  58. package/dist/ui/alert-dialog.js +26 -26
  59. package/dist/ui/aspect-ratio.js +1 -1
  60. package/dist/ui/autocomplete.js +7 -7
  61. package/dist/ui/avatar.d.ts.map +1 -1
  62. package/dist/ui/avatar.js +87 -82
  63. package/dist/ui/avatar.js.map +1 -1
  64. package/dist/ui/badge.d.ts.map +1 -1
  65. package/dist/ui/breadcrumb.d.ts +0 -1
  66. package/dist/ui/breadcrumb.d.ts.map +1 -1
  67. package/dist/ui/breadcrumb.js +58 -35
  68. package/dist/ui/breadcrumb.js.map +1 -1
  69. package/dist/ui/button.js +3 -3
  70. package/dist/ui/checkbox.d.ts +4 -2
  71. package/dist/ui/checkbox.d.ts.map +1 -1
  72. package/dist/ui/checkbox.js +33 -28
  73. package/dist/ui/checkbox.js.map +1 -1
  74. package/dist/ui/collapsible.js +4 -4
  75. package/dist/ui/combobox.d.ts +3 -0
  76. package/dist/ui/combobox.d.ts.map +1 -1
  77. package/dist/ui/combobox.js +137 -132
  78. package/dist/ui/combobox.js.map +1 -1
  79. package/dist/ui/context-menu.js +46 -46
  80. package/dist/ui/dialog.d.ts.map +1 -1
  81. package/dist/ui/dialog.js +53 -50
  82. package/dist/ui/dialog.js.map +1 -1
  83. package/dist/ui/dot.d.ts +38 -0
  84. package/dist/ui/dot.d.ts.map +1 -0
  85. package/dist/ui/dot.js +92 -0
  86. package/dist/ui/dot.js.map +1 -0
  87. package/dist/ui/dropdown-menu.d.ts.map +1 -1
  88. package/dist/ui/dropdown-menu.js +70 -65
  89. package/dist/ui/dropdown-menu.js.map +1 -1
  90. package/dist/ui/hover-card.js +11 -11
  91. package/dist/ui/index.d.ts +3 -2
  92. package/dist/ui/index.d.ts.map +1 -1
  93. package/dist/ui/index.js +67 -67
  94. package/dist/ui/index.js.map +1 -1
  95. package/dist/ui/input-otp.js +1 -1
  96. package/dist/ui/input-otp.js.map +1 -1
  97. package/dist/ui/input.d.ts +4 -2
  98. package/dist/ui/input.d.ts.map +1 -1
  99. package/dist/ui/input.js +38 -37
  100. package/dist/ui/input.js.map +1 -1
  101. package/dist/ui/label.js +1 -1
  102. package/dist/ui/lib/field-state.d.ts +21 -0
  103. package/dist/ui/lib/field-state.d.ts.map +1 -0
  104. package/dist/ui/lib/use-controllable-open.d.ts +32 -0
  105. package/dist/ui/lib/use-controllable-open.d.ts.map +1 -0
  106. package/dist/ui/link.js +1 -1
  107. package/dist/ui/number-input.d.ts +4 -2
  108. package/dist/ui/number-input.d.ts.map +1 -1
  109. package/dist/ui/number-input.js +51 -50
  110. package/dist/ui/number-input.js.map +1 -1
  111. package/dist/ui/pagination.js +1 -1
  112. package/dist/ui/popover.d.ts.map +1 -1
  113. package/dist/ui/progress.d.ts +66 -42
  114. package/dist/ui/progress.d.ts.map +1 -1
  115. package/dist/ui/progress.js +144 -40
  116. package/dist/ui/progress.js.map +1 -1
  117. package/dist/ui/radio.d.ts +6 -2
  118. package/dist/ui/radio.d.ts.map +1 -1
  119. package/dist/ui/radio.js +44 -33
  120. package/dist/ui/radio.js.map +1 -1
  121. package/dist/ui/select.d.ts +1 -1
  122. package/dist/ui/select.d.ts.map +1 -1
  123. package/dist/ui/select.js +58 -57
  124. package/dist/ui/select.js.map +1 -1
  125. package/dist/ui/separator.js +2 -2
  126. package/dist/ui/separator.js.map +1 -1
  127. package/dist/ui/sheet.d.ts.map +1 -1
  128. package/dist/ui/sheet.js +59 -56
  129. package/dist/ui/sheet.js.map +1 -1
  130. package/dist/ui/sidebar.js +5 -5
  131. package/dist/ui/sidebar.js.map +1 -1
  132. package/dist/ui/slider.js +6 -6
  133. package/dist/ui/slider.js.map +1 -1
  134. package/dist/ui/stat-card.d.ts.map +1 -1
  135. package/dist/ui/stat-card.js +122 -125
  136. package/dist/ui/stat-card.js.map +1 -1
  137. package/dist/ui/surface.js +1 -1
  138. package/dist/ui/switch.d.ts +3 -1
  139. package/dist/ui/switch.d.ts.map +1 -1
  140. package/dist/ui/switch.js +32 -27
  141. package/dist/ui/switch.js.map +1 -1
  142. package/dist/ui/textarea.d.ts +3 -3
  143. package/dist/ui/textarea.d.ts.map +1 -1
  144. package/dist/ui/textarea.js +18 -17
  145. package/dist/ui/textarea.js.map +1 -1
  146. package/dist/ui/toast.js +2 -2
  147. package/dist/ui/toast.js.map +1 -1
  148. package/dist/ui/toggle-group.js +1 -1
  149. package/dist/ui/toggle.js +1 -1
  150. package/dist/ui/tooltip.d.ts.map +1 -1
  151. package/dist/ui/tooltip.js +36 -33
  152. package/dist/ui/tooltip.js.map +1 -1
  153. package/docs/components/ai/ai-command-provider.md +46 -0
  154. package/docs/components/ai/block-renderer.md +59 -0
  155. package/docs/components/ai/command-bar.md +78 -0
  156. package/docs/components/ai/conversation.md +59 -0
  157. package/docs/components/ai/devadoot-icon.md +41 -0
  158. package/docs/components/composed/page-header.md +1 -1
  159. package/docs/components/composed/responsive-modal.md +66 -0
  160. package/docs/components/composed/schedule-view.md +6 -2
  161. package/docs/components/ui/breadcrumb.md +1 -1
  162. package/docs/components/ui/checkbox.md +4 -1
  163. package/docs/components/ui/combobox.md +4 -0
  164. package/docs/components/ui/dot.md +61 -0
  165. package/docs/components/ui/progress.md +54 -16
  166. package/docs/components/ui/radio.md +6 -2
  167. package/docs/components/ui/select.md +9 -5
  168. package/docs/components/ui/switch.md +4 -1
  169. package/docs/components/ui/table.md +2 -1
  170. package/llms.txt +11 -3
  171. package/make-kit/components/form.md +2 -2
  172. package/make-kit/components/icon.md +2 -2
  173. package/make-kit/components/overview.md +2 -2
  174. package/make-kit/components/select.md +1 -1
  175. package/make-kit/components/table.md +1 -1
  176. package/mcp-manifest.json +2656 -1068
  177. package/mcp-manifest.schema.json +18 -0
  178. package/package.json +11 -6
  179. package/skill/SKILL.md +1 -1
  180. package/skill/references/components.md +11 -3
  181. package/dist/ui/status-dot.d.ts +0 -27
  182. package/dist/ui/status-dot.d.ts.map +0 -1
  183. package/dist/ui/status-dot.js +0 -68
  184. package/dist/ui/status-dot.js.map +0 -1
  185. package/docs/components/ui/status-dot.md +0 -35
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","names":[],"sources":["../../src/ui/tooltip.tsx"],"sourcesContent":["'use client'\n\nimport * as TooltipPrimitive from '@primitives/react-tooltip'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { springs, tweens } from './lib/motion'\nimport { cn } from './lib/utils'\n\n// ── Auto-provider: wraps with TooltipPrimitive.Provider if none exists ──\n\nconst TooltipProviderContext = React.createContext(false)\n\nconst TooltipProvider: React.FC<React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>> = ({\n children,\n ...props\n}) => (\n <TooltipProviderContext.Provider value={true}>\n <TooltipPrimitive.Provider {...props}>\n {children}\n </TooltipPrimitive.Provider>\n </TooltipProviderContext.Provider>\n)\n\nfunction AutoProvider({ children }: { children: React.ReactNode }) {\n const hasProvider = React.useContext(TooltipProviderContext)\n if (hasProvider) return <>{children}</>\n return (\n <TooltipProviderContext.Provider value={true}>\n <TooltipPrimitive.Provider delayDuration={300}>\n {children}\n </TooltipPrimitive.Provider>\n </TooltipProviderContext.Provider>\n )\n}\n\n// ── Internal context to thread `open` state to animated children ──\n\ntype TooltipContextValue = { open: boolean }\nconst TooltipContext = React.createContext<TooltipContextValue>({ open: false })\n\nconst Tooltip: React.FC<React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>> = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}) => {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const isControlled = openProp !== undefined\n const open = isControlled ? openProp : internalOpen\n\n const handleOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n if (!isControlled) setInternalOpen(nextOpen)\n onOpenChange?.(nextOpen)\n },\n [isControlled, onOpenChange],\n )\n\n const contextValue = React.useMemo(() => ({ open }), [open])\n\n return (\n <AutoProvider>\n <TooltipContext.Provider value={contextValue}>\n <TooltipPrimitive.Root open={open} onOpenChange={handleOpenChange} {...props} />\n </TooltipContext.Provider>\n </AutoProvider>\n )\n}\nTooltip.displayName = 'Tooltip'\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\n// ── Side-based slide offsets ──\n\nconst sideOffset: Record<string, { x?: number; y?: number }> = {\n top: { y: 4 },\n bottom: { y: -4 },\n left: { x: 4 },\n right: { x: -4 },\n}\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset: sideOffsetProp = 4, side = 'top', children, ...props }, ref) => {\n const { open } = React.useContext(TooltipContext)\n const slideInit = sideOffset[side] ?? {}\n\n return (\n <AnimatePresence>\n {open && (\n <TooltipPrimitive.Portal forceMount>\n <TooltipPrimitive.Content\n ref={ref}\n forceMount\n sideOffset={sideOffsetProp}\n side={side}\n {...props}\n asChild\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95, ...slideInit }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, ...slideInit }}\n transition={{ ...springs.snappy, opacity: tweens.fade }}\n className={cn(\n 'z-tooltip overflow-hidden rounded-overlay-sm bg-surface-inverted px-ds-04 py-ds-02b text-ds-sm text-surface-inverted-fg shadow-floating',\n className,\n )}\n >\n {children}\n </motion.div>\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )}\n </AnimatePresence>\n )\n})\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n\nexport { Tooltip, TooltipContent, TooltipProvider,TooltipTrigger }\n"],"mappings":";;;;;;;;AAWA,IAAM,IAAyB,EAAM,cAAc,GAAM,EAEnD,KAA+F,EACnG,aACA,GAAG,QAEH,kBAAC,EAAuB,UAAxB;CAAiC,OAAO;WACtC,kBAAC,GAAD;EAA2B,GAAI;EAC5B;EACyB,CAAA;CACI,CAAA;AAGpC,SAAS,EAAa,EAAE,eAA2C;AAGjE,QAFoB,EAAM,WAAW,EAAuB,GACpC,kBAAA,GAAA,EAAG,aAAY,CAAA,GAErC,kBAAC,EAAuB,UAAxB;EAAiC,OAAO;YACtC,kBAAC,GAAD;GAA2B,eAAe;GACvC;GACyB,CAAA;EACI,CAAA;;AAOtC,IAAM,IAAiB,EAAM,cAAmC,EAAE,MAAM,IAAO,CAAC,EAE1E,KAAmF,EACvF,MAAM,GACN,gBACA,iBACA,GAAG,QACC;CACJ,IAAM,CAAC,GAAc,KAAmB,EAAM,SAAS,KAAe,GAAM,EACtE,IAAe,MAAa,KAAA,GAC5B,IAAO,IAAe,IAAW,GAEjC,IAAmB,EAAM,aAC5B,MAAsB;AAErB,EADK,KAAc,EAAgB,EAAS,EAC5C,IAAe,EAAS;IAE1B,CAAC,GAAc,EAAa,CAC7B,EAEK,IAAe,EAAM,eAAe,EAAE,SAAM,GAAG,CAAC,EAAK,CAAC;AAE5D,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,EAAe,UAAhB;EAAyB,OAAO;YAC9B,kBAAC,GAAD;GAA6B;GAAM,cAAc;GAAkB,GAAI;GAAS,CAAA;EACxD,CAAA,EACb,CAAA;;AAGnB,EAAQ,cAAc;AAEtB,IAAM,IAAiB,GAIjB,IAAyD;CAC7D,KAAK,EAAE,GAAG,GAAG;CACb,QAAQ,EAAE,GAAG,IAAI;CACjB,MAAM,EAAE,GAAG,GAAG;CACd,OAAO,EAAE,GAAG,IAAI;CACjB,EAEK,IAAiB,EAAM,YAG1B,EAAE,cAAW,YAAY,IAAiB,GAAG,UAAO,OAAO,aAAU,GAAG,KAAS,MAAQ;CAC1F,IAAM,EAAE,YAAS,EAAM,WAAW,EAAe,EAC3C,IAAY,EAAW,MAAS,EAAE;AAExC,QACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,GAAD;EAAyB,YAAA;YACvB,kBAAC,GAAD;GACO;GACL,YAAA;GACA,YAAY;GACN;GACN,GAAI;GACJ,SAAA;aAEA,kBAAC,EAAO,KAAR;IACE,SAAS;KAAE,SAAS;KAAG,OAAO;KAAM,GAAG;KAAW;IAClD,SAAS;KAAE,SAAS;KAAG,OAAO;KAAG,GAAG;KAAG,GAAG;KAAG;IAC7C,MAAM;KAAE,SAAS;KAAG,OAAO;KAAM,GAAG;KAAW;IAC/C,YAAY;KAAE,GAAG,EAAQ;KAAQ,SAAS,EAAO;KAAM;IACvD,WAAW,EACT,2IACA,EACD;IAEA;IACU,CAAA;GACY,CAAA;EACH,CAAA,EAEZ,CAAA;EAEpB;AACF,EAAe,cAAA,EAAuC"}
1
+ {"version":3,"file":"tooltip.js","names":[],"sources":["../../src/ui/tooltip.tsx"],"sourcesContent":["'use client'\n\nimport * as TooltipPrimitive from '@primitives/react-tooltip'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { springs, tweens } from './lib/motion'\nimport { useControllableOpen } from './lib/use-controllable-open'\nimport { cn } from './lib/utils'\n\n// ── Auto-provider: wraps with TooltipPrimitive.Provider if none exists ──\n\nconst TooltipProviderContext = React.createContext(false)\n\nconst TooltipProvider: React.FC<React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>> = ({\n children,\n ...props\n}) => (\n <TooltipProviderContext.Provider value={true}>\n <TooltipPrimitive.Provider {...props}>\n {children}\n </TooltipPrimitive.Provider>\n </TooltipProviderContext.Provider>\n)\n\nfunction AutoProvider({ children }: { children: React.ReactNode }) {\n const hasProvider = React.useContext(TooltipProviderContext)\n if (hasProvider) return <>{children}</>\n return (\n <TooltipProviderContext.Provider value={true}>\n <TooltipPrimitive.Provider delayDuration={300}>\n {children}\n </TooltipPrimitive.Provider>\n </TooltipProviderContext.Provider>\n )\n}\n\n// ── Internal context to thread `open` state to animated children ──\n\ntype TooltipContextValue = { open: boolean }\nconst TooltipContext = React.createContext<TooltipContextValue>({ open: false })\n\nconst Tooltip: React.FC<React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root>> = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}) => {\n const { open, setOpen } = useControllableOpen({ open: openProp, defaultOpen, onOpenChange })\n\n const contextValue = React.useMemo(() => ({ open }), [open])\n\n return (\n <AutoProvider>\n <TooltipContext.Provider value={contextValue}>\n <TooltipPrimitive.Root open={open} onOpenChange={setOpen} {...props} />\n </TooltipContext.Provider>\n </AutoProvider>\n )\n}\nTooltip.displayName = 'Tooltip'\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\n// ── Side-based slide offsets ──\n\nconst sideOffset: Record<string, { x?: number; y?: number }> = {\n top: { y: 4 },\n bottom: { y: -4 },\n left: { x: 4 },\n right: { x: -4 },\n}\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset: sideOffsetProp = 4, side = 'top', children, ...props }, ref) => {\n const { open } = React.useContext(TooltipContext)\n const slideInit = sideOffset[side] ?? {}\n\n return (\n <AnimatePresence>\n {open && (\n <TooltipPrimitive.Portal forceMount>\n <TooltipPrimitive.Content\n ref={ref}\n forceMount\n sideOffset={sideOffsetProp}\n side={side}\n {...props}\n asChild\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95, ...slideInit }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, ...slideInit }}\n transition={{ ...springs.snappy, opacity: tweens.fade }}\n className={cn(\n 'z-tooltip overflow-hidden rounded-overlay-sm bg-surface-inverted px-ds-04 py-ds-02b text-ds-sm text-surface-inverted-fg shadow-floating',\n className,\n )}\n >\n {children}\n </motion.div>\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )}\n </AnimatePresence>\n )\n})\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n\nexport { Tooltip, TooltipContent, TooltipProvider,TooltipTrigger }\n"],"mappings":";;;;;;;;;AAYA,IAAM,IAAyB,EAAM,cAAc,GAAM,EAEnD,KAA+F,EACnG,aACA,GAAG,QAEH,kBAAC,EAAuB,UAAxB;CAAiC,OAAO;WACtC,kBAAC,GAAD;EAA2B,GAAI;EAC5B;EACyB,CAAA;CACI,CAAA;AAGpC,SAAS,EAAa,EAAE,eAA2C;AAGjE,QAFoB,EAAM,WAAW,EAAuB,GACpC,kBAAA,GAAA,EAAG,aAAY,CAAA,GAErC,kBAAC,EAAuB,UAAxB;EAAiC,OAAO;YACtC,kBAAC,GAAD;GAA2B,eAAe;GACvC;GACyB,CAAA;EACI,CAAA;;AAOtC,IAAM,IAAiB,EAAM,cAAmC,EAAE,MAAM,IAAO,CAAC,EAE1E,KAAmF,EACvF,MAAM,GACN,gBACA,iBACA,GAAG,QACC;CACJ,IAAM,EAAE,SAAM,eAAY,EAAoB;EAAE,MAAM;EAAU;EAAa;EAAc,CAAC,EAEtF,IAAe,EAAM,eAAe,EAAE,SAAM,GAAG,CAAC,EAAK,CAAC;AAE5D,QACE,kBAAC,GAAD,EAAA,UACE,kBAAC,EAAe,UAAhB;EAAyB,OAAO;YAC9B,kBAAC,GAAD;GAA6B;GAAM,cAAc;GAAS,GAAI;GAAS,CAAA;EAC/C,CAAA,EACb,CAAA;;AAGnB,EAAQ,cAAc;AAEtB,IAAM,IAAiB,GAIjB,IAAyD;CAC7D,KAAK,EAAE,GAAG,GAAG;CACb,QAAQ,EAAE,GAAG,IAAI;CACjB,MAAM,EAAE,GAAG,GAAG;CACd,OAAO,EAAE,GAAG,IAAI;CACjB,EAEK,IAAiB,EAAM,YAG1B,EAAE,cAAW,YAAY,IAAiB,GAAG,UAAO,OAAO,aAAU,GAAG,KAAS,MAAQ;CAC1F,IAAM,EAAE,YAAS,EAAM,WAAW,EAAe,EAC3C,IAAY,EAAW,MAAS,EAAE;AAExC,QACE,kBAAC,GAAD,EAAA,UACG,KACC,kBAAC,GAAD;EAAyB,YAAA;YACvB,kBAAC,GAAD;GACO;GACL,YAAA;GACA,YAAY;GACN;GACN,GAAI;GACJ,SAAA;aAEA,kBAAC,EAAO,KAAR;IACE,SAAS;KAAE,SAAS;KAAG,OAAO;KAAM,GAAG;KAAW;IAClD,SAAS;KAAE,SAAS;KAAG,OAAO;KAAG,GAAG;KAAG,GAAG;KAAG;IAC7C,MAAM;KAAE,SAAS;KAAG,OAAO;KAAM,GAAG;KAAW;IAC/C,YAAY;KAAE,GAAG,EAAQ;KAAQ,SAAS,EAAO;KAAM;IACvD,WAAW,EACT,2IACA,EACD;IAEA;IACU,CAAA;GACY,CAAA;EACH,CAAA,EAEZ,CAAA;EAEpB;AACF,EAAe,cAAA,EAAuC"}
@@ -0,0 +1,46 @@
1
+ # AICommandProvider
2
+
3
+ - Import: @devalok/shilp-sutra/ai/ai-command-provider
4
+ - Server-safe: No
5
+ - Category: ai
6
+
7
+ Context provider for the AI command system. Supplies custom block renderers, the
8
+ action handler, and the agent identity to `AIConversation` / `BlockRenderer` below
9
+ it, so you configure them once instead of threading props through every message.
10
+ Ships a `useAICommand()` hook to read the context.
11
+
12
+ ## Props
13
+ children: ReactNode (required)
14
+ customBlocks: Record<string, ComponentType<BlockComponentProps>> — custom block-type renderers available to all descendants
15
+ onAction: (actionId: string, type: "confirm" | "cancel" | "undo") => void — default action handler for descendant blocks
16
+ agent: { name: string, icon?: IconInput } — default agent identity for assistant messages
17
+
18
+ ## Example
19
+ ```jsx
20
+ <AICommandProvider
21
+ agent={{ name: 'Devadoot', icon: <IconSparkles /> }}
22
+ customBlocks={{ chart: ChartBlock }}
23
+ onAction={(id, type) => handleAction(id, type)}
24
+ >
25
+ <AIConversation messages={messages} />
26
+ </AICommandProvider>
27
+
28
+ // Read the context in a descendant:
29
+ function MyBlock() {
30
+ const ctx = useAICommand() // { customBlocks, onAction, agent } | null
31
+ // ...
32
+ }
33
+ ```
34
+
35
+ ## Composability
36
+ - **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).
37
+ - **`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.
38
+ - **Optional** — `AIConversation`/`BlockRenderer` work without a provider if you pass their props directly; the provider is a convenience for app-wide config.
39
+
40
+ ## Gotchas
41
+ - Client component — mount inside a client boundary.
42
+ - `useAICommand()` returns `null` (not a throw) when there's no provider — guard for it in custom blocks.
43
+
44
+ ## Changes
45
+ ### v0.49.0
46
+ - **Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP).
@@ -0,0 +1,59 @@
1
+ # BlockRenderer
2
+
3
+ - Import: @devalok/shilp-sutra/ai/block-renderer
4
+ - Server-safe: No
5
+ - Category: ai
6
+
7
+ Renders an ordered list of typed AI "blocks" — the structured chunks an assistant/
8
+ server emits instead of plain text. A registry maps each block's `type` to a React
9
+ component; consumers can register their own types. This doc also covers the block
10
+ system and how to author a custom block.
11
+
12
+ ## Props
13
+ blocks: Block[] (required) — ordered blocks to render
14
+ onAction: (actionId: string, type: "confirm" | "cancel" | "undo") => void — fired by interactive blocks (e.g. confirm)
15
+ customBlocks: Record<string, ComponentType<BlockComponentProps>> — extra type→component renderers, merged OVER the built-ins (prop wins over context)
16
+ staggerDelay: number — ms between each block's entrance animation (default 50)
17
+ className: string
18
+
19
+ Block: { id?: string, type: string, data: Record<string, unknown>, confidence?: "high" | "medium" | "low" } (see ai/types)
20
+ BlockComponentProps<T>: { data: T, blockId?: string, confidence?: "high" | "medium" | "low", onAction?: (actionId, type) => void }
21
+
22
+ ## Defaults
23
+ staggerDelay defaults to 50
24
+
25
+ ## Example
26
+ ```jsx
27
+ // Render server-emitted blocks:
28
+ <BlockRenderer
29
+ blocks={message.blocks}
30
+ onAction={(id, type) => handleAction(id, type)}
31
+ />
32
+
33
+ // Register a custom block type:
34
+ function ChartBlock({ data }) {
35
+ return <MyChart series={data.series} />
36
+ }
37
+ <BlockRenderer
38
+ blocks={message.blocks}
39
+ customBlocks={{ chart: ChartBlock }}
40
+ />
41
+ ```
42
+
43
+ ## Composability
44
+ - **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).
45
+ - **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`).
46
+ - **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.
47
+ - **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.
48
+ - **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`.
49
+ - **Provider merge** — `customBlocks` from `AICommandProvider` (context) are merged with the `customBlocks` prop; the prop wins on key collision. Same for `onAction`.
50
+
51
+ ## Gotchas
52
+ - Client component — mount inside a client boundary.
53
+ - Requires a mounted `MotionProvider` (block entrances respect reduced-motion).
54
+ - Rendering `text`/`error` blocks requires the `react-markdown` + `remark-gfm` peer dependencies — install them if your blocks include Markdown.
55
+ - 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).
56
+
57
+ ## Changes
58
+ ### v0.49.0
59
+ - **Added** Component + block-system documentation (the AI layer is now covered by the docs gate + hosted MCP).
@@ -0,0 +1,78 @@
1
+ # CommandBar
2
+
3
+ - Import: @devalok/shilp-sutra/ai/command-bar
4
+ - Server-safe: No
5
+ - Category: ai
6
+
7
+ A unified AI command input with three layout variants. Supports natural-language
8
+ submission (`onSubmit`) and, optionally, command-palette filtering (`groups`) in the
9
+ same bar. Shows an animated brand-gradient border while processing.
10
+
11
+ ## Props
12
+ onSubmit: (query: string) => void — called on Enter (natural-language submission)
13
+ state: "idle" | "typing" | "processing" | "responded" — drives visual feedback (gradient border, placeholder)
14
+ groups: CommandGroup[] — when provided, enables command-palette filtering alongside AI submission
15
+ onSearch: (query: string) => void — fired as the query changes (palette mode)
16
+ emptyMessage: string — text when a palette search yields nothing
17
+ emptyState: ReactNode — replaces the default empty UI
18
+ variant: "hero" | "inline" | "floating" — layout (default "hero")
19
+ placeholder: string | string[] — static text, or an array that rotates on an interval
20
+ placeholderInterval: number — rotation interval in ms when placeholder is an array (default 4000)
21
+ greeting: string — text above the input (hero variant)
22
+ hints: string[] — hint strings below the input (hero variant)
23
+ agentName: string
24
+ agentIcon: ReactNode
25
+ open: boolean — controlled open state (floating variant)
26
+ defaultOpen: boolean — uncontrolled initial open (floating variant)
27
+ onOpenChange: (open: boolean) => void — floating variant
28
+ keybinding: string | string[] | false — global toggle for the floating bar (default "mod+j")
29
+ disabled: boolean
30
+ maxHeight: string | number — cap on the results/scroll region (default "320px")
31
+ children: ReactNode
32
+
33
+ CommandGroup / CommandItem: shared with composed/command-palette (see that doc)
34
+
35
+ ## Defaults
36
+ variant defaults to "hero"
37
+ placeholderInterval defaults to 4000
38
+ keybinding defaults to "mod+j"
39
+ maxHeight defaults to "320px"
40
+
41
+ ## Example
42
+ ```jsx
43
+ // Hero variant — the primary AI entry point on a dashboard:
44
+ <CommandBar
45
+ variant="hero"
46
+ greeting="What can I help with?"
47
+ placeholder={['Summarize this project…', 'Draft a status update…', 'Find overdue tasks…']}
48
+ hints={['⌘J to open anywhere', 'Ask in plain English']}
49
+ state={aiState}
50
+ onSubmit={(q) => runAgent(q)}
51
+ />
52
+
53
+ // Floating variant — global ⌘J overlay, palette + AI in one:
54
+ <CommandBar
55
+ variant="floating"
56
+ keybinding="mod+j"
57
+ groups={commandGroups}
58
+ onSearch={setQuery}
59
+ onSubmit={(q) => runAgent(q)}
60
+ />
61
+ ```
62
+
63
+ ## Composability
64
+ - **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.
65
+ - **`floating` reuses the Dialog primitive** (`DialogContentRaw`) with a global keybinding — same overlay pattern as CommandPalette, so focus-trap/Escape/scroll-lock come for free.
66
+ - **State-driven feedback** — set `state="processing"` to show the animated brand-gradient border; `"responded"` to settle it. Wire `state` to your agent's lifecycle.
67
+ - **Placeholder rotation** — pass an array to `placeholder` for the rotating-prompt effect (paused while typing; respects reduced-motion).
68
+ - **Pairs with `AIConversation`** — CommandBar is the input; AIConversation renders the response thread.
69
+
70
+ ## Gotchas
71
+ - Client component — mount inside a client boundary.
72
+ - Requires a mounted `MotionProvider`.
73
+ - `keybinding` only applies to the `floating` variant; pass `false` to disable the global shortcut.
74
+ - Largest component in the AI layer (3 variants share one implementation) — prefer `inline`/`hero` for embedded bars, `floating` for the app-wide launcher.
75
+
76
+ ## Changes
77
+ ### v0.49.0
78
+ - **Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP).
@@ -0,0 +1,59 @@
1
+ # AIConversation
2
+
3
+ - Import: @devalok/shilp-sutra/ai/conversation
4
+ - Server-safe: No
5
+ - Category: ai
6
+
7
+ A scrollable AI conversation thread: user + assistant turns, streaming processing
8
+ steps, an agent header, and structured content blocks (rendered via BlockRenderer)
9
+ with confirm/cancel/undo action support.
10
+
11
+ ## Props
12
+ messages: ConversationMessage[] (required) — ordered user + assistant turns
13
+ isProcessing: boolean — shows a live processing indicator below the last message
14
+ processingSteps: ProcessingStep[] — granular steps shown during processing (status: pending | active | done | error)
15
+ agent: { name: string, icon?: IconInput } — agent identity shown as a header on assistant messages
16
+ onAction: (actionId: string, type: "confirm" | "cancel" | "undo") => void — fired by action blocks
17
+ customBlocks: Record<string, ComponentType<BlockComponentProps>> — extra block-type renderers merged over the built-ins
18
+ maxHeight: string | number — max height of the container (enables scrolling)
19
+ autoScroll: boolean — auto-scroll to bottom on new messages (default true)
20
+ className: string
21
+
22
+ ConversationMessage: { id: string, role: "user" | "assistant", blocks: Block[], ... } (see ai/types)
23
+ ProcessingStep: { label: string, status: "pending" | "active" | "done" | "error" }
24
+
25
+ ## Defaults
26
+ autoScroll defaults to true
27
+
28
+ ## Example
29
+ ```jsx
30
+ <AICommandProvider agent={{ name: 'Devadoot' }} onAction={handleAction}>
31
+ <AIConversation
32
+ messages={messages}
33
+ isProcessing={isThinking}
34
+ processingSteps={[
35
+ { label: 'Reading project', status: 'done' },
36
+ { label: 'Drafting reply', status: 'active' },
37
+ ]}
38
+ agent={{ name: 'Devadoot', icon: <IconSparkles /> }}
39
+ onAction={(id, type) => handleAction(id, type)}
40
+ maxHeight="60vh"
41
+ />
42
+ </AICommandProvider>
43
+ ```
44
+
45
+ ## Composability
46
+ - **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.
47
+ - **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.
48
+ - **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.
49
+ - **Streaming** — set `isProcessing` + feed `processingSteps` to show step-by-step progress (Reading → Drafting → …) while the model works.
50
+ - **Actions** — action blocks (e.g. `confirm`) call `onAction(actionId, type)`; wire it to your confirm/cancel/undo handlers.
51
+
52
+ ## Gotchas
53
+ - Client component — mount inside a client boundary.
54
+ - Requires a mounted `MotionProvider` (respects reduced-motion for the step spinner and block entrances).
55
+ - `agent` set here labels assistant messages; `AICommandProvider`'s `agent` is the fallback when not passed per-conversation.
56
+
57
+ ## Changes
58
+ ### v0.49.0
59
+ - **Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP).
@@ -0,0 +1,41 @@
1
+ # DevadootIcon
2
+
3
+ - Import: @devalok/shilp-sutra/ai
4
+ - Server-safe: No
5
+ - Category: ai
6
+
7
+ The animated Devalok chakra glyph — the visual identity for the AI command system.
8
+ Uses fill-first animation (the gradient color *is* the animation, Gemini-style),
9
+ with a distinct state for idle, processing, responded, and error.
10
+
11
+ ## Props
12
+ state: "idle" | "processing" | "responded" | "error" — animation mode (default "idle")
13
+ size: number — pixel size (default 20)
14
+ className: string
15
+
16
+ ## Defaults
17
+ state defaults to "idle"
18
+ size defaults to 20
19
+
20
+ ## Example
21
+ ```jsx
22
+ // Drive the icon from the agent lifecycle:
23
+ <DevadootIcon state={isThinking ? 'processing' : hasReplied ? 'responded' : 'idle'} size={24} />
24
+
25
+ // Error state:
26
+ <DevadootIcon state="error" />
27
+ ```
28
+
29
+ ## Composability
30
+ - **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.
31
+ - **Pairs with `CommandBar` / `AIConversation`** — commonly placed in the CommandBar (hero/floating) or as the agent header avatar in the conversation.
32
+ - **Exported from the `ai` barrel** — `import { DevadootIcon } from '@devalok/shilp-sutra/ai'` (no dedicated subpath).
33
+
34
+ ## Gotchas
35
+ - Client component — mount inside a client boundary.
36
+ - Requires a mounted `MotionProvider`; renders a static chakra when reduced-motion is set.
37
+ - Brand-locked colors (Devalok pink↔purple palette) — it's a brand asset, not a generic spinner. Use `Spinner` for neutral loading.
38
+
39
+ ## Changes
40
+ ### v0.49.0
41
+ - **Added** Component documentation (the AI layer is now covered by the docs gate + hosted MCP).
@@ -32,7 +32,7 @@
32
32
  - **Server-safe page-top header** with title + subtitle + breadcrumbs + actions slot. Renders Breadcrumb internally from the `breadcrumbs` array.
33
33
  - **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.
34
34
  - **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.
35
- - **actions slot:** Typically one to three buttons (Save, Cancel, More). For larger action groups, use ButtonGroup or a toolbar.
35
+ - **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.
36
36
  - **Not for tabs / sub-navigation** — pair with Tabs rendered below PageHeader for that.
37
37
 
38
38
  ## Gotchas
@@ -0,0 +1,66 @@
1
+ # ResponsiveModal
2
+
3
+ - Import: @devalok/shilp-sutra/composed/responsive-modal
4
+ - Server-safe: No
5
+ - Category: composed
6
+
7
+ ## Props
8
+
9
+ ### ResponsiveModal (root)
10
+ open: boolean (controlled open state)
11
+ defaultOpen: boolean (uncontrolled initial state)
12
+ onOpenChange: (open: boolean) => void
13
+ dismissable: boolean (default: true — when false, Escape / outside-click / drag cannot close; only an explicit Close or onOpenChange does)
14
+
15
+ ### ResponsiveModalContent
16
+ snapPoints: number[] (mobile only; ascending viewport-height fractions like [0.4, 0.9] the sheet rests at. Omit for a content-height sheet. Ignored on desktop)
17
+ defaultSnapPoint: number (mobile only; index into snapPoints the sheet opens at. Defaults to the last/tallest)
18
+
19
+ ## Defaults
20
+ dismissable=true
21
+
22
+ ## Example
23
+ ```jsx
24
+ <ResponsiveModal>
25
+ <ResponsiveModalTrigger asChild><Button>Edit profile</Button></ResponsiveModalTrigger>
26
+ <ResponsiveModalContent snapPoints={[0.5, 0.9]}>
27
+ <ResponsiveModalBackground className="bg-linear-to-br from-accent-3 to-accent-6 opacity-40" />
28
+ <ResponsiveModalHeader>
29
+ <ResponsiveModalTitle>Edit profile</ResponsiveModalTitle>
30
+ <ResponsiveModalDescription>Changes save when you apply.</ResponsiveModalDescription>
31
+ </ResponsiveModalHeader>
32
+ <ResponsiveModalBody>{/* form fields — scrolls internally */}</ResponsiveModalBody>
33
+ <ResponsiveModalFooter>
34
+ <ResponsiveModalClose asChild><Button variant="soft">Cancel</Button></ResponsiveModalClose>
35
+ <Button>Apply</Button>
36
+ </ResponsiveModalFooter>
37
+ </ResponsiveModalContent>
38
+ </ResponsiveModal>
39
+ ```
40
+
41
+ ## Composability
42
+ - **Part:** ResponsiveModal (required) — root; owns open/close state and the desktop/mobile switch
43
+ - **Part:** ResponsiveModalTrigger — opens the modal; use `asChild` to wrap your own button
44
+ - **Part:** ResponsiveModalContent — the switching panel: centered Dialog at md+, bottom sheet below
45
+ - **Part:** ResponsiveModalBackground (slot: behind) — optional full-bleed layer painted at `-z-10`, clipped to the panel radius
46
+ - **Part:** ResponsiveModalHeader (slot: top) — pinned; stays put while the body scrolls
47
+ - **Part:** ResponsiveModalTitle (required) — labels the dialog for accessibility
48
+ - **Part:** ResponsiveModalDescription — optional subtitle
49
+ - **Part:** ResponsiveModalBody — internal scroll region (min-h-0 flex-1 overflow-y-auto), capped 85dvh desktop / 90dvh mobile
50
+ - **Part:** ResponsiveModalFooter (slot: bottom) — pinned action row; stacks on mobile, right-aligned inline on desktop
51
+ - **Part:** ResponsiveModalClose — manual close (Content already renders a built-in close button when dismissable)
52
+ - **Composes:** dialog (alternative-to) — use Dialog directly when you always want a centered modal
53
+ - **Composes:** sheet (alternative-to) — use Sheet directly when you always want an edge panel
54
+ - **Context:** ResponsiveModal — provides open / isMobile / dismissable / onClose to its parts via context
55
+
56
+ ## Gotchas
57
+ - 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.
58
+ - Put a `ResponsiveModalTitle` inside every modal — it sets the ARIA label. Omitting it triggers an accessibility warning.
59
+ - 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.
60
+ - `snapPoints` and `defaultSnapPoint` are mobile-only — they are ignored at md+ (always a centered Dialog).
61
+ - Height caps live on the panel (85dvh desktop / 90dvh mobile); do not add your own `max-h` to `ResponsiveModalBody` — it already scrolls.
62
+ - 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.
63
+
64
+ ## Changes
65
+ ### v0.49.0
66
+ - 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.
@@ -14,7 +14,7 @@
14
14
  endHour: number (default: 18, exclusive)
15
15
  slotDuration: number (minutes, default: 30)
16
16
 
17
- Event colors: "primary" | "success" | "warning" | "error" | "info" | "neutral"
17
+ Event colors: "accent" | "success" | "warning" | "error" | "info" | "neutral"
18
18
 
19
19
  ## Defaults
20
20
  startHour=8, endHour=18, slotDuration=30
@@ -33,7 +33,7 @@ Event colors: "primary" | "success" | "warning" | "error" | "info" | "neutral"
33
33
  - **Day / Week calendar view** for time-block display (meetings, shifts, availability). Not a full calendar app — no month view, no drag-to-create.
34
34
  - **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.
35
35
  - **Event click + slot click** — `onEventClick` for existing events; `onSlotClick` for creating new events (fires with start/end of the empty slot).
36
- - **Color vocabulary matches the DS** — `primary/success/warning/error/info/neutral`. Map your event types to these at the data layer.
36
+ - **Color vocabulary matches the DS** — `accent/success/warning/error/info/neutral`. Map your event types to these at the data layer.
37
37
  - **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`.
38
38
  - **Pairs with date-picker/composed** — use DatePicker or DateRangePicker to choose which date to show; pass that as ScheduleView's `date`.
39
39
 
@@ -43,5 +43,9 @@ Event colors: "primary" | "success" | "warning" | "error" | "info" | "neutral"
43
43
  - Events that span outside `startHour`/`endHour` may be clipped
44
44
 
45
45
  ## Changes
46
+ ### v0.49.0
47
+ - **BREAKING** `ScheduleEvent.color` value `"primary"` renamed `"accent"` (DS colour vocabulary). It was the default, so untyped events are unaffected.
48
+ - **Added** keyboard focus rings on slot cells + event blocks; current-time indicator uses the shared `<Dot>`.
49
+
46
50
  ### v0.1.0
47
51
  - **Added** Initial release
@@ -1,7 +1,7 @@
1
1
  # Breadcrumb
2
2
 
3
3
  - Import: @devalok/shilp-sutra/ui/breadcrumb
4
- - Server-safe: No
4
+ - Server-safe: Yes
5
5
  - Category: ui
6
6
 
7
7
  ## Compound Components
@@ -8,7 +8,7 @@
8
8
  checked: boolean | "indeterminate"
9
9
  onCheckedChange: (checked: boolean | "indeterminate") => void
10
10
  size: "sm" | "md" | "lg"
11
- error: boolean (shows red border)
11
+ state: "default" | "error" | "warning" | "success" (validation border/bg tint; error sets aria-invalid. Inherited from FormField when omitted)
12
12
  indeterminate: boolean (overrides checked, shows dash icon)
13
13
  disabled: boolean
14
14
 
@@ -37,6 +37,9 @@
37
37
  - WCAG 2.5.8 minimum target size met at md (24px); sm (20px) may fail if not paired with enough label hit area
38
38
 
39
39
  ## Changes
40
+ ### v0.49.0
41
+ - **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`.
42
+
40
43
  ### v0.22.0
41
44
  - **Changed** Check indicator animation from scale-bounce to path-draw (stroke draws progressively). Indeterminate dash also draws in.
42
45
  - **Fixed** Uncontrolled checkbox never showed checkmark — `checked` from props was `undefined`, so `isActive` was always `false`. Now tracks internal state.
@@ -7,6 +7,7 @@
7
7
  ## Props
8
8
  options: ComboboxOption[] (REQUIRED) — { value: string, label: string, description?: string, icon?: ReactNode, disabled?: boolean }
9
9
  size: "xs" | "sm" | "md" | "lg" (trigger height)
10
+ state: "default" | "error" | "warning" | "success" (validation border tint; error sets aria-invalid. Inherited from FormField when omitted)
10
11
  DISCRIMINATED UNION — type depends on `multiple` flag:
11
12
  Single (default): multiple?: false, value?: string, onValueChange: (value: string) => void
12
13
  Multiple: multiple: true, value?: string[], onValueChange: (value: string[]) => void
@@ -50,6 +51,9 @@
50
51
  - 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
51
52
 
52
53
  ## Changes
54
+ ### v0.49.0
55
+ - **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.)
56
+
53
57
  ### v0.18.0
54
58
  - **Added** `accessibleLabel` prop — custom aria-label for trigger, falls back to placeholder
55
59
 
@@ -0,0 +1,61 @@
1
+ # Dot
2
+
3
+ - Import: @devalok/shilp-sutra/ui/dot
4
+ - Server-safe: No
5
+ - Category: ui
6
+
7
+ A small semantic status/indicator dot — the low-level primitive behind status
8
+ pills, presence indicators, legend swatches, and `StatusDot`. Intent-coloured,
9
+ sized, optionally pulsing, filled or ring.
10
+
11
+ ## Props
12
+ color: "accent" | "success" | "warning" | "error" | "info" | "neutral" | "current" (intent colour; `current` inherits text colour)
13
+ size: "xs" | "sm" | "md" | "lg"
14
+ variant: "filled" | "ring" | "off" (`off` = faint fill + light border, i.e. inactive)
15
+ withBorder: boolean (contrast ring so the dot stays visible on busy/coloured backgrounds)
16
+ pulse: boolean (animate a pulsing ripple; ignored for `off`)
17
+ pulseSpeed: "slow" | "normal" | "fast" (pulse tempo)
18
+ label: ReactNode (inline text; makes the dot an announced status)
19
+ labelPosition: "start" | "end" (which side the label sits on)
20
+ labelClassName: string
21
+
22
+ ## Defaults
23
+ color: "neutral"
24
+ size: "md"
25
+ variant: "filled"
26
+ withBorder: false
27
+ pulse: false
28
+ pulseSpeed: "normal"
29
+ labelPosition: "end"
30
+
31
+ ## Example
32
+ ```jsx
33
+ <Dot color="success" /> {/* bare, decorative */}
34
+ <Dot color="error" pulse pulseSpeed="fast" label="Recording" /> {/* pulsing + announced */}
35
+ <Dot color="neutral" variant="off" label="Offline" /> {/* inactive: faint fill + light border */}
36
+ <Dot color="success" withBorder /> {/* contrast ring for busy backgrounds */}
37
+ <Dot color="accent" label="3 online" labelPosition="start" /> {/* label before the dot */}
38
+ <Dot color="neutral" variant="ring" size="lg" /> {/* hollow ring */}
39
+
40
+ // As leading content in a pill:
41
+ <Badge variant="soft" color="warning" startIcon={<Dot color="warning" size="sm" />}>
42
+ Pending
43
+ </Badge>
44
+ ```
45
+
46
+ ## Composability
47
+ - **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.
48
+ - **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.
49
+ - **`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.
50
+ - **Powers the higher-level pieces.** `StatusBadge` composes `<Badge>` + `<Dot>`; use `Dot` directly anywhere you need a coloured indicator without a pill.
51
+ - **Three treatments:** `filled` (active), `ring` (hollow outline), `off` (faint same-tone fill + light border — present but inactive/disabled).
52
+ - **`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.
53
+ - **`pulseSpeed`** (slow/normal/fast) tunes the pulse tempo — fast for urgent (recording), slow for ambient (syncing).
54
+
55
+ ## Gotchas
56
+ - 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.
57
+ - `pulse` respects `prefers-reduced-motion` (the ripple is disabled).
58
+
59
+ ## Changes
60
+ ### v0.49.0
61
+ - **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`.
@@ -4,38 +4,76 @@
4
4
  - Server-safe: No
5
5
  - Category: ui
6
6
 
7
+ A linear progress bar. Use the smart all-in-one `<Progress value={70} />` for the
8
+ common cases, or the compound parts (`Progress.Root` / `Track` / `Indicator` /
9
+ `Segment` / `Label` / `Value`) for full layout control and multi-segment bars.
10
+
7
11
  ## Props
8
- value: number (0-100) — omit for indeterminate
12
+ value: number | null (0–max) — omit or null for an indeterminate bar
13
+ max: number (scale maximum, default 100)
9
14
  size: "sm" | "md" | "lg" (track height)
10
- color: "default" | "success" | "warning" | "error" (indicator color)
11
- autoColor: boolean (auto-shifts color by value: 0-59=default, 60-84=warning, 85-100=success, >100=error)
12
- showLabel: boolean (shows percentage text)
13
- indicatorClassName: string
15
+ color: "accent" | "success" | "warning" | "error" (indicator color)
16
+ autoColor: boolean (auto-shift color by value: 0-59=accent, 60-84=warning, 85-100=success, >100=error)
17
+ label: ReactNode (descriptive label rendered before the bar; names the bar for a11y)
18
+ showValue: boolean (shows the "{n}%" readout after the bar)
19
+ segments: { value: number; color?: "accent" | "success" | "warning" | "error" }[] (multi-segment bar; overrides the single indicator)
20
+ trackClassName: string (class for the Track element)
21
+ indicatorClassName: string (class for the single Indicator; ignored when segments set)
22
+
23
+ ## Compound Components
24
+ Progress (smart all-in-one — value/size/color/label/showValue/autoColor/segments)
25
+ Progress.Root (layout container + context; owns value/max/size)
26
+ Progress.Label (descriptive label; give it id + point Track's aria-labelledby at it)
27
+ Progress.Track (the aria progressbar + track visual; holds Indicator or Segments)
28
+ Progress.Indicator (single fill; color, or auto-color by value)
29
+ Progress.Segment (one slice of a multi-segment bar — value + color)
30
+ Progress.Value (the "{n}%" readout; custom via children or a `format` fn)
14
31
 
15
32
  ## Defaults
16
33
  size: "md"
17
- color: "default"
34
+ color: "accent"
35
+ max: 100
18
36
 
19
37
  ## Example
20
38
  ```jsx
21
- <Progress value={75} color="success" showLabel />
22
- <Progress size="sm" /> {/* indeterminate */}
39
+ // Simple:
40
+ <Progress value={75} color="success" showValue />
41
+ <Progress size="sm" /> {/* indeterminate */}
42
+ <Progress value={80} autoColor showValue /> {/* color follows value */}
43
+
44
+ // Multi-segment (Mantine-style):
45
+ <Progress segments={[{ value: 40, color: 'success' }, { value: 30, color: 'warning' }]} />
46
+
47
+ // Compound — full control:
48
+ <Progress.Root value={62} size="lg">
49
+ <Progress.Label id="storage-lbl">Storage</Progress.Label>
50
+ <Progress.Track aria-labelledby="storage-lbl">
51
+ <Progress.Indicator color="warning" />
52
+ </Progress.Track>
53
+ <Progress.Value format={(pct) => `${pct}% of 50 GB`} />
54
+ </Progress.Root>
23
55
  ```
24
56
 
25
57
  ## Composability
26
- - **Radix Progress** underneath `value` (determinate) or absent (indeterminate). Standard ARIA: role=progressbar, aria-valuenow/min/max.
27
- - **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.
28
- - **Indeterminate:** Omit `value` to get a continuous animated indeterminate bar. Use for unknown-duration loads.
29
- - **Progress vs ProgressRing:** Progress is a linear bar (horizontal). ProgressRing is circular. ProgressRing offers multi-ring stacked variants; Progress doesn't.
30
- - **Inside Card/StatCard:** StatCard has a `progress` prop that renders a thin inline version use that inside StatCards instead of a separate Progress.
58
+ - **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.
59
+ - **`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.
60
+ - **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.
61
+ - **Segments** render side-by-side, each `value` as a % of `max`; the Track's aria value still reflects `Root`'s `value`.
62
+ - **Indeterminate:** omit `value` (or pass `null`) for the continuous sweep. Motion-reduced users get a static bar.
63
+ - **Progress vs ProgressRing:** Progress is linear; `ProgressRing` is circular (with multi-ring stacked variants).
31
64
 
32
65
  ## Gotchas
33
- - Omit value (or pass undefined) for indeterminate animation
34
- - `autoColor` overrides `color` when `value` is set — do not pass both unless you want autoColor to win
66
+ - Omit `value` (or pass `null`) for indeterminate.
67
+ - Pass an explicit `color` to override `autoColor`.
68
+ - 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).
69
+ - `Progress.Indicator` / `Segment` / `Value` throw if rendered outside `Progress.Root`.
35
70
 
36
71
  ## Changes
72
+ ### v0.49.0
73
+ - **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).
74
+
37
75
  ### v0.29.0
38
- - **Added** `autoColor` prop — automatically shifts indicator color based on value thresholds (0-59 default, 60-84 warning, 85-100 success, >100 error)
76
+ - **Added** `autoColor` prop — automatically shifts indicator color based on value thresholds
39
77
 
40
78
  ### v0.1.0
41
79
  - **Added** Initial release with `size`, `color`, `indeterminate` variants and optional label slot