@devalok/shilp-sutra 0.18.1 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/docs/components/_header.md +83 -0
  2. package/docs/components/composed/activity-feed.md +43 -0
  3. package/docs/components/composed/avatar-group.md +32 -0
  4. package/docs/components/composed/command-palette.md +40 -0
  5. package/docs/components/composed/confirm-dialog.md +46 -0
  6. package/docs/components/composed/content-card.md +36 -0
  7. package/docs/components/composed/date-picker.md +130 -0
  8. package/docs/components/composed/empty-state.md +53 -0
  9. package/docs/components/composed/error-boundary.md +29 -0
  10. package/docs/components/composed/global-loading.md +27 -0
  11. package/docs/components/composed/loading-skeleton.md +51 -0
  12. package/docs/components/composed/member-picker.md +35 -0
  13. package/docs/components/composed/page-header.md +41 -0
  14. package/docs/components/composed/page-skeletons.md +32 -0
  15. package/docs/components/composed/priority-indicator.md +32 -0
  16. package/docs/components/composed/rich-text-editor.md +71 -0
  17. package/docs/components/composed/schedule-view.md +39 -0
  18. package/docs/components/composed/simple-tooltip.md +33 -0
  19. package/docs/components/composed/status-badge.md +41 -0
  20. package/docs/components/shell/app-command-palette.md +44 -0
  21. package/docs/components/shell/bottom-navbar.md +48 -0
  22. package/docs/components/shell/command-registry.md +48 -0
  23. package/docs/components/shell/link-context.md +41 -0
  24. package/docs/components/shell/notification-center.md +63 -0
  25. package/docs/components/shell/notification-preferences.md +42 -0
  26. package/docs/components/shell/sidebar.md +88 -0
  27. package/docs/components/shell/top-bar.md +63 -0
  28. package/docs/components/ui/accordion.md +48 -0
  29. package/docs/components/ui/alert-dialog.md +58 -0
  30. package/docs/components/ui/alert.md +43 -0
  31. package/docs/components/ui/aspect-ratio.md +25 -0
  32. package/docs/components/ui/autocomplete.md +48 -0
  33. package/docs/components/ui/avatar.md +34 -0
  34. package/docs/components/ui/badge.md +48 -0
  35. package/docs/components/ui/banner.md +35 -0
  36. package/docs/components/ui/breadcrumb.md +37 -0
  37. package/docs/components/ui/button-group.md +32 -0
  38. package/docs/components/ui/button.md +55 -0
  39. package/docs/components/ui/card.md +48 -0
  40. package/docs/components/ui/charts.md +43 -0
  41. package/docs/components/ui/checkbox.md +31 -0
  42. package/docs/components/ui/chip.md +43 -0
  43. package/docs/components/ui/code.md +28 -0
  44. package/docs/components/ui/collapsible.md +40 -0
  45. package/docs/components/ui/color-input.md +37 -0
  46. package/docs/components/ui/combobox.md +54 -0
  47. package/docs/components/ui/container.md +26 -0
  48. package/docs/components/ui/context-menu.md +43 -0
  49. package/docs/components/ui/data-table-toolbar.md +44 -0
  50. package/docs/components/ui/data-table.md +91 -0
  51. package/docs/components/ui/dialog.md +51 -0
  52. package/docs/components/ui/dropdown-menu.md +45 -0
  53. package/docs/components/ui/file-upload.md +41 -0
  54. package/docs/components/ui/form.md +51 -0
  55. package/docs/components/ui/hover-card.md +32 -0
  56. package/docs/components/ui/icon-button.md +33 -0
  57. package/docs/components/ui/input-otp.md +44 -0
  58. package/docs/components/ui/input.md +48 -0
  59. package/docs/components/ui/label.md +25 -0
  60. package/docs/components/ui/link.md +29 -0
  61. package/docs/components/ui/menubar.md +44 -0
  62. package/docs/components/ui/navigation-menu.md +46 -0
  63. package/docs/components/ui/number-input.md +44 -0
  64. package/docs/components/ui/pagination.md +48 -0
  65. package/docs/components/ui/popover.md +30 -0
  66. package/docs/components/ui/progress.md +29 -0
  67. package/docs/components/ui/radio.md +34 -0
  68. package/docs/components/ui/search-input.md +43 -0
  69. package/docs/components/ui/segmented-control.md +50 -0
  70. package/docs/components/ui/select.md +49 -0
  71. package/docs/components/ui/separator.md +29 -0
  72. package/docs/components/ui/sheet.md +47 -0
  73. package/docs/components/ui/sidebar.md +72 -0
  74. package/docs/components/ui/skeleton.md +77 -0
  75. package/docs/components/ui/slider.md +29 -0
  76. package/docs/components/ui/spinner.md +50 -0
  77. package/docs/components/ui/stack.md +39 -0
  78. package/docs/components/ui/stat-card.md +61 -0
  79. package/docs/components/ui/stepper.md +49 -0
  80. package/docs/components/ui/switch.md +34 -0
  81. package/docs/components/ui/table.md +47 -0
  82. package/docs/components/ui/tabs.md +56 -0
  83. package/docs/components/ui/text.md +37 -0
  84. package/docs/components/ui/textarea.md +39 -0
  85. package/docs/components/ui/toast.md +65 -0
  86. package/docs/components/ui/toaster.md +47 -0
  87. package/docs/components/ui/toggle-group.md +43 -0
  88. package/docs/components/ui/toggle.md +37 -0
  89. package/docs/components/ui/tooltip.md +33 -0
  90. package/docs/components/ui/tree-view.md +65 -0
  91. package/docs/components/ui/visually-hidden.md +21 -0
  92. package/llms-full.txt +1 -1
  93. package/package.json +4 -2
