@devalok/shilp-sutra 0.18.2 → 0.19.1
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/alert-dialog.js +28 -28
- package/dist/ui/chip.d.ts.map +1 -1
- package/dist/ui/chip.js +13 -12
- package/dist/ui/dialog.js +4 -4
- 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/alert-dialog.md +3 -0
- package/docs/components/ui/autocomplete.md +1 -1
- package/docs/components/ui/banner.md +1 -0
- package/docs/components/ui/chip.md +4 -0
- package/docs/components/ui/combobox.md +2 -2
- package/docs/components/ui/dialog.md +3 -0
- 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 +173 -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.1
|
|
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
|
|
|
@@ -229,6 +231,9 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
229
231
|
- AlertDialogAction does NOT have color="error" styling — add it yourself via className or wrap a Button
|
|
230
232
|
|
|
231
233
|
## Changes
|
|
234
|
+
### v0.19.1
|
|
235
|
+
- **Fixed** AlertDialog not centered after Framer Motion animation completes — same `transform: none` fix as Dialog.
|
|
236
|
+
|
|
232
237
|
### v0.18.0
|
|
233
238
|
- **Changed** Overlay animations migrated to Framer Motion (physics-based springs)
|
|
234
239
|
- **Added** `AlertDialogContentProps`, `AlertDialogActionProps`, `AlertDialogCancelProps` type exports
|
|
@@ -273,7 +278,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
273
278
|
## Props
|
|
274
279
|
options: AutocompleteOption[] (REQUIRED) — { value: string, label: string }
|
|
275
280
|
value: AutocompleteOption | null
|
|
276
|
-
onValueChange
|
|
281
|
+
onValueChange?: (option: AutocompleteOption) => void
|
|
277
282
|
placeholder: string
|
|
278
283
|
emptyText: string (default: "No options")
|
|
279
284
|
disabled: boolean
|
|
@@ -419,6 +424,7 @@ Note: getFormFieldA11y() was removed in favor of useFormField() hook.
|
|
|
419
424
|
## Gotchas
|
|
420
425
|
- Banner is full-width (spans container). Alert is inline.
|
|
421
426
|
- Renders role="alert" automatically
|
|
427
|
+
- `onDismiss` fires after the exit animation completes, not immediately on dismiss button click
|
|
422
428
|
|
|
423
429
|
## Changes
|
|
424
430
|
### v0.3.1
|
|
@@ -707,8 +713,12 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
707
713
|
- MUST use label prop — children are NOT rendered
|
|
708
714
|
- `<Chip>text</Chip>` is WRONG — use `<Chip label="text" />`
|
|
709
715
|
- Wrap dynamic chip lists in `<ChipGroup>` for exit animations
|
|
716
|
+
- `color="primary"` will be renamed to `color="brand"` in v1.0 — use `color="primary"` for now
|
|
710
717
|
|
|
711
718
|
## Changes
|
|
719
|
+
### v0.19.1
|
|
720
|
+
- **Fixed** `active:scale-95` tap feedback broken by Framer Motion transform override — replaced with `whileTap={{ scale: 0.95 }}`
|
|
721
|
+
|
|
712
722
|
### v0.4.2
|
|
713
723
|
- **Changed** (BREAKING) `variant="filled"` renamed to `"subtle"`, `variant="outlined"` renamed to `"outline"`, `onDelete` renamed to `onDismiss`
|
|
714
724
|
|
|
@@ -832,8 +842,8 @@ import { BarChart } from '@devalok/shilp-sutra/ui/charts'
|
|
|
832
842
|
## Props
|
|
833
843
|
options: ComboboxOption[] (REQUIRED) — { value: string, label: string, description?: string, icon?: ReactNode, disabled?: boolean }
|
|
834
844
|
DISCRIMINATED UNION — type depends on `multiple` flag:
|
|
835
|
-
Single (default): multiple?: false, value
|
|
836
|
-
Multiple: multiple: true, value
|
|
845
|
+
Single (default): multiple?: false, value?: string, onValueChange: (value: string) => void
|
|
846
|
+
Multiple: multiple: true, value?: string[], onValueChange: (value: string[]) => void
|
|
837
847
|
placeholder: string (default: "Select...")
|
|
838
848
|
searchPlaceholder: string (default: "Search...")
|
|
839
849
|
emptyMessage: string (default: "No results found")
|
|
@@ -1122,6 +1132,9 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1122
1132
|
- DialogTitle is required for accessibility — screen readers announce it when the dialog opens
|
|
1123
1133
|
|
|
1124
1134
|
## Changes
|
|
1135
|
+
### v0.19.1
|
|
1136
|
+
- **Fixed** Dialog not centered after Framer Motion animation completes — `transform: none` inline style overrode Tailwind `translate-x/y` classes. Centering now handled via Framer Motion `x`/`y` properties.
|
|
1137
|
+
|
|
1125
1138
|
### v0.18.0
|
|
1126
1139
|
- **Changed** Overlay animations migrated to Framer Motion (physics-based springs)
|
|
1127
1140
|
- **Added** `DialogContentProps`, `DialogTitleProps` type exports
|
|
@@ -1362,7 +1375,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
1362
1375
|
- HTML native "size" attribute is excluded — use CSS width instead
|
|
1363
1376
|
- state="error" sets aria-invalid automatically
|
|
1364
1377
|
- 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
|
|
1378
|
+
- Resting border is border-subtle (soft); focus ring is `ring-1 ring-accent-7` (v0.12.0)
|
|
1366
1379
|
- All sizes (sm, md, lg) use text-ds-md (14px) font — size only affects height and padding (v0.15.0)
|
|
1367
1380
|
|
|
1368
1381
|
## Changes
|
|
@@ -2163,6 +2176,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2163
2176
|
variant: "filled" | "bare"
|
|
2164
2177
|
delay: number (ms — render delay to avoid flicker on fast operations)
|
|
2165
2178
|
onComplete: () => void (callback after success/error state transition)
|
|
2179
|
+
className: string
|
|
2166
2180
|
|
|
2167
2181
|
## Defaults
|
|
2168
2182
|
size: "md"
|
|
@@ -2476,7 +2490,7 @@ import { DataTableToolbar } from '@devalok/shilp-sutra/ui/data-table-toolbar'
|
|
|
2476
2490
|
|
|
2477
2491
|
## Gotchas
|
|
2478
2492
|
- variant goes on TabsList, NOT on individual TabsTrigger (propagates via context)
|
|
2479
|
-
-
|
|
2493
|
+
- Normally omit `variant` on TabsTrigger — it inherits from TabsList via context. You CAN set it per-trigger to override.
|
|
2480
2494
|
|
|
2481
2495
|
## Changes
|
|
2482
2496
|
### v0.18.0
|
|
@@ -2891,15 +2905,15 @@ export default function RootLayout({ children }) {
|
|
|
2891
2905
|
|
|
2892
2906
|
## Props
|
|
2893
2907
|
items: ActivityItem[] (REQUIRED) — { id, actor?: { name, image? }, action: string|ReactNode, timestamp: Date|string, icon?, color?: 'default'|'success'|'warning'|'error'|'info', detail?: ReactNode }
|
|
2894
|
-
onLoadMore
|
|
2908
|
+
onLoadMore?: () => void — "Load more" button callback
|
|
2895
2909
|
loading: boolean — skeleton shimmer
|
|
2896
|
-
hasMore
|
|
2897
|
-
emptyState
|
|
2910
|
+
hasMore?: boolean — shows "Load more" button
|
|
2911
|
+
emptyState?: ReactNode — empty state content
|
|
2898
2912
|
compact: boolean — tighter spacing, no avatars, smaller text
|
|
2899
2913
|
maxInitialItems: number — truncate with "Show all (N)" toggle
|
|
2900
2914
|
|
|
2901
2915
|
## Defaults
|
|
2902
|
-
loading=false, compact=false
|
|
2916
|
+
loading=false, compact=false, hasMore=false
|
|
2903
2917
|
|
|
2904
2918
|
## Example
|
|
2905
2919
|
```jsx
|
|
@@ -2965,7 +2979,7 @@ export default function RootLayout({ children }) {
|
|
|
2965
2979
|
- Category: composed
|
|
2966
2980
|
|
|
2967
2981
|
## Props
|
|
2968
|
-
groups
|
|
2982
|
+
groups?: CommandGroup[] (default: []) — { label: string, items: CommandItem[] }
|
|
2969
2983
|
placeholder: string (default: "Search or jump to...")
|
|
2970
2984
|
onSearch: (query: string) => void
|
|
2971
2985
|
emptyMessage: string (default: "No results found.")
|
|
@@ -2973,7 +2987,7 @@ export default function RootLayout({ children }) {
|
|
|
2973
2987
|
CommandItem shape: { id, label, description?, icon?, shortcut?, onSelect: () => void }
|
|
2974
2988
|
|
|
2975
2989
|
## Defaults
|
|
2976
|
-
placeholder="Search or jump to...", emptyMessage="No results found."
|
|
2990
|
+
placeholder="Search or jump to...", emptyMessage="No results found.", groups=[]
|
|
2977
2991
|
|
|
2978
2992
|
## Example
|
|
2979
2993
|
```jsx
|
|
@@ -3012,7 +3026,7 @@ CommandItem shape: { id, label, description?, icon?, shortcut?, onSelect: () =>
|
|
|
3012
3026
|
confirmText: string (default: "Confirm")
|
|
3013
3027
|
cancelText: string (default: "Cancel")
|
|
3014
3028
|
color: "default" | "error" (controls confirm button color)
|
|
3015
|
-
loading: boolean (default: false, disables buttons and
|
|
3029
|
+
loading: boolean (default: false, disables buttons and replaces confirm button text with 'Processing...')
|
|
3016
3030
|
onConfirm: () => void | Promise<void> (REQUIRED)
|
|
3017
3031
|
|
|
3018
3032
|
## Defaults
|
|
@@ -3089,8 +3103,8 @@ const [open, setOpen] = useState(false)
|
|
|
3089
3103
|
## Props
|
|
3090
3104
|
|
|
3091
3105
|
### DatePicker
|
|
3092
|
-
value
|
|
3093
|
-
onChange
|
|
3106
|
+
value?: Date | null
|
|
3107
|
+
onChange?: (date: Date | null) => void
|
|
3094
3108
|
placeholder: string (default: "Pick a date")
|
|
3095
3109
|
formatStr: string (default: "MMM d, yyyy")
|
|
3096
3110
|
minDate: Date
|
|
@@ -3099,9 +3113,9 @@ const [open, setOpen] = useState(false)
|
|
|
3099
3113
|
className: string
|
|
3100
3114
|
|
|
3101
3115
|
### DateRangePicker
|
|
3102
|
-
startDate
|
|
3103
|
-
endDate
|
|
3104
|
-
onChange
|
|
3116
|
+
startDate?: Date | null
|
|
3117
|
+
endDate?: Date | null
|
|
3118
|
+
onChange?: (range: { start: Date | null, end: Date | null }) => void
|
|
3105
3119
|
placeholder: string (default: "Pick a date range")
|
|
3106
3120
|
formatStr: string (default: "MMM d, yyyy")
|
|
3107
3121
|
minDate: Date
|
|
@@ -3122,8 +3136,8 @@ const [open, setOpen] = useState(false)
|
|
|
3122
3136
|
className: string
|
|
3123
3137
|
|
|
3124
3138
|
### TimePicker
|
|
3125
|
-
value
|
|
3126
|
-
onChange
|
|
3139
|
+
value?: Date | null (time stored as a Date object)
|
|
3140
|
+
onChange?: (date: Date) => void
|
|
3127
3141
|
format: "12h" | "24h" (default: "12h")
|
|
3128
3142
|
minuteStep: number (default: 1)
|
|
3129
3143
|
secondStep: number (default: 1)
|
|
@@ -3134,14 +3148,14 @@ const [open, setOpen] = useState(false)
|
|
|
3134
3148
|
|
|
3135
3149
|
### CalendarGrid
|
|
3136
3150
|
currentMonth: Date (REQUIRED)
|
|
3137
|
-
selected
|
|
3138
|
-
rangeStart
|
|
3139
|
-
rangeEnd
|
|
3140
|
-
hoverDate
|
|
3151
|
+
selected?: Date | null
|
|
3152
|
+
rangeStart?: Date | null
|
|
3153
|
+
rangeEnd?: Date | null
|
|
3154
|
+
hoverDate?: Date | null
|
|
3141
3155
|
onSelect: (date: Date) => void (REQUIRED)
|
|
3142
|
-
onHover
|
|
3156
|
+
onHover?: (date: Date | null) => void
|
|
3143
3157
|
onMonthChange: (date: Date) => void (REQUIRED)
|
|
3144
|
-
onHeaderClick
|
|
3158
|
+
onHeaderClick?: () => void
|
|
3145
3159
|
disabledDates: (date: Date) => boolean
|
|
3146
3160
|
minDate: Date
|
|
3147
3161
|
maxDate: Date
|
|
@@ -3591,8 +3605,8 @@ MentionItem: { id: string; label: string; avatar?: string }
|
|
|
3591
3605
|
view: "day" | "week" (REQUIRED)
|
|
3592
3606
|
date: Date (REQUIRED — current day or any date in target week)
|
|
3593
3607
|
events: ScheduleEvent[] (REQUIRED) — { id, title, start: Date, end: Date, color? }
|
|
3594
|
-
onEventClick
|
|
3595
|
-
onSlotClick
|
|
3608
|
+
onEventClick?: (event: ScheduleEvent) => void
|
|
3609
|
+
onSlotClick?: (start: Date, end: Date) => void
|
|
3596
3610
|
startHour: number (default: 8)
|
|
3597
3611
|
endHour: number (default: 18, exclusive)
|
|
3598
3612
|
slotDuration: number (minutes, default: 30)
|
|
@@ -3670,6 +3684,7 @@ Note: StatusBadge was server-safe prior to v0.18.0 but is NO LONGER server-safe
|
|
|
3670
3684
|
|
|
3671
3685
|
## Defaults
|
|
3672
3686
|
size="md", hideDot=false
|
|
3687
|
+
When neither status nor color is passed, defaults to status='pending' styling
|
|
3673
3688
|
|
|
3674
3689
|
## Example
|
|
3675
3690
|
```jsx
|
|
@@ -3784,6 +3799,10 @@ BottomNavbarUser: { name: string, role?: string }
|
|
|
3784
3799
|
- Requires LinkProvider for framework-specific link components (e.g., Next.js Link)
|
|
3785
3800
|
|
|
3786
3801
|
## Changes
|
|
3802
|
+
### v0.19.0
|
|
3803
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2` for visual hierarchy above app background
|
|
3804
|
+
- **Changed** "More" menu and interactive items bumped accordingly
|
|
3805
|
+
|
|
3787
3806
|
### v0.18.0
|
|
3788
3807
|
- **Fixed** Removed incorrect `role="button"` and `tabIndex` from overlay
|
|
3789
3808
|
|
|
@@ -3892,21 +3911,21 @@ import Link from 'next/link'
|
|
|
3892
3911
|
|
|
3893
3912
|
## Props
|
|
3894
3913
|
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
|
|
3914
|
+
unreadCount?: number (derived from notifications if not provided)
|
|
3915
|
+
open?: boolean (controlled mode)
|
|
3916
|
+
onOpenChange?: (open: boolean) => void
|
|
3917
|
+
isLoading?: boolean
|
|
3918
|
+
hasMore?: boolean
|
|
3919
|
+
onFetchMore?: () => void
|
|
3920
|
+
onMarkRead?: (id: string) => void
|
|
3921
|
+
onMarkAllRead?: () => void
|
|
3922
|
+
onNavigate?: (path: string) => void — called when a notification with a route is clicked
|
|
3923
|
+
getNotificationRoute?: (notification: Notification) => string | null — returns route for a notification; defaults to () => null
|
|
3924
|
+
footerSlot?: ReactNode — content rendered in a sticky footer below the scroll area
|
|
3925
|
+
emptyState?: ReactNode — replaces default empty state UI
|
|
3926
|
+
headerActions?: ReactNode — extra action buttons after "Mark all read"
|
|
3927
|
+
popoverClassName?: string — override default popover dimensions
|
|
3928
|
+
onDismiss?: (id: string) => void — when provided, each notification shows a dismiss button
|
|
3910
3929
|
|
|
3911
3930
|
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
3931
|
NotificationAction: { label: string, variant?: 'primary' | 'default' | 'danger', onClick: (id: string) => void }
|
|
@@ -4012,7 +4031,7 @@ NavItem: { title: string, href: string, icon: ReactNode, exact?: boolean, badge?
|
|
|
4012
4031
|
NavSubItem: { title: string, href: string, icon?: ReactNode, exact?: boolean }
|
|
4013
4032
|
NavGroup: { label: string, items: NavItem[], action?: ReactNode }
|
|
4014
4033
|
SidebarUser: { name: string, email?: string, image?: string | null, designation?: string, role?: string }
|
|
4015
|
-
SidebarFooterConfig: { links
|
|
4034
|
+
SidebarFooterConfig: { links?: Array<{ label: string, href: string }>, version?: string | { label: string, href: string }, slot?: ReactNode, promo?: SidebarPromo }
|
|
4016
4035
|
SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?: string, onClick?: () => void }, onDismiss?: () => void }
|
|
4017
4036
|
|
|
4018
4037
|
## Defaults
|
|
@@ -4048,6 +4067,10 @@ SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?:
|
|
|
4048
4067
|
- Badge numbers > 99 display as "99+"
|
|
4049
4068
|
|
|
4050
4069
|
## Changes
|
|
4070
|
+
### v0.19.0
|
|
4071
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2` for visual hierarchy above app background
|
|
4072
|
+
- **Changed** Interactive hover states bumped from `surface-2` to `surface-3`
|
|
4073
|
+
|
|
4051
4074
|
### v0.18.0
|
|
4052
4075
|
- **Fixed** `bg-interactive-subtle` changed to `bg-accent-2` (OKLCH migration)
|
|
4053
4076
|
|
|
@@ -4083,16 +4106,54 @@ SidebarPromo: { text: string, icon?: ReactNode, action?: { label: string, href?:
|
|
|
4083
4106
|
- Server-safe: No
|
|
4084
4107
|
- Category: shell
|
|
4085
4108
|
|
|
4109
|
+
## Overview
|
|
4110
|
+
|
|
4111
|
+
Composition-based application top bar. Uses dot-notation subcomponents for flexible layout.
|
|
4112
|
+
|
|
4113
|
+
## Subcomponents
|
|
4114
|
+
|
|
4115
|
+
| Component | Purpose |
|
|
4116
|
+
|-----------|---------|
|
|
4117
|
+
| `TopBar` | Root — bg-surface-2, border-b, sticky. Auto-switches to grid when Center is present. |
|
|
4118
|
+
| `TopBar.Left` | Left zone — sidebar trigger, title, breadcrumbs |
|
|
4119
|
+
| `TopBar.Center` | Optional center zone — search bar, tabs. Triggers 3-column grid layout. |
|
|
4120
|
+
| `TopBar.Right` | Right zone — action buttons, user menu. Gets ml-auto in flex mode. |
|
|
4121
|
+
| `TopBar.Section` | Groups items with configurable gap |
|
|
4122
|
+
| `TopBar.IconButton` | Circular icon button with tooltip (bg-surface-3, hover:bg-surface-4) |
|
|
4123
|
+
| `TopBar.Title` | Page title heading, hidden on mobile |
|
|
4124
|
+
| `TopBar.UserMenu` | Avatar dropdown with color mode toggle, profile, logout |
|
|
4125
|
+
|
|
4086
4126
|
## Props
|
|
4087
|
-
|
|
4088
|
-
|
|
4127
|
+
|
|
4128
|
+
### TopBar (root)
|
|
4129
|
+
children: ReactNode
|
|
4130
|
+
className?: string
|
|
4131
|
+
|
|
4132
|
+
### TopBar.Left / TopBar.Center / TopBar.Right
|
|
4133
|
+
children: ReactNode
|
|
4134
|
+
className?: string
|
|
4135
|
+
|
|
4136
|
+
### TopBar.Section
|
|
4137
|
+
gap?: "tight" | "default" | "loose" (default: "default")
|
|
4138
|
+
children: ReactNode
|
|
4139
|
+
className?: string
|
|
4140
|
+
|
|
4141
|
+
Gap values: tight = gap-ds-02, default = gap-ds-04, loose = gap-ds-06
|
|
4142
|
+
|
|
4143
|
+
### TopBar.IconButton
|
|
4144
|
+
icon: ReactNode
|
|
4145
|
+
tooltip: string
|
|
4146
|
+
...ButtonHTMLAttributes
|
|
4147
|
+
|
|
4148
|
+
### TopBar.Title
|
|
4149
|
+
children: ReactNode
|
|
4150
|
+
className?: string
|
|
4151
|
+
|
|
4152
|
+
### TopBar.UserMenu
|
|
4153
|
+
user: TopBarUser — { name, email?, image? }
|
|
4089
4154
|
onNavigate?: (path: string) => void
|
|
4090
4155
|
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
|
|
4156
|
+
userMenuItems?: UserMenuItem[]
|
|
4096
4157
|
className?: string
|
|
4097
4158
|
|
|
4098
4159
|
TopBarUser: { name: string, email?: string, image?: string | null }
|
|
@@ -4106,30 +4167,69 @@ UserMenuItem fields:
|
|
|
4106
4167
|
- badge — string for count badge, true for dot indicator
|
|
4107
4168
|
- disabled — greys out the item
|
|
4108
4169
|
|
|
4109
|
-
## Defaults
|
|
4110
|
-
None
|
|
4111
|
-
|
|
4112
4170
|
## Example
|
|
4171
|
+
|
|
4172
|
+
### Two-zone (standard)
|
|
4113
4173
|
```jsx
|
|
4114
|
-
<TopBar
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4174
|
+
<TopBar>
|
|
4175
|
+
<TopBar.Left>
|
|
4176
|
+
<SidebarTrigger />
|
|
4177
|
+
<TopBar.Title>Dashboard</TopBar.Title>
|
|
4178
|
+
</TopBar.Left>
|
|
4179
|
+
<TopBar.Right>
|
|
4180
|
+
<TopBar.Section gap="tight">
|
|
4181
|
+
<TopBar.IconButton icon={<IconSearch />} tooltip="Search (Ctrl+K)" onClick={openSearch} />
|
|
4182
|
+
<NotificationCenter notifications={notifications} />
|
|
4183
|
+
<TopBar.IconButton icon={<IconSparkles />} tooltip="AI Chat" onClick={openAI} />
|
|
4184
|
+
</TopBar.Section>
|
|
4185
|
+
<TopBar.UserMenu
|
|
4186
|
+
user={{ name: 'John', email: 'john@example.com' }}
|
|
4187
|
+
onNavigate={(p) => router.push(p)}
|
|
4188
|
+
onLogout={handleLogout}
|
|
4189
|
+
userMenuItems={[
|
|
4190
|
+
{ label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },
|
|
4191
|
+
]}
|
|
4192
|
+
/>
|
|
4193
|
+
</TopBar.Right>
|
|
4194
|
+
</TopBar>
|
|
4195
|
+
```
|
|
4196
|
+
|
|
4197
|
+
### Three-zone (centered search bar)
|
|
4198
|
+
```jsx
|
|
4199
|
+
<TopBar>
|
|
4200
|
+
<TopBar.Left>
|
|
4201
|
+
<SidebarTrigger />
|
|
4202
|
+
<TopBar.Title>Dashboard</TopBar.Title>
|
|
4203
|
+
</TopBar.Left>
|
|
4204
|
+
<TopBar.Center>
|
|
4205
|
+
<SearchBarTrigger />
|
|
4206
|
+
</TopBar.Center>
|
|
4207
|
+
<TopBar.Right>
|
|
4208
|
+
<TopBar.Section gap="tight">
|
|
4209
|
+
<TopBar.IconButton icon={<IconBell />} tooltip="Notifications" onClick={fn} />
|
|
4210
|
+
</TopBar.Section>
|
|
4211
|
+
<TopBar.UserMenu user={user} onLogout={logout} />
|
|
4212
|
+
</TopBar.Right>
|
|
4213
|
+
</TopBar>
|
|
4125
4214
|
```
|
|
4126
4215
|
|
|
4127
4216
|
## Gotchas
|
|
4128
|
-
- `
|
|
4129
|
-
- `
|
|
4130
|
-
-
|
|
4217
|
+
- Without `TopBar.Center`, layout is flex (two-zone). With it, layout switches to CSS grid `1fr auto 1fr` for true centering.
|
|
4218
|
+
- `TopBar.IconButton` renders any number of action buttons — no artificial limit. Use responsive hiding (`className="hidden md:flex"`) for mobile.
|
|
4219
|
+
- `TopBar.UserMenu` includes Profile link, color mode toggle, and logout automatically. `userMenuItems` are inserted between Profile and the toggle.
|
|
4220
|
+
- Requires SidebarProvider wrapper for SidebarTrigger to work.
|
|
4131
4221
|
|
|
4132
4222
|
## Changes
|
|
4223
|
+
### v0.19.0
|
|
4224
|
+
- **BREAKING** Rewritten as composition API. Old props-based API removed (`pageTitle`, `onSearchClick`, `onAiChatClick`, `notificationSlot`, `mobileLogo` props).
|
|
4225
|
+
- **Added** `TopBar.Left`, `TopBar.Center`, `TopBar.Right` zone components
|
|
4226
|
+
- **Added** `TopBar.Section` with `gap` prop (`tight` | `default` | `loose`)
|
|
4227
|
+
- **Added** `TopBar.IconButton` — reusable circular icon button with tooltip
|
|
4228
|
+
- **Added** `TopBar.Title` — responsive page title (hidden on mobile)
|
|
4229
|
+
- **Added** `TopBar.UserMenu` — extracted user dropdown as standalone subcomponent
|
|
4230
|
+
- **Added** Auto grid/flex layout detection based on Center zone presence
|
|
4231
|
+
- **Changed** Background elevated from `bg-surface-1` to `bg-surface-2`
|
|
4232
|
+
|
|
4133
4233
|
### v0.7.0
|
|
4134
4234
|
- **Added** `userMenuItems` prop for custom dropdown items
|
|
4135
4235
|
|
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)
|