@devalok/shilp-sutra 0.53.0 → 0.54.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.
Files changed (90) hide show
  1. package/AGENTS.md +7 -1
  2. package/BREAKING.json +29 -0
  3. package/MIGRATION.md +55 -0
  4. package/dist/composed/avatar-group.d.ts +11 -9
  5. package/dist/composed/avatar-group.d.ts.map +1 -1
  6. package/dist/composed/avatar-group.js +108 -140
  7. package/dist/composed/avatar-group.js.map +1 -1
  8. package/dist/composed/bulk-action-bar.d.ts +19 -11
  9. package/dist/composed/bulk-action-bar.d.ts.map +1 -1
  10. package/dist/composed/bulk-action-bar.js +81 -110
  11. package/dist/composed/bulk-action-bar.js.map +1 -1
  12. package/dist/composed/error-boundary.d.ts +15 -3
  13. package/dist/composed/error-boundary.d.ts.map +1 -1
  14. package/dist/composed/error-boundary.js +43 -26
  15. package/dist/composed/error-boundary.js.map +1 -1
  16. package/dist/composed/loading-skeleton.d.ts +2 -0
  17. package/dist/composed/loading-skeleton.d.ts.map +1 -1
  18. package/dist/composed/loading-skeleton.js +79 -56
  19. package/dist/composed/loading-skeleton.js.map +1 -1
  20. package/dist/composed/master-detail.d.ts +21 -8
  21. package/dist/composed/master-detail.d.ts.map +1 -1
  22. package/dist/composed/master-detail.js +91 -77
  23. package/dist/composed/master-detail.js.map +1 -1
  24. package/dist/composed/page-skeletons.d.ts +6 -0
  25. package/dist/composed/page-skeletons.d.ts.map +1 -1
  26. package/dist/composed/page-skeletons.js +93 -71
  27. package/dist/composed/page-skeletons.js.map +1 -1
  28. package/dist/shell/index.d.ts +5 -3
  29. package/dist/shell/index.d.ts.map +1 -1
  30. package/dist/shell/index.js +2 -3
  31. package/dist/shell/notification-preferences.d.ts.map +1 -1
  32. package/dist/shell/notification-preferences.js +2 -0
  33. package/dist/shell/notification-preferences.js.map +1 -1
  34. package/dist/ui/combobox.d.ts +1 -1
  35. package/dist/ui/combobox.d.ts.map +1 -1
  36. package/dist/ui/combobox.js +133 -128
  37. package/dist/ui/combobox.js.map +1 -1
  38. package/dist/ui/file-upload.d.ts.map +1 -1
  39. package/dist/ui/file-upload.js +124 -138
  40. package/dist/ui/file-upload.js.map +1 -1
  41. package/dist/ui/form.d.ts +7 -0
  42. package/dist/ui/form.d.ts.map +1 -1
  43. package/dist/ui/form.js +4 -2
  44. package/dist/ui/form.js.map +1 -1
  45. package/dist/ui/icon-button.d.ts +2 -1
  46. package/dist/ui/icon-button.d.ts.map +1 -1
  47. package/dist/ui/icon-button.js +1 -1
  48. package/dist/ui/icon-button.js.map +1 -1
  49. package/dist/ui/label.d.ts.map +1 -1
  50. package/dist/ui/label.js +7 -6
  51. package/dist/ui/label.js.map +1 -1
  52. package/dist/ui/spinner.d.ts.map +1 -1
  53. package/dist/ui/spinner.js +50 -44
  54. package/dist/ui/spinner.js.map +1 -1
  55. package/dist/ui/switch.d.ts.map +1 -1
  56. package/dist/ui/switch.js +24 -24
  57. package/dist/ui/switch.js.map +1 -1
  58. package/dist/ui/table.js +1 -1
  59. package/dist/ui/table.js.map +1 -1
  60. package/docs/components/composed/bulk-action-bar.md +9 -3
  61. package/docs/components/composed/error-boundary.md +18 -2
  62. package/docs/components/composed/master-detail.md +12 -2
  63. package/docs/components/composed/page-skeletons.md +2 -2
  64. package/docs/components/composed/rich-chat-input.md +18 -6
  65. package/docs/components/composed/simple-tooltip.md +1 -1
  66. package/docs/components/shell/app-command-palette.md +2 -1
  67. package/docs/components/shell/bottom-navbar.md +4 -4
  68. package/docs/components/shell/command-registry.md +2 -2
  69. package/docs/components/shell/link-context.md +2 -2
  70. package/docs/components/shell/top-bar.md +1 -1
  71. package/docs/components/ui/search-input.md +2 -2
  72. package/docs/components/ui/slider.md +2 -2
  73. package/docs/components/ui/split-button.md +3 -3
  74. package/llms.txt +2 -2
  75. package/make-kit/Guidelines.md +1 -1
  76. package/make-kit/components/overview.md +2 -2
  77. package/make-kit/foundations/surfaces.md +1 -1
  78. package/mcp-manifest.json +403 -147
  79. package/package.json +1 -6
  80. package/skill/SKILL.md +1 -1
  81. package/skill/chat-skill/README.md +18 -0
  82. package/skill/chat-skill/SKILL.md +78 -0
  83. package/skill/chat-skill/chatgpt-instructions.md +26 -0
  84. package/skill/chat-skill/gemini-instructions.md +25 -0
  85. package/skill/references/components.md +2 -2
  86. package/dist/shell/sidebar.d.ts +0 -113
  87. package/dist/shell/sidebar.d.ts.map +0 -1
  88. package/dist/shell/sidebar.js +0 -293
  89. package/dist/shell/sidebar.js.map +0 -1
  90. package/docs/components/shell/sidebar.md +0 -103