@@ -0,0 +1,32 @@
1
+ # PriorityIndicator
2
+
3
+ - Import: @devalok/shilp-sutra/composed/priority-indicator
4
+ - Server-safe: Yes
5
+ - Category: composed
6
+
7
+ ## Props
8
+ priority: Priority
9
+ display: "compact" | "full" (default: "full")
10
+
11
+ Priority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' | 'low' | 'medium' | 'high' | 'urgent'
12
+
13
+ ## Defaults
14
+ display="full"
15
+
16
+ ## Example
17
+ ```jsx
18
+ <PriorityIndicator priority="HIGH" />
19
+ <PriorityIndicator priority="low" display="compact" />
20
+ ```
21
+
22
+ ## Gotchas
23
+ - Case-insensitive — "low" and "LOW" both work
24
+ - Server-safe: can be imported directly in Next.js Server Components
25
+ - `compact` display shows only the icon; `full` shows icon + text label
26
+
27
+ ## Changes
28
+ ### v0.2.0
29
+ - **Added** Identified as server-safe component
30
+
31
+ ### v0.1.0
32
+ - **Added** Initial release
@@ -0,0 +1,71 @@
1
+ # RichTextEditor
2
+
3
+ - Import: @devalok/shilp-sutra/composed/rich-text-editor
4
+ - Server-safe: No
5
+ - Category: composed
6
+
7
+ Exports: RichTextEditor, RichTextViewer
8
+
9
+ ## Props
10
+
11
+ ### RichTextEditor
12
+ content: string (HTML string)
13
+ placeholder: string (default: "Start writing...")
14
+ onChange: (html: string) => void
15
+ className: string
16
+ editable: boolean (default: true)
17
+ onImageUpload?: (file: File) => Promise<string> — return URL. If omitted, images paste as base64
18
+ onFileUpload?: (file: File) => Promise<{ url: string; name: string; size: number }> — enables file attachments
19
+ mentions?: MentionItem[] — static list for @mention autocomplete
20
+ onMentionSearch?: (query: string) => Promise<MentionItem[]> — async search, takes precedence over static mentions
21
+ onMentionSelect?: (item: MentionItem) => void — called when a mention is selected
22
+
23
+ MentionItem: { id: string; label: string; avatar?: string }
24
+
25
+ ### RichTextViewer
26
+ content: string (REQUIRED, HTML string)
27
+ className: string
28
+
29
+ ## Defaults
30
+ RichTextEditor: placeholder="Start writing...", editable=true
31
+
32
+ ## Example
33
+ ```jsx
34
+ <RichTextEditor content={html} onChange={setHtml} placeholder="Write your message..." />
35
+
36
+ <RichTextEditor
37
+ content={html}
38
+ onChange={setHtml}
39
+ mentions={[{ id: '1', label: 'Aarav' }]}
40
+ onImageUpload={async (file) => uploadAndReturnUrl(file)}
41
+ onFileUpload={async (file) => ({ url: uploadUrl, name: file.name, size: file.size })}
42
+ />
43
+
44
+ <RichTextViewer content={savedHtml} />
45
+ ```
46
+
47
+ ## Gotchas
48
+ - Tiptap is bundled — no need to install `@tiptap/*` packages separately
49
+ - Emoji picker requires `@emoji-mart/react` + `@emoji-mart/data` peers
50
+ - Images without `onImageUpload` are stored as base64 in HTML — large images bloat content
51
+ - Mention rendering in viewer always works (no mention props needed, just the HTML)
52
+ - Features: bold, italic, underline, strikethrough, highlight, headings, blockquote, lists, task lists, code, links, images, file attachments, mentions, emoji, text alignment, horizontal rule
53
+
54
+ ## Changes
55
+ ### v0.18.0
56
+ - **Fixed** Use ref to track internal changes, prevent update loop
57
+
58
+ ### v0.9.0
59
+ - **Changed** All `@tiptap/*` packages moved from peerDependencies to bundled build-time dependencies — consumers no longer need to install tiptap separately
60
+
61
+ ### v0.8.0
62
+ - **Fixed** Emoji picker now renders above the editor (not clipped by overflow)
63
+ - **Fixed** Link/image URL injection prevented via protocol validation
64
+ - **Fixed** Escape key in emoji picker no longer closes parent dialogs
65
+ - **Fixed** Tiptap peer deps tightened to `>=2.27.2 <3.0.0`
66
+
67
+ ### v0.7.0
68
+ - **Added** Initial release — full-featured tiptap-based rich text editing with toolbar, mentions, emoji, image, alignment
69
+
70
+ ### v0.1.1
71
+ - **Fixed** Added content sync effect so editor updates when `content` prop changes externally
@@ -0,0 +1,39 @@
1
+ # ScheduleView
2
+
3
+ - Import: @devalok/shilp-sutra/composed/schedule-view
4
+ - Server-safe: No
5
+ - Category: composed
6
+
7
+ ## Props
8
+ view: "day" | "week" (REQUIRED)
9
+ date: Date (REQUIRED — current day or any date in target week)
10
+ events: ScheduleEvent[] (REQUIRED) — { id, title, start: Date, end: Date, color? }
11
+ onEventClick: (event: ScheduleEvent) => void
12
+ onSlotClick: (start: Date, end: Date) => void
13
+ startHour: number (default: 8)
14
+ endHour: number (default: 18, exclusive)
15
+ slotDuration: number (minutes, default: 30)
16
+
17
+ Event colors: "primary" | "success" | "warning" | "error" | "info" | "neutral"
18
+
19
+ ## Defaults
20
+ startHour=8, endHour=18, slotDuration=30
21
+
22
+ ## Example
23
+ ```jsx
24
+ <ScheduleView
25
+ view="week"
26
+ date={new Date()}
27
+ events={calendarEvents}
28
+ onEventClick={(e) => openEvent(e.id)}
29
+ />
30
+ ```
31
+
32
+ ## Gotchas
33
+ - `endHour` is exclusive — `endHour=18` means the last visible slot starts at 17:30 (with default 30min slots)
34
+ - `onSlotClick` fires when clicking an empty time slot — useful for creating new events
35
+ - Events that span outside `startHour`/`endHour` may be clipped
36
+
37
+ ## Changes
38
+ ### v0.1.0
39
+ - **Added** Initial release
@@ -0,0 +1,33 @@
1
+ # SimpleTooltip
2
+
3
+ - Import: @devalok/shilp-sutra/composed/simple-tooltip
4
+ - Server-safe: No
5
+ - Category: composed
6
+
7
+ ## Props
8
+ content: ReactNode (REQUIRED — tooltip content)
9
+ side: "top" | "right" | "bottom" | "left" (default: "top")
10
+ align: "start" | "center" | "end" (default: "center")
11
+ delayDuration: number (ms, default: 300)
12
+ children: ReactNode (trigger element)
13
+
14
+ ## Defaults
15
+ side="top", align="center", delayDuration=300
16
+
17
+ ## Example
18
+ ```jsx
19
+ <SimpleTooltip content="Edit this item">
20
+ <IconButton icon={<IconEdit />} aria-label="Edit" />
21
+ </SimpleTooltip>
22
+ ```
23
+
24
+ ## Gotchas
25
+ - Wraps the full Tooltip compound (Provider + Tooltip + Trigger + Content) into one component — no need for TooltipProvider
26
+ - Unlike the low-level Tooltip, SimpleTooltip does not require wrapping in a TooltipProvider
27
+
28
+ ## Changes
29
+ ### v0.18.0
30
+ - **Fixed** Type definition corrected
31
+
32
+ ### v0.1.0
33
+ - **Added** Initial release
@@ -0,0 +1,41 @@
1
+ # StatusBadge
2
+
3
+ - Import: @devalok/shilp-sutra/composed/status-badge
4
+ - Server-safe: No
5
+ - Category: composed
6
+
7
+ Note: StatusBadge was server-safe prior to v0.18.0 but is NO LONGER server-safe due to Framer Motion dependency.
8
+
9
+ ## Props
10
+ status: "active" | "pending" | "approved" | "rejected" | "completed" | "blocked" | "cancelled" | "draft"
11
+ color: "success" | "warning" | "error" | "info" | "neutral" (overrides status styling when set)
12
+ size: "sm" | "md"
13
+ label: string (auto-derived from status/color if omitted)
14
+ hideDot: boolean (default: false)
15
+
16
+ ## Defaults
17
+ size="md", hideDot=false
18
+
19
+ ## Example
20
+ ```jsx
21
+ <StatusBadge status="active" />
22
+ <StatusBadge color="warning" label="In Review" size="sm" />
23
+ ```
24
+
25
+ ## Gotchas
26
+ - When `color` is set, it takes priority over `status` for styling
27
+ - Props use a discriminated union — pass either `status` or `color`, not both
28
+ - As of v0.18.0, StatusBadge is NOT server-safe (Framer Motion dependency)
29
+
30
+ ## Changes
31
+ ### v0.18.0
32
+ - **Changed** No longer server-safe due to Framer Motion dependency
33
+
34
+ ### v0.8.0
35
+ - **Changed** Props now use discriminated union — pass either `status` or `color`, not both
36
+
37
+ ### v0.2.0
38
+ - **Added** Identified as server-safe component (later reverted in v0.18.0)
39
+
40
+ ### v0.1.0
41
+ - **Added** Initial release
@@ -0,0 +1,44 @@
1
+ # AppCommandPalette
2
+
3
+ - Import: @devalok/shilp-sutra/shell/app-command-palette
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ user?: AppCommandPaletteUser | null — { name, role? } (optional)
9
+ isAdmin?: boolean (shows admin command groups regardless of user.role; takes precedence over role-based detection)
10
+ extraGroups?: CommandGroup[]
11
+ onNavigate?: (path: string) => void
12
+ onSearch?: (query: string) => void
13
+ searchResults?: SearchResult[]
14
+ isSearching?: boolean (shows loading state while search is in progress)
15
+ onSearchResultSelect?: (result: SearchResult) => void
16
+
17
+ SearchResult: { id: string, title: string, snippet?: string, entityType: string, projectId?: string | null, metadata?: Record<string, unknown> }
18
+ AppCommandPaletteUser: { name: string, role?: string }
19
+
20
+ ## Defaults
21
+ None
22
+
23
+ ## Example
24
+ ```jsx
25
+ <AppCommandPalette
26
+ user={{ name: 'John', role: 'admin' }}
27
+ isAdmin={true}
28
+ onNavigate={(path) => router.push(path)}
29
+ searchResults={results}
30
+ onSearchResultSelect={(r) => router.push(`/${r.entityType}/${r.id}`)}
31
+ />
32
+ ```
33
+
34
+ ## Gotchas
35
+ - Uses CommandRegistry context for page navigation items (see CommandRegistryProvider)
36
+ - `isAdmin` takes precedence over `user.role` for showing admin command groups
37
+ - Should be placed at the app root level, typically alongside TopBar
38
+
39
+ ## Changes
40
+ ### v0.3.0
41
+ - **Fixed** Added missing `'use client'` directive
42
+
43
+ ### v0.1.0
44
+ - **Added** Initial release
@@ -0,0 +1,48 @@
1
+ # BottomNavbar
2
+
3
+ - Import: @devalok/shilp-sutra/shell/bottom-navbar
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ currentPath?: string (optional)
9
+ user?: BottomNavbarUser | null (optional)
10
+ primaryItems?: BottomNavItem[] (max 4 recommended, optional)
11
+ moreItems?: BottomNavItem[] (overflow items in "More" menu, optional)
12
+ className?: string
13
+
14
+ BottomNavItem: { title: string, href: string, icon: ReactNode, exact?: boolean, badge?: number }
15
+ BottomNavbarUser: { name: string, role?: string }
16
+
17
+ ## Defaults
18
+ None
19
+
20
+ ## Example
21
+ ```jsx
22
+ <BottomNavbar
23
+ currentPath="/dashboard"
24
+ primaryItems={[
25
+ { title: 'Home', href: '/', icon: <IconHome /> },
26
+ { title: 'Tasks', href: '/tasks', icon: <IconChecklist /> },
27
+ ]}
28
+ />
29
+ ```
30
+
31
+ ## Gotchas
32
+ - Designed for mobile viewports — fixed to bottom of screen
33
+ - Max 4 `primaryItems` recommended; overflow goes in `moreItems` shown in a "More" sheet
34
+ - Use with `useIsMobile()` hook to conditionally render instead of AppSidebar
35
+ - Requires LinkProvider for framework-specific link components (e.g., Next.js Link)
36
+
37
+ ## Changes
38
+ ### v0.18.0
39
+ - **Fixed** Removed incorrect `role="button"` and `tabIndex` from overlay
40
+
41
+ ### v0.16.0
42
+ - **Added** `badge?: number` on `BottomNavItem` — notification count badge (red dot, 99+ cap)
43
+
44
+ ### v0.1.1
45
+ - **Changed** Decoupled from Next.js via LinkProvider
46
+
47
+ ### v0.1.0
48
+ - **Added** Initial release
@@ -0,0 +1,48 @@
1
+ # CommandRegistry
2
+
3
+ - Import: @devalok/shilp-sutra/shell/command-registry
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ Exports: CommandRegistryProvider, useCommandRegistry
8
+
9
+ ## Props
10
+
11
+ ### CommandRegistryProvider
12
+ children: ReactNode
13
+ registry: CommandRegistry (REQUIRED)
14
+
15
+ CommandRegistry: { pages: CommandPageItem[], adminPages: CommandPageItem[] }
16
+ CommandPageItem: { id: string, label: string, icon: ReactNode, path: string, keywords?: string[] }
17
+
18
+ ### useCommandRegistry hook
19
+ Returns: CommandRegistry | null
20
+
21
+ ## Defaults
22
+ None
23
+
24
+ ## Example
25
+ ```jsx
26
+ <CommandRegistryProvider
27
+ registry={{
28
+ pages: [
29
+ { id: 'dashboard', label: 'Dashboard', icon: <IconHome />, path: '/dashboard' },
30
+ { id: 'projects', label: 'Projects', icon: <IconFolder />, path: '/projects' },
31
+ ],
32
+ adminPages: [
33
+ { id: 'users', label: 'Manage Users', icon: <IconUsers />, path: '/admin/users' },
34
+ ],
35
+ }}
36
+ >
37
+ <App />
38
+ </CommandRegistryProvider>
39
+ ```
40
+
41
+ ## Gotchas
42
+ - Provides the command registry context consumed by AppCommandPalette
43
+ - Place at app root, wrapping both AppCommandPalette and the rest of the app
44
+ - `useCommandRegistry()` returns `null` if no provider is found — handle this case
45
+
46
+ ## Changes
47
+ ### v0.1.0
48
+ - **Added** Initial release
@@ -0,0 +1,41 @@
1
+ # LinkProvider
2
+
3
+ - Import: @devalok/shilp-sutra/shell/link-context
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ Exports: LinkProvider, useLink
8
+
9
+ ## Props
10
+
11
+ ### LinkProvider
12
+ component: ForwardRefComponent (e.g. Next.js Link, Remix Link)
13
+ children: ReactNode
14
+
15
+ ### useLink hook
16
+ Returns: LinkComponent
17
+
18
+ ## Defaults
19
+ Without LinkProvider, shell components render plain `<a>` tags
20
+
21
+ ## Example
22
+ ```jsx
23
+ import Link from 'next/link'
24
+
25
+ <LinkProvider component={Link}>
26
+ <AppSidebar ... />
27
+ <BottomNavbar ... />
28
+ </LinkProvider>
29
+ ```
30
+
31
+ ## Gotchas
32
+ - Without LinkProvider, shell components render plain `<a>` tags (full page reloads)
33
+ - Place at app root, wrapping all shell components that render navigation links
34
+ - The `component` prop must be a forwardRef component (Next.js Link, Remix Link, etc.)
35
+
36
+ ## Changes
37
+ ### v0.1.1
38
+ - **Added** Shell components decoupled from Next.js — replaced hard `next/link` import with polymorphic `LinkProvider`/`useLink` context
39
+
40
+ ### v0.1.0
41
+ - **Added** Initial release (with hardcoded Next.js Link dependency)
@@ -0,0 +1,63 @@
1
+ # NotificationCenter
2
+
3
+ - Import: @devalok/shilp-sutra/shell/notification-center
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ notifications?: Notification[]
9
+ unreadCount: number (derived from notifications if not provided)
10
+ open: boolean (controlled mode)
11
+ onOpenChange: (open: boolean) => void
12
+ isLoading: boolean
13
+ hasMore: boolean
14
+ onFetchMore: () => void
15
+ onMarkRead: (id: string) => void
16
+ onMarkAllRead: () => void
17
+ onNavigate: (path: string) => void — called when a notification with a route is clicked
18
+ getNotificationRoute: (notification: Notification) => string | null — returns route for a notification; defaults to () => null
19
+ footerSlot: ReactNode — content rendered in a sticky footer below the scroll area
20
+ emptyState: ReactNode — replaces default empty state UI
21
+ headerActions: ReactNode — extra action buttons after "Mark all read"
22
+ popoverClassName: string — override default popover dimensions
23
+ onDismiss: (id: string) => void — when provided, each notification shows a dismiss button
24
+
25
+ Notification: { id: string, title: string, body?: string | null, tier: 'INFO' | 'IMPORTANT' | 'CRITICAL', isRead: boolean, createdAt: string, entityType?: string | null, entityId?: string | null, projectId?: string | null, project?: { title: string } | null, actions?: NotificationAction[] }
26
+ NotificationAction: { label: string, variant?: 'primary' | 'default' | 'danger', onClick: (id: string) => void }
27
+
28
+ ## Defaults
29
+ getNotificationRoute defaults to () => null (no hardcoded routes)
30
+
31
+ ## Example
32
+ ```jsx
33
+ <NotificationCenter
34
+ notifications={notifications}
35
+ onMarkRead={markAsRead}
36
+ onMarkAllRead={markAllAsRead}
37
+ onNavigate={(path) => router.push(path)}
38
+ getNotificationRoute={(n) => n.entityType === 'task' ? `/tasks/${n.entityId}` : null}
39
+ onDismiss={(id) => dismissNotification(id)}
40
+ footerSlot={<Link href="/notifications">View all notifications</Link>}
41
+ emptyState={<p>You're all caught up!</p>}
42
+ headerActions={<Button variant="ghost" size="sm">Settings</Button>}
43
+ popoverClassName="w-[480px]"
44
+ />
45
+ ```
46
+
47
+ ## Gotchas
48
+ - Typically rendered inside TopBar's `notificationSlot` prop
49
+ - `getNotificationRoute` must be provided for clickable notifications — no hardcoded routes
50
+ - Tier dot doubles as read/unread marker (opacity-based)
51
+ - `onDismiss` enables per-notification dismiss buttons when provided
52
+
53
+ ## Changes
54
+ ### v0.13.0
55
+ - **Added** `NotificationAction` type and `actions` prop on `Notification` — inline action buttons per notification row
56
+ - **Fixed** Tier dot now doubles as read/unread marker (opacity-based) — removed separate unread indicator dot
57
+
58
+ ### v0.1.1
59
+ - **Changed** Decoupled from Next.js via LinkProvider
60
+ - **Fixed** Added `aria-label` to bell button
61
+
62
+ ### v0.1.0
63
+ - **Added** Initial release
@@ -0,0 +1,42 @@
1
+ # NotificationPreferences
2
+
3
+ - Import: @devalok/shilp-sutra/shell/notification-preferences
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ preferences?: NotificationPreference[]
9
+ projects?: NotificationProject[]
10
+ isLoading?: boolean
11
+ onSave?: (preference: { projectId, channel, minTier, muted }) => void | Promise<void>
12
+ onToggleMute?: (preference: NotificationPreference) => void | Promise<void>
13
+ onUpdateTier?: (preference: NotificationPreference, newTier: string) => void | Promise<void>
14
+ onDelete?: (preferenceId: string) => void | Promise<void>
15
+ className?: string
16
+
17
+ NotificationPreference: { id: string, userId?: string, projectId: string | null, channel: string, minTier: string, muted: boolean }
18
+ NotificationProject: { id: string, title: string }
19
+
20
+ ## Defaults
21
+ None
22
+
23
+ ## Example
24
+ ```jsx
25
+ <NotificationPreferences
26
+ preferences={prefs}
27
+ projects={projectList}
28
+ onSave={handleSavePref}
29
+ onToggleMute={handleToggleMute}
30
+ onUpdateTier={handleUpdateTier}
31
+ onDelete={handleDeletePref}
32
+ />
33
+ ```
34
+
35
+ ## Gotchas
36
+ - Manages per-project notification preferences (channel, tier, mute)
37
+ - All callback props support async (Promise<void>) for server-side operations
38
+ - Typically rendered on a settings/preferences page
39
+
40
+ ## Changes
41
+ ### v0.1.0
42
+ - **Added** Initial release
@@ -0,0 +1,88 @@
1
+ # AppSidebar
2
+
3
+ - Import: @devalok/shilp-sutra/shell/sidebar
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ currentPath?: string (highlights active nav item)
9
+ user?: SidebarUser | null — { name, email?, image?, designation?, role? }
10
+ navGroups?: NavGroup[] — { label: string, items: NavItem[], action?: ReactNode }
11
+ logo?: ReactNode
12
+ footerLinks?: Array<{ label: string, href: string }> (DEPRECATED — use footer.links)
13
+ footer?: SidebarFooterConfig — structured footer (takes precedence over footerLinks)
14
+ headerSlot?: ReactNode — content between user info and navigation
15
+ preFooterSlot?: ReactNode — content between navigation and footer
16
+ preFooterClassName?: string — className on preFooterSlot wrapper div
17
+ renderItem?: (item: NavItem, defaultRender: () => ReactNode) => ReactNode | null — custom item rendering
18
+ className?: string
19
+
20
+ NavItem: { title: string, href: string, icon: ReactNode, exact?: boolean, badge?: string | number, children?: NavSubItem[], defaultOpen?: boolean }
21
+ NavSubItem: { title: string, href: string, icon?: ReactNode, exact?: boolean }
22
+ NavGroup: { label: string, items: NavItem[], action?: ReactNode }
23
+ SidebarUser: { name: string, email?: string, image?: string | null, designation?: string, role?: string }
24
+ SidebarFooterConfig: { links: Array<{ label: string, href: string }>, version: string | { label: string, href: string }, slot: ReactNode, promo: SidebarPromo }
25
+ SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?: string, onClick?: () => void }, onDismiss?: () => void }
26
+
27
+ ## Defaults
28
+ None
29
+
30
+ ## Example
31
+ ```jsx
32
+ <AppSidebar
33
+ currentPath="/dashboard"
34
+ user={{ name: 'Jane', email: 'jane@example.com' }}
35
+ navGroups={[{
36
+ label: 'Main',
37
+ items: [
38
+ { title: 'Dashboard', href: '/dashboard', icon: <IconHome /> },
39
+ { title: 'Projects', href: '/projects', icon: <IconFolder />, children: [
40
+ { title: 'Karm V2', href: '/projects/abc/board' },
41
+ ]},
42
+ ],
43
+ }]}
44
+ footer={{
45
+ links: [{ label: 'Terms', href: '/terms' }],
46
+ version: { label: 'v2.4.1', href: '/changelog' },
47
+ }}
48
+ />
49
+ ```
50
+
51
+ ## Gotchas
52
+ - Must be wrapped in SidebarProvider (from ui/sidebar)
53
+ - Requires LinkProvider for framework-specific link components
54
+ - `footerLinks` is deprecated — use `footer.links` instead
55
+ - `renderItem` returning `null` falls back to default rendering
56
+ - Collapsible nav items auto-open when a child is active (matching `currentPath`)
57
+ - Badge numbers > 99 display as "99+"
58
+
59
+ ## Changes
60
+ ### v0.18.0
61
+ - **Fixed** `bg-interactive-subtle` changed to `bg-accent-2` (OKLCH migration)
62
+
63
+ ### v0.16.0
64
+ - **Added** `preFooterClassName?: string` — custom className on preFooterSlot wrapper
65
+
66
+ ### v0.14.0
67
+ - **Changed** `footer.version` now accepts `string | { label: string; href: string }` — version can link to changelog
68
+
69
+ ### v0.13.0
70
+ - **Added** `SidebarPromo` type and `footer.promo` prop — dismissable promo/upsell banner
71
+ - **Changed** Footer links and version now render on a single line separated by dividers
72
+ - **Fixed** Collapsible chevron wrapped in fixed-height container to prevent drift
73
+ - **Fixed** Collapsible chevron no longer drifts into child elements when sub-list expands
74
+
75
+ ### v0.10.0
76
+ - **Added** Collapsible nav items with `children` array and `NavSubItem` type
77
+ - **Added** Nav item `badge` prop for counts/labels, caps at 99+
78
+ - **Added** Nav group `action` prop for buttons next to group labels
79
+ - **Added** Structured `footer` prop with `SidebarFooterConfig` — links, version, slot
80
+ - **Added** `headerSlot` and `preFooterSlot` content slots
81
+ - **Added** `renderItem` escape hatch for custom item rendering
82
+ - **Deprecated** `footerLinks` prop — use `footer.links` instead
83
+
84
+ ### v0.1.1
85
+ - **Changed** Decoupled from Next.js via LinkProvider
86
+
87
+ ### v0.1.0
88
+ - **Added** Initial release
@@ -0,0 +1,63 @@
1
+ # TopBar
2
+
3
+ - Import: @devalok/shilp-sutra/shell/top-bar
4
+ - Server-safe: No
5
+ - Category: shell
6
+
7
+ ## Props
8
+ pageTitle?: string (default: "")
9
+ user?: TopBarUser | null — { name, email?, image? }
10
+ onNavigate?: (path: string) => void
11
+ onLogout?: () => void
12
+ onSearchClick?: () => void
13
+ onAiChatClick?: () => void
14
+ mobileLogo?: ReactNode
15
+ notificationSlot?: ReactNode (render NotificationCenter here)
16
+ userMenuItems?: UserMenuItem[] — custom items between Profile and Dark/Light Mode toggle
17
+ className?: string
18
+
19
+ TopBarUser: { name: string, email?: string, image?: string | null }
20
+ UserMenuItem: { label: string, icon?: ReactNode, href?: string, onClick?: () => void, separator?: boolean, color?: string, badge?: string | boolean, disabled?: boolean }
21
+
22
+ UserMenuItem fields:
23
+ - href — navigates via onNavigate callback
24
+ - onClick — custom action (takes precedence over href)
25
+ - separator — renders a DropdownMenuSeparator before this item
26
+ - color — semantic text color (e.g. "error" for text-error)
27
+ - badge — string for count badge, true for dot indicator
28
+ - disabled — greys out the item
29
+
30
+ ## Defaults
31
+ None
32
+
33
+ ## Example
34
+ ```jsx
35
+ <TopBar
36
+ pageTitle="Dashboard"
37
+ user={{ name: 'John', email: 'john@example.com' }}
38
+ onNavigate={(p) => router.push(p)}
39
+ onLogout={handleLogout}
40
+ notificationSlot={<NotificationCenter notifications={notifications} />}
41
+ userMenuItems={[
42
+ { label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },
43
+ { label: 'Shortcuts', icon: <IconKeyboard />, onClick: () => openModal() },
44
+ ]}
45
+ />
46
+ ```
47
+
48
+ ## Gotchas
49
+ - `notificationSlot` is where NotificationCenter should be rendered
50
+ - `userMenuItems` are inserted between the Profile link and the Dark/Light Mode toggle in the user dropdown
51
+ - Requires LinkProvider for framework-specific navigation
52
+
53
+ ## Changes
54
+ ### v0.7.0
55
+ - **Added** `userMenuItems` prop for custom dropdown items
56
+
57
+ ### v0.1.1
58
+ - **Changed** Decoupled from Next.js via LinkProvider
59
+ - **Fixed** Added `aria-label` to search/AI buttons
60
+ - **Fixed** Added `type="button"` to search/AI/avatar buttons to prevent form submission
61
+
62
+ ### v0.1.0
63
+ - **Added** Initial release