@devalok/shilp-sutra 0.28.0 → 0.29.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 +91 -67
- 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.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 +31 -37
- 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.map +1 -1
- package/dist/composed/rich-text-editor.js +287 -306
- 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 +10 -0
- package/dist/tokens/semantic.css +70 -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 +15 -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 +1 -1
- 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/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 +666 -40
- package/llms.txt +37 -18
- package/package.json +7 -2
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Chat
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui/chat
|
|
4
|
+
- Server-safe: No (MessageList, Message, MessageInput, TypingIndicator use Framer Motion); DateSeparator and UnreadSeparator are server-safe
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
Seven primitives for building chat interfaces: MessageList, Message (compound), SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## MessageList
|
|
12
|
+
|
|
13
|
+
Scrollable container with auto-scroll, load-more, empty state, and "N new" floating pill.
|
|
14
|
+
|
|
15
|
+
### Props
|
|
16
|
+
autoScroll: boolean — auto-scroll to bottom on new content (default: true)
|
|
17
|
+
newMessageCount: number — count shown in floating pill (default: 0)
|
|
18
|
+
onScrollToBottom: () => void — called when user clicks the "N new" pill
|
|
19
|
+
onLoadMore: () => void — called when user scrolls near top
|
|
20
|
+
isLoadingMore: boolean — shows spinner at top (default: false)
|
|
21
|
+
emptySlot: ReactNode — content when there are no children
|
|
22
|
+
headerSlot: ReactNode — content above the scroll container (e.g. channel name)
|
|
23
|
+
scrollToBottomSlot: ReactNode — reserved slot for custom scroll-to-bottom button
|
|
24
|
+
children: ReactNode (REQUIRED)
|
|
25
|
+
|
|
26
|
+
### Example
|
|
27
|
+
```jsx
|
|
28
|
+
<MessageList autoScroll onLoadMore={loadMore} isLoadingMore={loading} newMessageCount={3} onScrollToBottom={markRead}>
|
|
29
|
+
{messages.map(m => <Message key={m.id}>...</Message>)}
|
|
30
|
+
</MessageList>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Message (Compound)
|
|
36
|
+
|
|
37
|
+
Compound component: `Message`, `Message.Avatar`, `Message.Content`, `Message.Author`, `Message.Body`, `Message.EditableBody`, `Message.Reactions`, `Message.Actions`, `Message.Action`.
|
|
38
|
+
|
|
39
|
+
### Message (root) Props
|
|
40
|
+
variant: "flat" | "bubble" (default: "flat")
|
|
41
|
+
placement: "start" | "end" (default: "start")
|
|
42
|
+
highlight: "mention" | "internal"
|
|
43
|
+
grouped: boolean — hides avatar/author for consecutive messages (default: false)
|
|
44
|
+
deleted: boolean — renders deleted placeholder (default: false)
|
|
45
|
+
deletedText: string (default: "This message was deleted")
|
|
46
|
+
|
|
47
|
+
### Message.Avatar Props
|
|
48
|
+
src: string | null — avatar image URL
|
|
49
|
+
fallback: string — initials text
|
|
50
|
+
icon: ReactNode — custom icon instead of avatar
|
|
51
|
+
size: "sm" | "md" (default: "md")
|
|
52
|
+
children: ReactNode — fully custom avatar slot
|
|
53
|
+
|
|
54
|
+
### Message.Author Props
|
|
55
|
+
name: string (REQUIRED)
|
|
56
|
+
badge: ReactNode
|
|
57
|
+
timestamp: Date
|
|
58
|
+
formattedTimestamp: string — pre-formatted timestamp (overrides timestamp)
|
|
59
|
+
timestampFormat: (date: Date) => string — custom formatter
|
|
60
|
+
|
|
61
|
+
### Message.Body Props
|
|
62
|
+
children: ReactNode (REQUIRED)
|
|
63
|
+
|
|
64
|
+
### Message.EditableBody Props
|
|
65
|
+
content: string (REQUIRED)
|
|
66
|
+
onSave: (newContent: string) => void (REQUIRED)
|
|
67
|
+
onCancel: () => void
|
|
68
|
+
canEdit: boolean (default: false)
|
|
69
|
+
renderContent: (content: string) => ReactNode — custom render for display mode
|
|
70
|
+
|
|
71
|
+
### Message.Reactions Props
|
|
72
|
+
reactions: { emoji: string; count: number; reacted: boolean }[] (REQUIRED)
|
|
73
|
+
onReact: (emoji: string) => void (REQUIRED)
|
|
74
|
+
|
|
75
|
+
### Message.Content Props
|
|
76
|
+
children: ReactNode (REQUIRED)
|
|
77
|
+
className: string
|
|
78
|
+
|
|
79
|
+
### Message.Actions Props
|
|
80
|
+
children: ReactNode (REQUIRED)
|
|
81
|
+
delay: number — hover reveal delay in ms (default: 100)
|
|
82
|
+
|
|
83
|
+
### Message.Action Props
|
|
84
|
+
icon: IconProps["icon"] (REQUIRED) — pass the Tabler component reference, e.g. `IconReply` (not `<IconReply />`)
|
|
85
|
+
label: string (REQUIRED)
|
|
86
|
+
onClick: () => void (REQUIRED)
|
|
87
|
+
variant: "default" | "danger" (default: "default")
|
|
88
|
+
|
|
89
|
+
### Example
|
|
90
|
+
```jsx
|
|
91
|
+
<Message variant="flat" highlight="mention">
|
|
92
|
+
<Message.Avatar src={user.photo} fallback="JD" />
|
|
93
|
+
<Message.Content>
|
|
94
|
+
<Message.Author name="Jane Doe" timestamp={new Date()} badge={<Badge>Admin</Badge>} />
|
|
95
|
+
<Message.Body>Hello, world!</Message.Body>
|
|
96
|
+
<Message.Reactions reactions={reactions} onReact={handleReact} />
|
|
97
|
+
<Message.Actions>
|
|
98
|
+
<Message.Action icon={IconReply} label="Reply" onClick={handleReply} />
|
|
99
|
+
<Message.Action icon={IconTrash} label="Delete" onClick={handleDelete} variant="danger" />
|
|
100
|
+
</Message.Actions>
|
|
101
|
+
</Message.Content>
|
|
102
|
+
</Message>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## SystemMessage
|
|
108
|
+
|
|
109
|
+
Inline system event or alert message (e.g. "Alice joined the channel").
|
|
110
|
+
|
|
111
|
+
### Props
|
|
112
|
+
icon: ReactNode — custom icon
|
|
113
|
+
timestamp: string — ISO timestamp string
|
|
114
|
+
variant: "event" | "alert" (default: "event")
|
|
115
|
+
children: ReactNode (REQUIRED)
|
|
116
|
+
|
|
117
|
+
### Example
|
|
118
|
+
```jsx
|
|
119
|
+
<SystemMessage>Alice joined the channel</SystemMessage>
|
|
120
|
+
<SystemMessage variant="alert" timestamp="2026-03-26T10:00:00Z">Connection lost</SystemMessage>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## MessageInput
|
|
126
|
+
|
|
127
|
+
Auto-resizing textarea with send/stop buttons, streaming support, and slot-based extensibility.
|
|
128
|
+
|
|
129
|
+
### Props
|
|
130
|
+
onSubmit: (text: string) => void (REQUIRED)
|
|
131
|
+
placeholder: string (default: "Type a message...")
|
|
132
|
+
disabled: boolean (default: false)
|
|
133
|
+
isStreaming: boolean — shows stop button instead of send (default: false)
|
|
134
|
+
onCancel: () => void — called when stop button is clicked
|
|
135
|
+
leadingSlot: ReactNode — content before the textarea (e.g. attachment button)
|
|
136
|
+
trailingSlot: ReactNode — content after the send button
|
|
137
|
+
disclaimer: string — centered text below the input (e.g. "AI can make mistakes")
|
|
138
|
+
sendIcon: ReactNode — custom send icon
|
|
139
|
+
|
|
140
|
+
### Example
|
|
141
|
+
```jsx
|
|
142
|
+
<MessageInput
|
|
143
|
+
onSubmit={handleSend}
|
|
144
|
+
isStreaming={streaming}
|
|
145
|
+
onCancel={handleStop}
|
|
146
|
+
disclaimer="AI can make mistakes"
|
|
147
|
+
/>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## DateSeparator
|
|
153
|
+
|
|
154
|
+
Horizontal rule with a formatted date label.
|
|
155
|
+
|
|
156
|
+
### Props
|
|
157
|
+
date: Date | string (REQUIRED)
|
|
158
|
+
format: (date: Date) => string — custom date formatter
|
|
159
|
+
className: string
|
|
160
|
+
|
|
161
|
+
### Example
|
|
162
|
+
```jsx
|
|
163
|
+
<DateSeparator date={new Date()} />
|
|
164
|
+
<DateSeparator date="2026-03-25" format={(d) => d.toLocaleDateString()} />
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## UnreadSeparator
|
|
170
|
+
|
|
171
|
+
Accent-colored horizontal rule marking the unread boundary.
|
|
172
|
+
|
|
173
|
+
### Props
|
|
174
|
+
label: string (default: "NEW")
|
|
175
|
+
count: number — prepended to label (e.g. "5 NEW")
|
|
176
|
+
className: string
|
|
177
|
+
|
|
178
|
+
### Example
|
|
179
|
+
```jsx
|
|
180
|
+
<UnreadSeparator />
|
|
181
|
+
<UnreadSeparator count={5} />
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## TypingIndicator
|
|
187
|
+
|
|
188
|
+
Animated bouncing dots with a text description of who is typing.
|
|
189
|
+
|
|
190
|
+
### Props
|
|
191
|
+
users: { name: string; image?: string }[] (REQUIRED)
|
|
192
|
+
className: string
|
|
193
|
+
|
|
194
|
+
### Example
|
|
195
|
+
```jsx
|
|
196
|
+
<TypingIndicator users={[{ name: 'Alice' }]} />
|
|
197
|
+
<TypingIndicator users={[{ name: 'Alice' }, { name: 'Bob' }]} />
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Gotchas
|
|
203
|
+
- MessageList uses `role="log"` with `aria-live="polite"` — screen readers announce new messages
|
|
204
|
+
- Message entrance animations use Framer Motion springs — AnimatePresence wraps children in MessageList
|
|
205
|
+
- `grouped` hides avatar and author — use for consecutive messages from the same user
|
|
206
|
+
- MessageInput sends on Enter (Shift+Enter for newline) — textarea auto-resizes up to 160px
|
|
207
|
+
- TypingIndicator renders nothing when `users` is empty
|
|
208
|
+
- 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.
|
|
209
|
+
- Message.Content is the flex column wrapper for Author + Body — required for proper layout in flat variant
|
|
210
|
+
- DateSeparator's default formatter shows "Today", "Yesterday", or "Mon DD" / "Mon DD, YYYY"
|
|
211
|
+
|
|
212
|
+
## Changes
|
|
213
|
+
### v0.29.0
|
|
214
|
+
- **Added** Initial release — 7 chat primitives (MessageList, Message, SystemMessage, MessageInput, DateSeparator, UnreadSeparator, TypingIndicator)
|
|
@@ -65,6 +65,9 @@ import { DataTable } from '@devalok/shilp-sutra/ui/data-table'
|
|
|
65
65
|
- Use defaultDensity="compact" for Karm-style h-9 rows
|
|
66
66
|
|
|
67
67
|
## Changes
|
|
68
|
+
### v0.29.0
|
|
69
|
+
- **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`.
|
|
70
|
+
|
|
68
71
|
### v0.16.1
|
|
69
72
|
- **Fixed** `serverPagination` object reference in `useCallback` dependency caused stale closure — now uses stable ref for `onPageChange`
|
|
70
73
|
- **Fixed** `onSelectionChange` effect fired every render due to `table` in dependency array — now derives selected rows directly
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# DevalokGrain
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui/devalok-grain
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
intensity: "subtle" | "medium" | "heavy" — grain intensity level
|
|
9
|
+
surface: "solid" | "soft" — affects noise opacity ('solid' for filled backgrounds, 'soft' for tinted/muted)
|
|
10
|
+
sheen: boolean — inner highlight (top-lit emboss) for premium 3D feel
|
|
11
|
+
animated: boolean — fade-in entrance animation on mount
|
|
12
|
+
hoverIntensify: boolean — increase grain visibility on parent hover (requires parent `group` class)
|
|
13
|
+
tint: string — CSS color for the directional gradient (e.g. "oklch(0.55 0.19 360)", "var(--color-accent-9)")
|
|
14
|
+
|
|
15
|
+
## Defaults
|
|
16
|
+
intensity: "subtle"
|
|
17
|
+
surface: "solid"
|
|
18
|
+
sheen: false
|
|
19
|
+
animated: false
|
|
20
|
+
hoverIntensify: false
|
|
21
|
+
tint: undefined (no gradient, noise texture only)
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
```jsx
|
|
25
|
+
{/* Inside a Button (Button already has relative/overflow-hidden/isolate): */}
|
|
26
|
+
<Button>
|
|
27
|
+
<DevalokGrain />
|
|
28
|
+
Save changes
|
|
29
|
+
</Button>
|
|
30
|
+
|
|
31
|
+
{/* Inside a Card: */}
|
|
32
|
+
<Card className="relative overflow-hidden isolate">
|
|
33
|
+
<DevalokGrain surface="soft" />
|
|
34
|
+
Card content
|
|
35
|
+
</Card>
|
|
36
|
+
|
|
37
|
+
{/* Heavy grain with tint on a hero section: */}
|
|
38
|
+
<div className="relative overflow-hidden isolate rounded-ds-lg bg-accent-9 p-8">
|
|
39
|
+
<DevalokGrain intensity="heavy" tint="oklch(0.55 0.19 360)" />
|
|
40
|
+
<h1 className="relative z-[2]">Hero</h1>
|
|
41
|
+
</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Gotchas
|
|
45
|
+
- Parent element MUST have `relative overflow-hidden isolate` for the grain to render correctly
|
|
46
|
+
- The grain layers are absolute-positioned at `z-[1]` — content that should appear above must use `z-[2]` or higher
|
|
47
|
+
- Uses `rounded-[inherit]` to match parent border-radius automatically
|
|
48
|
+
- Renders `aria-hidden="true"` — purely decorative
|
|
49
|
+
- Without `tint`, only the noise texture renders (no directional gradient)
|
|
50
|
+
- `hoverIntensify` requires the parent to have a `group` class for `group-hover:` to work
|
|
51
|
+
- Respects `prefers-reduced-motion` — entrance animation disabled when user prefers reduced motion
|
|
52
|
+
|
|
53
|
+
## Changes
|
|
54
|
+
### v0.29.0
|
|
55
|
+
- **Added** Initial release — brand noise texture with directional gradient, sheen, animation, and hover intensification
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
- Category: ui
|
|
6
6
|
|
|
7
7
|
## Props
|
|
8
|
-
icon:
|
|
8
|
+
icon: ReactElement (REQUIRED — use <Icon icon={...} />)
|
|
9
9
|
aria-label: string (REQUIRED — WCAG AA mandatory)
|
|
10
10
|
shape: "square" | "circle"
|
|
11
11
|
size: "sm" | "md" | "lg"
|
|
12
|
-
variant: same as Button (solid, outline, ghost, link)
|
|
13
|
-
color: same as Button (
|
|
12
|
+
variant: same as Button (solid, soft, outline, ghost, link)
|
|
13
|
+
color: same as Button (accent, error, success, warning, neutral)
|
|
14
14
|
loading: boolean
|
|
15
15
|
disabled: boolean
|
|
16
16
|
|
|
@@ -20,14 +20,21 @@
|
|
|
20
20
|
|
|
21
21
|
## Example
|
|
22
22
|
```jsx
|
|
23
|
-
<IconButton icon={<IconEdit />} variant="ghost" aria-label="Edit item" />
|
|
24
|
-
<IconButton icon={<IconX />} shape="circle" variant="ghost" size="sm" aria-label="Close" />
|
|
23
|
+
<IconButton icon={<Icon icon={IconEdit} />} variant="ghost" aria-label="Edit item" />
|
|
24
|
+
<IconButton icon={<Icon icon={IconX} />} shape="circle" variant="ghost" size="sm" aria-label="Close" />
|
|
25
|
+
<IconButton icon={<Icon icon={IconTrash} />} variant="solid" color="error" aria-label="Delete" />
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
## Gotchas
|
|
28
29
|
- aria-label is enforced by TypeScript — you MUST provide it
|
|
29
30
|
- Prefer IconButton over Button with size="icon-*" for icon-only buttons
|
|
31
|
+
- `icon` prop should use `<Icon icon={...} />` wrapper (auto-sized via Button's IconProvider)
|
|
30
32
|
|
|
31
33
|
## Changes
|
|
34
|
+
### v0.29.0
|
|
35
|
+
- **Changed** `icon` prop now expects `<Icon icon={...} />` wrapper (auto-sized via Button's IconProvider context)
|
|
36
|
+
- **Changed** Inherits all new Button v2 colors: `accent`, `error`, `success`, `warning`, `neutral` (was `default`/`error` only)
|
|
37
|
+
- **Changed** Inherits Button v2 variants including new `soft` variant
|
|
38
|
+
|
|
32
39
|
### v0.1.0
|
|
33
40
|
- **Added** Initial release
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# IconContext
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
## Exports
|
|
8
|
+
IconContext — React.Context<IconContextValue>
|
|
9
|
+
IconProvider — Provider component (props: size?, stroke?, children)
|
|
10
|
+
useIconContext() — Hook returning { size?, stroke? }
|
|
11
|
+
IconSize — Type: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
|
12
|
+
IconStroke — Type: "light" | "regular" | "bold"
|
|
13
|
+
|
|
14
|
+
## IconProvider Props
|
|
15
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"
|
|
16
|
+
stroke: "light" | "regular" | "bold"
|
|
17
|
+
children: ReactNode (REQUIRED)
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
```jsx
|
|
21
|
+
import { IconProvider, useIconContext } from '@devalok/shilp-sutra/ui'
|
|
22
|
+
|
|
23
|
+
<IconProvider size="sm" stroke="bold">
|
|
24
|
+
<MyCustomIconComponent />
|
|
25
|
+
</IconProvider>
|
|
26
|
+
|
|
27
|
+
// Inside MyCustomIconComponent:
|
|
28
|
+
const { size, stroke } = useIconContext()
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Gotchas
|
|
32
|
+
- Used internally by IconGroup and Button to propagate icon sizing to children
|
|
33
|
+
- If no provider is present, `useIconContext()` returns `{}` (empty object) — consumers should fall back to defaults
|
|
34
|
+
- Value is memoized — safe for frequent re-renders
|
|
35
|
+
|
|
36
|
+
## Changes
|
|
37
|
+
### v0.29.0
|
|
38
|
+
- **Added** Initial release — React context for propagating icon size and stroke weight
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# IconGroup
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" — propagated to children via IconContext
|
|
9
|
+
stroke: "light" | "regular" | "bold" — propagated to children via IconContext
|
|
10
|
+
gap: "tight" | "default" | "loose" — flex gap between icons
|
|
11
|
+
label: string — accessible label (used as aria-label when role="toolbar")
|
|
12
|
+
role: "toolbar" — optional, set for toolbar patterns
|
|
13
|
+
className: string
|
|
14
|
+
children: ReactNode (REQUIRED)
|
|
15
|
+
|
|
16
|
+
## Defaults
|
|
17
|
+
gap: "default"
|
|
18
|
+
role: undefined (no ARIA role)
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
```jsx
|
|
22
|
+
<IconGroup size="sm" gap="tight" role="toolbar" label="Formatting">
|
|
23
|
+
<Icon icon={IconBold} label="Bold" />
|
|
24
|
+
<Icon icon={IconItalic} label="Italic" />
|
|
25
|
+
<Icon icon={IconUnderline} label="Underline" />
|
|
26
|
+
</IconGroup>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Gotchas
|
|
30
|
+
- Wraps children in an IconProvider — all child Icons inherit size/stroke from the group
|
|
31
|
+
- `label` is only applied as `aria-label` when `role="toolbar"` is set
|
|
32
|
+
- Gap values: tight=2px, default=4px, loose=8px
|
|
33
|
+
|
|
34
|
+
## Changes
|
|
35
|
+
### v0.29.0
|
|
36
|
+
- **Added** Initial release — icon grouping with shared context, toolbar ARIA support
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Icon
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra/ui (barrel export)
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: ui
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
icon: ForwardRefExoticComponent (REQUIRED — Tabler icon or any ForwardRef SVG icon component)
|
|
9
|
+
size: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" — reads from IconContext if not set
|
|
10
|
+
stroke: "light" | "regular" | "bold" — reads from IconContext if not set
|
|
11
|
+
label: string — accessible label (renders <title> + sets aria-label; without it, icon is aria-hidden)
|
|
12
|
+
animate: "spin" | "pulse" | "bounce" | "draw" | "none" | { rotate?: number; scale?: number }
|
|
13
|
+
state: "idle" | "loading" | "success" | "error" — delegates to Spinner (bare variant)
|
|
14
|
+
className: string
|
|
15
|
+
|
|
16
|
+
## Defaults
|
|
17
|
+
size: "md" (from context or fallback)
|
|
18
|
+
stroke: "regular" (from context or fallback)
|
|
19
|
+
state: undefined (no state machine)
|
|
20
|
+
animate: undefined (static render)
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
```jsx
|
|
24
|
+
<Icon icon={IconPlus} />
|
|
25
|
+
<Icon icon={IconPlus} size="xs" stroke="light" />
|
|
26
|
+
<Icon icon={IconPlus} label="Add item" />
|
|
27
|
+
<Icon icon={IconPlus} animate="spin" />
|
|
28
|
+
<Icon icon={IconCheck} animate="draw" />
|
|
29
|
+
<Icon icon={IconPlus} state="loading" />
|
|
30
|
+
<Icon icon={IconPlus} state="success" />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Gotchas
|
|
34
|
+
- Without `label`, the icon renders `aria-hidden="true"` (decorative)
|
|
35
|
+
- With `label`, the icon renders `role="img"` with `aria-label` and a `<title>` element
|
|
36
|
+
- **Priority rule:** If both `state` and `animate` are set, `state` wins
|
|
37
|
+
- `state="loading"` renders a bare Spinner; `state="success"` / `state="error"` render animated checkmark/cross
|
|
38
|
+
- Size tiers map to pixel values: xs=14, sm=16, md=18, lg=20, xl=24, 2xl=32
|
|
39
|
+
- Stroke weight varies by size tier (lighter strokes on smaller icons)
|
|
40
|
+
- Reads size/stroke from IconContext (provided by Button, IconGroup, etc.); explicit props override context
|
|
41
|
+
- `animate="draw"` works with IconCheck, IconX, and CircleCheck only — other icons fall back to static render
|
|
42
|
+
- Respects `prefers-reduced-motion` — animations disabled when user prefers reduced motion
|
|
43
|
+
|
|
44
|
+
## Changes
|
|
45
|
+
### v0.29.0
|
|
46
|
+
- **Added** Initial release — context-aware Icon wrapper with size tiers, stroke weights, accessibility, animations, state machine
|
|
47
|
+
- **Added** `animate="draw"` — SVG path-draw animation using `pathLength`. Draws check/X strokes progressively (0.35s easeOut). Respects `prefers-reduced-motion`.
|
|
@@ -5,10 +5,17 @@
|
|
|
5
5
|
- Category: ui
|
|
6
6
|
|
|
7
7
|
## Props
|
|
8
|
-
size: "sm" | "md" | "lg"
|
|
8
|
+
size: "xs" | "sm" | "md" | "lg"
|
|
9
9
|
state: InputState
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
startSection: ReactNode (icon or content in the leading slot)
|
|
11
|
+
endSection: ReactNode (icon or content in the trailing slot)
|
|
12
|
+
startSectionClickable: boolean (enables pointer events on start section)
|
|
13
|
+
endSectionClickable: boolean (enables pointer events on end section)
|
|
14
|
+
startSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
|
|
15
|
+
endSectionType: 'icon' | 'label' (section display type — auto-inferred from content)
|
|
16
|
+
wrapperClassName: string (classes for the wrapper div — border, bg, ring)
|
|
17
|
+
startIcon: ReactNode (@deprecated — use startSection)
|
|
18
|
+
endIcon: ReactNode (@deprecated — use endSection)
|
|
12
19
|
(plus all standard HTML input attributes except native "size")
|
|
13
20
|
|
|
14
21
|
## Types
|
|
@@ -19,17 +26,36 @@
|
|
|
19
26
|
|
|
20
27
|
## Example
|
|
21
28
|
```jsx
|
|
22
|
-
<Input type="email" placeholder="you@example.com" state="error"
|
|
29
|
+
<Input type="email" placeholder="you@example.com" state="error" startSection={<Icon icon={IconMail} />} />
|
|
30
|
+
<Input size="xs" placeholder="Quick search" startSection={<Icon icon={IconSearch} />} />
|
|
31
|
+
<Input startSection="https://" startSectionType="label" placeholder="example.com" />
|
|
32
|
+
<Input endSection=".00" endSectionType="label" startSection={<Icon icon={IconCurrencyDollar} />} placeholder="0" />
|
|
23
33
|
```
|
|
24
34
|
|
|
25
35
|
## Gotchas
|
|
26
36
|
- HTML native "size" attribute is excluded — use CSS width instead
|
|
27
37
|
- state="error" sets aria-invalid automatically
|
|
28
38
|
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
|
|
29
|
-
-
|
|
30
|
-
-
|
|
39
|
+
- `className` targets the `<input>` element; use `wrapperClassName` for border/bg/ring overrides
|
|
40
|
+
- Focus ring is on the wrapper container (focus-within), not the input itself
|
|
41
|
+
- Icons in startSection/endSection are auto-sized via IconProvider per input size
|
|
42
|
+
- Sections are `pointer-events-none` by default — set `startSectionClickable`/`endSectionClickable` for interactive sections
|
|
43
|
+
- Section type is auto-inferred: strings default to `'label'` (tinted bg + border), React elements default to `'icon'` (fixed-width centered). Override with `startSectionType`/`endSectionType`.
|
|
31
44
|
|
|
32
45
|
## Changes
|
|
46
|
+
### v0.29.0
|
|
47
|
+
- **Changed** v2 rewrite: container-first architecture with wrapper div holding focus ring
|
|
48
|
+
- **Added** `xs` size (28px height)
|
|
49
|
+
- **Added** `startSection` / `endSection` props replacing `startIcon` / `endIcon` (deprecated but still work)
|
|
50
|
+
- **Added** `startSectionClickable` / `endSectionClickable` props for interactive sections
|
|
51
|
+
- **Added** `wrapperClassName` prop for styling the wrapper div (border, bg, ring)
|
|
52
|
+
- **Changed** Focus ring now on wrapper via `focus-within` (container-level ring, not input-level)
|
|
53
|
+
- **Changed** Icons auto-sized via `IconProvider` context per input size
|
|
54
|
+
- **Deprecated** `startIcon` / `endIcon` — use `startSection` / `endSection`
|
|
55
|
+
- **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).
|
|
56
|
+
- **Changed** Sections use flexbox layout for consistent alignment
|
|
57
|
+
- **Deprecated** `inputVariants` export — use `inputWrapperVariants` (semantics changed to target wrapper)
|
|
58
|
+
|
|
33
59
|
### v0.15.0
|
|
34
60
|
- **Changed** `lg` size font changed from `text-ds-lg` (18px) to `text-ds-md` (14px) — all input sizes now use 14px for consistency
|
|
35
61
|
- **Changed** `md` size font standardized to `text-ds-md` (14px) from mixed values
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
value: number (0-100) — omit for indeterminate
|
|
9
9
|
size: "sm" | "md" | "lg" (track height)
|
|
10
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)
|
|
11
12
|
showLabel: boolean (shows percentage text)
|
|
12
13
|
indicatorClassName: string
|
|
13
14
|
|
|
@@ -23,7 +24,11 @@
|
|
|
23
24
|
|
|
24
25
|
## Gotchas
|
|
25
26
|
- Omit value (or pass undefined) for indeterminate animation
|
|
27
|
+
- `autoColor` overrides `color` when `value` is set — do not pass both unless you want autoColor to win
|
|
26
28
|
|
|
27
29
|
## Changes
|
|
30
|
+
### v0.29.0
|
|
31
|
+
- **Added** `autoColor` prop — automatically shifts indicator color based on value thresholds (0-59 default, 60-84 warning, 85-100 success, >100 error)
|
|
32
|
+
|
|
28
33
|
### v0.1.0
|
|
29
34
|
- **Added** Initial release with `size`, `color`, `indeterminate` variants and optional label slot
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
- No longer server-safe as of v0.18.0 (uses Framer Motion)
|
|
33
33
|
|
|
34
34
|
## Changes
|
|
35
|
+
### v0.29.0
|
|
36
|
+
- **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
|
|
37
|
+
|
|
35
38
|
### v0.18.0
|
|
36
39
|
- **Changed** (BREAKING) Complete rewrite with Framer Motion arc animation and state transitions
|
|
37
40
|
- **Added** `state` prop: 'spinning' | 'success' | 'error'
|
|
@@ -9,16 +9,29 @@
|
|
|
9
9
|
onCheckedChange: (checked: boolean) => void
|
|
10
10
|
error: boolean (shows red border/bg)
|
|
11
11
|
disabled: boolean
|
|
12
|
+
size: "sm" | "md" | "lg"
|
|
13
|
+
color: "accent" | "success" | "warning"
|
|
14
|
+
thumbIcon: ReactNode (icon rendered inside the thumb)
|
|
15
|
+
|
|
16
|
+
## Defaults
|
|
17
|
+
size="md", color="accent"
|
|
12
18
|
|
|
13
19
|
## Example
|
|
14
20
|
```jsx
|
|
15
21
|
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
|
22
|
+
<Switch size="lg" color="success" thumbIcon={<IconCheck size={14} />} />
|
|
16
23
|
```
|
|
17
24
|
|
|
18
25
|
## Gotchas
|
|
19
26
|
- Use error prop for validation states (matches Checkbox API)
|
|
27
|
+
- `error` overrides `color` — when error is true, checked state always uses error-9
|
|
20
28
|
|
|
21
29
|
## Changes
|
|
30
|
+
### v0.29.0
|
|
31
|
+
- **Added** `size` prop: `"sm"` (18px track) | `"md"` (24px, default) | `"lg"` (28px track)
|
|
32
|
+
- **Added** `color` prop: `"accent"` (default) | `"success"` | `"warning"` for checked-state color
|
|
33
|
+
- **Added** `thumbIcon` prop — renders any ReactNode inside the thumb circle (e.g., check icon)
|
|
34
|
+
|
|
22
35
|
### v0.18.0
|
|
23
36
|
- **Changed** Migrated to Framer Motion spring thumb animation
|
|
24
37
|
- **Fixed** Added visible border on unchecked state (`border-surface-border-strong`) — was borderless, making unchecked state hard to see
|