@@ -9,19 +9,24 @@ Compact rich text chat input for unified human+AI workspaces. Built on TipTap.
9
9
  ## Props
10
10
 
11
11
  ### RichChatInputProps
12
- onSubmit: (html: string, plainText: string) => void (REQUIRED)
12
+ onSubmit: (message: RichChatInputMessage) => void (REQUIRED)
13
13
  placeholder: string (default: "Type a message...")
14
14
  disabled: boolean (default: false)
15
- variant: 'compact' | 'expanded' | 'minimal' (default: 'compact')
16
- maxRows: number
15
+ content: string initial HTML (not reactive; use for message editing)
16
+ variant: 'compact' | 'expanded' | 'minimal' | 'inline' (default: 'compact')
17
17
  enterBehavior: 'send' | 'newline' (default: 'send')
18
18
  maxLength: number — enables character counter
19
+ charCountDisplay: 'always' | 'focus' | 'near-limit' | 'hidden' (default: 'near-limit')
19
20
  mentions: MentionItem[] — static list for @mention autocomplete
20
21
  onMentionSearch: (query: string) => Promise<MentionItem[]> — async search
21
22
  onMentionSelect: (item: MentionItem) => void
22
23
  onFileUpload: (file: File) => Promise<{ url: string; name: string; size: number }>
23
24
  onImageUpload: (file: File) => Promise<string>
24
25
  slashCommands: SlashCommandGroup[] — enables / command palette
26
+ onVoiceRecord: (audio: Blob, duration: number) => void
27
+ onTranscribe: (blob: Blob, duration: number) => Promise<string | null> — transcribe after recording; return null to attach as a voice note
28
+ maxDuration: number — max voice-recording seconds
29
+ replyTo: { id: string; author: string; preview: string; onDismiss: () => void } — reply banner above the input
25
30
  onTyping: (isTyping: boolean) => void — typing indicator callback
26
31
  onEmpty: (isEmpty: boolean) => void
27
32
  isStreaming: boolean (default: false) — shows stop button instead of send
@@ -29,9 +34,15 @@ Compact rich text chat input for unified human+AI workspaces. Built on TipTap.
29
34
  leadingSlot: ReactNode — rendered above the editor
30
35
  trailingSlot: ReactNode — rendered below the toolbar
31
36
  disclaimer: string — small text below the input
