@devalok/shilp-sutra 0.25.1 → 0.27.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/framer.js +4824 -805
- package/dist/_chunks/primitives.js +39 -39
- package/dist/_chunks/sonner.js +747 -0
- package/dist/_chunks/tiptap.js +3949 -2969
- package/dist/_chunks/vendor-client.js +1071 -1793
- package/dist/_chunks/vendor-utils.js +632 -5795
- package/dist/ai/index.js +1 -1
- package/dist/composed/avatar-group.js +1 -1
- package/dist/composed/bulk-action-bar.d.ts +29 -0
- package/dist/composed/bulk-action-bar.d.ts.map +1 -0
- package/dist/composed/bulk-action-bar.js +123 -0
- package/dist/composed/content-card.js +1 -1
- package/dist/composed/deadline-indicator.d.ts +18 -0
- package/dist/composed/deadline-indicator.d.ts.map +1 -0
- package/dist/composed/deadline-indicator.js +75 -0
- package/dist/composed/emoji-picker.d.ts +26 -0
- package/dist/composed/emoji-picker.d.ts.map +1 -0
- package/dist/composed/emoji-picker.js +104 -0
- package/dist/composed/file-preview.d.ts +22 -0
- package/dist/composed/file-preview.d.ts.map +1 -0
- package/dist/composed/file-preview.js +675 -0
- package/dist/composed/filter-bar.d.ts +38 -0
- package/dist/composed/filter-bar.d.ts.map +1 -0
- package/dist/composed/filter-bar.js +133 -0
- package/dist/composed/form-section.d.ts +12 -0
- package/dist/composed/form-section.d.ts.map +1 -0
- package/dist/composed/form-section.js +45 -0
- package/dist/composed/index.d.ts +22 -0
- package/dist/composed/index.d.ts.map +1 -1
- package/dist/composed/index.js +61 -36
- package/dist/composed/inline-edit.d.ts +16 -0
- package/dist/composed/inline-edit.d.ts.map +1 -0
- package/dist/composed/inline-edit.js +107 -0
- package/dist/composed/markdown-viewer.d.ts +14 -0
- package/dist/composed/markdown-viewer.d.ts.map +1 -0
- package/dist/composed/markdown-viewer.js +143 -0
- package/dist/composed/master-detail.d.ts +35 -0
- package/dist/composed/master-detail.d.ts.map +1 -0
- package/dist/composed/master-detail.js +124 -0
- package/dist/composed/member-picker.d.ts.map +1 -1
- package/dist/composed/member-picker.js +41 -88
- package/dist/composed/multi-select-popover.d.ts +44 -0
- package/dist/composed/multi-select-popover.d.ts.map +1 -0
- package/dist/composed/multi-select-popover.js +185 -0
- package/dist/composed/priority-indicator.js +1 -1
- package/dist/composed/responsive-overlay.d.ts +15 -0
- package/dist/composed/responsive-overlay.d.ts.map +1 -0
- package/dist/composed/responsive-overlay.js +45 -0
- package/dist/composed/status-badge.js +1 -1
- package/dist/tailwind/index.cjs +37 -3
- package/dist/tailwind/preset.js +1 -1
- package/dist/ui/alert-dialog.js +10 -10
- package/dist/ui/alert.js +1 -1
- package/dist/ui/avatar.js +2 -2
- package/dist/ui/badge.js +1 -1
- package/dist/ui/banner.js +4 -4
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +48 -42
- package/dist/ui/card.d.ts +6 -48
- package/dist/ui/card.d.ts.map +1 -1
- package/dist/ui/card.js +92 -49
- package/dist/ui/checkbox.js +1 -1
- package/dist/ui/chip.js +1 -1
- package/dist/ui/collapsible.js +1 -1
- package/dist/ui/color-swatch.d.ts +27 -0
- package/dist/ui/color-swatch.d.ts.map +1 -0
- package/dist/ui/color-swatch.js +91 -0
- package/dist/ui/data-table.d.ts +7 -1
- package/dist/ui/data-table.d.ts.map +1 -1
- package/dist/ui/data-table.js +221 -215
- package/dist/ui/dialog.js +4 -4
- package/dist/ui/dropdown-menu.js +31 -31
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +187 -180
- package/dist/ui/input.d.ts +1 -1
- package/dist/ui/input.d.ts.map +1 -1
- package/dist/ui/input.js +11 -10
- package/dist/ui/label.js +1 -1
- package/dist/ui/lib/utils.js +1 -1
- package/dist/ui/progress-ring.d.ts +46 -0
- package/dist/ui/progress-ring.d.ts.map +1 -0
- package/dist/ui/progress-ring.js +144 -0
- package/dist/ui/progress.js +12 -12
- package/dist/ui/search-input.d.ts +1 -1
- package/dist/ui/search-input.d.ts.map +1 -1
- package/dist/ui/search-input.js +9 -8
- package/dist/ui/segmented-control.js +1 -1
- package/dist/ui/select.d.ts +1 -1
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +29 -28
- package/dist/ui/sheet.js +6 -6
- package/dist/ui/sidebar.js +15 -15
- package/dist/ui/skeleton.js +1 -1
- package/dist/ui/status-dot.d.ts +27 -0
- package/dist/ui/status-dot.d.ts.map +1 -0
- package/dist/ui/status-dot.js +64 -0
- package/dist/ui/tabs.js +18 -18
- package/dist/ui/text.js +1 -1
- package/dist/ui/textarea.d.ts +1 -1
- package/dist/ui/textarea.d.ts.map +1 -1
- package/dist/ui/textarea.js +14 -13
- package/dist/ui/toast.js +1 -1
- package/dist/ui/toaster.js +1 -1
- package/dist/ui/toggle.js +4 -4
- package/docs/components/composed/bulk-action-bar.md +40 -0
- package/docs/components/composed/deadline-indicator.md +27 -0
- package/docs/components/composed/emoji-picker.md +43 -0
- package/docs/components/composed/file-preview.md +40 -0
- package/docs/components/composed/filter-bar.md +57 -0
- package/docs/components/composed/form-section.md +31 -0
- package/docs/components/composed/inline-edit.md +35 -0
- package/docs/components/composed/markdown-viewer.md +27 -0
- package/docs/components/composed/master-detail.md +48 -0
- package/docs/components/composed/multi-select-popover.md +53 -0
- package/docs/components/composed/responsive-overlay.md +34 -0
- package/docs/components/ui/color-swatch.md +25 -0
- package/docs/components/ui/progress-ring.md +41 -0
- package/docs/components/ui/status-dot.md +26 -0
- package/llms-full.txt +528 -1
- package/llms.txt +53 -9
- package/package.json +820 -733
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.27.0
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -871,6 +871,31 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
871
871
|
|
|
872
872
|
### v0.1.0
|
|
873
873
|
- **Added** Initial release
|
|
874
|
+
# ColorSwatch
|
|
875
|
+
|
|
876
|
+
- Import: @devalok/shilp-sutra/ui/color-swatch
|
|
877
|
+
- Server-safe: Yes
|
|
878
|
+
- Category: ui
|
|
879
|
+
|
|
880
|
+
## Props
|
|
881
|
+
color: string (any valid CSS color — hex, rgb, oklch, etc.)
|
|
882
|
+
size: "sm" | "md" | "lg"
|
|
883
|
+
shape: "circle" | "square" | "rounded"
|
|
884
|
+
ring: boolean (shows subtle ring border — useful for light colors that blend into the background)
|
|
885
|
+
|
|
886
|
+
## Defaults
|
|
887
|
+
size="md", shape="circle", ring={false}
|
|
888
|
+
|
|
889
|
+
## Example
|
|
890
|
+
```jsx
|
|
891
|
+
<ColorSwatch color="#FF5733" />
|
|
892
|
+
<ColorSwatch color={org.brandColor} size="lg" ring />
|
|
893
|
+
<ColorSwatch color="oklch(0.7 0.15 200)" shape="rounded" />
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
## Gotchas
|
|
897
|
+
- Color is applied via inline `backgroundColor` style, not a token class — accepts any runtime CSS color string
|
|
898
|
+
- Renders `role="presentation"` — purely decorative, not interactive
|
|
874
899
|
# Combobox
|
|
875
900
|
|
|
876
901
|
- Import: @devalok/shilp-sutra/ui/combobox
|
|
@@ -1775,6 +1800,47 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1775
1800
|
## Changes
|
|
1776
1801
|
### v0.1.0
|
|
1777
1802
|
- **Added** Initial release with `size`, `color`, `indeterminate` variants and optional label slot
|
|
1803
|
+
# ProgressRing
|
|
1804
|
+
|
|
1805
|
+
- Import: @devalok/shilp-sutra/ui/progress-ring
|
|
1806
|
+
- Server-safe: No
|
|
1807
|
+
- Category: ui
|
|
1808
|
+
|
|
1809
|
+
## Props
|
|
1810
|
+
|
|
1811
|
+
### ProgressRing
|
|
1812
|
+
value: number (current progress value)
|
|
1813
|
+
max: number (maximum value)
|
|
1814
|
+
size: "sm" | "md" | "lg"
|
|
1815
|
+
color: "default" | "success" | "warning" | "error" | "info"
|
|
1816
|
+
showValue: boolean (show percentage text in center)
|
|
1817
|
+
label: string (accessible label — falls back to "{n}% progress")
|
|
1818
|
+
|
|
1819
|
+
### MultiProgressRing
|
|
1820
|
+
rings: Array<{ value: number; max?: number; color?: "default" | "success" | "warning" | "error" | "info"; label?: string }>
|
|
1821
|
+
size: "sm" | "md" | "lg"
|
|
1822
|
+
|
|
1823
|
+
## Defaults
|
|
1824
|
+
max={100}, size="md", color="default", showValue={false}
|
|
1825
|
+
|
|
1826
|
+
## Example
|
|
1827
|
+
```jsx
|
|
1828
|
+
<ProgressRing value={75} />
|
|
1829
|
+
<ProgressRing value={3} max={12} size="lg" color="warning" showValue />
|
|
1830
|
+
|
|
1831
|
+
<MultiProgressRing
|
|
1832
|
+
rings={[
|
|
1833
|
+
{ value: 80, color: 'error', label: 'Move' },
|
|
1834
|
+
{ value: 60, color: 'success', label: 'Exercise' },
|
|
1835
|
+
]}
|
|
1836
|
+
size="lg"
|
|
1837
|
+
/>
|
|
1838
|
+
```
|
|
1839
|
+
|
|
1840
|
+
## Gotchas
|
|
1841
|
+
- Uses Framer Motion for the animated fill — not server-safe
|
|
1842
|
+
- Value is clamped to `[0, max]` internally
|
|
1843
|
+
- MultiProgressRing skips rings whose computed radius would be <= 0 (too many rings for the size)
|
|
1778
1844
|
# RadioGroup
|
|
1779
1845
|
|
|
1780
1846
|
- Import: @devalok/shilp-sutra/ui/radio
|
|
@@ -2359,6 +2425,32 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2359
2425
|
|
|
2360
2426
|
### v0.1.0
|
|
2361
2427
|
- **Added** Initial release
|
|
2428
|
+
# StatusDot
|
|
2429
|
+
|
|
2430
|
+
- Import: @devalok/shilp-sutra/ui/status-dot
|
|
2431
|
+
- Server-safe: Yes
|
|
2432
|
+
- Category: ui
|
|
2433
|
+
|
|
2434
|
+
## Props
|
|
2435
|
+
status: "healthy" | "warning" | "critical" | "neutral" | "inactive"
|
|
2436
|
+
size: "sm" | "md" | "lg"
|
|
2437
|
+
pulse: boolean (ping animation; defaults to true for "healthy", false for others)
|
|
2438
|
+
label: string (inline text rendered after the dot)
|
|
2439
|
+
labelClassName: string (extra classes on the label span)
|
|
2440
|
+
|
|
2441
|
+
## Defaults
|
|
2442
|
+
size="md", pulse={status === "healthy"}
|
|
2443
|
+
|
|
2444
|
+
## Example
|
|
2445
|
+
```jsx
|
|
2446
|
+
<StatusDot status="healthy" />
|
|
2447
|
+
<StatusDot status="critical" label="Service down" pulse />
|
|
2448
|
+
<StatusDot status="warning" size="lg" label="Elevated load" />
|
|
2449
|
+
```
|
|
2450
|
+
|
|
2451
|
+
## Gotchas
|
|
2452
|
+
- The `pulse` prop auto-enables for "healthy" status — pass `pulse={false}` to suppress
|
|
2453
|
+
- Status type is exported as `StatusDotStatus` if you need it in consumer code
|
|
2362
2454
|
# Stepper / Step
|
|
2363
2455
|
|
|
2364
2456
|
- Import: @devalok/shilp-sutra/ui/stepper
|
|
@@ -3063,6 +3155,46 @@ export default function RootLayout({ children }) {
|
|
|
3063
3155
|
|
|
3064
3156
|
### v0.1.0
|
|
3065
3157
|
- **Added** Initial release
|
|
3158
|
+
# BulkActionBar
|
|
3159
|
+
|
|
3160
|
+
- Import: @devalok/shilp-sutra/composed/bulk-action-bar
|
|
3161
|
+
- Server-safe: No
|
|
3162
|
+
- Category: composed
|
|
3163
|
+
|
|
3164
|
+
## Props
|
|
3165
|
+
show: boolean (controls visibility)
|
|
3166
|
+
count: number (number of selected items — displayed in badge)
|
|
3167
|
+
onClearSelection: () => void
|
|
3168
|
+
actions: BulkActionBarAction[]
|
|
3169
|
+
className: string
|
|
3170
|
+
|
|
3171
|
+
### BulkActionBarAction
|
|
3172
|
+
label: string
|
|
3173
|
+
icon: ComponentType<{ className?: string }> (optional icon component)
|
|
3174
|
+
onClick: () => void
|
|
3175
|
+
color: "default" | "error"
|
|
3176
|
+
disabled: boolean
|
|
3177
|
+
|
|
3178
|
+
## Defaults
|
|
3179
|
+
(no optional props with defaults)
|
|
3180
|
+
|
|
3181
|
+
## Example
|
|
3182
|
+
```jsx
|
|
3183
|
+
<BulkActionBar
|
|
3184
|
+
show={selected.length > 0}
|
|
3185
|
+
count={selected.length}
|
|
3186
|
+
onClearSelection={() => setSelected([])}
|
|
3187
|
+
actions={[
|
|
3188
|
+
{ label: 'Archive', icon: IconArchive, onClick: archiveSelected },
|
|
3189
|
+
{ label: 'Delete', icon: IconTrash, onClick: deleteSelected, color: 'error' },
|
|
3190
|
+
]}
|
|
3191
|
+
/>
|
|
3192
|
+
```
|
|
3193
|
+
|
|
3194
|
+
## Gotchas
|
|
3195
|
+
- Renders via `createPortal` into `document.body` — will not appear during SSR (mounts only client-side)
|
|
3196
|
+
- Positioned fixed at bottom-center with `z-50`; ensure no other fixed elements conflict
|
|
3197
|
+
- Uses Framer Motion AnimatePresence for slide-in/out animation
|
|
3066
3198
|
# CommandPalette
|
|
3067
3199
|
|
|
3068
3200
|
- Import: @devalok/shilp-sutra/composed/command-palette
|
|
@@ -3315,6 +3447,76 @@ PresetKey: 'today' | 'yesterday' | 'last7days' | 'last30days' | 'thisMonth' | 'l
|
|
|
3315
3447
|
|
|
3316
3448
|
### v0.1.0
|
|
3317
3449
|
- **Added** Initial release
|
|
3450
|
+
# DeadlineIndicator
|
|
3451
|
+
|
|
3452
|
+
- Import: @devalok/shilp-sutra/composed/deadline-indicator
|
|
3453
|
+
- Server-safe: Yes
|
|
3454
|
+
- Category: composed
|
|
3455
|
+
|
|
3456
|
+
## Props
|
|
3457
|
+
deadline: Date | string (deadline timestamp)
|
|
3458
|
+
warningThreshold: number (minutes before deadline to show warning color)
|
|
3459
|
+
criticalThreshold: number (minutes before deadline to show critical/error color)
|
|
3460
|
+
format: "relative" | "absolute"
|
|
3461
|
+
showIcon: boolean (show clock icon prefix)
|
|
3462
|
+
|
|
3463
|
+
## Defaults
|
|
3464
|
+
warningThreshold={1440} (24h), criticalThreshold={240} (4h), format="relative", showIcon={false}
|
|
3465
|
+
|
|
3466
|
+
## Example
|
|
3467
|
+
```jsx
|
|
3468
|
+
<DeadlineIndicator deadline={task.dueDate} />
|
|
3469
|
+
<DeadlineIndicator deadline="2026-03-20T17:00:00Z" showIcon format="absolute" />
|
|
3470
|
+
<DeadlineIndicator deadline={task.dueDate} warningThreshold={2880} criticalThreshold={480} />
|
|
3471
|
+
```
|
|
3472
|
+
|
|
3473
|
+
## Gotchas
|
|
3474
|
+
- Color is semantic: green (on-track) -> yellow (warning threshold) -> red (critical/overdue)
|
|
3475
|
+
- Overdue deadlines show bold red text with "Overdue by Xd/h/m"
|
|
3476
|
+
- Relative format uses `Date.now()` at render time — does not live-update (re-render to refresh)
|
|
3477
|
+
# EmojiPicker
|
|
3478
|
+
|
|
3479
|
+
- Import: @devalok/shilp-sutra/composed/emoji-picker
|
|
3480
|
+
- Server-safe: No
|
|
3481
|
+
- Category: composed
|
|
3482
|
+
|
|
3483
|
+
## Exports
|
|
3484
|
+
EmojiPicker, EmojiPickerPopover
|
|
3485
|
+
|
|
3486
|
+
## Props
|
|
3487
|
+
|
|
3488
|
+
### EmojiPicker
|
|
3489
|
+
onSelect: (emoji: EmojiData) => void
|
|
3490
|
+
theme: "auto" | "light" | "dark"
|
|
3491
|
+
previewPosition: "top" | "bottom" | "none"
|
|
3492
|
+
skinTonePosition: "search" | "preview" | "none"
|
|
3493
|
+
className: string
|
|
3494
|
+
|
|
3495
|
+
### EmojiPickerPopover (extends EmojiPicker props)
|
|
3496
|
+
children: ReactNode (trigger element)
|
|
3497
|
+
align: "start" | "center" | "end"
|
|
3498
|
+
|
|
3499
|
+
### EmojiData
|
|
3500
|
+
id: string
|
|
3501
|
+
native: string (the emoji character)
|
|
3502
|
+
shortcodes: string
|
|
3503
|
+
|
|
3504
|
+
## Defaults
|
|
3505
|
+
theme="auto", previewPosition="none", skinTonePosition="search", align="start"
|
|
3506
|
+
|
|
3507
|
+
## Example
|
|
3508
|
+
```jsx
|
|
3509
|
+
<EmojiPickerPopover onSelect={(emoji) => insertEmoji(emoji.native)}>
|
|
3510
|
+
<Button variant="ghost" size="icon-sm">😀</Button>
|
|
3511
|
+
</EmojiPickerPopover>
|
|
3512
|
+
|
|
3513
|
+
<EmojiPicker onSelect={handleEmoji} theme="dark" />
|
|
3514
|
+
```
|
|
3515
|
+
|
|
3516
|
+
## Gotchas
|
|
3517
|
+
- Wraps `@emoji-mart/react` which is lazy-loaded — shows a Skeleton placeholder while loading
|
|
3518
|
+
- `theme="auto"` reads the `.dark` class on `<html>` to pick light/dark
|
|
3519
|
+
- EmojiPickerPopover auto-closes after selection
|
|
3318
3520
|
# EmptyState
|
|
3319
3521
|
|
|
3320
3522
|
- Import: @devalok/shilp-sutra/composed/empty-state
|
|
@@ -3397,6 +3599,134 @@ Note: EmptyState was server-safe prior to v0.18.0 but is NO LONGER server-safe d
|
|
|
3397
3599
|
|
|
3398
3600
|
### v0.1.0
|
|
3399
3601
|
- **Added** Initial release
|
|
3602
|
+
# FilePreview
|
|
3603
|
+
|
|
3604
|
+
- Import: @devalok/shilp-sutra/composed/file-preview
|
|
3605
|
+
- Server-safe: No
|
|
3606
|
+
- Category: composed
|
|
3607
|
+
|
|
3608
|
+
## Props
|
|
3609
|
+
url: string (file URL — required)
|
|
3610
|
+
type: "image" | "pdf" | "video" | "audio" | "embed" (auto-detected from URL/mimeType)
|
|
3611
|
+
mimeType: string (helps auto-detection)
|
|
3612
|
+
alt: string (image alt text)
|
|
3613
|
+
initialPage: number (PDF starting page, default 1)
|
|
3614
|
+
fileName: string (displayed in file info bar)
|
|
3615
|
+
fileSize: string (displayed as badge, e.g. "2.4 MB")
|
|
3616
|
+
onError: (error: string) => void (called on load failures)
|
|
3617
|
+
|
|
3618
|
+
## Defaults
|
|
3619
|
+
initialPage={1}, type auto-detected
|
|
3620
|
+
|
|
3621
|
+
## Features by Type
|
|
3622
|
+
|
|
3623
|
+
**Image:** Pinch/scroll zoom (0.1x–8x), double-click toggle, floating toolbar (zoom %/reset/fullscreen), keyboard (+/-/0/F/Esc)
|
|
3624
|
+
**PDF:** react-pdf page nav (prev/next + direct input), keyboard (←→), crossfade between pages
|
|
3625
|
+
**Video:** Custom branded player, play overlay, auto-hiding controls, progress bar + scrub handle, mute, fullscreen
|
|
3626
|
+
**Audio:** Branded mini-player, full-width progress bar with hover tooltip + scrub handle, volume, file name display
|
|
3627
|
+
**Embed:** 16:9 aspect ratio, auto-converts YouTube/Vimeo/Figma/Loom URLs, 15s timeout
|
|
3628
|
+
|
|
3629
|
+
## Example
|
|
3630
|
+
```jsx
|
|
3631
|
+
<FilePreview url="/uploads/mockup.png" fileName="mockup.png" fileSize="2.4 MB" />
|
|
3632
|
+
<FilePreview url="/docs/contract.pdf" initialPage={3} />
|
|
3633
|
+
<FilePreview url="https://youtube.com/watch?v=..." />
|
|
3634
|
+
```
|
|
3635
|
+
|
|
3636
|
+
## Gotchas
|
|
3637
|
+
- Image/PDF lazy-loaded (Skeleton on first render)
|
|
3638
|
+
- PDF worker from unpkg CDN — configure workerSrc for offline apps
|
|
3639
|
+
- All types have error fallback with download link
|
|
3640
|
+
- Embed URLs auto-converted to embed format
|
|
3641
|
+
- Audio player doesn't show separate Download button (integrated in card)
|
|
3642
|
+
# FilterBar
|
|
3643
|
+
|
|
3644
|
+
- Import: @devalok/shilp-sutra/composed/filter-bar
|
|
3645
|
+
- Server-safe: No
|
|
3646
|
+
- Category: composed
|
|
3647
|
+
|
|
3648
|
+
## Exports
|
|
3649
|
+
FilterBar, FilterSelect, FilterMultiSelect
|
|
3650
|
+
|
|
3651
|
+
## Props
|
|
3652
|
+
|
|
3653
|
+
### FilterBar
|
|
3654
|
+
searchValue: string
|
|
3655
|
+
onSearchChange: (value: string) => void (renders SearchInput when provided)
|
|
3656
|
+
searchPlaceholder: string
|
|
3657
|
+
onClearAll: () => void (renders "Clear all" button when provided)
|
|
3658
|
+
size: "xs" | "sm" | "md" (propagated to all child controls via context)
|
|
3659
|
+
children: ReactNode (FilterSelect / FilterMultiSelect controls)
|
|
3660
|
+
|
|
3661
|
+
### FilterSelect
|
|
3662
|
+
label: string
|
|
3663
|
+
value: string
|
|
3664
|
+
onValueChange: (value: string) => void
|
|
3665
|
+
options: { value: string; label: string }[]
|
|
3666
|
+
allLabel: string (label for the "all" option)
|
|
3667
|
+
|
|
3668
|
+
### FilterMultiSelect
|
|
3669
|
+
label: string
|
|
3670
|
+
value: string[]
|
|
3671
|
+
onValueChange: (values: string[]) => void
|
|
3672
|
+
options: { value: string; label: string }[]
|
|
3673
|
+
|
|
3674
|
+
## Defaults
|
|
3675
|
+
size="sm", searchPlaceholder="Search...", allLabel="All"
|
|
3676
|
+
|
|
3677
|
+
## Example
|
|
3678
|
+
```jsx
|
|
3679
|
+
<FilterBar searchValue={search} onSearchChange={setSearch} onClearAll={clearFilters}>
|
|
3680
|
+
<FilterSelect
|
|
3681
|
+
label="Status"
|
|
3682
|
+
value={status}
|
|
3683
|
+
onValueChange={setStatus}
|
|
3684
|
+
options={[{ value: 'active', label: 'Active' }, { value: 'done', label: 'Done' }]}
|
|
3685
|
+
/>
|
|
3686
|
+
<FilterMultiSelect
|
|
3687
|
+
label="Assignees"
|
|
3688
|
+
value={assignees}
|
|
3689
|
+
onValueChange={setAssignees}
|
|
3690
|
+
options={memberOptions}
|
|
3691
|
+
/>
|
|
3692
|
+
</FilterBar>
|
|
3693
|
+
```
|
|
3694
|
+
|
|
3695
|
+
## Gotchas
|
|
3696
|
+
- FilterSelect and FilterMultiSelect must be direct children of FilterBar to inherit the size context
|
|
3697
|
+
- FilterSelect uses `"all"` as the sentinel value for "no filter" — do not use `"all"` as a real option value
|
|
3698
|
+
- Active filters get an accent border highlight automatically
|
|
3699
|
+
# FormSection
|
|
3700
|
+
|
|
3701
|
+
- Import: @devalok/shilp-sutra/composed/form-section
|
|
3702
|
+
- Server-safe: No
|
|
3703
|
+
- Category: composed
|
|
3704
|
+
|
|
3705
|
+
## Props
|
|
3706
|
+
title: string
|
|
3707
|
+
description: string (subtitle text below the title)
|
|
3708
|
+
collapsible: boolean (wraps content in a Collapsible)
|
|
3709
|
+
defaultOpen: boolean (initial open state when collapsible)
|
|
3710
|
+
children: ReactNode (form fields)
|
|
3711
|
+
|
|
3712
|
+
## Defaults
|
|
3713
|
+
collapsible={false}, defaultOpen={true}
|
|
3714
|
+
|
|
3715
|
+
## Example
|
|
3716
|
+
```jsx
|
|
3717
|
+
<FormSection title="General" description="Basic project settings">
|
|
3718
|
+
<FormField .../>
|
|
3719
|
+
<FormField .../>
|
|
3720
|
+
</FormSection>
|
|
3721
|
+
|
|
3722
|
+
<FormSection title="Advanced" collapsible defaultOpen={false}>
|
|
3723
|
+
<FormField .../>
|
|
3724
|
+
</FormSection>
|
|
3725
|
+
```
|
|
3726
|
+
|
|
3727
|
+
## Gotchas
|
|
3728
|
+
- `defaultOpen` only applies when `collapsible={true}` — otherwise the section is always open
|
|
3729
|
+
- Renders a horizontal rule between the header and content automatically
|
|
3400
3730
|
# GlobalLoading
|
|
3401
3731
|
|
|
3402
3732
|
- Import: @devalok/shilp-sutra/composed/global-loading
|
|
@@ -3424,6 +3754,41 @@ Note: EmptyState was server-safe prior to v0.18.0 but is NO LONGER server-safe d
|
|
|
3424
3754
|
|
|
3425
3755
|
### v0.1.0
|
|
3426
3756
|
- **Added** Initial release
|
|
3757
|
+
# InlineEdit
|
|
3758
|
+
|
|
3759
|
+
- Import: @devalok/shilp-sutra/composed/inline-edit
|
|
3760
|
+
- Server-safe: No
|
|
3761
|
+
- Category: composed
|
|
3762
|
+
|
|
3763
|
+
## Props
|
|
3764
|
+
value: string (current text value)
|
|
3765
|
+
onSave: (newValue: string) => void | Promise<void> (called on commit; async shows spinner)
|
|
3766
|
+
placeholder: string (shown when value is empty)
|
|
3767
|
+
textClassName: string (CSS class for the editable text, e.g. "text-ds-lg font-semibold")
|
|
3768
|
+
readOnly: boolean
|
|
3769
|
+
maxLength: number
|
|
3770
|
+
saving: boolean (external saving state — shows spinner, disables editing)
|
|
3771
|
+
|
|
3772
|
+
## Defaults
|
|
3773
|
+
placeholder="Click to edit", readOnly={false}, saving={false}
|
|
3774
|
+
|
|
3775
|
+
## Example
|
|
3776
|
+
```jsx
|
|
3777
|
+
<InlineEdit
|
|
3778
|
+
value={title}
|
|
3779
|
+
onSave={(v) => updateTitle(v)}
|
|
3780
|
+
textClassName="text-ds-lg font-semibold"
|
|
3781
|
+
/>
|
|
3782
|
+
```
|
|
3783
|
+
|
|
3784
|
+
## Gotchas
|
|
3785
|
+
- Uses contentEditable — the text IS the editor. No input field appears.
|
|
3786
|
+
- Click to focus → cursor appears in text. Type to edit. Enter saves. Escape reverts.
|
|
3787
|
+
- Text is auto-selected on focus (like renaming a file in Finder)
|
|
3788
|
+
- Paste is restricted to plain text (no rich content)
|
|
3789
|
+
- The value is trimmed before calling `onSave`; if unchanged, `onSave` is not called
|
|
3790
|
+
- If `onSave` returns a Promise, a spinner is shown and editing is disabled until it resolves
|
|
3791
|
+
- On Promise rejection, the text reverts to the original value
|
|
3427
3792
|
# LoadingSkeleton
|
|
3428
3793
|
|
|
3429
3794
|
- Import: @devalok/shilp-sutra/composed/loading-skeleton
|
|
@@ -3475,6 +3840,81 @@ Exports: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton
|
|
|
3475
3840
|
|
|
3476
3841
|
### v0.1.0
|
|
3477
3842
|
- **Added** Initial release
|
|
3843
|
+
# MarkdownViewer
|
|
3844
|
+
|
|
3845
|
+
- Import: @devalok/shilp-sutra/composed/markdown-viewer
|
|
3846
|
+
- Server-safe: No
|
|
3847
|
+
- Category: composed
|
|
3848
|
+
|
|
3849
|
+
## Props
|
|
3850
|
+
content: string (markdown source)
|
|
3851
|
+
compact: boolean (tighter spacing for inline use)
|
|
3852
|
+
allowHtml: boolean (allow raw HTML in markdown)
|
|
3853
|
+
linkTarget: string (target attribute for links)
|
|
3854
|
+
|
|
3855
|
+
## Defaults
|
|
3856
|
+
compact={false}, allowHtml={false}, linkTarget="_blank"
|
|
3857
|
+
|
|
3858
|
+
## Example
|
|
3859
|
+
```jsx
|
|
3860
|
+
<MarkdownViewer content={message.body} />
|
|
3861
|
+
<MarkdownViewer content={comment} compact />
|
|
3862
|
+
<MarkdownViewer content={trustedHtml} allowHtml />
|
|
3863
|
+
```
|
|
3864
|
+
|
|
3865
|
+
## Gotchas
|
|
3866
|
+
- Code blocks with a language fence are syntax-highlighted via `react-syntax-highlighter` (lazy-loaded) — the first render shows a plain `<pre>` fallback
|
|
3867
|
+
- GFM (tables, strikethrough, task lists) is supported via `remark-gfm`
|
|
3868
|
+
- Raw HTML is stripped by default — only enable `allowHtml` for trusted content
|
|
3869
|
+
- Links open in a new tab by default (`target="_blank"` with `rel="noopener noreferrer"`)
|
|
3870
|
+
# MasterDetail
|
|
3871
|
+
|
|
3872
|
+
- Import: @devalok/shilp-sutra/composed/master-detail
|
|
3873
|
+
- Server-safe: No
|
|
3874
|
+
- Category: composed
|
|
3875
|
+
|
|
3876
|
+
## Compound Components
|
|
3877
|
+
MasterDetail (root), MasterDetail.List, MasterDetail.Detail, MasterDetail.ListItem
|
|
3878
|
+
|
|
3879
|
+
## Props
|
|
3880
|
+
|
|
3881
|
+
### MasterDetail (root)
|
|
3882
|
+
selected: string | null (ID of currently selected item; null = show list on mobile)
|
|
3883
|
+
onBack: () => void (called when mobile back button is pressed)
|
|
3884
|
+
masterWidth: string (master panel width on desktop)
|
|
3885
|
+
breakpoint: "sm" | "md" | "lg" (below this, stacked mobile mode activates)
|
|
3886
|
+
|
|
3887
|
+
### MasterDetail.ListItem
|
|
3888
|
+
active: boolean (highlights the item)
|
|
3889
|
+
(extends ButtonHTMLAttributes)
|
|
3890
|
+
|
|
3891
|
+
## Defaults
|
|
3892
|
+
selected={null}, masterWidth="280px", breakpoint="md"
|
|
3893
|
+
|
|
3894
|
+
## Example
|
|
3895
|
+
```jsx
|
|
3896
|
+
<MasterDetail selected={selectedId} onBack={() => setSelectedId(null)}>
|
|
3897
|
+
<MasterDetail.List>
|
|
3898
|
+
{items.map((item) => (
|
|
3899
|
+
<MasterDetail.ListItem
|
|
3900
|
+
key={item.id}
|
|
3901
|
+
active={item.id === selectedId}
|
|
3902
|
+
onClick={() => setSelectedId(item.id)}
|
|
3903
|
+
>
|
|
3904
|
+
{item.name}
|
|
3905
|
+
</MasterDetail.ListItem>
|
|
3906
|
+
))}
|
|
3907
|
+
</MasterDetail.List>
|
|
3908
|
+
<MasterDetail.Detail>
|
|
3909
|
+
{selectedId ? <ItemDetail id={selectedId} /> : <EmptyState />}
|
|
3910
|
+
</MasterDetail.Detail>
|
|
3911
|
+
</MasterDetail>
|
|
3912
|
+
```
|
|
3913
|
+
|
|
3914
|
+
## Gotchas
|
|
3915
|
+
- On mobile (below breakpoint), List and Detail are mutually exclusive — selecting an item hides the list
|
|
3916
|
+
- The `onBack` callback is required for the mobile back button to appear in the Detail pane
|
|
3917
|
+
- Uses `window.matchMedia` — SSR renders desktop layout initially, then hydrates to correct mode
|
|
3478
3918
|
# MemberPicker
|
|
3479
3919
|
|
|
3480
3920
|
- Import: @devalok/shilp-sutra/composed/member-picker
|
|
@@ -3510,6 +3950,59 @@ Exports: CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton
|
|
|
3510
3950
|
|
|
3511
3951
|
### v0.1.0
|
|
3512
3952
|
- **Added** Initial release
|
|
3953
|
+
# MultiSelectPopover
|
|
3954
|
+
|
|
3955
|
+
- Import: @devalok/shilp-sutra/composed/multi-select-popover
|
|
3956
|
+
- Server-safe: No
|
|
3957
|
+
- Category: composed
|
|
3958
|
+
|
|
3959
|
+
## Props
|
|
3960
|
+
items: MultiSelectItem[] (flat list — use `groups` for grouped rendering)
|
|
3961
|
+
groups: MultiSelectGroup[] (grouped items with section headers)
|
|
3962
|
+
value: string[] (currently selected item IDs)
|
|
3963
|
+
onValueChange: (ids: string[]) => void
|
|
3964
|
+
searchPlaceholder: string
|
|
3965
|
+
onSearch: (query: string) => Promise<MultiSelectItem[]> (async search — replaces local filter)
|
|
3966
|
+
searchDebounce: number (debounce for async search in ms)
|
|
3967
|
+
renderItem: (item: MultiSelectItem, selected: boolean) => ReactNode (custom item renderer)
|
|
3968
|
+
emptyMessage: string (message when no items match)
|
|
3969
|
+
maxSelections: number (cap on selections)
|
|
3970
|
+
align: "start" | "center" | "end"
|
|
3971
|
+
width: string | number (popover width)
|
|
3972
|
+
children: ReactNode (trigger element)
|
|
3973
|
+
|
|
3974
|
+
### MultiSelectItem
|
|
3975
|
+
id: string
|
|
3976
|
+
label: string
|
|
3977
|
+
image?: string
|
|
3978
|
+
description?: string
|
|
3979
|
+
disabled?: boolean
|
|
3980
|
+
|
|
3981
|
+
### MultiSelectGroup
|
|
3982
|
+
label: string
|
|
3983
|
+
items: MultiSelectItem[]
|
|
3984
|
+
|
|
3985
|
+
## Defaults
|
|
3986
|
+
searchPlaceholder="Search...", searchDebounce={300}, emptyMessage="No results found", align="start", width={240}
|
|
3987
|
+
|
|
3988
|
+
## Example
|
|
3989
|
+
```jsx
|
|
3990
|
+
<MultiSelectPopover
|
|
3991
|
+
items={[
|
|
3992
|
+
{ id: '1', label: 'Alice', image: '/alice.jpg' },
|
|
3993
|
+
{ id: '2', label: 'Bob' },
|
|
3994
|
+
]}
|
|
3995
|
+
value={selected}
|
|
3996
|
+
onValueChange={setSelected}
|
|
3997
|
+
>
|
|
3998
|
+
<Button>Assign members</Button>
|
|
3999
|
+
</MultiSelectPopover>
|
|
4000
|
+
```
|
|
4001
|
+
|
|
4002
|
+
## Gotchas
|
|
4003
|
+
- Supply either `items` (flat) or `groups` (sectioned), not both
|
|
4004
|
+
- When `onSearch` is provided, local filtering is disabled — the callback must return results
|
|
4005
|
+
- Search state resets when the popover closes
|
|
3513
4006
|
# PageHeader
|
|
3514
4007
|
|
|
3515
4008
|
- Import: @devalok/shilp-sutra/composed/page-header
|
|
@@ -3615,6 +4108,40 @@ Priority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' | 'low' | 'medium' | 'high' | 'u
|
|
|
3615
4108
|
|
|
3616
4109
|
### v0.1.0
|
|
3617
4110
|
- **Added** Initial release
|
|
4111
|
+
# ResponsiveOverlay
|
|
4112
|
+
|
|
4113
|
+
- Import: @devalok/shilp-sutra/composed/responsive-overlay
|
|
4114
|
+
- Server-safe: No
|
|
4115
|
+
- Category: composed
|
|
4116
|
+
|
|
4117
|
+
## Props
|
|
4118
|
+
open: boolean
|
|
4119
|
+
onOpenChange: (open: boolean) => void
|
|
4120
|
+
title: string
|
|
4121
|
+
description: string
|
|
4122
|
+
breakpoint: "sm" | "md" (below this renders as bottom Sheet; above as Dialog)
|
|
4123
|
+
children: ReactNode
|
|
4124
|
+
className: string
|
|
4125
|
+
|
|
4126
|
+
## Defaults
|
|
4127
|
+
breakpoint="md"
|
|
4128
|
+
|
|
4129
|
+
## Example
|
|
4130
|
+
```jsx
|
|
4131
|
+
<ResponsiveOverlay
|
|
4132
|
+
open={open}
|
|
4133
|
+
onOpenChange={setOpen}
|
|
4134
|
+
title="Edit task"
|
|
4135
|
+
description="Update the task details"
|
|
4136
|
+
>
|
|
4137
|
+
<TaskForm />
|
|
4138
|
+
</ResponsiveOverlay>
|
|
4139
|
+
```
|
|
4140
|
+
|
|
4141
|
+
## Gotchas
|
|
4142
|
+
- Renders a centered Dialog on desktop and a bottom Sheet on mobile — same content, different container
|
|
4143
|
+
- Uses `window.matchMedia` internally — SSR defaults to desktop (Dialog) until hydration
|
|
4144
|
+
- Title and description are optional; if omitted, no header is rendered in either mode
|
|
3618
4145
|
# RichTextEditor
|
|
3619
4146
|
|
|
3620
4147
|
- Import: @devalok/shilp-sutra/composed/rich-text-editor
|