@devalok/shilp-sutra 0.28.0 → 0.30.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.
- package/dist/_chunks/badge-group.js +299 -0
- package/dist/_chunks/framer.js +1915 -1980
- package/dist/_chunks/keybinding.js +4 -5
- package/dist/_chunks/primitives.js +3198 -3272
- package/dist/_chunks/sonner.js +29 -31
- package/dist/_chunks/stat-row.js +110 -131
- package/dist/_chunks/tiptap.js +42 -78
- package/dist/_chunks/tree-view.js +138 -149
- package/dist/_chunks/typing-indicator.js +565 -0
- package/dist/_chunks/use-calendar.js +416 -439
- package/dist/_chunks/vendor-client.js +5 -5
- package/dist/_chunks/vendor-utils.js +5 -5
- package/dist/ai/block-renderer.js +22 -22
- package/dist/ai/blocks/loading.d.ts.map +1 -1
- package/dist/ai/command-bar.d.ts.map +1 -1
- package/dist/ai/command-bar.js +241 -263
- package/dist/ai/conversation.d.ts.map +1 -1
- package/dist/ai/conversation.js +87 -107
- package/dist/composed/activity-feed.d.ts +2 -0
- package/dist/composed/activity-feed.d.ts.map +1 -1
- package/dist/composed/activity-feed.js +118 -90
- package/dist/composed/avatar-group.d.ts +1 -0
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +125 -86
- package/dist/composed/bulk-action-bar.d.ts.map +1 -1
- package/dist/composed/bulk-action-bar.js +29 -28
- package/dist/composed/command-palette.d.ts.map +1 -1
- package/dist/composed/command-palette.js +99 -113
- package/dist/composed/content-card.js +1 -1
- package/dist/composed/date-picker/calendar-grid.d.ts.map +1 -1
- package/dist/composed/date-picker/date-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/date-range-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/date-time-picker.d.ts.map +1 -1
- package/dist/composed/date-picker/time-picker.d.ts.map +1 -1
- package/dist/composed/deadline-indicator.d.ts.map +1 -1
- package/dist/composed/deadline-indicator.js +29 -28
- package/dist/composed/error-boundary.d.ts.map +1 -1
- package/dist/composed/error-boundary.js +30 -27
- package/dist/composed/extensions/file-attachment.d.ts.map +1 -1
- package/dist/composed/file-preview.d.ts.map +1 -1
- package/dist/composed/file-preview.js +261 -271
- package/dist/composed/filter-bar.d.ts.map +1 -1
- package/dist/composed/filter-bar.js +49 -48
- package/dist/composed/form-section.d.ts.map +1 -1
- package/dist/composed/form-section.js +12 -11
- package/dist/composed/global-loading.js +1 -1
- package/dist/composed/index.d.ts +1 -1
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +63 -63
- package/dist/composed/inline-edit.d.ts.map +1 -1
- package/dist/composed/inline-edit.js +55 -54
- package/dist/composed/markdown-viewer.d.ts.map +1 -1
- package/dist/composed/markdown-viewer.js +44 -43
- package/dist/composed/master-detail.d.ts.map +1 -1
- package/dist/composed/master-detail.js +35 -34
- package/dist/composed/multi-select-popover.d.ts.map +1 -1
- package/dist/composed/multi-select-popover.js +73 -73
- package/dist/composed/page-header.d.ts.map +1 -1
- package/dist/composed/page-header.js +42 -35
- package/dist/composed/priority-indicator.d.ts.map +1 -1
- package/dist/composed/priority-indicator.js +37 -36
- package/dist/composed/rich-text-editor.d.ts +3 -0
- package/dist/composed/rich-text-editor.d.ts.map +1 -1
- package/dist/composed/rich-text-editor.js +295 -311
- package/dist/composed/schedule-view.js +62 -62
- package/dist/composed/status-badge.d.ts +4 -2
- package/dist/composed/status-badge.d.ts.map +1 -1
- package/dist/composed/status-badge.js +58 -45
- package/dist/shell/app-command-palette.d.ts.map +1 -1
- package/dist/shell/app-command-palette.js +93 -93
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +21 -20
- package/dist/shell/index.js +18 -18
- package/dist/shell/notification-center.d.ts.map +1 -1
- package/dist/shell/notification-center.js +96 -95
- package/dist/shell/notification-preferences.d.ts.map +1 -1
- package/dist/shell/notification-preferences.js +82 -85
- package/dist/shell/sidebar.js +59 -60
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +103 -103
- package/dist/tailwind/index.cjs +37 -4
- package/dist/tailwind/preset.d.ts.map +1 -1
- package/dist/tailwind/preset.js +38 -5
- package/dist/tokens/primitives.css +20 -0
- package/dist/tokens/semantic.css +74 -7
- package/dist/ui/accordion.d.ts +5 -2
- package/dist/ui/accordion.d.ts.map +1 -1
- package/dist/ui/accordion.js +44 -39
- package/dist/ui/alert-dialog.js +57 -57
- package/dist/ui/alert.d.ts +1 -1
- package/dist/ui/alert.d.ts.map +1 -1
- package/dist/ui/alert.js +30 -29
- package/dist/ui/aspect-ratio.js +4 -4
- package/dist/ui/autocomplete.js +56 -56
- package/dist/ui/avatar.js +2 -2
- package/dist/ui/badge-group.d.ts +22 -0
- package/dist/ui/badge-group.d.ts.map +1 -0
- package/dist/ui/badge-group.js +8 -0
- package/dist/ui/badge-indicator.d.ts +32 -0
- package/dist/ui/badge-indicator.d.ts.map +1 -0
- package/dist/ui/badge-indicator.js +54 -0
- package/dist/ui/badge.d.ts +27 -24
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/badge.js +13 -129
- package/dist/ui/banner.d.ts +1 -1
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +27 -26
- package/dist/ui/breadcrumb.d.ts.map +1 -1
- package/dist/ui/breadcrumb.js +37 -36
- package/dist/ui/button-group.d.ts +12 -6
- package/dist/ui/button-group.d.ts.map +1 -1
- package/dist/ui/button-group.js +18 -18
- package/dist/ui/button-processing.d.ts +16 -0
- package/dist/ui/button-processing.d.ts.map +1 -0
- package/dist/ui/button-processing.js +77 -0
- package/dist/ui/button.d.ts +50 -25
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +243 -127
- package/dist/ui/card.js +20 -21
- package/dist/ui/charts/index.js +499 -508
- package/dist/ui/chat/date-separator.d.ts +12 -0
- package/dist/ui/chat/date-separator.d.ts.map +1 -0
- package/dist/ui/chat/index.d.ts +9 -0
- package/dist/ui/chat/index.d.ts.map +1 -0
- package/dist/ui/chat/index.js +12 -0
- package/dist/ui/chat/message-input.d.ts +16 -0
- package/dist/ui/chat/message-input.d.ts.map +1 -0
- package/dist/ui/chat/message-list.d.ts +24 -0
- package/dist/ui/chat/message-list.d.ts.map +1 -0
- package/dist/ui/chat/message.d.ts +108 -0
- package/dist/ui/chat/message.d.ts.map +1 -0
- package/dist/ui/chat/system-message.d.ts +11 -0
- package/dist/ui/chat/system-message.d.ts.map +1 -0
- package/dist/ui/chat/typing-indicator.d.ts +14 -0
- package/dist/ui/chat/typing-indicator.d.ts.map +1 -0
- package/dist/ui/chat/unread-separator.d.ts +12 -0
- package/dist/ui/chat/unread-separator.d.ts.map +1 -0
- package/dist/ui/checkbox.js +18 -18
- package/dist/ui/chip.d.ts +13 -62
- package/dist/ui/chip.d.ts.map +1 -1
- package/dist/ui/chip.js +10 -109
- package/dist/ui/collapsible.js +4 -4
- package/dist/ui/color-input.js +134 -134
- package/dist/ui/color-swatch.js +11 -11
- package/dist/ui/combobox.d.ts.map +1 -1
- package/dist/ui/combobox.js +74 -80
- package/dist/ui/context-menu.d.ts.map +1 -1
- package/dist/ui/context-menu.js +86 -85
- package/dist/ui/data-table-toolbar.d.ts.map +1 -1
- package/dist/ui/data-table-toolbar.js +51 -57
- package/dist/ui/data-table.d.ts.map +1 -1
- package/dist/ui/data-table.js +268 -296
- package/dist/ui/devalok-grain.d.ts +81 -0
- package/dist/ui/devalok-grain.d.ts.map +1 -0
- package/dist/ui/devalok-grain.js +69 -0
- package/dist/ui/dialog.d.ts.map +1 -1
- package/dist/ui/dialog.js +73 -72
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +93 -92
- package/dist/ui/file-upload.d.ts.map +1 -1
- package/dist/ui/file-upload.js +82 -82
- package/dist/ui/hover-card.js +29 -29
- package/dist/ui/icon-button.d.ts +7 -7
- package/dist/ui/icon-button.d.ts.map +1 -1
- package/dist/ui/icon-context.d.ts +15 -0
- package/dist/ui/icon-context.d.ts.map +1 -0
- package/dist/ui/icon-context.js +20 -0
- package/dist/ui/icon-group.d.ts +22 -0
- package/dist/ui/icon-group.d.ts.map +1 -0
- package/dist/ui/icon-group.js +32 -0
- package/dist/ui/icon.d.ts +57 -0
- package/dist/ui/icon.d.ts.map +1 -0
- package/dist/ui/icon.js +122 -0
- package/dist/ui/index.d.ts +8 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +351 -329
- package/dist/ui/input-otp.d.ts.map +1 -1
- package/dist/ui/input-otp.js +21 -20
- package/dist/ui/input.d.ts +32 -11
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +149 -44
- package/dist/ui/lib/motion.d.ts +2 -0
- package/dist/ui/lib/motion.d.ts.map +1 -1
- package/dist/ui/lib/motion.js +13 -11
- package/dist/ui/lib/utils.js +4 -4
- package/dist/ui/menubar.d.ts.map +1 -1
- package/dist/ui/menubar.js +87 -86
- package/dist/ui/navigation-menu.d.ts.map +1 -1
- package/dist/ui/navigation-menu.js +23 -28
- package/dist/ui/number-input.d.ts.map +1 -1
- package/dist/ui/number-input.js +54 -53
- package/dist/ui/pagination.d.ts.map +1 -1
- package/dist/ui/pagination.js +45 -44
- package/dist/ui/popover.js +28 -28
- package/dist/ui/progress.d.ts +3 -1
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +43 -39
- package/dist/ui/search-input.d.ts.map +1 -1
- package/dist/ui/search-input.js +47 -60
- package/dist/ui/segmented-control.js +1 -1
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +54 -53
- package/dist/ui/sheet.d.ts.map +1 -1
- package/dist/ui/sheet.js +46 -45
- package/dist/ui/sidebar.d.ts.map +1 -1
- package/dist/ui/sidebar.js +196 -193
- package/dist/ui/skeleton.js +1 -1
- package/dist/ui/spinner.js +74 -74
- package/dist/ui/stat-card.d.ts.map +1 -1
- package/dist/ui/stat-card.js +85 -86
- package/dist/ui/switch.d.ts +3 -0
- package/dist/ui/switch.d.ts.map +1 -1
- package/dist/ui/switch.js +41 -27
- package/dist/ui/tabs.js +43 -43
- package/dist/ui/text.js +1 -1
- package/dist/ui/textarea.js +10 -10
- package/dist/ui/toast.d.ts.map +1 -1
- package/dist/ui/toast.js +169 -169
- package/dist/ui/toggle.js +4 -4
- package/dist/ui/tooltip.js +40 -40
- package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
- package/docs/components/_header.md +4 -4
- package/docs/components/composed/activity-feed.md +7 -0
- package/docs/components/composed/avatar-group.md +8 -5
- package/docs/components/composed/rich-text-editor.md +6 -0
- package/docs/components/composed/status-badge.md +14 -1
- package/docs/components/ui/accordion.md +5 -2
- package/docs/components/ui/badge-group.md +38 -0
- package/docs/components/ui/badge-indicator.md +40 -0
- package/docs/components/ui/badge.md +36 -5
- package/docs/components/ui/button-processing.md +15 -0
- package/docs/components/ui/button.md +40 -11
- package/docs/components/ui/chat.md +214 -0
- package/docs/components/ui/data-table.md +3 -0
- package/docs/components/ui/devalok-grain.md +55 -0
- package/docs/components/ui/icon-button.md +12 -5
- package/docs/components/ui/icon-context.md +38 -0
- package/docs/components/ui/icon-group.md +36 -0
- package/docs/components/ui/icon.md +47 -0
- package/docs/components/ui/input.md +32 -6
- package/docs/components/ui/progress.md +5 -0
- package/docs/components/ui/spinner.md +3 -0
- package/docs/components/ui/switch.md +13 -0
- package/llms-full.txt +672 -40
- package/llms.txt +46 -21
- package/package.json +7 -2
package/llms-full.txt
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
> All variant values and props verified from source CVA definitions.
|
|
6
6
|
>
|
|
7
7
|
> Package: @devalok/shilp-sutra
|
|
8
|
-
> Version: 0.
|
|
8
|
+
> Version: 0.30.0
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -54,15 +54,15 @@ Color tokens use OKLCH (perceptually uniform) with 12 functional steps per palet
|
|
|
54
54
|
Semantic layer:
|
|
55
55
|
- Accent (swappable): --color-accent-{1-12} + --color-accent-fg
|
|
56
56
|
- Secondary: --color-secondary-{1-12} + --color-secondary-fg
|
|
57
|
-
- Surface: --color-surface-{
|
|
58
|
-
- Border mapping: light mode border=step5, border-
|
|
59
|
-
- Shell chrome (sidebar, topbar, bottom nav) uses surface-
|
|
57
|
+
- Surface: --color-surface-{base,raised,sunken} + --color-surface-fg / fg-muted / fg-subtle / border / border-subtle
|
|
58
|
+
- Border mapping: light mode border=step5, border-subtle=step3; dark mode border=step3, border-subtle=step2
|
|
59
|
+
- Shell chrome (sidebar, topbar, bottom nav) uses surface-sunken with brand tint for recessed chrome
|
|
60
60
|
- Status: --color-{error,success,warning,info}-{3,7,9,11}
|
|
61
61
|
- Category: --color-category-{teal,amber,slate,indigo,cyan,orange,emerald}
|
|
62
62
|
|
|
63
63
|
Consumer rebranding: Override accent scale CSS vars or use generateScale(options) utility.
|
|
64
64
|
|
|
65
|
-
Tailwind utilities: accent-1..12, secondary-1..12, surface-
|
|
65
|
+
Tailwind utilities: accent-1..12, secondary-1..12, surface-base/raised/sunken, plus fg/border variants.
|
|
66
66
|
|
|
67
67
|
### Toast Setup Pattern
|
|
68
68
|
|
|
@@ -108,11 +108,11 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
108
108
|
## Compound Components
|
|
109
109
|
Accordion (root)
|
|
110
110
|
AccordionItem (value: string, REQUIRED)
|
|
111
|
-
AccordionTrigger (clickable header, chevron auto-renders)
|
|
111
|
+
AccordionTrigger (clickable header, chevron auto-renders; chevronPosition: "left" | "right")
|
|
112
112
|
AccordionContent (collapsible body)
|
|
113
113
|
|
|
114
114
|
## Defaults
|
|
115
|
-
none (type is required)
|
|
115
|
+
none (type is required); AccordionTrigger: chevronPosition="right"
|
|
116
116
|
|
|
117
117
|
## Example
|
|
118
118
|
```jsx
|
|
@@ -129,6 +129,9 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
129
129
|
- collapsible only works with type="single"
|
|
130
130
|
|
|
131
131
|
## Changes
|
|
132
|
+
### v0.29.0
|
|
133
|
+
- **Added** `chevronPosition` prop on AccordionTrigger: `"left"` | `"right"` (default: `"right"`) — controls which side the chevron icon renders
|
|
134
|
+
|
|
132
135
|
### v0.18.0
|
|
133
136
|
- **Changed** Accordion content fade animation migrated to Framer Motion (height animation still uses CSS keyframes)
|
|
134
137
|
|
|
@@ -380,13 +383,25 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
380
383
|
- Category: ui
|
|
381
384
|
|
|
382
385
|
## Props
|
|
383
|
-
variant: "subtle" | "solid" | "outline" | "
|
|
384
|
-
color: "default" | "
|
|
386
|
+
variant: "subtle" | "solid" | "outline" | "soft"
|
|
387
|
+
color: "default" | "accent" | "error" | "success" | "warning" | "info" | "neutral" | "teal" | "amber" | "slate" | "indigo" | "cyan" | "orange" | "emerald" | "custom"
|
|
385
388
|
size: "xs" | "sm" | "md" | "lg"
|
|
386
|
-
|
|
387
|
-
|
|
389
|
+
startIcon: ReactElement | null
|
|
390
|
+
endIcon: ReactElement | null
|
|
391
|
+
dot: boolean (shows animated leading dot indicator)
|
|
392
|
+
onClick: () => void (makes badge interactive as button)
|
|
393
|
+
selected: boolean (toggle state — shows check icon when true)
|
|
394
|
+
disabled: boolean
|
|
395
|
+
onDismiss: () => void (shows dismiss X button)
|
|
396
|
+
maxWidth: number (enables truncation with title tooltip)
|
|
397
|
+
circle: boolean (square aspect-ratio, centered content)
|
|
398
|
+
asChild: boolean
|
|
388
399
|
children: ReactNode
|
|
389
400
|
|
|
401
|
+
## Compound Components
|
|
402
|
+
Badge.Indicator — status indicator sub-component
|
|
403
|
+
Badge.Group — layout wrapper for badge collections
|
|
404
|
+
|
|
390
405
|
## Defaults
|
|
391
406
|
variant="subtle", color="default", size="md"
|
|
392
407
|
|
|
@@ -394,13 +409,32 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
394
409
|
```jsx
|
|
395
410
|
<Badge variant="solid" color="success">Active</Badge>
|
|
396
411
|
<Badge color="teal" onDismiss={() => removeFilter('teal')}>Teal team</Badge>
|
|
412
|
+
<Badge onClick={() => toggle()} selected={isSelected}>Filterable</Badge>
|
|
413
|
+
<Badge color="custom" style={{ '--badge-color': '#8b5cf6' }}>Custom</Badge>
|
|
397
414
|
```
|
|
398
415
|
|
|
399
416
|
## Gotchas
|
|
400
417
|
- DO NOT use variant="destructive" — use variant="solid" color="error"
|
|
401
|
-
- Badge is
|
|
418
|
+
- Badge is now interactive when `onClick` is provided (renders as `<button>`)
|
|
419
|
+
- When both `onClick` and `onDismiss` are provided, renders as `div[role="button"]` to avoid nested buttons
|
|
420
|
+
- Chip is deprecated — use Badge with `onClick` for interactive tags
|
|
421
|
+
- `color="custom"` requires `--badge-color` CSS variable (and optionally `--badge-fg-color` for solid variant)
|
|
402
422
|
|
|
403
423
|
## Changes
|
|
424
|
+
### v0.29.0
|
|
425
|
+
- **Changed** (BREAKING) v2 rewrite — Badge is now a full interactive component
|
|
426
|
+
- **Added** `soft` variant (tinted bg, no border — completes the 4-variant set: subtle/solid/outline/soft)
|
|
427
|
+
- **Added** `custom` color with CSS variable `--badge-color` (and `--badge-fg-color` for solid)
|
|
428
|
+
- **Added** Interactive mode: `onClick` makes Badge a clickable button, `selected` shows animated check icon
|
|
429
|
+
- **Added** `disabled` prop with reduced opacity and pointer-events-none
|
|
430
|
+
- **Added** `startIcon` / `endIcon` props (auto-sized per badge size)
|
|
431
|
+
- **Added** `maxWidth` prop for truncation with title tooltip
|
|
432
|
+
- **Added** `circle` prop for square aspect-ratio badges
|
|
433
|
+
- **Added** `asChild` prop for Slot composition
|
|
434
|
+
- **Added** `Badge.Indicator` and `Badge.Group` compound sub-components
|
|
435
|
+
- **Deprecated** Chip component — use Badge with `onClick` instead
|
|
436
|
+
- **Changed** Dot animation now uses Framer Motion spring entrance + continuous pulse
|
|
437
|
+
|
|
404
438
|
### v0.18.0
|
|
405
439
|
- **Changed** Pulse-ring animation migrated to Framer Motion
|
|
406
440
|
- **Fixed** Accent color variants — `text-accent-9` changed to `text-accent-11`, `border-accent-9` changed to `border-accent-7`
|
|
@@ -421,6 +455,84 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
421
455
|
|
|
422
456
|
### v0.1.0
|
|
423
457
|
- **Added** Initial release
|
|
458
|
+
# BadgeGroup
|
|
459
|
+
|
|
460
|
+
- Import: @devalok/shilp-sutra/ui (as Badge.Group)
|
|
461
|
+
- Server-safe: Yes
|
|
462
|
+
- Category: ui
|
|
463
|
+
|
|
464
|
+
## Props
|
|
465
|
+
max: number — Show at most N badges, rest collapsed into "+N" overflow
|
|
466
|
+
gap: "tight" | "default" | "loose" (default: "default")
|
|
467
|
+
size: BadgeProps["size"] — Size passed to the overflow "+N" badge
|
|
468
|
+
onOverflowClick: () => void — Click handler for the overflow "+N" badge
|
|
469
|
+
className: string
|
|
470
|
+
children: ReactNode (REQUIRED)
|
|
471
|
+
|
|
472
|
+
## Defaults
|
|
473
|
+
gap="default", max=undefined (show all), size="sm" (overflow badge)
|
|
474
|
+
|
|
475
|
+
## Example
|
|
476
|
+
```jsx
|
|
477
|
+
<Badge.Group max={3} size="sm" onOverflowClick={() => setShowAll(true)}>
|
|
478
|
+
<Badge>React</Badge>
|
|
479
|
+
<Badge>TypeScript</Badge>
|
|
480
|
+
<Badge>Tailwind</Badge>
|
|
481
|
+
<Badge>Vite</Badge>
|
|
482
|
+
<Badge>Vitest</Badge>
|
|
483
|
+
</Badge.Group>
|
|
484
|
+
{/* Renders: React, TypeScript, Tailwind, +2 */}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## Gotchas
|
|
488
|
+
- Overflow badge is always `variant="outline" color="neutral"`
|
|
489
|
+
- `size` only applies to the overflow badge — child badges keep their own size
|
|
490
|
+
- Gap values: tight=4px, default=6px, loose=8px
|
|
491
|
+
- Without `onOverflowClick`, the overflow badge is not interactive
|
|
492
|
+
|
|
493
|
+
## Changes
|
|
494
|
+
### v0.29.0
|
|
495
|
+
- **Added** Initial release — badge grouping with overflow collapse and click handler
|
|
496
|
+
# BadgeIndicator
|
|
497
|
+
|
|
498
|
+
- Import: @devalok/shilp-sutra/ui (as Badge.Indicator)
|
|
499
|
+
- Server-safe: No
|
|
500
|
+
- Category: ui
|
|
501
|
+
|
|
502
|
+
## Props
|
|
503
|
+
count: number — Numeric value to display
|
|
504
|
+
max: number (default: 99) — Cap display at this value, shows "99+" when exceeded
|
|
505
|
+
dot: boolean (default: false) — Show a small dot instead of count
|
|
506
|
+
color: "error" | "success" | "warning" | "accent" | "info" (default: "error")
|
|
507
|
+
invisible: boolean (default: false) — Hide the indicator while keeping layout
|
|
508
|
+
showZero: boolean (default: false) — Show indicator when count is 0
|
|
509
|
+
placement: "top-right" | "top-left" | "bottom-right" | "bottom-left" (default: "top-right")
|
|
510
|
+
className: string
|
|
511
|
+
children: ReactNode (REQUIRED) — The element to attach the indicator to
|
|
512
|
+
|
|
513
|
+
## Defaults
|
|
514
|
+
max=99, dot=false, color="error", invisible=false, showZero=false, placement="top-right"
|
|
515
|
+
|
|
516
|
+
## Example
|
|
517
|
+
```jsx
|
|
518
|
+
<Badge.Indicator count={5}>
|
|
519
|
+
<IconButton icon={IconBell} variant="ghost" />
|
|
520
|
+
</Badge.Indicator>
|
|
521
|
+
|
|
522
|
+
<Badge.Indicator dot color="success">
|
|
523
|
+
<Avatar src={user.avatar} fallback={user.name} />
|
|
524
|
+
</Badge.Indicator>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Gotchas
|
|
528
|
+
- Wraps children in `position: relative` span — the indicator is absolutely positioned
|
|
529
|
+
- Animation uses spring physics, respects `prefers-reduced-motion`
|
|
530
|
+
- When `count > max`, displays `${max}+` (e.g., "99+")
|
|
531
|
+
- `invisible` keeps the layout but hides the dot/count (useful for transitions)
|
|
532
|
+
|
|
533
|
+
## Changes
|
|
534
|
+
### v0.29.0
|
|
535
|
+
- **Added** Initial release — animated notification indicator with count, dot, placement, and color
|
|
424
536
|
# Banner
|
|
425
537
|
|
|
426
538
|
- Import: @devalok/shilp-sutra/ui/banner
|
|
@@ -507,37 +619,66 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
507
619
|
- Category: ui
|
|
508
620
|
|
|
509
621
|
## Props
|
|
510
|
-
variant: "solid" | "
|
|
511
|
-
color: "
|
|
512
|
-
size: "sm" | "md" | "lg" | "icon" | "icon-sm" | "icon-md" | "icon-lg"
|
|
513
|
-
|
|
514
|
-
|
|
622
|
+
variant: "solid" | "soft" | "outline" | "ghost" | "link" | "default" (alias->solid) | "destructive" (alias->solid+error)
|
|
623
|
+
color: "accent" | "error" | "success" | "warning" | "neutral" | "default" (alias->accent)
|
|
624
|
+
size: "xs" | "sm" | "md" | "lg" | "compact-xs" | "compact-sm" | "compact-md" | "icon" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg"
|
|
625
|
+
weight: "semibold" | "normal"
|
|
626
|
+
shape: "default" | "pill"
|
|
627
|
+
startIcon: ReactElement (use <Icon icon={...} />) | null
|
|
628
|
+
endIcon: ReactElement (use <Icon icon={...} />) | null
|
|
515
629
|
loading: boolean (disables button, shows spinner)
|
|
516
630
|
loadingPosition: "start" | "end" | "center" (default: "start")
|
|
517
631
|
fullWidth: boolean
|
|
518
632
|
asChild: boolean
|
|
519
|
-
|
|
633
|
+
processing: boolean | 'ambient' | 'working' | 'urgent' (marching ants SVG border)
|
|
634
|
+
processingColor: 'accent' | 'error' | 'success' | 'warning' | 'neutral' (override animation color)
|
|
635
|
+
processingDisabled: boolean (disable button during processing, default: true)
|
|
636
|
+
onClickAsync: (e: MouseEvent) => Promise<void> (auto loading->success/error->idle, auto-activates processing)
|
|
520
637
|
asyncFeedbackDuration: number (ms, default 1500)
|
|
521
638
|
|
|
522
639
|
## Defaults
|
|
523
|
-
variant="solid", color="
|
|
640
|
+
variant="solid", color="accent", weight="semibold", size="md", shape="default"
|
|
524
641
|
|
|
525
642
|
## Example
|
|
526
643
|
```jsx
|
|
527
|
-
<Button variant="solid" color="error" startIcon={<IconTrash />} loading={isDeleting}>
|
|
644
|
+
<Button variant="solid" color="error" startIcon={<Icon icon={IconTrash} />} loading={isDeleting}>
|
|
528
645
|
Delete project
|
|
529
646
|
</Button>
|
|
647
|
+
<Button variant="soft" color="success" startIcon={<Icon icon={IconCheck} />}>Approved</Button>
|
|
648
|
+
<Button variant="soft" color="warning" size="compact-sm" shape="pill">Overdue</Button>
|
|
530
649
|
```
|
|
531
650
|
|
|
532
651
|
## Gotchas
|
|
533
652
|
- DO NOT use variant="destructive" — use variant="solid" color="error"
|
|
534
653
|
- DO NOT use variant="secondary" — use variant="outline" or variant="ghost"
|
|
535
654
|
- DO NOT use size="default" — use size="md"
|
|
536
|
-
- DO NOT use color="danger" — use color="error"
|
|
537
|
-
-
|
|
538
|
-
-
|
|
655
|
+
- DO NOT use color="danger" or color="default" — use color="error" or color="accent"
|
|
656
|
+
- startIcon/endIcon now expect `<Icon icon={...} />` wrapper, not bare icon components
|
|
657
|
+
- Inherits variant/color/size/weight/shape from ButtonGroup context if present
|
|
658
|
+
- onClickAsync overrides onClick and loading when active; also auto-activates processing='working' during loading phase
|
|
659
|
+
- processing forces soft variant so marching ants pop against the background
|
|
660
|
+
- processingDisabled=true (default) makes button aria-disabled and pointer-events-none during processing
|
|
661
|
+
- Grain children (DevalokGrain) are auto-separated and rendered as direct button children for absolute positioning
|
|
539
662
|
|
|
540
663
|
## Changes
|
|
664
|
+
### v0.29.0
|
|
665
|
+
- **Added** `soft` variant — tinted background, colored text (new middle ground between solid and ghost)
|
|
666
|
+
- **Added** 5 color options: `accent` (default), `error`, `success`, `warning`, `neutral` (replaces old `default`/`error`-only axis)
|
|
667
|
+
- **Added** `shape` prop: `"default"` | `"pill"` (rounded-full with extra horizontal padding)
|
|
668
|
+
- **Added** compact sizes: `compact-xs`, `compact-sm`, `compact-md` (height-less inline buttons)
|
|
669
|
+
- **Added** `xs` size and `icon-xs` size
|
|
670
|
+
- **Added** `weight` prop: `"semibold"` (default) | `"normal"` for lighter labels
|
|
671
|
+
- **Changed** `startIcon`/`endIcon` now accept `<Icon icon={...} />` wrapper (auto-sized via IconProvider context per button size)
|
|
672
|
+
- **Changed** Default color is now `"accent"` (was `"default"`)
|
|
673
|
+
- **Changed** Solid hover adds tinted shadows per color (e.g., `hover:shadow-brand`, `hover:shadow-error`)
|
|
674
|
+
- **Changed** Icon slots get negative-margin inset to tighten padding against button edges
|
|
675
|
+
- **Added** DevalokGrain support — grain children are auto-separated and rendered for texture overlays
|
|
676
|
+
- **Added** `processing` prop — marching ants SVG border while content stays visible (`"ambient"` (3s) | `"working"` (2s) | `"urgent"` (1s) | boolean). Forces soft variant so ants pop.
|
|
677
|
+
- **Added** `processingColor` — override processing animation color independently of button color
|
|
678
|
+
- **Added** `processingDisabled` — disable button during processing (default: true). Set false for cancel-by-click patterns.
|
|
679
|
+
- **Added** Auto-processing during `onClickAsync` — loading phase auto-activates `processing='working'` when no explicit `processing` prop is set
|
|
680
|
+
- **Added** Always-on layout animation — smooth width/height transitions via Framer Motion FLIP
|
|
681
|
+
|
|
541
682
|
### v0.22.0
|
|
542
683
|
- **Changed** Active/pressed scale from `0.97` to `0.95` for snappier press feedback.
|
|
543
684
|
- **Fixed** Ghost/outline hover not fading — `transition-transform` in base overrode `transition-colors` from variant. Combined into single `transition-[color,background-color,border-color,box-shadow,transform]`.
|
|
@@ -592,6 +733,21 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
592
733
|
|
|
593
734
|
### v0.1.0
|
|
594
735
|
- **Added** Initial release
|
|
736
|
+
# ButtonProcessing (Internal)
|
|
737
|
+
|
|
738
|
+
- Import: Internal — not exported from barrel. Used only by Button.
|
|
739
|
+
- Server-safe: No
|
|
740
|
+
- Category: ui
|
|
741
|
+
|
|
742
|
+
## Description
|
|
743
|
+
|
|
744
|
+
Internal component that renders the processing animation overlay for Button. Consumers use the `processing` prop on Button, not this component directly.
|
|
745
|
+
|
|
746
|
+
See `Button` docs for the public API.
|
|
747
|
+
|
|
748
|
+
## Changes
|
|
749
|
+
### v0.29.0
|
|
750
|
+
- **Added** Initial release — marching ants processing overlay (SVG dashed rect with animated stroke-dashoffset). Speed tiers: ambient (3s), working (2s), urgent (1s). Color maps to step-11 tokens for visibility on all variants.
|
|
595
751
|
# Card
|
|
596
752
|
|
|
597
753
|
- Import: @devalok/shilp-sutra/ui/card
|
|
@@ -683,6 +839,220 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
683
839
|
|
|
684
840
|
### v0.1.0
|
|
685
841
|
- **Added** Initial release
|
|
842
|
+
# Chat
|
|
843
|
+
|
|
844
|
+
- Import: @devalok/shilp-sutra/ui/chat
|
|
845
|
+
- Server-safe: No (MessageList, Message, MessageInput, TypingIndicator use Framer Motion); DateSeparator and UnreadSeparator are server-safe
|
|
846
|
+
- Category: ui
|
|
847
|
+
|
|
848
|
+
Seven primitives for building chat interfaces: MessageList, Message (compound), SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator.
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
## MessageList
|
|
853
|
+
|
|
854
|
+
Scrollable container with auto-scroll, load-more, empty state, and "N new" floating pill.
|
|
855
|
+
|
|
856
|
+
### Props
|
|
857
|
+
autoScroll: boolean — auto-scroll to bottom on new content (default: true)
|
|
858
|
+
newMessageCount: number — count shown in floating pill (default: 0)
|
|
859
|
+
onScrollToBottom: () => void — called when user clicks the "N new" pill
|
|
860
|
+
onLoadMore: () => void — called when user scrolls near top
|
|
861
|
+
isLoadingMore: boolean — shows spinner at top (default: false)
|
|
862
|
+
emptySlot: ReactNode — content when there are no children
|
|
863
|
+
headerSlot: ReactNode — content above the scroll container (e.g. channel name)
|
|
864
|
+
scrollToBottomSlot: ReactNode — reserved slot for custom scroll-to-bottom button
|
|
865
|
+
children: ReactNode (REQUIRED)
|
|
866
|
+
|
|
867
|
+
### Example
|
|
868
|
+
```jsx
|
|
869
|
+
<MessageList autoScroll onLoadMore={loadMore} isLoadingMore={loading} newMessageCount={3} onScrollToBottom={markRead}>
|
|
870
|
+
{messages.map(m => <Message key={m.id}>...</Message>)}
|
|
871
|
+
</MessageList>
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
---
|
|
875
|
+
|
|
876
|
+
## Message (Compound)
|
|
877
|
+
|
|
878
|
+
Compound component: `Message`, `Message.Avatar`, `Message.Content`, `Message.Author`, `Message.Body`, `Message.EditableBody`, `Message.Reactions`, `Message.Actions`, `Message.Action`.
|
|
879
|
+
|
|
880
|
+
### Message (root) Props
|
|
881
|
+
variant: "flat" | "bubble" (default: "flat")
|
|
882
|
+
placement: "start" | "end" (default: "start")
|
|
883
|
+
highlight: "mention" | "internal"
|
|
884
|
+
grouped: boolean — hides avatar/author for consecutive messages (default: false)
|
|
885
|
+
deleted: boolean — renders deleted placeholder (default: false)
|
|
886
|
+
deletedText: string (default: "This message was deleted")
|
|
887
|
+
|
|
888
|
+
### Message.Avatar Props
|
|
889
|
+
src: string | null — avatar image URL
|
|
890
|
+
fallback: string — initials text
|
|
891
|
+
icon: ReactNode — custom icon instead of avatar
|
|
892
|
+
size: "sm" | "md" (default: "md")
|
|
893
|
+
children: ReactNode — fully custom avatar slot
|
|
894
|
+
|
|
895
|
+
### Message.Author Props
|
|
896
|
+
name: string (REQUIRED)
|
|
897
|
+
badge: ReactNode
|
|
898
|
+
timestamp: Date
|
|
899
|
+
formattedTimestamp: string — pre-formatted timestamp (overrides timestamp)
|
|
900
|
+
timestampFormat: (date: Date) => string — custom formatter
|
|
901
|
+
|
|
902
|
+
### Message.Body Props
|
|
903
|
+
children: ReactNode (REQUIRED)
|
|
904
|
+
|
|
905
|
+
### Message.EditableBody Props
|
|
906
|
+
content: string (REQUIRED)
|
|
907
|
+
onSave: (newContent: string) => void (REQUIRED)
|
|
908
|
+
onCancel: () => void
|
|
909
|
+
canEdit: boolean (default: false)
|
|
910
|
+
renderContent: (content: string) => ReactNode — custom render for display mode
|
|
911
|
+
|
|
912
|
+
### Message.Reactions Props
|
|
913
|
+
reactions: { emoji: string; count: number; reacted: boolean }[] (REQUIRED)
|
|
914
|
+
onReact: (emoji: string) => void (REQUIRED)
|
|
915
|
+
|
|
916
|
+
### Message.Content Props
|
|
917
|
+
children: ReactNode (REQUIRED)
|
|
918
|
+
className: string
|
|
919
|
+
|
|
920
|
+
### Message.Actions Props
|
|
921
|
+
children: ReactNode (REQUIRED)
|
|
922
|
+
delay: number — hover reveal delay in ms (default: 100)
|
|
923
|
+
|
|
924
|
+
### Message.Action Props
|
|
925
|
+
icon: IconProps["icon"] (REQUIRED) — pass the Tabler component reference, e.g. `IconReply` (not `<IconReply />`)
|
|
926
|
+
label: string (REQUIRED)
|
|
927
|
+
onClick: () => void (REQUIRED)
|
|
928
|
+
variant: "default" | "danger" (default: "default")
|
|
929
|
+
|
|
930
|
+
### Example
|
|
931
|
+
```jsx
|
|
932
|
+
<Message variant="flat" highlight="mention">
|
|
933
|
+
<Message.Avatar src={user.photo} fallback="JD" />
|
|
934
|
+
<Message.Content>
|
|
935
|
+
<Message.Author name="Jane Doe" timestamp={new Date()} badge={<Badge>Admin</Badge>} />
|
|
936
|
+
<Message.Body>Hello, world!</Message.Body>
|
|
937
|
+
<Message.Reactions reactions={reactions} onReact={handleReact} />
|
|
938
|
+
<Message.Actions>
|
|
939
|
+
<Message.Action icon={IconReply} label="Reply" onClick={handleReply} />
|
|
940
|
+
<Message.Action icon={IconTrash} label="Delete" onClick={handleDelete} variant="danger" />
|
|
941
|
+
</Message.Actions>
|
|
942
|
+
</Message.Content>
|
|
943
|
+
</Message>
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
---
|
|
947
|
+
|
|
948
|
+
## SystemMessage
|
|
949
|
+
|
|
950
|
+
Inline system event or alert message (e.g. "Alice joined the channel").
|
|
951
|
+
|
|
952
|
+
### Props
|
|
953
|
+
icon: ReactNode — custom icon
|
|
954
|
+
timestamp: string — ISO timestamp string
|
|
955
|
+
variant: "event" | "alert" (default: "event")
|
|
956
|
+
children: ReactNode (REQUIRED)
|
|
957
|
+
|
|
958
|
+
### Example
|
|
959
|
+
```jsx
|
|
960
|
+
<SystemMessage>Alice joined the channel</SystemMessage>
|
|
961
|
+
<SystemMessage variant="alert" timestamp="2026-03-26T10:00:00Z">Connection lost</SystemMessage>
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
---
|
|
965
|
+
|
|
966
|
+
## MessageInput
|
|
967
|
+
|
|
968
|
+
Auto-resizing textarea with send/stop buttons, streaming support, and slot-based extensibility.
|
|
969
|
+
|
|
970
|
+
### Props
|
|
971
|
+
onSubmit: (text: string) => void (REQUIRED)
|
|
972
|
+
placeholder: string (default: "Type a message...")
|
|
973
|
+
disabled: boolean (default: false)
|
|
974
|
+
isStreaming: boolean — shows stop button instead of send (default: false)
|
|
975
|
+
onCancel: () => void — called when stop button is clicked
|
|
976
|
+
leadingSlot: ReactNode — content before the textarea (e.g. attachment button)
|
|
977
|
+
trailingSlot: ReactNode — content after the send button
|
|
978
|
+
disclaimer: string — centered text below the input (e.g. "AI can make mistakes")
|
|
979
|
+
sendIcon: ReactNode — custom send icon
|
|
980
|
+
|
|
981
|
+
### Example
|
|
982
|
+
```jsx
|
|
983
|
+
<MessageInput
|
|
984
|
+
onSubmit={handleSend}
|
|
985
|
+
isStreaming={streaming}
|
|
986
|
+
onCancel={handleStop}
|
|
987
|
+
disclaimer="AI can make mistakes"
|
|
988
|
+
/>
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
---
|
|
992
|
+
|
|
993
|
+
## DateSeparator
|
|
994
|
+
|
|
995
|
+
Horizontal rule with a formatted date label.
|
|
996
|
+
|
|
997
|
+
### Props
|
|
998
|
+
date: Date | string (REQUIRED)
|
|
999
|
+
format: (date: Date) => string — custom date formatter
|
|
1000
|
+
className: string
|
|
1001
|
+
|
|
1002
|
+
### Example
|
|
1003
|
+
```jsx
|
|
1004
|
+
<DateSeparator date={new Date()} />
|
|
1005
|
+
<DateSeparator date="2026-03-25" format={(d) => d.toLocaleDateString()} />
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
---
|
|
1009
|
+
|
|
1010
|
+
## UnreadSeparator
|
|
1011
|
+
|
|
1012
|
+
Accent-colored horizontal rule marking the unread boundary.
|
|
1013
|
+
|
|
1014
|
+
### Props
|
|
1015
|
+
label: string (default: "NEW")
|
|
1016
|
+
count: number — prepended to label (e.g. "5 NEW")
|
|
1017
|
+
className: string
|
|
1018
|
+
|
|
1019
|
+
### Example
|
|
1020
|
+
```jsx
|
|
1021
|
+
<UnreadSeparator />
|
|
1022
|
+
<UnreadSeparator count={5} />
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
---
|
|
1026
|
+
|
|
1027
|
+
## TypingIndicator
|
|
1028
|
+
|
|
1029
|
+
Animated bouncing dots with a text description of who is typing.
|
|
1030
|
+
|
|
1031
|
+
### Props
|
|
1032
|
+
users: { name: string; image?: string }[] (REQUIRED)
|
|
1033
|
+
className: string
|
|
1034
|
+
|
|
1035
|
+
### Example
|
|
1036
|
+
```jsx
|
|
1037
|
+
<TypingIndicator users={[{ name: 'Alice' }]} />
|
|
1038
|
+
<TypingIndicator users={[{ name: 'Alice' }, { name: 'Bob' }]} />
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
---
|
|
1042
|
+
|
|
1043
|
+
## Gotchas
|
|
1044
|
+
- MessageList uses `role="log"` with `aria-live="polite"` — screen readers announce new messages
|
|
1045
|
+
- Message entrance animations use Framer Motion springs — AnimatePresence wraps children in MessageList
|
|
1046
|
+
- `grouped` hides avatar and author — use for consecutive messages from the same user
|
|
1047
|
+
- MessageInput sends on Enter (Shift+Enter for newline) — textarea auto-resizes up to 160px
|
|
1048
|
+
- TypingIndicator renders nothing when `users` is empty
|
|
1049
|
+
- Message.Actions toolbar is hidden by default (opacity-0) — it reveals on hover of the parent Message root via `group-hover/message`. Only works when Actions is inside a Message root.
|
|
1050
|
+
- Message.Content is the flex column wrapper for Author + Body — required for proper layout in flat variant
|
|
1051
|
+
- DateSeparator's default formatter shows "Today", "Yesterday", or "Mon DD" / "Mon DD, YYYY"
|
|
1052
|
+
|
|
1053
|
+
## Changes
|
|
1054
|
+
### v0.29.0
|
|
1055
|
+
- **Added** Initial release — 7 chat primitives (MessageList, Message, SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator)
|
|
686
1056
|
# Checkbox
|
|
687
1057
|
|
|
688
1058
|
- Import: @devalok/shilp-sutra/ui/checkbox
|
|
@@ -1140,6 +1510,9 @@ import { DataTable } from '@devalok/shilp-sutra/ui/data-table'
|
|
|
1140
1510
|
- Use defaultDensity="compact" for Karm-style h-9 rows
|
|
1141
1511
|
|
|
1142
1512
|
## Changes
|
|
1513
|
+
### v0.29.0
|
|
1514
|
+
- **Fixed** Controlled selection infinite re-render loop — inline `getRowId` callback caused `onSelectionChange` effect to fire every render, creating a setState cycle with `selectedIds`. Now uses a stable ref for `getRowId`.
|
|
1515
|
+
|
|
1143
1516
|
### v0.16.1
|
|
1144
1517
|
- **Fixed** `serverPagination` object reference in `useCallback` dependency caused stale closure — now uses stable ref for `onPageChange`
|
|
1145
1518
|
- **Fixed** `onSelectionChange` effect fired every render due to `table` in dependency array — now derives selected rows directly
|
|
@@ -1208,6 +1581,61 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1208
1581
|
|
|
1209
1582
|
### v0.1.0
|
|
1210
1583
|
- **Added** Initial release
|
|
1584
|
+
# DevalokGrain
|
|
1585
|
+
|
|
1586
|
+
- Import: @devalok/shilp-sutra/ui/devalok-grain
|
|
1587
|
+
- Server-safe: No
|
|
1588
|
+
- Category: ui
|
|
1589
|
+
|
|
1590
|
+
## Props
|
|
1591
|
+
intensity: "subtle" | "medium" | "heavy" — grain intensity level
|
|
1592
|
+
surface: "solid" | "soft" — affects noise opacity ('solid' for filled backgrounds, 'soft' for tinted/muted)
|
|
1593
|
+
sheen: boolean — inner highlight (top-lit emboss) for premium 3D feel
|
|
1594
|
+
animated: boolean — fade-in entrance animation on mount
|
|
1595
|
+
hoverIntensify: boolean — increase grain visibility on parent hover (requires parent `group` class)
|
|
1596
|
+
tint: string — CSS color for the directional gradient (e.g. "oklch(0.55 0.19 360)", "var(--color-accent-9)")
|
|
1597
|
+
|
|
1598
|
+
## Defaults
|
|
1599
|
+
intensity: "subtle"
|
|
1600
|
+
surface: "solid"
|
|
1601
|
+
sheen: false
|
|
1602
|
+
animated: false
|
|
1603
|
+
hoverIntensify: false
|
|
1604
|
+
tint: undefined (no gradient, noise texture only)
|
|
1605
|
+
|
|
1606
|
+
## Example
|
|
1607
|
+
```jsx
|
|
1608
|
+
{/* Inside a Button (Button already has relative/overflow-hidden/isolate): */}
|
|
1609
|
+
<Button>
|
|
1610
|
+
<DevalokGrain />
|
|
1611
|
+
Save changes
|
|
1612
|
+
</Button>
|
|
1613
|
+
|
|
1614
|
+
{/* Inside a Card: */}
|
|
1615
|
+
<Card className="relative overflow-hidden isolate">
|
|
1616
|
+
<DevalokGrain surface="soft" />
|
|
1617
|
+
Card content
|
|
1618
|
+
</Card>
|
|
1619
|
+
|
|
1620
|
+
{/* Heavy grain with tint on a hero section: */}
|
|
1621
|
+
<div className="relative overflow-hidden isolate rounded-ds-lg bg-accent-9 p-8">
|
|
1622
|
+
<DevalokGrain intensity="heavy" tint="oklch(0.55 0.19 360)" />
|
|
1623
|
+
<h1 className="relative z-[2]">Hero</h1>
|
|
1624
|
+
</div>
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
## Gotchas
|
|
1628
|
+
- Parent element MUST have `relative overflow-hidden isolate` for the grain to render correctly
|
|
1629
|
+
- The grain layers are absolute-positioned at `z-[1]` — content that should appear above must use `z-[2]` or higher
|
|
1630
|
+
- Uses `rounded-[inherit]` to match parent border-radius automatically
|
|
1631
|
+
- Renders `aria-hidden="true"` — purely decorative
|
|
1632
|
+
- Without `tint`, only the noise texture renders (no directional gradient)
|
|
1633
|
+
- `hoverIntensify` requires the parent to have a `group` class for `group-hover:` to work
|
|
1634
|
+
- Respects `prefers-reduced-motion` — entrance animation disabled when user prefers reduced motion
|
|
1635
|
+
|
|
1636
|
+
## Changes
|
|
1637
|
+
### v0.29.0
|
|
1638
|
+
- **Added** Initial release — brand noise texture with directional gradient, sheen, animation, and hover intensification
|
|
1211
1639
|
# Dialog
|
|
1212
1640
|
|
|
1213
1641
|
- Import: @devalok/shilp-sutra/ui/dialog
|
|
@@ -1434,6 +1862,53 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1434
1862
|
|
|
1435
1863
|
### v0.1.0
|
|
1436
1864
|
- **Added** Initial release
|
|
1865
|
+
# Icon
|
|
1866
|
+
|
|
1867
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
1868
|
+
- Server-safe: No
|
|
1869
|
+
- Category: ui
|
|
1870
|
+
|
|
1871
|
+
## Props
|
|
1872
|
+
icon: ForwardRefExoticComponent (REQUIRED — Tabler icon or any ForwardRef SVG icon component)
|
|
1873
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" — reads from IconContext if not set
|
|
1874
|
+
stroke: "light" | "regular" | "bold" — reads from IconContext if not set
|
|
1875
|
+
label: string — accessible label (renders <title> + sets aria-label; without it, icon is aria-hidden)
|
|
1876
|
+
animate: "spin" | "pulse" | "bounce" | "draw" | "none" | { rotate?: number; scale?: number }
|
|
1877
|
+
state: "idle" | "loading" | "success" | "error" — delegates to Spinner (bare variant)
|
|
1878
|
+
className: string
|
|
1879
|
+
|
|
1880
|
+
## Defaults
|
|
1881
|
+
size: "md" (from context or fallback)
|
|
1882
|
+
stroke: "regular" (from context or fallback)
|
|
1883
|
+
state: undefined (no state machine)
|
|
1884
|
+
animate: undefined (static render)
|
|
1885
|
+
|
|
1886
|
+
## Example
|
|
1887
|
+
```jsx
|
|
1888
|
+
<Icon icon={IconPlus} />
|
|
1889
|
+
<Icon icon={IconPlus} size="xs" stroke="light" />
|
|
1890
|
+
<Icon icon={IconPlus} label="Add item" />
|
|
1891
|
+
<Icon icon={IconPlus} animate="spin" />
|
|
1892
|
+
<Icon icon={IconCheck} animate="draw" />
|
|
1893
|
+
<Icon icon={IconPlus} state="loading" />
|
|
1894
|
+
<Icon icon={IconPlus} state="success" />
|
|
1895
|
+
```
|
|
1896
|
+
|
|
1897
|
+
## Gotchas
|
|
1898
|
+
- Without `label`, the icon renders `aria-hidden="true"` (decorative)
|
|
1899
|
+
- With `label`, the icon renders `role="img"` with `aria-label` and a `<title>` element
|
|
1900
|
+
- **Priority rule:** If both `state` and `animate` are set, `state` wins
|
|
1901
|
+
- `state="loading"` renders a bare Spinner; `state="success"` / `state="error"` render animated checkmark/cross
|
|
1902
|
+
- Size tiers map to pixel values: xs=14, sm=16, md=18, lg=20, xl=24, 2xl=32
|
|
1903
|
+
- Stroke weight varies by size tier (lighter strokes on smaller icons)
|
|
1904
|
+
- Reads size/stroke from IconContext (provided by Button, IconGroup, etc.); explicit props override context
|
|
1905
|
+
- `animate="draw"` works with IconCheck, IconX, and CircleCheck only — other icons fall back to static render
|
|
1906
|
+
- Respects `prefers-reduced-motion` — animations disabled when user prefers reduced motion
|
|
1907
|
+
|
|
1908
|
+
## Changes
|
|
1909
|
+
### v0.29.0
|
|
1910
|
+
- **Added** Initial release — context-aware Icon wrapper with size tiers, stroke weights, accessibility, animations, state machine
|
|
1911
|
+
- **Added** `animate="draw"` — SVG path-draw animation using `pathLength`. Draws check/X strokes progressively (0.35s easeOut). Respects `prefers-reduced-motion`.
|
|
1437
1912
|
# IconButton
|
|
1438
1913
|
|
|
1439
1914
|
- Import: @devalok/shilp-sutra/ui/icon-button
|
|
@@ -1441,12 +1916,12 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1441
1916
|
- Category: ui
|
|
1442
1917
|
|
|
1443
1918
|
## Props
|
|
1444
|
-
icon:
|
|
1919
|
+
icon: ReactElement (REQUIRED — use <Icon icon={...} />)
|
|
1445
1920
|
aria-label: string (REQUIRED — WCAG AA mandatory)
|
|
1446
1921
|
shape: "square" | "circle"
|
|
1447
1922
|
size: "sm" | "md" | "lg"
|
|
1448
|
-
variant: same as Button (solid, outline, ghost, link)
|
|
1449
|
-
color: same as Button (
|
|
1923
|
+
variant: same as Button (solid, soft, outline, ghost, link)
|
|
1924
|
+
color: same as Button (accent, error, success, warning, neutral)
|
|
1450
1925
|
loading: boolean
|
|
1451
1926
|
disabled: boolean
|
|
1452
1927
|
|
|
@@ -1456,17 +1931,98 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1456
1931
|
|
|
1457
1932
|
## Example
|
|
1458
1933
|
```jsx
|
|
1459
|
-
<IconButton icon={<IconEdit />} variant="ghost" aria-label="Edit item" />
|
|
1460
|
-
<IconButton icon={<IconX />} shape="circle" variant="ghost" size="sm" aria-label="Close" />
|
|
1934
|
+
<IconButton icon={<Icon icon={IconEdit} />} variant="ghost" aria-label="Edit item" />
|
|
1935
|
+
<IconButton icon={<Icon icon={IconX} />} shape="circle" variant="ghost" size="sm" aria-label="Close" />
|
|
1936
|
+
<IconButton icon={<Icon icon={IconTrash} />} variant="solid" color="error" aria-label="Delete" />
|
|
1461
1937
|
```
|
|
1462
1938
|
|
|
1463
1939
|
## Gotchas
|
|
1464
1940
|
- aria-label is enforced by TypeScript — you MUST provide it
|
|
1465
1941
|
- Prefer IconButton over Button with size="icon-*" for icon-only buttons
|
|
1942
|
+
- `icon` prop should use `<Icon icon={...} />` wrapper (auto-sized via Button's IconProvider)
|
|
1466
1943
|
|
|
1467
1944
|
## Changes
|
|
1945
|
+
### v0.29.0
|
|
1946
|
+
- **Changed** `icon` prop now expects `<Icon icon={...} />` wrapper (auto-sized via Button's IconProvider context)
|
|
1947
|
+
- **Changed** Inherits all new Button v2 colors: `accent`, `error`, `success`, `warning`, `neutral` (was `default`/`error` only)
|
|
1948
|
+
- **Changed** Inherits Button v2 variants including new `soft` variant
|
|
1949
|
+
|
|
1468
1950
|
### v0.1.0
|
|
1469
1951
|
- **Added** Initial release
|
|
1952
|
+
# IconContext
|
|
1953
|
+
|
|
1954
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
1955
|
+
- Server-safe: No
|
|
1956
|
+
- Category: ui
|
|
1957
|
+
|
|
1958
|
+
## Exports
|
|
1959
|
+
IconContext — React.Context<IconContextValue>
|
|
1960
|
+
IconProvider — Provider component (props: size?, stroke?, children)
|
|
1961
|
+
useIconContext() — Hook returning { size?, stroke? }
|
|
1962
|
+
IconSize — Type: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
|
1963
|
+
IconStroke — Type: "light" | "regular" | "bold"
|
|
1964
|
+
|
|
1965
|
+
## IconProvider Props
|
|
1966
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
|
1967
|
+
stroke: "light" | "regular" | "bold"
|
|
1968
|
+
children: ReactNode (REQUIRED)
|
|
1969
|
+
|
|
1970
|
+
## Example
|
|
1971
|
+
```jsx
|
|
1972
|
+
import { IconProvider, useIconContext } from '@devalok/shilp-sutra/ui'
|
|
1973
|
+
|
|
1974
|
+
<IconProvider size="sm" stroke="bold">
|
|
1975
|
+
<MyCustomIconComponent />
|
|
1976
|
+
</IconProvider>
|
|
1977
|
+
|
|
1978
|
+
// Inside MyCustomIconComponent:
|
|
1979
|
+
const { size, stroke } = useIconContext()
|
|
1980
|
+
```
|
|
1981
|
+
|
|
1982
|
+
## Gotchas
|
|
1983
|
+
- Used internally by IconGroup and Button to propagate icon sizing to children
|
|
1984
|
+
- If no provider is present, `useIconContext()` returns `{}` (empty object) — consumers should fall back to defaults
|
|
1985
|
+
- Value is memoized — safe for frequent re-renders
|
|
1986
|
+
|
|
1987
|
+
## Changes
|
|
1988
|
+
### v0.29.0
|
|
1989
|
+
- **Added** Initial release — React context for propagating icon size and stroke weight
|
|
1990
|
+
# IconGroup
|
|
1991
|
+
|
|
1992
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
1993
|
+
- Server-safe: No
|
|
1994
|
+
- Category: ui
|
|
1995
|
+
|
|
1996
|
+
## Props
|
|
1997
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" — propagated to children via IconContext
|
|
1998
|
+
stroke: "light" | "regular" | "bold" — propagated to children via IconContext
|
|
1999
|
+
gap: "tight" | "default" | "loose" — flex gap between icons
|
|
2000
|
+
label: string — accessible label (used as aria-label when role="toolbar")
|
|
2001
|
+
role: "toolbar" — optional, set for toolbar patterns
|
|
2002
|
+
className: string
|
|
2003
|
+
children: ReactNode (REQUIRED)
|
|
2004
|
+
|
|
2005
|
+
## Defaults
|
|
2006
|
+
gap: "default"
|
|
2007
|
+
role: undefined (no ARIA role)
|
|
2008
|
+
|
|
2009
|
+
## Example
|
|
2010
|
+
```jsx
|
|
2011
|
+
<IconGroup size="sm" gap="tight" role="toolbar" label="Formatting">
|
|
2012
|
+
<Icon icon={IconBold} label="Bold" />
|
|
2013
|
+
<Icon icon={IconItalic} label="Italic" />
|
|
2014
|
+
<Icon icon={IconUnderline} label="Underline" />
|
|
2015
|
+
</IconGroup>
|
|
2016
|
+
```
|
|
2017
|
+
|
|
2018
|
+
## Gotchas
|
|
2019
|
+
- Wraps children in an IconProvider — all child Icons inherit size/stroke from the group
|
|
2020
|
+
- `label` is only applied as `aria-label` when `role="toolbar"` is set
|
|
2021
|
+
- Gap values: tight=2px, default=4px, loose=8px
|
|
2022
|
+
|
|
2023
|
+
## Changes
|
|
2024
|
+
### v0.29.0
|
|
2025
|
+
- **Added** Initial release — icon grouping with shared context, toolbar ARIA support
|
|
1470
2026
|
# Input
|
|
1471
2027
|
|
|
1472
2028
|
- Import: @devalok/shilp-sutra/ui/input
|
|
@@ -1474,10 +2030,17 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1474
2030
|
- Category: ui
|
|
1475
2031
|
|
|
1476
2032
|
## Props
|
|
1477
|
-
size: "sm" | "md" | "lg"
|
|
2033
|
+
size: "xs" | "sm" | "md" | "lg"
|
|
1478
2034
|
state: InputState
|
|
1479
|
-
|
|
1480
|
-
|
|
2035
|
+
startSection: ReactNode (icon or content in the leading slot)
|
|
2036
|
+
endSection: ReactNode (icon or content in the trailing slot)
|
|
2037
|
+
startSectionClickable: boolean (enables pointer events on start section)
|
|
2038
|
+
endSectionClickable: boolean (enables pointer events on end section)
|
|
2039
|
+
startSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
|
|
2040
|
+
endSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
|
|
2041
|
+
wrapperClassName: string (classes for the wrapper div — border, bg, ring)
|
|
2042
|
+
startIcon: ReactNode (@deprecated — use startSection)
|
|
2043
|
+
endIcon: ReactNode (@deprecated — use endSection)
|
|
1481
2044
|
(plus all standard HTML input attributes except native "size")
|
|
1482
2045
|
|
|
1483
2046
|
## Types
|
|
@@ -1488,17 +2051,36 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1488
2051
|
|
|
1489
2052
|
## Example
|
|
1490
2053
|
```jsx
|
|
1491
|
-
<Input type="email" placeholder="you@example.com" state="error"
|
|
2054
|
+
<Input type="email" placeholder="you@example.com" state="error" startSection={<Icon icon={IconMail} />} />
|
|
2055
|
+
<Input size="xs" placeholder="Quick search" startSection={<Icon icon={IconSearch} />} />
|
|
2056
|
+
<Input startSection="https://" startSectionType="label" placeholder="example.com" />
|
|
2057
|
+
<Input endSection=".00" endSectionType="label" startSection={<Icon icon={IconCurrencyDollar} />} placeholder="0" />
|
|
1492
2058
|
```
|
|
1493
2059
|
|
|
1494
2060
|
## Gotchas
|
|
1495
2061
|
- HTML native "size" attribute is excluded — use CSS width instead
|
|
1496
2062
|
- state="error" sets aria-invalid automatically
|
|
1497
2063
|
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
|
|
1498
|
-
-
|
|
1499
|
-
-
|
|
2064
|
+
- `className` targets the `<input>` element; use `wrapperClassName` for border/bg/ring overrides
|
|
2065
|
+
- Focus ring is on the wrapper container (focus-within), not the input itself
|
|
2066
|
+
- Icons in startSection/endSection are auto-sized via IconProvider per input size
|
|
2067
|
+
- Sections are `pointer-events-none` by default — set `startSectionClickable`/`endSectionClickable` for interactive sections
|
|
2068
|
+
- Section type is auto-inferred: strings default to `'label'` (tinted bg + border), React elements default to `'icon'` (fixed-width centered). Override with `startSectionType`/`endSectionType`.
|
|
1500
2069
|
|
|
1501
2070
|
## Changes
|
|
2071
|
+
### v0.29.0
|
|
2072
|
+
- **Changed** v2 rewrite: container-first architecture with wrapper div holding focus ring
|
|
2073
|
+
- **Added** `xs` size (28px height)
|
|
2074
|
+
- **Added** `startSection` / `endSection` props replacing `startIcon` / `endIcon` (deprecated but still work)
|
|
2075
|
+
- **Added** `startSectionClickable` / `endSectionClickable` props for interactive sections
|
|
2076
|
+
- **Added** `wrapperClassName` prop for styling the wrapper div (border, bg, ring)
|
|
2077
|
+
- **Changed** Focus ring now on wrapper via `focus-within` (container-level ring, not input-level)
|
|
2078
|
+
- **Changed** Icons auto-sized via `IconProvider` context per input size
|
|
2079
|
+
- **Deprecated** `startIcon` / `endIcon` — use `startSection` / `endSection`
|
|
2080
|
+
- **Added** `startSectionType` / `endSectionType` props — `'icon'` (fixed-width centered cell) or `'label'` (tinted background with border separator). Auto-inferred from content type (strings → label, React elements → icon).
|
|
2081
|
+
- **Changed** Sections use flexbox layout for consistent alignment
|
|
2082
|
+
- **Deprecated** `inputVariants` export — use `inputWrapperVariants` (semantics changed to target wrapper)
|
|
2083
|
+
|
|
1502
2084
|
### v0.15.0
|
|
1503
2085
|
- **Changed** `lg` size font changed from `text-ds-lg` (18px) to `text-ds-md` (14px) — all input sizes now use 14px for consistency
|
|
1504
2086
|
- **Changed** `md` size font standardized to `text-ds-md` (14px) from mixed values
|
|
@@ -1835,6 +2417,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1835
2417
|
value: number (0-100) — omit for indeterminate
|
|
1836
2418
|
size: "sm" | "md" | "lg" (track height)
|
|
1837
2419
|
color: "default" | "success" | "warning" | "error" (indicator color)
|
|
2420
|
+
autoColor: boolean (auto-shifts color by value: 0-59=default, 60-84=warning, 85-100=success, >100=error)
|
|
1838
2421
|
showLabel: boolean (shows percentage text)
|
|
1839
2422
|
indicatorClassName: string
|
|
1840
2423
|
|
|
@@ -1850,8 +2433,12 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1850
2433
|
|
|
1851
2434
|
## Gotchas
|
|
1852
2435
|
- Omit value (or pass undefined) for indeterminate animation
|
|
2436
|
+
- `autoColor` overrides `color` when `value` is set — do not pass both unless you want autoColor to win
|
|
1853
2437
|
|
|
1854
2438
|
## Changes
|
|
2439
|
+
### v0.29.0
|
|
2440
|
+
- **Added** `autoColor` prop — automatically shifts indicator color based on value thresholds (0-59 default, 60-84 warning, 85-100 success, >100 error)
|
|
2441
|
+
|
|
1855
2442
|
### v0.1.0
|
|
1856
2443
|
- **Added** Initial release with `size`, `color`, `indeterminate` variants and optional label slot
|
|
1857
2444
|
# ProgressRing
|
|
@@ -2362,6 +2949,9 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2362
2949
|
- No longer server-safe as of v0.18.0 (uses Framer Motion)
|
|
2363
2950
|
|
|
2364
2951
|
## Changes
|
|
2952
|
+
### v0.29.0
|
|
2953
|
+
- **Changed** `bare` variant spinning state now uses `currentColor` instead of `var(--color-accent-9)` — inherits text color from parent for seamless embedding in buttons/toolbars
|
|
2954
|
+
|
|
2365
2955
|
### v0.18.0
|
|
2366
2956
|
- **Changed** (BREAKING) Complete rewrite with Framer Motion arc animation and state transitions
|
|
2367
2957
|
- **Added** `state` prop: 'spinning' | 'success' | 'error'
|
|
@@ -2565,16 +3155,29 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2565
3155
|
onCheckedChange: (checked: boolean) => void
|
|
2566
3156
|
error: boolean (shows red border/bg)
|
|
2567
3157
|
disabled: boolean
|
|
3158
|
+
size: "sm" | "md" | "lg"
|
|
3159
|
+
color: "accent" | "success" | "warning"
|
|
3160
|
+
thumbIcon: ReactNode (icon rendered inside the thumb)
|
|
3161
|
+
|
|
3162
|
+
## Defaults
|
|
3163
|
+
size="md", color="accent"
|
|
2568
3164
|
|
|
2569
3165
|
## Example
|
|
2570
3166
|
```jsx
|
|
2571
3167
|
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
|
3168
|
+
<Switch size="lg" color="success" thumbIcon={<IconCheck size={14} />} />
|
|
2572
3169
|
```
|
|
2573
3170
|
|
|
2574
3171
|
## Gotchas
|
|
2575
3172
|
- Use error prop for validation states (matches Checkbox API)
|
|
3173
|
+
- `error` overrides `color` — when error is true, checked state always uses error-9
|
|
2576
3174
|
|
|
2577
3175
|
## Changes
|
|
3176
|
+
### v0.29.0
|
|
3177
|
+
- **Added** `size` prop: `"sm"` (18px track) | `"md"` (24px, default) | `"lg"` (28px track)
|
|
3178
|
+
- **Added** `color` prop: `"accent"` (default) | `"success"` | `"warning"` for checked-state color
|
|
3179
|
+
- **Added** `thumbIcon` prop — renders any ReactNode inside the thumb circle (e.g., check icon)
|
|
3180
|
+
|
|
2578
3181
|
### v0.18.0
|
|
2579
3182
|
- **Changed** Migrated to Framer Motion spring thumb animation
|
|
2580
3183
|
- **Fixed** Added visible border on unchecked state (`border-surface-border-strong`) — was borderless, making unchecked state hard to see
|
|
@@ -3108,6 +3711,7 @@ export default function RootLayout({ children }) {
|
|
|
3108
3711
|
maxInitialItems: number — truncate with "Show all (N)" toggle
|
|
3109
3712
|
groupBy?: 'time' | 'none' — group items by time buckets (today, yesterday, this week, older)
|
|
3110
3713
|
groupLabels?: GroupLabels — custom labels for time groups: { today?, yesterday?, thisWeek?, older? }
|
|
3714
|
+
renderItem?: (item: ActivityItem, index: number) => ReactNode | undefined — custom renderer per item; return undefined to fall back to default ActivityEntry
|
|
3111
3715
|
|
|
3112
3716
|
## Defaults
|
|
3113
3717
|
loading=false, compact=false, hasMore=false, groupBy='none'
|
|
@@ -3135,8 +3739,14 @@ export default function RootLayout({ children }) {
|
|
|
3135
3739
|
- `maxInitialItems` truncates with a "Show all (N)" toggle button
|
|
3136
3740
|
- `maxInitialItems` applies to the flat list BEFORE grouping — items are sliced first, then grouped
|
|
3137
3741
|
- Empty time groups are automatically skipped
|
|
3742
|
+
- `renderItem` receives the item and index; return `undefined` to use the default ActivityEntry rendering
|
|
3743
|
+
- Custom `renderItem` content is wrapped in the same dot + layout container as default entries for consistent vertical rhythm
|
|
3138
3744
|
|
|
3139
3745
|
## Changes
|
|
3746
|
+
### v0.29.0
|
|
3747
|
+
- **Added** `renderItem` prop — custom render function per item; return ReactNode for custom rendering, return `undefined` to fall back to default ActivityEntry
|
|
3748
|
+
- **Added** Internal `CustomEntry` wrapper that keeps dot + layout consistent with default entries
|
|
3749
|
+
|
|
3140
3750
|
### v0.20.0
|
|
3141
3751
|
- **Added** `groupBy="time"` prop — groups items into Today, Yesterday, This Week, Older with section headers
|
|
3142
3752
|
- **Added** `groupLabels` prop for custom group label text
|
|
@@ -3158,7 +3768,7 @@ export default function RootLayout({ children }) {
|
|
|
3158
3768
|
max: number (default: 4, overflow shows "+N" badge)
|
|
3159
3769
|
size: "xs" | "sm" | "md" | "lg" | "xl"
|
|
3160
3770
|
showTooltip: boolean (default: true)
|
|
3161
|
-
borderColor: "surface-
|
|
3771
|
+
borderColor: "surface-base" | "surface-raised" (default: "surface-raised") — overlap border color
|
|
3162
3772
|
onOverflowClick: () => void — makes the "+N" badge interactive (button)
|
|
3163
3773
|
renderAvatar: (user: AvatarUser, index: number) => ReactNode — custom avatar render
|
|
3164
3774
|
expandDirection: "left" | "right" (default: "right") — direction group expands on hover
|
|
@@ -3168,9 +3778,10 @@ export default function RootLayout({ children }) {
|
|
|
3168
3778
|
name: string (REQUIRED)
|
|
3169
3779
|
image?: string | null
|
|
3170
3780
|
ring?: "none" | "lead" | "admin" | "client" — role ring per user in group
|
|
3781
|
+
indicator?: "lead" | "admin" | ReactNode — small dot indicator at top-right of avatar
|
|
3171
3782
|
|
|
3172
3783
|
## Defaults
|
|
3173
|
-
size="md", max=4, showTooltip=true, borderColor="surface-
|
|
3784
|
+
size="md", max=4, showTooltip=true, borderColor="surface-raised", expandDirection="right", expandAmount="default"
|
|
3174
3785
|
|
|
3175
3786
|
## Example
|
|
3176
3787
|
```jsx
|
|
@@ -3181,7 +3792,7 @@ export default function RootLayout({ children }) {
|
|
|
3181
3792
|
]}
|
|
3182
3793
|
max={3}
|
|
3183
3794
|
size="md"
|
|
3184
|
-
borderColor="surface-
|
|
3795
|
+
borderColor="surface-base"
|
|
3185
3796
|
onOverflowClick={() => setShowAll(true)}
|
|
3186
3797
|
/>
|
|
3187
3798
|
```
|
|
@@ -3191,10 +3802,13 @@ export default function RootLayout({ children }) {
|
|
|
3191
3802
|
- Users beyond `max` are collapsed into a "+N" overflow badge
|
|
3192
3803
|
- Missing `image` falls back to initials derived from `name`
|
|
3193
3804
|
- Hover expand animation uses CSS `group-hover` — parent must not clip overflow
|
|
3194
|
-
- `borderColor` should match the surface
|
|
3805
|
+
- `borderColor` should match the surface the group sits on (`surface-base` on page bg, `surface-raised` on cards)
|
|
3195
3806
|
- `renderAvatar` wrapper is positioning-only — pass `size` directly to your Avatar (do NOT use `className="h-full w-full"`)
|
|
3196
3807
|
|
|
3197
3808
|
## Changes
|
|
3809
|
+
### v0.29.0
|
|
3810
|
+
- **Added** `indicator` prop on AvatarUser: `"lead"` (warning dot) | `"admin"` (accent dot) | ReactNode (custom indicator) — animated dot at the top-right corner of each avatar
|
|
3811
|
+
|
|
3198
3812
|
### v0.22.3
|
|
3199
3813
|
- **Fixed** `renderAvatar` wrapper no longer clips consumer Avatar content (removed overflow-hidden, border, and size classes from wrapper)
|
|
3200
3814
|
- **Fixed** Removed redundant text-size classes from wrapper — Avatar handles font scaling internally
|
|
@@ -3203,7 +3817,6 @@ export default function RootLayout({ children }) {
|
|
|
3203
3817
|
- **Added** `xs` and `xl` size variants
|
|
3204
3818
|
- **Added** `borderColor` prop for overlap border matching surface context
|
|
3205
3819
|
- **Added** `onOverflowClick` prop making the overflow badge an interactive button
|
|
3206
|
-
- **Added** `overflowContent` prop for popover content on overflow click
|
|
3207
3820
|
- **Added** `renderAvatar` prop for custom per-avatar rendering
|
|
3208
3821
|
- **Added** `AvatarUser.ring` field for per-user role rings in groups
|
|
3209
3822
|
|
|
@@ -4225,8 +4838,11 @@ Exports: RichTextEditor, RichTextViewer
|
|
|
4225
4838
|
onFileUpload?: (file: File) => Promise<{ url: string; name: string; size: number }> — enables file attachments
|
|
4226
4839
|
mentions?: MentionItem[] — static list for @mention autocomplete
|
|
4227
4840
|
onMentionSearch?: (query: string) => Promise<MentionItem[]> — async search, takes precedence over static mentions
|
|
4841
|
+
toolbar?: ToolbarItem[] — whitelist of toolbar items to show. Omit to show all.
|
|
4228
4842
|
onMentionSelect?: (item: MentionItem) => void — called when a mention is selected
|
|
4229
4843
|
|
|
4844
|
+
ToolbarItem: 'bold' | 'italic' | 'underline' | 'strike' | 'highlight' | 'h2' | 'h3' | 'blockquote' | 'bulletList' | 'orderedList' | 'taskList' | 'codeBlock' | 'link' | 'image' | 'file' | 'hr' | 'alignLeft' | 'alignCenter' | 'alignRight' | 'emoji' | 'undo' | 'redo'
|
|
4845
|
+
|
|
4230
4846
|
MentionItem: { id: string; label: string; avatar?: string }
|
|
4231
4847
|
|
|
4232
4848
|
### RichTextViewer
|
|
@@ -4259,6 +4875,9 @@ MentionItem: { id: string; label: string; avatar?: string }
|
|
|
4259
4875
|
- Features: bold, italic, underline, strikethrough, highlight, headings, blockquote, lists, task lists, code, links, images, file attachments, mentions, emoji, text alignment, horizontal rule
|
|
4260
4876
|
|
|
4261
4877
|
## Changes
|
|
4878
|
+
### v0.30.0
|
|
4879
|
+
- **Added** `toolbar` prop — whitelist of `ToolbarItem` names to control which toolbar buttons appear. Dividers render only between groups that have visible items. `ToolbarItem` type exported from barrel.
|
|
4880
|
+
|
|
4262
4881
|
### v0.18.0
|
|
4263
4882
|
- **Fixed** Use ref to track internal changes, prevent update loop
|
|
4264
4883
|
|
|
@@ -4357,11 +4976,13 @@ Event colors: "primary" | "success" | "warning" | "error" | "info" | "neutral"
|
|
|
4357
4976
|
Note: StatusBadge was server-safe prior to v0.18.0 but is NO LONGER server-safe due to Framer Motion dependency.
|
|
4358
4977
|
|
|
4359
4978
|
## Props
|
|
4360
|
-
status: "active" | "pending" | "approved" | "rejected" | "completed" | "blocked" | "cancelled" | "draft"
|
|
4979
|
+
status: "active" | "pending" | "approved" | "rejected" | "completed" | "blocked" | "in-progress" | "review" | "cancelled" | "draft"
|
|
4361
4980
|
color: "success" | "warning" | "error" | "info" | "neutral" (overrides status styling when set)
|
|
4362
4981
|
size: "sm" | "md"
|
|
4363
4982
|
label: string (auto-derived from status/color if omitted)
|
|
4364
4983
|
hideDot: boolean (default: false)
|
|
4984
|
+
onClick: () => void (makes badge clickable — renders as button with chevron)
|
|
4985
|
+
icon: ReactNode (custom trailing icon — replaces default chevron when clickable)
|
|
4365
4986
|
|
|
4366
4987
|
## Defaults
|
|
4367
4988
|
size="md", hideDot=false
|
|
@@ -4370,15 +4991,26 @@ Note: StatusBadge was server-safe prior to v0.18.0 but is NO LONGER server-safe
|
|
|
4370
4991
|
## Example
|
|
4371
4992
|
```jsx
|
|
4372
4993
|
<StatusBadge status="active" />
|
|
4994
|
+
<StatusBadge status="in-progress" />
|
|
4995
|
+
<StatusBadge status="review" label="Needs Review" />
|
|
4373
4996
|
<StatusBadge color="warning" label="In Review" size="sm" />
|
|
4997
|
+
<StatusBadge status="active" onClick={() => openStatusPicker()} />
|
|
4374
4998
|
```
|
|
4375
4999
|
|
|
4376
5000
|
## Gotchas
|
|
4377
5001
|
- When `color` is set, it takes priority over `status` for styling
|
|
4378
5002
|
- Props use a discriminated union — pass either `status` or `color`, not both
|
|
4379
5003
|
- As of v0.18.0, StatusBadge is NOT server-safe (Framer Motion dependency)
|
|
5004
|
+
- When `onClick` is provided, badge renders as a `<button>` with a trailing chevron icon
|
|
5005
|
+
- Pass `icon` to replace the default chevron with a custom trailing icon
|
|
4380
5006
|
|
|
4381
5007
|
## Changes
|
|
5008
|
+
### v0.29.0
|
|
5009
|
+
- **Added** `in-progress` status (accent/blue styling)
|
|
5010
|
+
- **Added** `review` status (info styling)
|
|
5011
|
+
- **Added** `onClick` prop — renders as a `<button>` with trailing chevron and hover opacity
|
|
5012
|
+
- **Added** `icon` prop — custom trailing icon (replaces the default chevron when clickable)
|
|
5013
|
+
|
|
4382
5014
|
### v0.18.0
|
|
4383
5015
|
- **Changed** No longer server-safe due to Framer Motion dependency
|
|
4384
5016
|
|