@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/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.18.2
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 | Component bg active | Active/pressed state |
46
- | 6 | Border subtle | Dividers, soft borders |
47
- | 7 | Border default | Input borders, card borders |
48
- | 8 | Border strong | Focus rings, emphasis borders |
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: (option: AutocompleteOption) => void
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: string, onValueChange: (value: string) => void
836
- Multiple: multiple: true, value: string[], onValueChange: (value: string[]) => void
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 at 50% opacity (v0.12.0)
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
- - DO NOT put variant on TabsTrigger — it inherits from TabsList
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: () => void — "Load more" button callback
2899
+ onLoadMore?: () => void — "Load more" button callback
2895
2900
  loading: boolean — skeleton shimmer
2896
- hasMore: boolean — shows "Load more" button
2897
- emptyState: ReactNode — empty state content
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: CommandGroup[] — { label: string, items: CommandItem[] }
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 shows spinner)
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: Date | null
3093
- onChange: (date: Date | null) => void
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: Date | null
3103
- endDate: Date | null
3104
- onChange: (range: { start: Date | null, end: Date | null }) => void
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: Date | null (time stored as a Date object)
3126
- onChange: (date: Date) => void
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: Date | null
3138
- rangeStart: Date | null
3139
- rangeEnd: Date | null
3140
- hoverDate: Date | null
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: (date: Date | null) => void
3147
+ onHover?: (date: Date | null) => void
3143
3148
  onMonthChange: (date: Date) => void (REQUIRED)
3144
- onHeaderClick: () => void
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: (event: ScheduleEvent) => void
3595
- onSlotClick: (start: Date, end: Date) => void
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: number (derived from notifications if not provided)
3896
- open: boolean (controlled mode)
3897
- onOpenChange: (open: boolean) => void
3898
- isLoading: boolean
3899
- hasMore: boolean
3900
- onFetchMore: () => void
3901
- onMarkRead: (id: string) => void
3902
- onMarkAllRead: () => void
3903
- onNavigate: (path: string) => void — called when a notification with a route is clicked
3904
- getNotificationRoute: (notification: Notification) => string | null — returns route for a notification; defaults to () => null
3905
- footerSlot: ReactNode — content rendered in a sticky footer below the scroll area
3906
- emptyState: ReactNode — replaces default empty state UI
3907
- headerActions: ReactNode — extra action buttons after "Mark all read"
3908
- popoverClassName: string — override default popover dimensions
3909
- onDismiss: (id: string) => void — when provided, each notification shows a dismiss button
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: Array<{ label: string, href: string }>, version: string | { label: string, href: string }, slot: ReactNode, promo: SidebarPromo }
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
- pageTitle?: string (default: "")
4088
- user?: TopBarUser | null — { name, email?, image? }
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
- onSearchClick?: () => void
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
- pageTitle="Dashboard"
4116
- user={{ name: 'John', email: 'john@example.com' }}
4117
- onNavigate={(p) => router.push(p)}
4118
- onLogout={handleLogout}
4119
- notificationSlot={<NotificationCenter notifications={notifications} />}
4120
- userMenuItems={[
4121
- { label: 'Changelog', icon: <IconNews />, href: '/changelog', badge: '3' },
4122
- { label: 'Shortcuts', icon: <IconKeyboard />, onClick: () => openModal() },
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
- - `notificationSlot` is where NotificationCenter should be rendered
4129
- - `userMenuItems` are inserted between the Profile link and the Dark/Light Mode toggle in the user dropdown
4130
- - Requires LinkProvider for framework-specific navigation
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: pageTitle, user, onNavigate, onLogout, notificationSlot, mobileLogo, userMenuItems?(UserMenuItem[]). Types: TopBarUser = { name, email?, image? }, UserMenuItem = { label, icon?, href?, onClick?, separator?, color?, badge?, disabled? }
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)