@devalok/shilp-sutra 0.18.2 → 0.19.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/shell/bottom-navbar.js +4 -4
- package/dist/shell/sidebar.js +2 -2
- package/dist/shell/top-bar.d.ts +45 -20
- package/dist/shell/top-bar.d.ts.map +1 -1
- package/dist/shell/top-bar.js +222 -159
- package/dist/tokens/semantic.css +5 -5
- package/dist/ui/sidebar.js +11 -11
- package/docs/components/_header.md +7 -5
- package/docs/components/composed/activity-feed.md +4 -4
- package/docs/components/composed/command-palette.md +2 -2
- package/docs/components/composed/confirm-dialog.md +1 -1
- package/docs/components/composed/date-picker.md +13 -13
- package/docs/components/composed/schedule-view.md +2 -2
- package/docs/components/composed/status-badge.md +1 -0
- package/docs/components/shell/bottom-navbar.md +4 -0
- package/docs/components/shell/notification-center.md +15 -15
- package/docs/components/shell/sidebar.md +5 -1
- package/docs/components/shell/top-bar.md +101 -24
- package/docs/components/ui/autocomplete.md +1 -1
- package/docs/components/ui/banner.md +1 -0
- package/docs/components/ui/chip.md +1 -0
- package/docs/components/ui/combobox.md +2 -2
- package/docs/components/ui/input.md +1 -1
- package/docs/components/ui/spinner.md +1 -0
- package/docs/components/ui/tabs.md +1 -1
- package/llms-full.txt +164 -73
- package/llms.txt +1 -1
- package/package.json +699 -699
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.19.0
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
@@ -42,10 +42,10 @@ Color tokens use OKLCH (perceptually uniform) with 12 functional steps per palet
|
|
|
42
42
|
| 2 | Subtle background | Sidebar, card alt |
|
|
43
43
|
| 3 | Component bg | Input bg, badge bg |
|
|
44
44
|
| 4 | Component bg hover | Button hover state |
|
|
45
|
-
| 5 |
|
|
46
|
-
| 6 | Border
|
|
47
|
-
| 7 | Border
|
|
48
|
-
| 8 | Border
|
|
45
|
+
| 5 | Border subtle | Semantic `surface-border` in light mode |
|
|
46
|
+
| 6 | Border default | Semantic `surface-border-strong` in light mode |
|
|
47
|
+
| 7 | Border strong | Focus rings, emphasis borders |
|
|
48
|
+
| 8 | Border emphasis | High-contrast outlines |
|
|
49
49
|
| 9 | Solid / accent | Button bg, primary CTA |
|
|
50
50
|
| 10 | Solid hover | Button hover bg |
|
|
51
51
|
| 11 | Low-contrast text | Secondary accent text |
|
|
@@ -54,7 +54,9 @@ Color tokens use OKLCH (perceptually uniform) with 12 functional steps per palet
|
|
|
54
54
|
Semantic layer:
|
|
55
55
|
- Accent (swappable): --color-accent-{1-12} + --color-accent-fg
|
|
56
56
|
- Secondary: --color-secondary-{1-12} + --color-secondary-fg
|
|
57
|
-
- Surface: --color-surface-{1-4} + --color-surface-fg / fg-muted / fg-subtle / border
|
|
57
|
+
- Surface: --color-surface-{1-4} + --color-surface-fg / fg-muted / fg-subtle / border / border-strong
|
|
58
|
+
- Border mapping: light mode border=step5, border-strong=step6; dark mode border=step3, border-strong=step4
|
|
59
|
+
- Shell chrome (sidebar, topbar, bottom nav) uses surface-2 for elevation above surface-1 app background
|
|
58
60
|
- Status: --color-{error,success,warning,info}-{3,7,9,11}
|
|
59
61
|
- Category: --color-category-{teal,amber,slate,indigo,cyan,orange,emerald}
|
|
60
62
|
|
|
@@ -273,7 +275,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
273
275
|
## Props
|
|
274
276
|
options: AutocompleteOption[] (REQUIRED) — { value: string, label: string }
|
|
275
277
|
value: AutocompleteOption | null
|
|
276
|
-
onValueChange
|
|
278
|
+
onValueChange?: (option: AutocompleteOption) => void
|
|
277
279
|
placeholder: string
|
|
278
280
|
emptyText: string (default: "No options")
|
|
279
281
|
disabled: boolean
|
|
@@ -419,6 +421,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
419
421
|
## Gotchas
|
|
420
422
|
- Banner is full-width (spans container). Alert is inline.
|
|
421
423
|
- Renders role="alert" automatically
|
|
424
|
+
- `onDismiss` fires after the exit animation completes, not immediately on dismiss button click
|
|
422
425
|
|
|
423
426
|
## Changes
|
|
424
427
|
### v0.3.1
|
|
@@ -707,6 +710,7 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
707
710
|
- MUST use label prop — children are NOT rendered
|
|
708
711
|
- `<Chip>text</Chip>` is WRONG — use `<Chip label="text" />`
|
|
709
712
|
- Wrap dynamic chip lists in `<ChipGroup>` for exit animations
|
|
713
|
+
- `color="primary"` will be renamed to `color="brand"` in v1.0 — use `color="primary"` for now
|
|
710
714
|
|
|
711
715
|
## Changes
|
|
712
716
|
### v0.4.2
|
|
@@ -832,8 +836,8 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
832
836
|
## Props
|
|
833
837
|
options: ComboboxOption[] (REQUIRED) — { value: string, label: string, description?: string, icon?: ReactNode, disabled?: boolean }
|
|
834
838
|
DISCRIMINATED UNION — type depends on `multiple` flag:
|
|
835
|
-
Single (default): multiple?: false, value
|
|
836
|
-
Multiple: multiple: true, value
|
|
839
|
+
Single (default): multiple?: false, value?: string, onValueChange: (value: string) => void
|
|
840
|
+
Multiple: multiple: true, value?: string[], onValueChange: (value: string[]) => void
|
|
837
841
|
placeholder: string (default: "Select...")
|
|
838
842
|
searchPlaceholder: string (default: "Search...")
|
|
839
843
|
emptyMessage: string (default: "No results found")
|
|
@@ -1362,7 +1366,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1362
1366
|
- HTML native "size" attribute is excluded — use CSS width instead
|
|
1363
1367
|
- state="error" sets aria-invalid automatically
|
|
1364
1368
|
- Inside FormField: auto-inherits state, aria-describedby, aria-required from context (explicit props override)
|
|
1365
|
-
- Resting border is border-subtle (soft); focus ring is ring-1
|
|
1369
|
+
- Resting border is border-subtle (soft); focus ring is `ring-1 ring-accent-7` (v0.12.0)
|
|
1366
1370
|
- All sizes (sm, md, lg) use text-ds-md (14px) font — size only affects height and padding (v0.15.0)
|
|
1367
1371
|
|
|
1368
1372
|
## Changes
|
|
@@ -2163,6 +2167,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2163
2167
|
variant: "filled" | "bare"
|
|
2164
2168
|
delay: number (ms — render delay to avoid flicker on fast operations)
|
|
2165
2169
|
onComplete: () => void (callback after success/error state transition)
|
|
2170
|
+
className: string
|
|
2166
2171
|
|
|
2167
2172
|
## Defaults
|
|
2168
2173
|
size: "md"
|
|
@@ -2476,7 +2481,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2476
2481
|
|
|
2477
2482
|
## Gotchas
|
|
2478
2483
|
- variant goes on TabsList, NOT on individual TabsTrigger (propagates via context)
|
|
2479
|
-
-
|
|
2484
|
+
- Normally omit `variant` on TabsTrigger — it inherits from TabsList via context. You CAN set it per-trigger to override.
|
|
2480
2485
|
|
|
2481
2486
|
## Changes
|
|
2482
2487
|
### v0.18.0
|
|
@@ -2891,15 +2896,15 @@ export default function RootLayout({ children }) {
|
|
|
2891
2896
|
|
|
2892
2897
|
## Props
|
|
2893
2898
|
items: ActivityItem[] (REQUIRED) — { id, actor?: { name, image? }, action: string|ReactNode, timestamp: Date|string, icon?, color?: 'default'|'success'|'warning'|'error'|'info', detail?: ReactNode }
|
|
2894
|
-
onLoadMore
|
|
2899
|
+
onLoadMore?: () => void — "Load more" button callback
|
|
2895
2900
|
loading: boolean — skeleton shimmer
|
|
2896
|
-
hasMore
|
|
2897
|
-
emptyState
|
|
2901
|
+
hasMore?: boolean — shows "Load more" button
|
|
2902
|
+
emptyState?: ReactNode — empty state content
|
|
2898
2903
|
compact: boolean — tighter spacing, no avatars, smaller text
|
|
2899
2904
|
maxInitialItems: number — truncate with "Show all (N)" toggle
|
|
2900
2905
|
|
|
2901
2906
|
## Defaults
|
|
2902
|
-
loading=false, compact=false
|
|
2907
|
+
loading=false, compact=false, hasMore=false
|
|
2903
2908
|
|
|
2904
2909
|
## Example
|
|
2905
2910
|
```jsx
|
|
@@ -2965,7 +2970,7 @@ export default function RootLayout({ children }) {
|
|
|
2965
2970
|
- Category: composed
|
|
2966
2971
|
|
|
2967
2972
|
## Props
|
|
2968
|
-
groups
|
|
2973
|
+
groups?: CommandGroup[] (default: []) — { label: string, items: CommandItem[] }
|
|
2969
2974
|
placeholder: string (default: "Search or jump to...")
|
|
2970
2975
|
onSearch: (query: string) => void
|
|
2971
2976
|
emptyMessage: string (default: "No results found.")
|
|
@@ -2973,7 +2978,7 @@ export default function RootLayout({ children }) {
|
|
|
2973
2978
|
CommandItem shape: { id, label, description?, icon?, shortcut?, onSelect: () => void }
|
|
2974
2979
|
|
|
2975
2980
|
## Defaults
|
|
2976
|
-
placeholder="Search or jump to...", emptyMessage="No results found."
|
|
2981
|
+
placeholder="Search or jump to...", emptyMessage="No results found.", groups=[]
|
|
2977
2982
|
|
|
2978
2983
|
## Example
|
|
2979
2984
|
```jsx
|
|
@@ -3012,7 +3017,7 @@ CommandItem shape: { id, label, description?, icon?, shortcut?, onSelect: () =>
|
|
|
3012
3017
|
confirmText: string (default: "Confirm")
|
|
3013
3018
|
cancelText: string (default: "Cancel")
|
|
3014
3019
|
color: "default" | "error" (controls confirm button color)
|
|
3015
|
-
loading: boolean (default: false, disables buttons and
|
|
3020
|
+
loading: boolean (default: false, disables buttons and replaces confirm button text with 'Processing...')
|
|
3016
3021
|
onConfirm: () => void | Promise<void> (REQUIRED)
|
|
3017
3022
|
|
|
3018
3023
|
## Defaults
|
|
@@ -3089,8 +3094,8 @@ const [open, setOpen] = useState(false)
|
|
|
3089
3094
|
## Props
|
|
3090
3095
|
|
|
3091
3096
|
### DatePicker
|
|
3092
|
-
value
|
|
3093
|
-
onChange
|
|
3097
|
+
value?: Date | null
|
|
3098
|
+
onChange?: (date: Date | null) => void
|
|
3094
3099
|
placeholder: string (default: "Pick a date")
|
|
3095
3100
|
formatStr: string (default: "MMM d, yyyy")
|
|
3096
3101
|
minDate: Date
|
|
@@ -3099,9 +3104,9 @@ const [open, setOpen] = useState(false)
|
|
|
3099
3104
|
className: string
|
|
3100
3105
|
|
|
3101
3106
|
### DateRangePicker
|
|
3102
|
-
startDate
|
|
3103
|
-
endDate
|
|
3104
|
-
onChange
|
|
3107
|
+
startDate?: Date | null
|
|
3108
|
+
endDate?: Date | null
|
|
3109
|
+
onChange?: (range: { start: Date | null, end: Date | null }) => void
|
|
3105
3110
|
placeholder: string (default: "Pick a date range")
|
|
3106
3111
|
formatStr: string (default: "MMM d, yyyy")
|
|
3107
3112
|
minDate: Date
|
|
@@ -3122,8 +3127,8 @@ const [open, setOpen] = useState(false)
|
|
|
3122
3127
|
className: string
|
|
3123
3128
|
|
|
3124
3129
|
### TimePicker
|
|
3125
|
-
value
|
|
3126
|
-
onChange
|
|
3130
|
+
value?: Date | null (time stored as a Date object)
|
|
3131
|
+
onChange?: (date: Date) => void
|
|
3127
3132
|
format: "12h" | "24h" (default: "12h")
|
|
3128
3133
|
minuteStep: number (default: 1)
|
|
3129
3134
|
secondStep: number (default: 1)
|
|
@@ -3134,14 +3139,14 @@ const [open, setOpen] = useState(false)
|
|
|
3134
3139
|
|
|
3135
3140
|
### CalendarGrid
|
|
3136
3141
|
currentMonth: Date (REQUIRED)
|
|
3137
|
-
selected
|
|
3138
|
-
rangeStart
|
|
3139
|
-
rangeEnd
|
|
3140
|
-
hoverDate
|
|
3142
|
+
selected?: Date | null
|
|
3143
|
+
rangeStart?: Date | null
|
|
3144
|
+
rangeEnd?: Date | null
|
|
3145
|
+
hoverDate?: Date | null
|
|
3141
3146
|
onSelect: (date: Date) => void (REQUIRED)
|
|
3142
|
-
onHover
|
|
3147
|
+
onHover?: (date: Date | null) => void
|
|
3143
3148
|
onMonthChange: (date: Date) => void (REQUIRED)
|
|
3144
|
-
onHeaderClick
|
|
3149
|
+
onHeaderClick?: () => void
|
|
3145
3150
|
disabledDates: (date: Date) => boolean
|
|
3146
3151
|
minDate: Date
|
|
3147
3152
|
maxDate: Date
|
|
@@ -3591,8 +3596,8 @@ MentionItem: { id: string; label: string; avatar?: string }
|
|
|
3591
3596
|
view: "day" | "week" (REQUIRED)
|
|
3592
3597
|
date: Date (REQUIRED — current day or any date in target week)
|
|
3593
3598
|
events: ScheduleEvent[] (REQUIRED) — { id, title, start: Date, end: Date, color? }
|
|
3594
|
-
onEventClick
|
|
3595
|
-
onSlotClick
|
|
3599
|
+
onEventClick?: (event: ScheduleEvent) => void
|
|
3600
|
+
onSlotClick?: (start: Date, end: Date) => void
|
|
3596
3601
|
startHour: number (default: 8)
|
|
3597
3602
|
endHour: number (default: 18, exclusive)
|
|
3598
3603
|
slotDuration: number (minutes, default: 30)
|
|
@@ -3670,6 +3675,7 @@ Note: StatusBadge was server-safe prior to v0.18.0 but is NO LONGER server-safe
|
|
|
3670
3675
|
|
|
3671
3676
|
## Defaults
|
|
3672
3677
|
size="md", hideDot=false
|
|
3678
|
+
When neither status nor color is passed, defaults to status='pending' styling
|
|
3673
3679
|
|
|
3674
3680
|
## Example
|
|
3675
3681
|
```jsx
|
|
@@ -3784,6 +3790,10 @@ BottomNavbarUser: { name: string, role?: string }
|
|
|
3784
3790
|
- Requires LinkProvider for framework-specific link components (e.g., Next.js Link)
|
|
3785
3791
|
|
|
3786
3792
|
## Changes
|
|
3793
|
+
### v0.19.0
|
|
3794
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2` for visual hierarchy above app background
|
|
3795
|
+
- **Changed** "More" menu and interactive items bumped accordingly
|
|
3796
|
+
|
|
3787
3797
|
### v0.18.0
|
|
3788
3798
|
- **Fixed** Removed incorrect `role="button"` and `tabIndex` from overlay
|
|
3789
3799
|
|
|
@@ -3892,21 +3902,21 @@ import Link from 'next/link'
|
|
|
3892
3902
|
|
|
3893
3903
|
## Props
|
|
3894
3904
|
notifications?: Notification[]
|
|
3895
|
-
unreadCount
|
|
3896
|
-
open
|
|
3897
|
-
onOpenChange
|
|
3898
|
-
isLoading
|
|
3899
|
-
hasMore
|
|
3900
|
-
onFetchMore
|
|
3901
|
-
onMarkRead
|
|
3902
|
-
onMarkAllRead
|
|
3903
|
-
onNavigate
|
|
3904
|
-
getNotificationRoute
|
|
3905
|
-
footerSlot
|
|
3906
|
-
emptyState
|
|
3907
|
-
headerActions
|
|
3908
|
-
popoverClassName
|
|
3909
|
-
onDismiss
|
|
3905
|
+
unreadCount?: number (derived from notifications if not provided)
|
|
3906
|
+
open?: boolean (controlled mode)
|
|
3907
|
+
onOpenChange?: (open: boolean) => void
|
|
3908
|
+
isLoading?: boolean
|
|
3909
|
+
hasMore?: boolean
|
|
3910
|
+
onFetchMore?: () => void
|
|
3911
|
+
onMarkRead?: (id: string) => void
|
|
3912
|
+
onMarkAllRead?: () => void
|
|
3913
|
+
onNavigate?: (path: string) => void — called when a notification with a route is clicked
|
|
3914
|
+
getNotificationRoute?: (notification: Notification) => string | null — returns route for a notification; defaults to () => null
|
|
3915
|
+
footerSlot?: ReactNode — content rendered in a sticky footer below the scroll area
|
|
3916
|
+
emptyState?: ReactNode — replaces default empty state UI
|
|
3917
|
+
headerActions?: ReactNode — extra action buttons after "Mark all read"
|
|
3918
|
+
popoverClassName?: string — override default popover dimensions
|
|
3919
|
+
onDismiss?: (id: string) => void — when provided, each notification shows a dismiss button
|
|
3910
3920
|
|
|
3911
3921
|
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[] }
|
|
3912
3922
|
NotificationAction: { label: string, variant?: 'primary' | 'default' | 'danger', onClick: (id: string) => void }
|
|
@@ -4012,7 +4022,7 @@ NavItem: { title: string, href: string, icon: ReactNode, exact?: boolean, badge?
|
|
|
4012
4022
|
NavSubItem: { title: string, href: string, icon?: ReactNode, exact?: boolean }
|
|
4013
4023
|
NavGroup: { label: string, items: NavItem[], action?: ReactNode }
|
|
4014
4024
|
SidebarUser: { name: string, email?: string, image?: string | null, designation?: string, role?: string }
|
|
4015
|
-
SidebarFooterConfig: { links
|
|
4025
|
+
SidebarFooterConfig: { links?: Array<{ label: string, href: string }>, version?: string | { label: string, href: string }, slot?: ReactNode, promo?: SidebarPromo }
|
|
4016
4026
|
SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?: string, onClick?: () => void }, onDismiss?: () => void }
|
|
4017
4027
|
|
|
4018
4028
|
## Defaults
|
|
@@ -4048,6 +4058,10 @@ SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?:
|
|
|
4048
4058
|
- Badge numbers > 99 display as "99+"
|
|
4049
4059
|
|
|
4050
4060
|
## Changes
|
|
4061
|
+
### v0.19.0
|
|
4062
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2` for visual hierarchy above app background
|
|
4063
|
+
- **Changed** Interactive hover states bumped from `surface-2` to `surface-3`
|
|
4064
|
+
|
|
4051
4065
|
### v0.18.0
|
|
4052
4066
|
- **Fixed** `bg-interactive-subtle` changed to `bg-accent-2` (OKLCH migration)
|
|
4053
4067
|
|
|
@@ -4083,16 +4097,54 @@ SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?:
|
|
|
4083
4097
|
- Server-safe: No
|
|
4084
4098
|
- Category: shell
|
|
4085
4099
|
|
|
4100
|
+
## Overview
|
|
4101
|
+
|
|
4102
|
+
Composition-based application top bar. Uses dot-notation subcomponents for flexible layout.
|
|
4103
|
+
|
|
4104
|
+
## Subcomponents
|
|
4105
|
+
|
|
4106
|
+
| Component | Purpose |
|
|
4107
|
+
|-----------|---------|
|
|
4108
|
+
| `TopBar` | Root — bg-surface-2, border-b, sticky. Auto-switches to grid when Center is present. |
|
|
4109
|
+
| `TopBar.Left` | Left zone — sidebar trigger, title, breadcrumbs |
|
|
4110
|
+
| `TopBar.Center` | Optional center zone — search bar, tabs. Triggers 3-column grid layout. |
|
|
4111
|
+
| `TopBar.Right` | Right zone — action buttons, user menu. Gets ml-auto in flex mode. |
|
|
4112
|
+
| `TopBar.Section` | Groups items with configurable gap |
|
|
4113
|
+
| `TopBar.IconButton` | Circular icon button with tooltip (bg-surface-3, hover:bg-surface-4) |
|
|
4114
|
+
| `TopBar.Title` | Page title heading, hidden on mobile |
|
|
4115
|
+
| `TopBar.UserMenu` | Avatar dropdown with color mode toggle, profile, logout |
|
|
4116
|
+
|
|
4086
4117
|
## Props
|
|
4087
|
-
|
|
4088
|
-
|
|
4118
|
+
|
|
4119
|
+
### TopBar (root)
|
|
4120
|
+
children: ReactNode
|
|
4121
|
+
className?: string
|
|
4122
|
+
|
|
4123
|
+
### TopBar.Left / TopBar.Center / TopBar.Right
|
|
4124
|
+
children: ReactNode
|
|
4125
|
+
className?: string
|
|
4126
|
+
|
|
4127
|
+
### TopBar.Section
|
|
4128
|
+
gap?: "tight" | "default" | "loose" (default: "default")
|
|
4129
|
+
children: ReactNode
|
|
4130
|
+
className?: string
|
|
4131
|
+
|
|
4132
|
+
Gap values: tight = gap-ds-02, default = gap-ds-04, loose = gap-ds-06
|
|
4133
|
+
|
|
4134
|
+
### TopBar.IconButton
|
|
4135
|
+
icon: ReactNode
|
|
4136
|
+
tooltip: string
|
|
4137
|
+
...ButtonHTMLAttributes
|
|
4138
|
+
|
|
4139
|
+
### TopBar.Title
|
|
4140
|
+
children: ReactNode
|
|
4141
|
+
className?: string
|
|
4142
|
+
|
|
4143
|
+
### TopBar.UserMenu
|
|
4144
|
+
user: TopBarUser — { name, email?, image? }
|
|
4089
4145
|
onNavigate?: (path: string) => void
|
|
4090
4146
|
onLogout?: () => void
|
|
4091
|
-
|
|
4092
|
-
onAiChatClick?: () => void
|
|
4093
|
-
mobileLogo?: ReactNode
|
|
4094
|
-
notificationSlot?: ReactNode (render NotificationCenter here)
|
|
4095
|
-
userMenuItems?: UserMenuItem[] — custom items between Profile and Dark/Light Mode toggle
|
|
4147
|
+
userMenuItems?: UserMenuItem[]
|
|
4096
4148
|
className?: string
|
|
4097
4149
|
|
|
4098
4150
|
TopBarUser: { name: string, email?: string, image?: string | null }
|
|
@@ -4106,30 +4158,69 @@ UserMenuItem fields:
|
|
|
4106
4158
|
- badge — string for count badge, true for dot indicator
|
|
4107
4159
|
- disabled — greys out the item
|
|
4108
4160
|
|
|
4109
|
-
## Defaults
|
|
4110
|
-
None
|
|
4111
|
-
|
|
4112
4161
|
## Example
|
|
4162
|
+
|
|
4163
|
+
### Two-zone (standard)
|
|
4113
4164
|
```jsx
|
|
4114
|
-
<TopBar
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4165
|
+
<TopBar>
|
|
4166
|
+
<TopBar.Left>
|
|
4167
|
+
<SidebarTrigger />
|
|
4168
|
+
<TopBar.Title>Dashboard</TopBar.Title>
|
|
4169
|
+
</TopBar.Left>
|
|
4170
|
+
<TopBar.Right>
|
|
4171
|
+
<TopBar.Section gap="tight">
|
|
4172
|
+
<TopBar.IconButton icon={<IconSearch />} tooltip="Search (Ctrl+K)" onClick={openSearch} />
|
|
4173
|
+
<NotificationCenter notifications={notifications} />
|
|
4174
|
+
<TopBar.IconButton icon={<IconSparkles />} tooltip="AI Chat" onClick={openAI} />
|
|
4175
|
+
</TopBar.Section>
|
|
4176
|
+
<TopBar.UserMenu
|
|
4177
|
+
user={{ name: 'John', email: 'john@example.com' }}
|
|
4178
|
+
onNavigate={(p) => router.push(p)}
|
|
4179
|
+
onLogout={handleLogout}
|
|
4180
|
+
userMenuItems={[
|
|
4181
|
+
{ label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },
|
|
4182
|
+
]}
|
|
4183
|
+
/>
|
|
4184
|
+
</TopBar.Right>
|
|
4185
|
+
</TopBar>
|
|
4186
|
+
```
|
|
4187
|
+
|
|
4188
|
+
### Three-zone (centered search bar)
|
|
4189
|
+
```jsx
|
|
4190
|
+
<TopBar>
|
|
4191
|
+
<TopBar.Left>
|
|
4192
|
+
<SidebarTrigger />
|
|
4193
|
+
<TopBar.Title>Dashboard</TopBar.Title>
|
|
4194
|
+
</TopBar.Left>
|
|
4195
|
+
<TopBar.Center>
|
|
4196
|
+
<SearchBarTrigger />
|
|
4197
|
+
</TopBar.Center>
|
|
4198
|
+
<TopBar.Right>
|
|
4199
|
+
<TopBar.Section gap="tight">
|
|
4200
|
+
<TopBar.IconButton icon={<IconBell />} tooltip="Notifications" onClick={fn} />
|
|
4201
|
+
</TopBar.Section>
|
|
4202
|
+
<TopBar.UserMenu user={user} onLogout={logout} />
|
|
4203
|
+
</TopBar.Right>
|
|
4204
|
+
</TopBar>
|
|
4125
4205
|
```
|
|
4126
4206
|
|
|
4127
4207
|
## Gotchas
|
|
4128
|
-
- `
|
|
4129
|
-
- `
|
|
4130
|
-
-
|
|
4208
|
+
- Without `TopBar.Center`, layout is flex (two-zone). With it, layout switches to CSS grid `1fr auto 1fr` for true centering.
|
|
4209
|
+
- `TopBar.IconButton` renders any number of action buttons — no artificial limit. Use responsive hiding (`className="hidden md:flex"`) for mobile.
|
|
4210
|
+
- `TopBar.UserMenu` includes Profile link, color mode toggle, and logout automatically. `userMenuItems` are inserted between Profile and the toggle.
|
|
4211
|
+
- Requires SidebarProvider wrapper for SidebarTrigger to work.
|
|
4131
4212
|
|
|
4132
4213
|
## Changes
|
|
4214
|
+
### v0.19.0
|
|
4215
|
+
- **BREAKING** Rewritten as composition API. Old props-based API removed (`pageTitle`, `onSearchClick`, `onAiChatClick`, `notificationSlot`, `mobileLogo` props).
|
|
4216
|
+
- **Added** `TopBar.Left`, `TopBar.Center`, `TopBar.Right` zone components
|
|
4217
|
+
- **Added** `TopBar.Section` with `gap` prop (`tight` | `default` | `loose`)
|
|
4218
|
+
- **Added** `TopBar.IconButton` — reusable circular icon button with tooltip
|
|
4219
|
+
- **Added** `TopBar.Title` — responsive page title (hidden on mobile)
|
|
4220
|
+
- **Added** `TopBar.UserMenu` — extracted user dropdown as standalone subcomponent
|
|
4221
|
+
- **Added** Auto grid/flex layout detection based on Center zone presence
|
|
4222
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2`
|
|
4223
|
+
|
|
4133
4224
|
### v0.7.0
|
|
4134
4225
|
- **Added** `userMenuItems` prop for custom dropdown items
|
|
4135
4226
|
|
package/llms.txt
CHANGED
|
@@ -245,7 +245,7 @@ NOTIFICATION SELECTION GUIDE:
|
|
|
245
245
|
- Page skeletons: DashboardSkeleton, ProjectListSkeleton, TaskDetailSkeleton (no props, server-safe)
|
|
246
246
|
|
|
247
247
|
### Shell Components (app-level layout)
|
|
248
|
-
- TopBar:
|
|
248
|
+
- TopBar: Composition-based. Subcomponents: TopBar.Left, TopBar.Center (optional, triggers grid), TopBar.Right, TopBar.Section(gap: tight|default|loose), TopBar.IconButton(icon, tooltip), TopBar.Title, TopBar.UserMenu(user, onNavigate?, onLogout?, userMenuItems?). Types: TopBarUser = { name, email?, image? }, UserMenuItem = { label, icon?, href?, onClick?, separator?, color?, badge?, disabled? }
|
|
249
249
|
- AppSidebar: navigation tree with NavItem[], NavGroup[]. Types: NavItem = { title, href, icon, exact?, badge?, children?, defaultOpen? }, NavSubItem = { title, href, icon?, exact? }, NavGroup = { label, items, action? }, SidebarUser = { name, email?, image?, designation?, role? }
|
|
250
250
|
|
|
251
251
|
### AppSidebar (v0.10.0 additions)
|