32
- toolbar: boolean | ChatToolbarItem[] (default: true)
37
+ toolbar: boolean | ChatToolbarItem[] | ReactNode (default: true) — true = default toolbar, array = whitelist, ReactNode = custom, false = hidden
38
+ actionButton: ReactNode | false — custom left-side button (replaces the default attach button; false hides it)
39
+ emojiSet: 'native' | 'apple' | 'google' | 'twitter' | 'facebook' (default: 'native')
40
+ onSchedule: (message: RichChatInputMessage, scheduledAt: Date) => void — if set, a schedule button appears next to send
41
+ sendOptions: Array<{ label: string; icon?: ComponentType<{ className?: string }>; onSelect: () => void }> — split-send dropdown options
33
42
 
34
- ChatToolbarItem: 'bold' | 'italic' | 'underline' | 'strike' | 'highlight' | 'code' | 'bulletList' | 'orderedList' | 'mention' | 'emoji' | 'attach' | 'slash'
43
+ RichChatInputMessage: { html: string; plainText: string; attachments?: Array<{ url: string; name: string; size: number; type: string }>; voiceNote?: { blob: Blob; duration: number } }
44
+
45
+ ChatToolbarItem: 'bold' | 'italic' | 'underline' | 'strike' | 'highlight' | 'code' | 'bulletList' | 'orderedList' | 'blockquote' | 'link' | 'mention' | 'emoji' | 'slash'
35
46
 
36
47
  MentionItem: { id: string; label: string; avatar?: string }
37
48
 
@@ -43,11 +54,12 @@ SlashCommandGroup: { label: string; commands: SlashCommand[] }
43
54
  - `compact` (default) — 2-3 lines, inline toolbar
44
55
  - `expanded` — 5+ lines, always-visible toolbar, suited for AI prompts
45
56
  - `minimal` — single line, toolbar appears on focus
57
+ - `inline` — 40px min-height, no toolbar; for tight inline composers
46
58
 
47
59
  ## Example
48
60
  ```jsx
49
61
  <RichChatInput
50
- onSubmit={(html, text) => sendMessage(html)}
62
+ onSubmit={(message) => sendMessage(message.html)}
51
63
  mentions={teamMembers}
52
64
  onFileUpload={uploadFile}
53
65
  slashCommands={[{ label: 'Actions', commands: [...] }]}
@@ -24,7 +24,7 @@
24
24
  ## Composability
25
25
  - **One-liner Tooltip** — wraps TooltipProvider + Tooltip + TooltipTrigger + TooltipContent so consumers don't have to manually compose them for a simple label.
26
26
  - **When to use:** 90% of tooltip use cases (icon-only button labels, abbreviated text expansions, secondary info). Use the ui/Tooltip compound for advanced cases (controlled open, nested triggers, custom animations).
27
- - **Auto-provides its own TooltipProvider** — safe to drop anywhere. You can still wrap a broader TooltipProvider at layout level for shared `delayDuration`; SimpleTooltip respects it if present.
27
+ - **Always mounts its own TooltipProvider** — safe to drop anywhere. Note it does NOT inherit an ancestor `TooltipProvider`'s `delayDuration`; its own `delayDuration` prop (default 300ms) always wins. Set it per-tooltip via the prop.
28
28
  - **Content must be inert** — same rule as ui/Tooltip. For interactive popped content, use Popover or HoverCard.
29
29
  - **Pairs with IconButton** — the canonical pattern for labeled icon buttons.
30
30
 
@@ -23,7 +23,7 @@ AppCommandPaletteUser: { name: string, role?: string }
23
23
  ## Example
24
24
  ```jsx
25
25
  <AppCommandPalette
26
- user={{ name: 'John', role: 'admin' }}
26
+ user={{ name: 'John', role: 'Admin' }}
27
27
  isAdmin={true}
28
28
  onNavigate={(path) => router.push(path)}
29
29
  searchResults={results}
@@ -42,6 +42,7 @@ AppCommandPaletteUser: { name: string, role?: string }
42
42
  ## Gotchas
43
43
  - Uses CommandRegistry context for page navigation items (see CommandRegistryProvider)
44
44
  - `isAdmin` takes precedence over `user.role` for showing admin command groups
45
+ - **Role detection is case-sensitive:** `user.role` only auto-enables admin groups when it is exactly `'Admin'` or `'SuperAdmin'`. `'admin'` (lowercase) silently shows nothing — pass `isAdmin` explicitly if your role strings differ.
45
46
  - Should be placed at the app root level, typically alongside TopBar
46
47
 
47
48
  ## Changes
@@ -36,11 +36,11 @@ BottomNavbarUser: { name: string, role?: string }
36
36
  ```
37
37
 
38
38
  ## Composability
39
- - **Mobile-only bottom nav** — fixed to bottom of viewport. Desktop should use AppSidebar instead.
40
- - **Responsive switch pattern:** Use `useIsMobile()` hook to conditionally render AppSidebar (desktop) or BottomNavbar (mobile). Example:
39
+ - **Mobile-only bottom nav** — fixed to bottom of viewport. Desktop should use Sidebar instead.
40
+ - **Responsive switch pattern:** Use `useIsMobile()` hook to conditionally render Sidebar (desktop) or BottomNavbar (mobile). Example:
41
41
  ```jsx
42
42
  const isMobile = useIsMobile()
43
- return isMobile ? <BottomNavbar ... /> : <AppSidebar ... />
43
+ return isMobile ? <BottomNavbar ... /> : <Sidebar ... />
44
44
  ```
45
45
  - **Primary vs overflow:** `primaryItems` (max 4) for the always-visible slots; `moreItems` go into a "More" sheet that opens on tap. Don't exceed 4 primary — the bar becomes cramped.
46
46
  - **Router integration via LinkProvider:** Each nav item is rendered using the framework-specific Link component registered in LinkProvider. Without LinkProvider, you get full-page reloads on tap.
@@ -54,7 +54,7 @@ BottomNavbarUser: { name: string, role?: string }
54
54
  ## Gotchas
55
55
  - Designed for mobile viewports — fixed to bottom of screen
56
56
  - Max 4 `primaryItems` recommended; overflow goes in `moreItems` shown in a "More" sheet
57
- - Use with `useIsMobile()` hook to conditionally render instead of AppSidebar
57
+ - Use with `useIsMobile()` hook to conditionally render instead of Sidebar
58
58
  - Requires LinkProvider for framework-specific link components (e.g., Next.js Link)
59
59
 
60
60
  ## Changes
@@ -13,7 +13,7 @@ Exports: CommandRegistryProvider, useCommandRegistry
13
13
  registry: CommandRegistry (REQUIRED)
14
14
 
15
15
  CommandRegistry: { pages: CommandPageItem[], adminPages: CommandPageItem[] }
16
- CommandPageItem: { id: string, label: string, icon: ReactNode, path: string, keywords?: string[] }
16
+ CommandPageItem: { id: string, label: string, icon: IconInput, path: string, keywords?: string[] }
17
17
 
18
18
  ### useCommandRegistry hook
19
19
  Returns: CommandRegistry | null
@@ -41,7 +41,7 @@ CommandPageItem: { id: string, label: string, icon: ReactNode, path: string, key
41
41
  ## Composability
42
42
  - **Context provider for AppCommandPalette.** Registers page-level navigation items that the command palette surfaces as commands.
43
43
  - **Place at app root** — wrap both AppCommandPalette and the rest of the app inside `<CommandRegistryProvider>`. Positioning matters: any AppCommandPalette outside the provider gets `useCommandRegistry() === null` and falls back to minimal functionality.
44
- - **Separation of pages vs adminPages** — the palette filters based on user role / `isAdmin` flag. Keep admin-only routes in the adminPages array to avoid leaking them to regular users.
44
+ - **Separation of pages vs adminPages** — this is an ORGANIZATIONAL split, not access control. The component does NOT enforce anything: YOU populate `adminPages` conditionally (e.g. only when the signed-in user is an admin). Anything you put in `adminPages` is still shipped to the client do real authorization on the server, not here.
45
45
  - **useCommandRegistry()** is the consumer hook — returns the full registry or null. Use in your own command-aware components (e.g. a Spotlight-style keyboard-search embed elsewhere in the app).
46
46
  - **Works with LinkProvider** — CommandPaletteItems navigate via `onNavigate` prop on AppCommandPalette, which routes to your framework's Link component.
47
47
 
@@ -23,13 +23,13 @@ Exports: LinkProvider, useLink
23
23
  import Link from 'next/link'
24
24
 
25
25
  <LinkProvider component={Link}>
26
- <AppSidebar ... />
26
+ <Sidebar ... />
27
27
  <BottomNavbar ... />
28
28
  </LinkProvider>
29
29
  ```
30
30
 
31
31
  ## Composability
32
- - **The framework router bridge for all shell components.** Without LinkProvider, AppSidebar / BottomNavbar / TopBar.UserMenu / AppCommandPalette render plain `<a>` tags — that means full page reloads instead of client-side navigation.
32
+ - **The framework router bridge for all shell components.** Without LinkProvider, Sidebar / BottomNavbar / TopBar.UserMenu / AppCommandPalette render plain `<a>` tags — that means full page reloads instead of client-side navigation.
33
33
  - **Required setup:**
34
34
  ```tsx
35
35
  // Next.js
@@ -120,7 +120,7 @@ UserMenuItem fields:
120
120
  - **NotificationCenter lives inside TopBar.Right** — it's a complete bell+popover component. Drop it in a TopBar.Section next to other icon buttons.
121
121
  - **UserMenu is composable:** `userMenuItems` inserts custom items between the built-in Profile and the color-mode toggle. Each item can navigate (href), run an action (onClick), or show a separator/badge/color decoration.
122
122
  - **Responsive hiding:** Actions that shouldn't appear on mobile use `className="hidden md:flex"` on the IconButton — the component doesn't enforce mobile hiding; that's layout responsibility.
123
- - **Pairs with AppSidebar** — desktop app shell is typically `<TopBar>` + `<AppSidebar>` + main content region.
123
+ - **Pairs with Sidebar** — desktop app shell is typically `<TopBar>` + `<Sidebar>` + main content region.
124
124
 
125
125
  ## Gotchas
126
126
  - Without `TopBar.Center`, layout is flex (two-zone). With it, layout switches to CSS grid `1fr auto 1fr` for true centering.
@@ -5,7 +5,7 @@
5
5
  - Category: ui
6
6
 
7
7
  ## Props
8
- size: "sm" | "md" | "lg"
8
+ size: "xs" | "sm" | "md" | "lg"
9
9
  loading: boolean (shows spinner instead of clear button)
10
10
  onClear: () => void (shows X button when value is non-empty)
11
11
  value: string
@@ -31,7 +31,7 @@
31
31
  - **`onClear` makes the X button appear** only when `value` is non-empty. Pair them so users can reset.
32
32
  - **`loading={true}` swaps the clear button for a spinner** with `aria-busy="true"` on the input — useful for debounced/async search.
33
33
  - Doesn't auto-consume FormField (no `state` prop) — wrap a regular Input inside FormField for validated search fields.
34
- - Keyboard: Escape auto-triggers `onClear` when wired (handled via `type="search"`'s native behavior on most browsers).
34
+ - Keyboard: Escape is NOT wired to clear (the input is not `type="search"`). Reset via the X button, or handle Escape yourself and call your `value` setter.
35
35
 
36
36
  ## Gotchas
37
37
  - HTML native "size" attribute is excluded — use CSS width instead
@@ -22,14 +22,14 @@
22
22
  - Radix Slider primitive — keyboard navigation (arrow keys, Home/End, PageUp/PageDown) pre-wired.
23
23
  - **Value is always an array** — single-thumb: `[50]`; range: `[25, 75]`. Don't pass a plain number.
24
24
  - **Multi-thumb range:** Pass `[start, end]` — renders two thumbs that can cross each other by default. Use `minStepsBetweenThumbs` to enforce a gap.
25
- - **FormField:** Slider does NOT auto-consume FormField state. No validation UX sliders usually don't need it (values are always valid by construction).
25
+ - **FormField:** Slider consumes FormField for a11y wiring (`aria-invalid` / `aria-describedby` / `aria-required`) but renders no visual validation treatment values are valid by construction, so there's no error UX to hand-wire.
26
26
  - **No label pairing via Label** — use `aria-label` or `aria-labelledby` directly on the Slider. The thumb is the focusable/labeled element.
27
27
  - Not portal-rendered — inline; overflow rules of parents apply.
28
28
 
29
29
  ## Gotchas
30
30
  - value is number[] (array), not a single number
31
31
  - Multi-thumb: Pass array `defaultValue={[25, 75]}` for range sliders — renders one thumb per value
32
- - Slider does NOT auto-consume FormFieldsliders don't have validation state visuals by design
32
+ - Slider consumes FormField for a11y wiring (aria-invalid/describedby/required) but shows no validation visuals by design — don't hand-wire what it already does
33
33
 
34
34
  ## Changes
35
35
  ### v0.18.0
@@ -37,9 +37,9 @@ import { SplitButton } from '@devalok/shilp-sutra'
37
37
 
38
38
  ## Composability
39
39
  - **Two-in-one button:** visually unified `[Action | ▼]` with the left half being the primary click and the right half opening a dropdown. Use for actions that have a most-common choice plus alternatives (Save vs. Save-As-Draft, Send vs. Schedule).
40
- - **Built on Button + Popover internally** — inherits Button's variant/color/size vocabulary and Popover's placement prop (`top-end` default works for most top-of-page toolbars).
40
+ - **Composes the DS Popover internally** and shares the `color` type + a `variant`/`size` subset with Button (currently `solid`/`soft`/`outline` × the Button colors; no `ghost`/`link`/`lg`). Note: the half styling is implemented locally, not inherited from `Button` a few Button niceties (e.g. `solid`'s `hover:shadow-brand`) don't apply. Popover placement via `top-end` default suits most top-of-page toolbars.
41
41
  - **Dropdown content is consumer-provided** — pass any JSX via `dropdownContent` (typically a DropdownMenu, list of actions, a custom panel, or a small form). Don't try to shove a full-featured menu into the chevron; keep it focused on 2–5 alternatives.
42
- - **ButtonGroup compatibility:** Put SplitButton inside a `<ButtonGroup>`it inherits variant/color/size from the group context just like Button does. Position-aware corners work too.
42
+ - **ButtonGroup:** SplitButton does NOT consume `ButtonGroup` context set its `variant`/`color`/`size` explicitly to match a surrounding group.
43
43
  - **Controlled dropdown:** Pass `open` + `onOpenChange` for controlled state; omit for uncontrolled. Useful when the dropdown must close programmatically after a selection.
44
44
 
45
45
  ## Gotchas
@@ -49,7 +49,7 @@ import { SplitButton } from '@devalok/shilp-sutra'
49
49
  ## Changes
50
50
 
51
51
  ### v0.44.2
52
- - **Fixed** The dropdown is now keyboard-accessible. It previously used a hand-rolled floating panel (`role="menu"`) with no focus management, arrow keys, or Escape — keyboard users couldn't reach or dismiss it. It now composes the DS **Popover** primitive: focus moves in on open, Escape and outside-click close, focus returns to the trigger, and on mobile it opens as a bottom sheet. (Full menu semantics with arrow-key item navigation via DropdownMenu are planned for 0.45.0.)
52
+ - **Fixed** The dropdown is now keyboard-accessible. It previously used a hand-rolled floating panel (`role="menu"`) with no focus management, arrow keys, or Escape — keyboard users couldn't reach or dismiss it. It now composes the DS **Popover** primitive: focus moves in on open, Escape and outside-click close, focus returns to the trigger, and on mobile it opens as a bottom sheet.
53
53
 
54
54
  ### v0.33.0
55
55
  - **Added** Initial release
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # @devalok/shilp-sutra
2
2
 
3
- > Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.53.0.
3
+ > Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.54.0.
4
4
  > Built on the same primitives as shadcn/ui but with DIFFERENT prop APIs — never guess from shadcn knowledge; verify every prop.
5
5
  > This file is a ROUTER: it tells you what exists and where to get details. Do not look for prop tables here — fetch them per component (MCP tool or per-component doc file below).
6
6
 
@@ -92,6 +92,7 @@ Format: `[name](doc path): summary`. Import paths follow `@devalok/shilp-sutra/<
92
92
  - [select](docs/components/ui/select.md)
93
93
  - [separator](docs/components/ui/separator.md)
94
94
  - [sheet](docs/components/ui/sheet.md)
95
+ - [sidebar](docs/components/ui/sidebar.md)
95
96
  - [skeleton](docs/components/ui/skeleton.md)
96
97
  - [slider](docs/components/ui/slider.md)
97
98
  - [spinner](docs/components/ui/spinner.md)
@@ -156,7 +157,6 @@ Format: `[name](doc path): summary`. Import paths follow `@devalok/shilp-sutra/<
156
157
  - [link-context](docs/components/shell/link-context.md): Exports: LinkProvider, useLink
157
158
  - [notification-center](docs/components/shell/notification-center.md)
158
159
  - [notification-preferences](docs/components/shell/notification-preferences.md)
159
- - [sidebar](docs/components/shell/sidebar.md)
160
160
  - [top-bar](docs/components/shell/top-bar.md)
161
161
 
162
162
  ### ai
@@ -34,7 +34,7 @@ These are not preferences. Generated code that violates them is wrong.
34
34
 
35
35
  ## Workflow — before generating any screen
36
36
 
37
- 1. **Identify the layout shell.** AppSidebar + TopBar for product pages. Container + Stack for marketing. Dialog/Sheet for modal flows.
37
+ 1. **Identify the layout shell.** Sidebar + TopBar for product pages. Container + Stack for marketing. Dialog/Sheet for modal flows.
38
38
  2. **Pick the surface for each region.** Read `foundations/surfaces.md`. Default page bg is `surface-base`; everything else stacks up from there.
39
39
  3. **Pick components from `components/overview.md`.** That file has decision trees for the common confusions (Button variant, Input vs Combobox vs Autocomplete, Dialog vs Sheet vs Popover).
40
40
  4. **Lay things out with `<Stack>` + `<Container>`.** Use `gap-ds-03/05/07`. Don't reach for arbitrary flex divs.
@@ -116,7 +116,7 @@ Top of every page?
116
116
  → <TopBar> (shell)
117
117
 
118
118
  Side nav (product)?
119
- → <AppSidebar> (shell) — collapsible, with sections, footer
119
+ → <Sidebar> primitives (ui) — or the sidebar-app preset (shilp-sutra.devalok.in/presets)
120
120
 
121
121
  Tabs within a page?
122
122
  → <Tabs> — horizontal default
@@ -279,7 +279,7 @@ Code?
279
279
  | Pagination | `/ui/pagination` |
280
280
  | Stepper | `/ui/stepper` |
281
281
  | NavigationMenu | `/ui/navigation-menu` |
282
- | Sidebar (AppSidebar) | `/shell/sidebar` |
282
+ | Sidebar | `/ui/sidebar` |
283
283
  | TopBar | `/shell/top-bar` |
284
284
  | BottomNavbar | `/shell/bottom-navbar` |
285
285
 
@@ -109,7 +109,7 @@ In dark mode the kit lightens surfaces with elevation (so `surface-overlay` is *
109
109
  </div>
110
110
  ```
111
111
 
112
- (In practice you wouldn't write the `bg-*` / `shadow-*` directly — `<Card>`, `<DialogContent>`, `<AppSidebar>` apply them. This is just the layer model.)
112
+ (In practice you wouldn't write the `bg-*` / `shadow-*` directly — `<Card>`, `<DialogContent>`, `<Sidebar>` apply them. This is just the layer model.)
113
113
 
114
114
  ## Rules
115
115