@ngrok/mantle 0.82.0 → 0.83.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 (175) hide show
  1. package/dist/accordion.d.ts +7 -7
  2. package/dist/accordion.js +1 -1
  3. package/dist/agent.json +3 -1
  4. package/dist/{alert-BWwNPOMI.d.ts → alert-B1HXfkYn.d.ts} +9 -7
  5. package/dist/{alert-QMs0PqMq.js → alert-BuG2qS5l.js} +1 -1
  6. package/dist/alert-center.d.ts +220 -22
  7. package/dist/alert-center.js +1 -1
  8. package/dist/alert-dialog.d.ts +18 -18
  9. package/dist/alert-dialog.js +1 -1
  10. package/dist/alert.d.ts +1 -1
  11. package/dist/alert.js +1 -1
  12. package/dist/{anchor-DvbNsphX.js → anchor-3OGK2UKU.js} +1 -1
  13. package/dist/anchor.d.ts +2 -2
  14. package/dist/anchor.js +1 -1
  15. package/dist/app-layout.d.ts +296 -213
  16. package/dist/app-layout.js +1 -1
  17. package/dist/area-chart.d.ts +67 -19
  18. package/dist/area-chart.js +1 -1
  19. package/dist/avatar.d.ts +319 -0
  20. package/dist/avatar.js +1 -0
  21. package/dist/badge.js +1 -1
  22. package/dist/bar-chart.d.ts +73 -20
  23. package/dist/bar-chart.js +1 -1
  24. package/dist/breadcrumb.d.ts +50 -17
  25. package/dist/breadcrumb.js +1 -1
  26. package/dist/browser-only.d.ts +3 -3
  27. package/dist/{button-C-gMbPso.d.ts → button-BIf69CSV.d.ts} +2 -2
  28. package/dist/button-BLDjW1u9.js +1 -0
  29. package/dist/{button-C0S8RbaJ.js → button-CCkGqE1t.js} +1 -1
  30. package/dist/{button-BUospUB3.js → button-Cnja9Bsr.js} +1 -1
  31. package/dist/{button-C7vAl6lS.d.ts → button-DJ7AAgII.d.ts} +4 -6
  32. package/dist/{button-BO2CKsz6.js → button-DmJkYfyl.js} +1 -1
  33. package/dist/{button-DARFK2KJ.d.ts → button-PoIujPMX.d.ts} +2 -2
  34. package/dist/button.d.ts +3 -3
  35. package/dist/button.js +1 -1
  36. package/dist/calendar.d.ts +1 -1
  37. package/dist/calendar.js +1 -1
  38. package/dist/card.d.ts +15 -15
  39. package/dist/card.js +1 -1
  40. package/dist/centered-layout.js +1 -1
  41. package/dist/{chart-1cVjAcj8.d.ts → chart-0zcFJh4n.d.ts} +75 -22
  42. package/dist/chart-DBxT9BNl.js +2 -0
  43. package/dist/{choice-BNRQXszu.d.ts → choice-CVdQrs-m.d.ts} +118 -6
  44. package/dist/{choice-C9gLKECf.js → choice-CnwfjSEu.js} +1 -1
  45. package/dist/choice.d.ts +1 -1
  46. package/dist/choice.js +1 -1
  47. package/dist/{code-block-C9uaM9-V.js → code-block-CIE0F2fu.js} +1 -1
  48. package/dist/{code-block-B6OlZrSI.d.ts → code-block-CZWPrV4k.d.ts} +3 -3
  49. package/dist/code-block.d.ts +10 -7
  50. package/dist/code-block.js +2 -2
  51. package/dist/code-block_highlight-utils.d.ts +1 -1
  52. package/dist/code-block_highlight-utils.js +1 -1
  53. package/dist/code.js +1 -1
  54. package/dist/combobox.d.ts +8 -9
  55. package/dist/combobox.js +1 -1
  56. package/dist/command.d.ts +668 -106
  57. package/dist/command.js +1 -1
  58. package/dist/cookie-ca4g5CKp.js +1 -0
  59. package/dist/data-table.d.ts +6 -6
  60. package/dist/data-table.js +1 -1
  61. package/dist/description-list.js +1 -1
  62. package/dist/dialog-02mNrAT1.d.ts +806 -0
  63. package/dist/{dialog-Bsj_dX6r.js → dialog-BRjTD83p.js} +1 -1
  64. package/dist/dialog.d.ts +2 -805
  65. package/dist/dialog.js +1 -1
  66. package/dist/{dropdown-menu-fUMqjRC0.js → dropdown-menu-BRH0Wd_z.js} +1 -1
  67. package/dist/dropdown-menu-BcALUQMp.d.ts +1 -0
  68. package/dist/{dropdown-menu-D6pMAY7I.d.ts → dropdown-menu-DZOfj6HB.d.ts} +1 -1
  69. package/dist/dropdown-menu.d.ts +2 -2
  70. package/dist/dropdown-menu.js +1 -1
  71. package/dist/empty.js +1 -1
  72. package/dist/field.d.ts +5 -5
  73. package/dist/field.js +1 -1
  74. package/dist/flag.js +1 -1
  75. package/dist/hooks.d.ts +16 -17
  76. package/dist/hooks.js +1 -1
  77. package/dist/icons-DEVx1oP9.js +1 -0
  78. package/dist/icons.d.ts +7 -6
  79. package/dist/icons.js +1 -1
  80. package/dist/{in-view-DDEGUKDR.d.ts → in-view-gxyc9Q1_.d.ts} +1 -1
  81. package/dist/{input-BuYDU6CF.d.ts → input-DpnC3Xgj.d.ts} +2 -2
  82. package/dist/input.d.ts +1 -1
  83. package/dist/kbd.d.ts +1 -1
  84. package/dist/line-chart.d.ts +60 -13
  85. package/dist/line-chart.js +1 -1
  86. package/dist/list-CwL23L_B.js +1 -0
  87. package/dist/list.d.ts +2 -2
  88. package/dist/list.js +1 -1
  89. package/dist/llms.txt +3 -1
  90. package/dist/main.d.ts +32 -1
  91. package/dist/mantle-dark-high-contrast.css +30 -17
  92. package/dist/mantle-dark.css +48 -13
  93. package/dist/mantle-light-high-contrast.css +33 -15
  94. package/dist/mantle.css +436 -26
  95. package/dist/media-object.d.ts +5 -1
  96. package/dist/media-object.js +1 -1
  97. package/dist/multi-select.d.ts +7 -7
  98. package/dist/multi-select.js +1 -1
  99. package/dist/otp-input.d.ts +4 -4
  100. package/dist/otp-input.js +1 -1
  101. package/dist/pagination.d.ts +2 -2
  102. package/dist/pagination.js +1 -1
  103. package/dist/{primitive-Dv-3snU3.js → primitive-D-9GIFWb.js} +1 -1
  104. package/dist/progress.d.ts +4 -4
  105. package/dist/qr-code.d.ts +2 -2
  106. package/dist/qr-code.js +1 -1
  107. package/dist/radio-group.js +1 -1
  108. package/dist/sandbar.d.ts +471 -0
  109. package/dist/sandbar.js +1 -0
  110. package/dist/sandboxed-on-click.d.ts +4 -6
  111. package/dist/sandboxed-on-click.js +1 -1
  112. package/dist/scatter-plot.d.ts +69 -24
  113. package/dist/scatter-plot.js +1 -1
  114. package/dist/{select-0z7HVS6r.d.ts → select-DVHmgih8.d.ts} +13 -7
  115. package/dist/select-LK9NX-vV.js +1 -0
  116. package/dist/select.d.ts +1 -1
  117. package/dist/select.js +1 -1
  118. package/dist/selectable-list.d.ts +4 -4
  119. package/dist/selectable-list.js +1 -1
  120. package/dist/{separator-B5UmkVRL.d.ts → separator-CNDs98Dv.d.ts} +2 -2
  121. package/dist/{separator-BepAcFFy.js → separator-D0D6VyyM.js} +1 -1
  122. package/dist/separator.d.ts +1 -1
  123. package/dist/separator.js +1 -1
  124. package/dist/{sheet-_fXLjiq2.js → sheet-BOSknSN9.js} +1 -1
  125. package/dist/sheet.d.ts +1 -1
  126. package/dist/sheet.js +1 -1
  127. package/dist/sidebar.d.ts +783 -328
  128. package/dist/sidebar.js +1 -1
  129. package/dist/{skeleton-DsHXIa9j.js → skeleton-BhcJMpem.js} +1 -1
  130. package/dist/skeleton.js +1 -1
  131. package/dist/skip-to-main-link.js +1 -1
  132. package/dist/slider.d.ts +1 -1
  133. package/dist/slot-DdgxmuI5.d.ts +67 -0
  134. package/dist/slot-DpNWVci8.js +1 -0
  135. package/dist/slot.d.ts +1 -1
  136. package/dist/slot.js +1 -1
  137. package/dist/split-button.d.ts +12 -12
  138. package/dist/split-button.js +1 -1
  139. package/dist/switch.d.ts +2 -1
  140. package/dist/{table-CGxJwtbL.js → table-C_Nm_RSV.js} +1 -1
  141. package/dist/{table-CZBYEmyK.d.ts → table-D51ZtV4U.d.ts} +18 -8
  142. package/dist/table.d.ts +1 -1
  143. package/dist/table.js +1 -1
  144. package/dist/tabs.d.ts +8 -13
  145. package/dist/tabs.js +1 -1
  146. package/dist/{theme-FbfjYiD3.d.ts → theme-6OxNhf6l.d.ts} +6 -6
  147. package/dist/theme-CVfq037P.js +1 -0
  148. package/dist/theme-switcher.d.ts +4 -4
  149. package/dist/theme-switcher.js +1 -1
  150. package/dist/theme.d.ts +86 -23
  151. package/dist/theme.js +1 -1
  152. package/dist/toast.d.ts +9 -9
  153. package/dist/toast.js +1 -1
  154. package/dist/tooltip-Dnu35cjU.js +1 -0
  155. package/dist/tooltip-DuXGxIse.d.ts +220 -0
  156. package/dist/tooltip.d.ts +1 -217
  157. package/dist/tooltip.js +1 -1
  158. package/dist/use-breakpoint-Dqu12Szq.js +1 -0
  159. package/dist/use-callback-ref-IYti9y7x.js +1 -0
  160. package/dist/use-is-apple-platform-Cxwrb86L.js +1 -0
  161. package/dist/use-matches-media-query-Bd_GhhVd.js +1 -0
  162. package/dist/utils.d.ts +1 -1
  163. package/dist/well.js +1 -1
  164. package/package.json +4 -2
  165. package/dist/button-DvHMWAPl.js +0 -1
  166. package/dist/chart-DdBQ3xwx.js +0 -2
  167. package/dist/dropdown-menu-BbbQuae2.d.ts +0 -1
  168. package/dist/icons-CPbOq7cF.js +0 -1
  169. package/dist/list-CQFWx6Z8.js +0 -1
  170. package/dist/select-B-9yWrif.js +0 -1
  171. package/dist/slot-BtwKJTLq.d.ts +0 -25
  172. package/dist/slot-Dpsqz16D.js +0 -1
  173. package/dist/theme-IAnQ35bd.js +0 -1
  174. package/dist/use-breakpoint-Wd7_5-Mu.js +0 -1
  175. package/dist/use-matches-media-query-CMSxHR9n.js +0 -1
package/dist/sidebar.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { n as WithAsChild } from "./as-child-D23mGo4f.js";
2
- import { n as IconButtonProps } from "./button-C7vAl6lS.js";
3
2
  import { t as WithDataSlot } from "./data-slot-CChfb_cv.js";
4
- import { n as Separator } from "./separator-B5UmkVRL.js";
5
- import { ComponentProps, ReactNode } from "react";
3
+ import { n as IconButtonProps } from "./button-DJ7AAgII.js";
4
+ import { n as Separator } from "./separator-CNDs98Dv.js";
5
+ import { t as Tooltip } from "./tooltip-DuXGxIse.js";
6
+ import { ComponentProps, ReactElement, ReactNode } from "react";
6
7
  //#region src/components/sidebar/sidebar.d.ts
7
8
  /**
8
9
  * The breakpoints below which `Sidebar.Nav` swaps from the inline desktop
@@ -78,13 +79,19 @@ type SidebarState = {
78
79
  * triggers.
79
80
  */
80
81
  navId: string;
82
+ /**
83
+ * Whether this root owns the `⌘B` / `Ctrl+B` shortcut. `Sidebar.Trigger`
84
+ * reads it to decide whether its tooltip advertises the chord, so the hint
85
+ * can never name a binding that is not bound.
86
+ */
87
+ keyboardShortcut: boolean;
81
88
  };
82
89
  /**
83
90
  * Read the nearest `Sidebar.Root` state. Throws when called outside a
84
91
  * `Sidebar.Root` so misuse fails loudly. Use it to build custom triggers,
85
92
  * a keyboard shortcut, or close-on-navigate behavior.
86
93
  *
87
- * @see https://mantle.ngrok.com/components/navigation/sidebar
94
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#usesidebar
88
95
  *
89
96
  * @example
90
97
  * ```tsx
@@ -100,6 +107,11 @@ type SidebarState = {
100
107
  */
101
108
  declare function useSidebar(): SidebarState;
102
109
  type SidebarRootProps = {
110
+ /**
111
+ * The sidebar's parts — a `Sidebar.Nav` and anything that reads the state,
112
+ * including a `Sidebar.Trigger` rendered anywhere below (an
113
+ * `AppLayout.Header`, for example). `Root` renders no DOM of its own.
114
+ */
103
115
  children?: ReactNode;
104
116
  /**
105
117
  * The initial desktop expanded state for the uncontrolled case.
@@ -132,10 +144,18 @@ type SidebarRootProps = {
132
144
  mobileBreakpoint?: SidebarMobileBreakpoint;
133
145
  /**
134
146
  * Toggle the sidebar with `⌘B` (macOS) / `Ctrl+B` (Windows/Linux). The
135
- * shortcut requires exactly the platform modifier + `b` combinations with
136
- * `Shift`/`Alt` (e.g. the browser's own `⌘⇧B`) are left alone. Set `false`
137
- * to opt out, e.g. when the app embeds a rich-text editor where `⌘B` means
138
- * bold.
147
+ * shortcut requires exactly the platform modifier + `b`: `⌘` on Apple
148
+ * platforms and `Ctrl` everywhere else, resolved per host the two never
149
+ * substitute for each other, so macOS's native `Ctrl+B` ("move the caret
150
+ * back one character") is left alone. Combinations with `Shift`/`Alt` (e.g.
151
+ * the browser's own `⌘⇧B`) pass through too.
152
+ *
153
+ * The shortcut is also ignored while focus is in a text-editing or form
154
+ * control — an `<input>`, `<textarea>`, `<select>`, or any `contenteditable`
155
+ * host — because the chord is usually already bound there (`⌘B` is "bold")
156
+ * and this is a `window` listener that calls `preventDefault()`. That covers
157
+ * embedded editors like Monaco and CodeMirror, which attach to exactly those
158
+ * elements. Set `false` to opt out entirely.
139
159
  *
140
160
  * The shortcut has exactly one owner per window: the first mounted root
141
161
  * with the shortcut enabled. Additional roots (nested or siblings) queue
@@ -148,7 +168,7 @@ type SidebarRootProps = {
148
168
  };
149
169
  /**
150
170
  * The state owner for a sidebar. Renders no DOM of its own (like
151
- * `Tooltip.Root`) — it provides the expanded/collapsed and mobile-sheet state
171
+ * `Tooltip.Root`) — it carries the expanded/collapsed and mobile-sheet state
152
172
  * to every part below it, so `Sidebar.Trigger` can live anywhere in the tree
153
173
  * (for example inside an `AppLayout.Header`) without coupling the app shell
154
174
  * to the sidebar.
@@ -156,13 +176,24 @@ type SidebarRootProps = {
156
176
  * Render exactly one `Sidebar.Nav` per `Sidebar.Root`. Nested roots shadow
157
177
  * the outer sidebar for everything below them.
158
178
  *
159
- * @see https://mantle.ngrok.com/components/navigation/sidebar
179
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarroot
160
180
  *
161
181
  * @example
162
182
  * ```tsx
163
183
  * <Sidebar.Root>
164
184
  * <Sidebar.Nav aria-label="Main">
165
- * <Sidebar.Header>…</Sidebar.Header>
185
+ * <Sidebar.Header>
186
+ * <DropdownMenu.Root>
187
+ * <DropdownMenu.Trigger asChild>
188
+ * <Sidebar.SwitcherTrigger>
189
+ * <GlobeIcon />
190
+ * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
191
+ * <CaretDownIcon className="text-muted size-4 shrink-0" />
192
+ * </Sidebar.SwitcherTrigger>
193
+ * </DropdownMenu.Trigger>
194
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
195
+ * </DropdownMenu.Root>
196
+ * </Sidebar.Header>
166
197
  * <Sidebar.Body>
167
198
  * <Sidebar.Group>
168
199
  * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
@@ -178,11 +209,22 @@ type SidebarRootProps = {
178
209
  * </Sidebar.List>
179
210
  * </Sidebar.Group>
180
211
  * </Sidebar.Body>
181
- * <Sidebar.Footer>…</Sidebar.Footer>
212
+ * <Sidebar.Footer>
213
+ * <Sidebar.Separator />
214
+ * <DropdownMenu.Root>
215
+ * <DropdownMenu.Trigger asChild>
216
+ * <Sidebar.SwitcherTrigger>
217
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
218
+ * <Avatar.Fallback name="Acme Corp" />
219
+ * </Avatar.Root>
220
+ * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
221
+ * </Sidebar.SwitcherTrigger>
222
+ * </DropdownMenu.Trigger>
223
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
224
+ * </DropdownMenu.Root>
225
+ * </Sidebar.Footer>
182
226
  * </Sidebar.Nav>
183
- * <main>
184
- * <Sidebar.Trigger />
185
- * </main>
227
+ * <Sidebar.Trigger />
186
228
  * </Sidebar.Root>
187
229
  * ```
188
230
  */
@@ -226,19 +268,39 @@ type SidebarNavProps = ComponentProps<"div"> & WithDataSlot;
226
268
  * opens from. Override `--sidebar-width` at `:root` to move both together, or
227
269
  * set `--sidebar-row-width` on the outside surface itself.
228
270
  *
229
- * @see https://mantle.ngrok.com/components/navigation/sidebar
271
+ * **Data attributes:**
272
+ *
273
+ * | Data Attribute | Value | Description |
274
+ * | --- | --- | --- |
275
+ * | `data-state` | `"expanded"` \| `"collapsed"` | On the desktop panel surface. Mirrors the root's expanded state and drives the width collapse to the icon rail; descendant parts style off it with `group-data-[state=collapsed]/sidebar-nav:`. |
276
+ * | `data-hydrated` | present after hydration | Presence-only, desktop panel surface. The CSS-side twin of the `isHydrated` gate: descendant collapse transitions are enabled only under `group-data-hydrated/sidebar-nav:`, so an SSR state correction snaps instead of animating on page load. |
277
+ * | `data-mobile` | present in the mobile sheet | Presence-only. Marks the `Sheet.Content` presentation used below the root's `mobileBreakpoint`. |
278
+ * | `data-state` | `"open"` \| `"closed"` | In the mobile sheet only, where the panel *is* the `Sheet`'s Radix dialog content element and Radix owns the attribute — the sheet's open/close animation state, not the desktop expanded state. Consumers style against it too. |
279
+ *
280
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarnav
230
281
  *
231
282
  * @example
232
283
  * ```tsx
233
284
  * <Sidebar.Root>
234
285
  * <Sidebar.Nav aria-label="Main">
235
- * <Sidebar.Header>…</Sidebar.Header>
286
+ * <Sidebar.Header>
287
+ * <DropdownMenu.Root>
288
+ * <DropdownMenu.Trigger asChild>
289
+ * <Sidebar.SwitcherTrigger>
290
+ * <GlobeIcon />
291
+ * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
292
+ * <CaretDownIcon className="text-muted size-4 shrink-0" />
293
+ * </Sidebar.SwitcherTrigger>
294
+ * </DropdownMenu.Trigger>
295
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
296
+ * </DropdownMenu.Root>
297
+ * </Sidebar.Header>
236
298
  * <Sidebar.Body>
237
299
  * <Sidebar.Group>
238
300
  * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
239
301
  * <Sidebar.List>
240
302
  * <Sidebar.Item>
241
- * <Sidebar.ItemButton asChild>
303
+ * <Sidebar.ItemButton asChild current>
242
304
  * <a href="/endpoints">
243
305
  * <GraphIcon />
244
306
  * Endpoints
@@ -248,8 +310,22 @@ type SidebarNavProps = ComponentProps<"div"> & WithDataSlot;
248
310
  * </Sidebar.List>
249
311
  * </Sidebar.Group>
250
312
  * </Sidebar.Body>
251
- * <Sidebar.Footer>…</Sidebar.Footer>
313
+ * <Sidebar.Footer>
314
+ * <Sidebar.Separator />
315
+ * <DropdownMenu.Root>
316
+ * <DropdownMenu.Trigger asChild>
317
+ * <Sidebar.SwitcherTrigger>
318
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
319
+ * <Avatar.Fallback name="Acme Corp" />
320
+ * </Avatar.Root>
321
+ * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
322
+ * </Sidebar.SwitcherTrigger>
323
+ * </DropdownMenu.Trigger>
324
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
325
+ * </DropdownMenu.Root>
326
+ * </Sidebar.Footer>
252
327
  * </Sidebar.Nav>
328
+ * <Sidebar.Trigger />
253
329
  * </Sidebar.Root>
254
330
  * ```
255
331
  */
@@ -281,12 +357,24 @@ type SidebarTriggerProps = Omit<IconButtonProps, "appearance" | "asChild" | "chi
281
357
  */
282
358
  intent?: IconButtonProps["intent"];
283
359
  /**
284
- * The accessible name for the trigger. Visually hidden but announced to
285
- * assistive technology. Override it for localization.
360
+ * The accessible name for the trigger, and what its tooltip says. Visually
361
+ * hidden on the button itself but announced to assistive technology.
362
+ * Override it for localization.
286
363
  *
287
364
  * @default "Toggle Sidebar"
288
365
  */
289
366
  label?: string;
367
+ /**
368
+ * The keyboard chord that also toggles the sidebar, rendered after the label
369
+ * in the tooltip — usually `<><MetaKey /><Kbd>B</Kbd></>`.
370
+ *
371
+ * Ignored under `Sidebar.Root keyboardShortcut={false}`, so the tooltip can
372
+ * never name a binding that is not bound. Passed rather than built in so the
373
+ * sidebar does not have to reach into another component for the platform
374
+ * modifier glyph — `aria-keyshortcuts` is stamped either way, which is also
375
+ * why the chips render `aria-hidden`.
376
+ */
377
+ shortcut?: ReactNode;
290
378
  };
291
379
  /**
292
380
  * The button that toggles the sidebar: the mobile sheet below the root's
@@ -296,7 +384,28 @@ type SidebarTriggerProps = Omit<IconButtonProps, "appearance" | "asChild" | "chi
296
384
  * `AppLayout.Header`) — it must stay visible at every breakpoint where the
297
385
  * sidebar can collapse, or users have no way to reopen it.
298
386
  *
299
- * @see https://mantle.ngrok.com/components/navigation/sidebar
387
+ * The button is icon-only at every breakpoint, so it always renders a tooltip
388
+ * showing `label` (plus the optional `shortcut` chips). **That means it requires
389
+ * a `TooltipProvider` ancestor, like any `Tooltip.Root`, and throws without
390
+ * one** — mount a single provider at your app root, decoupled from the sidebar,
391
+ * so the app-wide delay and hover settings stay app-wide.
392
+ *
393
+ * It also stamps `aria-keyshortcuts` for the `⌘B` / `Ctrl+B` chord the root
394
+ * binds, resolved after hydration: the server cannot know the host, so the
395
+ * first paint is the non-Apple answer. Both the attribute and the chips are
396
+ * omitted under `Sidebar.Root keyboardShortcut={false}`.
397
+ *
398
+ * **Data attributes:**
399
+ *
400
+ * | Data Attribute | Value | Description |
401
+ * | --- | --- | --- |
402
+ * | `data-state` | `"expanded"` \| `"collapsed"` | Mirrors what the trigger toggles: the mobile sheet below the root's `mobileBreakpoint`, the desktop panel otherwise. Pairs with `aria-expanded`. |
403
+ * | `data-slot` | `"sidebar-trigger-tooltip"` | On the tooltip surface, not the button — the styling hook for the label-and-chord popup this part renders. |
404
+ * | `data-appearance` | `"ghost"` \| `"outlined"` | Read, not stamped: the underlying `IconButton` reflects its `appearance`, which this part defaults to `"ghost"`. |
405
+ * | `data-intent` | `"accent"` \| `"danger"` \| `"neutral"` | Read, not stamped: the underlying `IconButton` reflects its `intent`, which this part defaults to `"neutral"`. |
406
+ * | `data-size` | `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` | Read, not stamped: the underlying `IconButton` reflects its `size` and its own `"md"` default. |
407
+ *
408
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebartrigger
300
409
  *
301
410
  * @example
302
411
  * ```tsx
@@ -334,9 +443,10 @@ type SidebarTriggerProps = Omit<IconButtonProps, "appearance" | "asChild" | "chi
334
443
  * <DropdownMenu.Root>
335
444
  * <DropdownMenu.Trigger asChild>
336
445
  * <Sidebar.SwitcherTrigger>
337
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
446
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
447
+ * <Avatar.Fallback name="Acme Corp" />
448
+ * </Avatar.Root>
338
449
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
339
- * <Sidebar.UserAvatar alt="Jane Doe" />
340
450
  * </Sidebar.SwitcherTrigger>
341
451
  * </DropdownMenu.Trigger>
342
452
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -351,19 +461,19 @@ type SidebarTriggerProps = Omit<IconButtonProps, "appearance" | "asChild" | "chi
351
461
  * Placement within an `AppLayout` shell:
352
462
  * ```tsx
353
463
  * <Sidebar.Root>
354
- * <Sidebar.Nav aria-label="Main">…</Sidebar.Nav>
355
- * <AppLayout.Inset>
464
+ * <AppLayout.Workspace>
465
+ * <Sidebar.Nav aria-label="Main">…</Sidebar.Nav>
356
466
  * <AppLayout.Content>
357
467
  * <AppLayout.Header>
358
468
  * <Sidebar.Trigger />
359
469
  * </AppLayout.Header>
360
- *
470
+ * <AppLayout.Body>…</AppLayout.Body>
361
471
  * </AppLayout.Content>
362
- * </AppLayout.Inset>
472
+ * </AppLayout.Workspace>
363
473
  * </Sidebar.Root>
364
474
  * ```
365
475
  */
366
- declare const Trigger: ({ appearance, "data-slot": dataSlot, icon, intent, label, onClick, ...props }: SidebarTriggerProps) => import("react").JSX.Element;
476
+ declare const Trigger: ({ appearance, "data-slot": dataSlot, icon, intent, label, onClick, shortcut, ...props }: SidebarTriggerProps) => import("react").JSX.Element;
367
477
  type SidebarHeaderProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
368
478
  /**
369
479
  * The top container of a `Sidebar.Nav`, pinned above the scrollable
@@ -382,7 +492,7 @@ type SidebarHeaderProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
382
492
  * | --- | --- | --- |
383
493
  * | `--sidebar-header-height` | `4.5rem` | The header row height (72px). Set it on a common ancestor of the sidebar and `AppLayout.Header`, not on `Sidebar.Nav`, so both rows read one value. |
384
494
  *
385
- * @see https://mantle.ngrok.com/components/navigation/sidebar
495
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarheader
386
496
  *
387
497
  * @example
388
498
  * ```tsx
@@ -420,9 +530,10 @@ type SidebarHeaderProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
420
530
  * <DropdownMenu.Root>
421
531
  * <DropdownMenu.Trigger asChild>
422
532
  * <Sidebar.SwitcherTrigger>
423
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
533
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
534
+ * <Avatar.Fallback name="Acme Corp" />
535
+ * </Avatar.Root>
424
536
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
425
- * <Sidebar.UserAvatar alt="Jane Doe" />
426
537
  * </Sidebar.SwitcherTrigger>
427
538
  * </DropdownMenu.Trigger>
428
539
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -442,7 +553,7 @@ type SidebarBodyProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
442
553
  * `scroll-fade-y` mask; inside the collapsed icon rail the scrollbar and its
443
554
  * reserved gutter are hidden and the fade is the only overflow signal.
444
555
  *
445
- * @see https://mantle.ngrok.com/components/navigation/sidebar
556
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarbody
446
557
  *
447
558
  * @example
448
559
  * ```tsx
@@ -480,9 +591,10 @@ type SidebarBodyProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
480
591
  * <DropdownMenu.Root>
481
592
  * <DropdownMenu.Trigger asChild>
482
593
  * <Sidebar.SwitcherTrigger>
483
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
594
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
595
+ * <Avatar.Fallback name="Acme Corp" />
596
+ * </Avatar.Root>
484
597
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
485
- * <Sidebar.UserAvatar alt="Jane Doe" />
486
598
  * </Sidebar.SwitcherTrigger>
487
599
  * </DropdownMenu.Trigger>
488
600
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -498,10 +610,10 @@ type SidebarFooterProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
498
610
  /**
499
611
  * The bottom container of a `Sidebar.Nav`, pinned below the scrollable
500
612
  * `Sidebar.Body`. Typically holds cross-product items and the account/user
501
- * switcher row (`Sidebar.SwitcherTrigger` with `Sidebar.AccountAvatar` and
502
- * `Sidebar.UserAvatar`).
613
+ * switcher row (`Sidebar.SwitcherTrigger` with an
614
+ * [Avatar](https://mantle.ngrok.com/components/data-display/avatar)).
503
615
  *
504
- * @see https://mantle.ngrok.com/components/navigation/sidebar
616
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarfooter
505
617
  *
506
618
  * @example
507
619
  * ```tsx
@@ -539,9 +651,10 @@ type SidebarFooterProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
539
651
  * <DropdownMenu.Root>
540
652
  * <DropdownMenu.Trigger asChild>
541
653
  * <Sidebar.SwitcherTrigger>
542
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
654
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
655
+ * <Avatar.Fallback name="Acme Corp" />
656
+ * </Avatar.Root>
543
657
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
544
- * <Sidebar.UserAvatar alt="Jane Doe" />
545
658
  * </Sidebar.SwitcherTrigger>
546
659
  * </DropdownMenu.Trigger>
547
660
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -560,7 +673,7 @@ type SidebarGroupProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
560
673
  * group wires it to the list via `aria-labelledby` so assistive technology
561
674
  * announces the list with the group's name.
562
675
  *
563
- * @see https://mantle.ngrok.com/components/navigation/sidebar
676
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebargroup
564
677
  *
565
678
  * @example
566
679
  * ```tsx
@@ -598,9 +711,10 @@ type SidebarGroupProps = ComponentProps<"div"> & WithAsChild & WithDataSlot;
598
711
  * <DropdownMenu.Root>
599
712
  * <DropdownMenu.Trigger asChild>
600
713
  * <Sidebar.SwitcherTrigger>
601
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
714
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
715
+ * <Avatar.Fallback name="Acme Corp" />
716
+ * </Avatar.Root>
602
717
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
603
- * <Sidebar.UserAvatar alt="Jane Doe" />
604
718
  * </Sidebar.SwitcherTrigger>
605
719
  * </DropdownMenu.Trigger>
606
720
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -620,7 +734,7 @@ type SidebarGroupLabelProps = ComponentProps<"div"> & WithAsChild & WithDataSlot
620
734
  * the sibling list via `aria-labelledby`. Pass `asChild` to render a heading
621
735
  * at a level you control.
622
736
  *
623
- * @see https://mantle.ngrok.com/components/navigation/sidebar
737
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebargrouplabel
624
738
  *
625
739
  * @example
626
740
  * ```tsx
@@ -658,9 +772,10 @@ type SidebarGroupLabelProps = ComponentProps<"div"> & WithAsChild & WithDataSlot
658
772
  * <DropdownMenu.Root>
659
773
  * <DropdownMenu.Trigger asChild>
660
774
  * <Sidebar.SwitcherTrigger>
661
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
775
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
776
+ * <Avatar.Fallback name="Acme Corp" />
777
+ * </Avatar.Root>
662
778
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
663
- * <Sidebar.UserAvatar alt="Jane Doe" />
664
779
  * </Sidebar.SwitcherTrigger>
665
780
  * </DropdownMenu.Trigger>
666
781
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -678,7 +793,7 @@ type SidebarListProps = ComponentProps<"ul"> & WithAsChild & WithDataSlot;
678
793
  * has a `Sidebar.GroupLabel`, the list is announced with the group's name via
679
794
  * `aria-labelledby`.
680
795
  *
681
- * @see https://mantle.ngrok.com/components/navigation/sidebar
796
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarlist
682
797
  *
683
798
  * @example
684
799
  * ```tsx
@@ -716,9 +831,10 @@ type SidebarListProps = ComponentProps<"ul"> & WithAsChild & WithDataSlot;
716
831
  * <DropdownMenu.Root>
717
832
  * <DropdownMenu.Trigger asChild>
718
833
  * <Sidebar.SwitcherTrigger>
719
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
834
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
835
+ * <Avatar.Fallback name="Acme Corp" />
836
+ * </Avatar.Root>
720
837
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
721
- * <Sidebar.UserAvatar alt="Jane Doe" />
722
838
  * </Sidebar.SwitcherTrigger>
723
839
  * </DropdownMenu.Trigger>
724
840
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -736,7 +852,7 @@ type SidebarItemProps = ComponentProps<"li"> & WithAsChild & WithDataSlot;
736
852
  * element is the `Sidebar.ItemButton` child, so props, `ref`, and `className`
737
853
  * all target the list item itself.
738
854
  *
739
- * @see https://mantle.ngrok.com/components/navigation/sidebar
855
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebaritem
740
856
  *
741
857
  * @example
742
858
  * ```tsx
@@ -774,9 +890,10 @@ type SidebarItemProps = ComponentProps<"li"> & WithAsChild & WithDataSlot;
774
890
  * <DropdownMenu.Root>
775
891
  * <DropdownMenu.Trigger asChild>
776
892
  * <Sidebar.SwitcherTrigger>
777
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
893
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
894
+ * <Avatar.Fallback name="Acme Corp" />
895
+ * </Avatar.Root>
778
896
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
779
- * <Sidebar.UserAvatar alt="Jane Doe" />
780
897
  * </Sidebar.SwitcherTrigger>
781
898
  * </DropdownMenu.Trigger>
782
899
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -793,6 +910,10 @@ type SidebarItemButtonProps = ComponentProps<"button"> & WithAsChild & WithDataS
793
910
  * Marks this row as the current page: sets `aria-current="page"` and the
794
911
  * `data-current` styling state. Consumers control it from their router,
795
912
  * e.g. `current={pathname === "/endpoints"}`.
913
+ *
914
+ * A composed child that sets `aria-current="page"` itself — react-router's
915
+ * `NavLink` does — already gets the current-row treatment, so it needs no
916
+ * `current`. This prop is for the rows whose parent knows.
796
917
  */
797
918
  current?: boolean;
798
919
  };
@@ -802,6 +923,20 @@ type SidebarItemButtonProps = ComponentProps<"button"> & WithAsChild & WithDataS
802
923
  * compose with a router link. `current` sets `aria-current="page"` and the
803
924
  * `data-current` visual state.
804
925
  *
926
+ * The current-row treatment follows either attribute, so a composed child that
927
+ * marks itself as the current page gets it without `current` — a react-router
928
+ * `NavLink` needs nothing but its `to`, since it already resolved the match the
929
+ * parent would otherwise re-derive:
930
+ *
931
+ * ```tsx
932
+ * <Sidebar.ItemButton asChild>
933
+ * <NavLink to="/endpoints">
934
+ * <GraphIcon />
935
+ * Endpoints
936
+ * </NavLink>
937
+ * </Sidebar.ItemButton>
938
+ * ```
939
+ *
805
940
  * The row sizes its **leading** icon to 20px and leaves trailing visuals — a
806
941
  * caret, a count, a status dot — to size themselves, so a row composed with
807
942
  * `DropdownMenu.Trigger asChild` can end in `<CaretDownIcon className="text-muted
@@ -811,7 +946,15 @@ type SidebarItemButtonProps = ComponentProps<"button"> & WithAsChild & WithDataS
811
946
  * it keeps the expanded row's width instead of shrinking to this row's 28px
812
947
  * rail chip (see `Sidebar.SwitcherTrigger` for the whole contract).
813
948
  *
814
- * @see https://mantle.ngrok.com/components/navigation/sidebar
949
+ * **Data attributes:**
950
+ *
951
+ * | Data Attribute | Value | Description |
952
+ * | --- | --- | --- |
953
+ * | `data-current` | present when `current` | Presence-only — never `"false"`, since the `data-current:` variant matches the attribute's existence. Styles the current row. |
954
+ * | `aria-current` | `"page"` when `current` | Set alongside `data-current`. The current-row styling follows *either*, so a composed child that marks itself (react-router's `NavLink`) gets the treatment without the prop. |
955
+ * | `data-state` | `"open"` | **Read, not stamped** — supplied by a composing `DropdownMenu.Trigger` / `Dialog.Trigger`. The row styles against it so it stays highlighted while its menu is open. |
956
+ *
957
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebaritembutton
815
958
  *
816
959
  * @example
817
960
  * ```tsx
@@ -849,9 +992,10 @@ type SidebarItemButtonProps = ComponentProps<"button"> & WithAsChild & WithDataS
849
992
  * <DropdownMenu.Root>
850
993
  * <DropdownMenu.Trigger asChild>
851
994
  * <Sidebar.SwitcherTrigger>
852
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
995
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
996
+ * <Avatar.Fallback name="Acme Corp" />
997
+ * </Avatar.Root>
853
998
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
854
- * <Sidebar.UserAvatar alt="Jane Doe" />
855
999
  * </Sidebar.SwitcherTrigger>
856
1000
  * </DropdownMenu.Trigger>
857
1001
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -863,53 +1007,112 @@ type SidebarItemButtonProps = ComponentProps<"button"> & WithAsChild & WithDataS
863
1007
  * ```
864
1008
  */
865
1009
  declare const ItemButton: ({ asChild, children, className, current, "data-slot": dataSlot, type, ...props }: SidebarItemButtonProps) => import("react").JSX.Element;
866
- type SidebarSwitcherTriggerProps = ComponentProps<"button"> & WithAsChild & WithDataSlot;
1010
+ type SidebarSearchTriggerProps = ComponentProps<"button"> & WithDataSlot & ({
1011
+ /**
1012
+ * Compose the search row's styling onto your own element. Then the
1013
+ * row's entire content is yours — including any shortcut hint, which
1014
+ * `shortcut` cannot add to a cloned child.
1015
+ */
1016
+ asChild: true;
1017
+ shortcut?: never;
1018
+ } | {
1019
+ /**
1020
+ * Compose the search row's styling onto your own element. Then the
1021
+ * row's entire content is yours — including any shortcut hint, which
1022
+ * `shortcut` cannot add to a cloned child.
1023
+ */
1024
+ asChild?: false;
1025
+ /**
1026
+ * The keyboard hint for the chord that opens the same palette — usually
1027
+ * `<><MetaKey /><Kbd>K</Kbd></>`.
1028
+ *
1029
+ * Rendered pinned to the end of the row and **revealed only on hover or
1030
+ * keyboard focus**, so the row reads as a quiet navigation item at rest
1031
+ * and teaches the chord at the moment a user reaches for it. It is
1032
+ * `aria-hidden` and dropped outright in the collapsed rail: the chord is
1033
+ * announced by the `aria-keyshortcuts` that `Command.SearchTrigger`
1034
+ * adds, so repeating it here would announce it twice.
1035
+ *
1036
+ * Passed rather than built in, so the sidebar does not have to know
1037
+ * which chord your palette binds.
1038
+ */
1039
+ shortcut?: ReactNode;
1040
+ });
867
1041
  /**
868
- * The styled row for the sidebar's switchers: the app/product switcher in
869
- * `Sidebar.Header` and the account/user row in `Sidebar.Footer`. A styled
870
- * button only — it is not wired to any state; compose it with
871
- * `DropdownMenu.Trigger asChild` or `Dialog.Trigger asChild`, which supply
872
- * the open state (`data-state="open"` styling comes for free from those
873
- * primitives).
1042
+ * The search row the row that opens a search or command palette.
874
1043
  *
875
- * Inside the collapsed icon rail, the row collapses to
876
- * its **first child element** the leading visual (product icon, account
877
- * avatar) and the remaining children become visually hidden while staying
878
- * in the accessibility tree, so the button's accessible name is unchanged.
879
- * Wrap loose text in an element (e.g. a `<span>`) so it participates.
1044
+ * Put it at the top of `Sidebar.Body`, above the first `Sidebar.Group`: it
1045
+ * needs no height change, and it lands in the same `px-3` gutter as the
1046
+ * navigation rows, so it shares their column in both panel states.
880
1047
  *
881
- * A menu opened from the row should be as wide as the row: `width="trigger"`
882
- * does that while the panel is expanded, but the row shrinks to a 36px chip in
883
- * the icon rail and would drag the menu down to it. Floor the menu at the
884
- * expanded row width with `className="min-w-(--sidebar-row-width)"` the
885
- * token `mantle.css` declares at `:root` for exactly this, since the menu
886
- * renders in a portal and inherits nothing from the panel. The floor is a
887
- * no-op while the panel is expanded (the row already measures that wide), and
888
- * inert in the mobile sheet as long as its row is the wider of the two
889
- * (`--sidebar-width-mobile` minus `1.5rem` and the sheet's 1px border, vs
890
- * `--sidebar-width` minus `1rem`; 263px vs 240px at the defaults) — so widen
891
- * `--sidebar-width-mobile` whenever you widen `--sidebar-width`, or the floor
892
- * overhangs the sheet.
1048
+ * `Sidebar.Header`, under the switcher, also works the header's own `gap-2`
1049
+ * sets the spacing — at the cost of a taller header. That height is a fixed one
1050
+ * row so it can align with an `AppLayout.Header` toolbar, so a stack of two
1051
+ * needs `--sidebar-header-height` raised on a **common ancestor of both rows**
1052
+ * (`<AppLayout.Root className="[--sidebar-header-height:6rem]">`). Setting it on
1053
+ * `Sidebar.Nav` only looks right: custom properties inherit downward, so
1054
+ * `AppLayout.Header` would keep the `4.5rem` default and the two rows would stop
1055
+ * being center-aligned.
893
1056
  *
894
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1057
+ * It is deliberately a navigation row and not a text field. The row is the same
1058
+ * chrome as a `Sidebar.ItemButton` — same height, padding, radius, hover, and
1059
+ * the same 28px chip in the collapsed icon rail — because a search entry point
1060
+ * in a sidebar is one of the rows, not a form control wedged among them. The
1061
+ * `shortcut` hint appears on hover or focus and is otherwise invisible, which
1062
+ * keeps the resting panel quiet.
1063
+ *
1064
+ * A styled button only — it is not wired to any state. Compose it with
1065
+ * [`Command.SearchTrigger`](https://mantle.ngrok.com/components/navigation/command#commandsearchtrigger),
1066
+ * which supplies the dialog wiring, `aria-keyshortcuts`, and the behavior that
1067
+ * makes typing or pasting into the row open the palette with that text already
1068
+ * in the query. Wrap the pair in `Sidebar.Tooltip` so the row keeps a visible
1069
+ * label once the panel collapses.
1070
+ *
1071
+ * Like every row, the rail clips everything after the leading icon rather than
1072
+ * removing it, so the button keeps its accessible name as a chip.
1073
+ *
1074
+ * **Data attributes:**
1075
+ *
1076
+ * | Data Attribute | Value | Description |
1077
+ * | --- | --- | --- |
1078
+ * | `data-state` | `"open"` \| `"closed"` | **Read, not stamped** — supplied by the composing `Command.SearchTrigger` / `Dialog.Trigger`. The row stays highlighted while its palette is open. |
1079
+ *
1080
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarsearchtrigger
895
1081
  *
896
1082
  * @example
897
1083
  * ```tsx
898
1084
  * <Sidebar.Root>
899
1085
  * <Sidebar.Nav aria-label="Main">
900
1086
  * <Sidebar.Header>
901
- * <DropdownMenu.Root>
902
- * <DropdownMenu.Trigger asChild>
903
- * <Sidebar.SwitcherTrigger>
904
- * <GlobeIcon />
905
- * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
906
- * <CaretDownIcon className="text-muted size-4 shrink-0" />
907
- * </Sidebar.SwitcherTrigger>
908
- * </DropdownMenu.Trigger>
909
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
910
- * </DropdownMenu.Root>
1087
+ * <Sidebar.SwitcherTrigger>
1088
+ * <GlobeIcon />
1089
+ * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
1090
+ * </Sidebar.SwitcherTrigger>
911
1091
  * </Sidebar.Header>
912
1092
  * <Sidebar.Body>
1093
+ * <Command.DialogRoot>
1094
+ * <Sidebar.Tooltip label="Search">
1095
+ * <Command.SearchTrigger>
1096
+ * <Sidebar.SearchTrigger
1097
+ * shortcut={
1098
+ * <>
1099
+ * <MetaKey />
1100
+ * <Kbd>K</Kbd>
1101
+ * </>
1102
+ * }
1103
+ * >
1104
+ * <MagnifyingGlassIcon />
1105
+ * <span className="min-w-0 flex-1 truncate">Search</span>
1106
+ * </Sidebar.SearchTrigger>
1107
+ * </Command.SearchTrigger>
1108
+ * </Sidebar.Tooltip>
1109
+ * <Command.DialogContent>
1110
+ * <Command.Input placeholder="Search endpoints, agents, and settings..." />
1111
+ * <Command.List>
1112
+ * <Command.Empty>No results found.</Command.Empty>
1113
+ * </Command.List>
1114
+ * </Command.DialogContent>
1115
+ * </Command.DialogRoot>
913
1116
  * <Sidebar.Group>
914
1117
  * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
915
1118
  * <Sidebar.List>
@@ -924,35 +1127,47 @@ type SidebarSwitcherTriggerProps = ComponentProps<"button"> & WithAsChild & With
924
1127
  * </Sidebar.List>
925
1128
  * </Sidebar.Group>
926
1129
  * </Sidebar.Body>
927
- * <Sidebar.Footer>
928
- * <Sidebar.Separator />
929
- * <DropdownMenu.Root>
930
- * <DropdownMenu.Trigger asChild>
931
- * <Sidebar.SwitcherTrigger>
932
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
933
- * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
934
- * <Sidebar.UserAvatar alt="Jane Doe" />
935
- * </Sidebar.SwitcherTrigger>
936
- * </DropdownMenu.Trigger>
937
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
938
- * </DropdownMenu.Root>
939
- * </Sidebar.Footer>
940
1130
  * </Sidebar.Nav>
941
1131
  * <Sidebar.Trigger />
942
1132
  * </Sidebar.Root>
943
1133
  * ```
944
1134
  */
945
- declare const SwitcherTrigger: ({ asChild, children, className, "data-slot": dataSlot, type, ...props }: SidebarSwitcherTriggerProps) => import("react").JSX.Element;
946
- type SidebarSeparatorProps = ComponentProps<typeof Separator>;
1135
+ declare const SearchTrigger: ({ asChild, children, className, "data-slot": dataSlot, shortcut, type, ...props }: SidebarSearchTriggerProps) => import("react").JSX.Element;
1136
+ type SidebarSwitcherTriggerProps = ComponentProps<"button"> & WithAsChild & WithDataSlot;
947
1137
  /**
948
- * An inset hairline between sidebar regions. Composes the mantle `Separator`,
949
- * staying aligned with the `px-3` content padding of `Sidebar.Body` and
950
- * `Sidebar.Footer` (it deliberately does not run edge to edge) with `my-3`
951
- * breathing room above and below. When collapsed to the icon rail, it widens
952
- * to the same 36px chip width as `Sidebar.SwitcherTrigger`, balancing the
953
- * adjacent app-content gutter that sits outside the rail.
1138
+ * The styled row for the sidebar's switchers: the app/product switcher in
1139
+ * `Sidebar.Header` and the account/user row in `Sidebar.Footer`. A styled
1140
+ * button only — it is not wired to any state; compose it with
1141
+ * `DropdownMenu.Trigger asChild` or `Dialog.Trigger asChild`, which supply
1142
+ * the open state (`data-state="open"` styling comes for free from those
1143
+ * primitives).
954
1144
  *
955
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1145
+ * Inside the collapsed icon rail, the row collapses to
1146
+ * its **first child element** — the leading visual (product icon, account
1147
+ * avatar) — and the remaining children become visually hidden while staying
1148
+ * in the accessibility tree, so the button's accessible name is unchanged.
1149
+ * Wrap loose text in an element (e.g. a `<span>`) so it participates.
1150
+ *
1151
+ * A menu opened from the row should be as wide as the row: `width="trigger"`
1152
+ * does that while the panel is expanded, but the row shrinks to a 36px chip in
1153
+ * the icon rail and would drag the menu down to it. Floor the menu at the
1154
+ * expanded row width with `className="min-w-(--sidebar-row-width)"` — the
1155
+ * token `mantle.css` declares at `:root` for exactly this, since the menu
1156
+ * renders in a portal and inherits nothing from the panel. The floor is a
1157
+ * no-op while the panel is expanded (the row already measures that wide), and
1158
+ * inert in the mobile sheet as long as its row is the wider of the two
1159
+ * (`--sidebar-width-mobile` minus `1.5rem` and the sheet's 1px border, vs
1160
+ * `--sidebar-width` minus `1rem`; 263px vs 240px at the defaults) — so widen
1161
+ * `--sidebar-width-mobile` whenever you widen `--sidebar-width`, or the floor
1162
+ * overhangs the sheet.
1163
+ *
1164
+ * **Data attributes:**
1165
+ *
1166
+ * | Data Attribute | Value | Description |
1167
+ * | --- | --- | --- |
1168
+ * | `data-state` | `"open"` | **Read, not stamped** — supplied by the composing `DropdownMenu.Trigger` / `Dialog.Trigger`. The row styles against it so it stays highlighted while its menu is open. |
1169
+ *
1170
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarswitchertrigger
956
1171
  *
957
1172
  * @example
958
1173
  * ```tsx
@@ -990,9 +1205,10 @@ type SidebarSeparatorProps = ComponentProps<typeof Separator>;
990
1205
  * <DropdownMenu.Root>
991
1206
  * <DropdownMenu.Trigger asChild>
992
1207
  * <Sidebar.SwitcherTrigger>
993
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1208
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1209
+ * <Avatar.Fallback name="Acme Corp" />
1210
+ * </Avatar.Root>
994
1211
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
995
- * <Sidebar.UserAvatar alt="Jane Doe" />
996
1212
  * </Sidebar.SwitcherTrigger>
997
1213
  * </DropdownMenu.Trigger>
998
1214
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1003,105 +1219,138 @@ type SidebarSeparatorProps = ComponentProps<typeof Separator>;
1003
1219
  * </Sidebar.Root>
1004
1220
  * ```
1005
1221
  */
1006
- declare const SidebarSeparator: ({ className, ...props }: SidebarSeparatorProps) => import("react").JSX.Element;
1007
- type SidebarAccountAvatarProps = Omit<ComponentProps<"div">, "children"> & {
1222
+ declare const SwitcherTrigger: ({ asChild, children, className, "data-slot": dataSlot, type, ...props }: SidebarSwitcherTriggerProps) => import("react").JSX.Element;
1223
+ /**
1224
+ * The props for `Sidebar.Tooltip`. `Tooltip.Content`'s props — so `className`,
1225
+ * `style`, `ref`, `asChild`, and any `data-*` reach the tooltip surface — except
1226
+ * the parts this row owns: `children` is the row being labeled (not the tooltip
1227
+ * body, which is `label`), and `side` becomes optional with a sidebar default.
1228
+ */
1229
+ type SidebarTooltipProps = Omit<ComponentProps<typeof Tooltip.Content>, "children" | "side"> & WithDataSlot & {
1230
+ /**
1231
+ * The row this labels — a `Sidebar.ItemButton` or `Sidebar.SwitcherTrigger`,
1232
+ * optionally already wrapped in a `DropdownMenu.Trigger asChild`.
1233
+ *
1234
+ * A single element, required: `Tooltip.Trigger asChild` clones its child, so
1235
+ * text renders nothing a pointer can hover and no children renders no row at
1236
+ * all — both silently.
1237
+ */
1238
+ children: ReactElement;
1239
+ /**
1240
+ * What the tooltip says. Normally the row's own label text: the rail clips the
1241
+ * visible one, so this is what a sighted pointer user reads.
1242
+ */
1243
+ label: ReactNode;
1008
1244
  /**
1009
- * The account's stable identifier. Used to deterministically select a
1010
- * background swatch from the design system's palette so the same account
1011
- * always gets the same color.
1245
+ * The keyboard chord that reaches the same row, rendered after the label —
1246
+ * usually `<><MetaKey /><Kbd>K</Kbd></>`. The rail hides the row's own
1247
+ * shortcut hint along with its label, so the tooltip is where a pointer user
1248
+ * can still learn the chord. The chips are `aria-hidden`: a tooltip is wired
1249
+ * as its row's `aria-describedby`, and the chord is already announced by the
1250
+ * row's `aria-keyshortcuts`.
1251
+ *
1252
+ * Passed rather than built in, so the sidebar does not have to know which
1253
+ * chord the row's palette or action binds.
1012
1254
  */
1013
- accountId: string | undefined;
1255
+ shortcut?: ReactNode;
1014
1256
  /**
1015
- * The account's display name. The first one or two letters become the
1016
- * avatar's initials. Falls back to `?` when the name is empty.
1257
+ * Which side of the row the tooltip opens on. The rail sits at the inline
1258
+ * start of the viewport, so the default points the tooltip away from it.
1259
+ *
1260
+ * @default "right"
1017
1261
  */
1018
- accountName: string | undefined;
1262
+ side?: ComponentProps<typeof Tooltip.Content>["side"];
1019
1263
  };
1020
1264
  /**
1021
- * A small rounded-square avatar that represents an account (workspace,
1022
- * organization, etc.). The background color is derived deterministically from
1023
- * the `accountId` so an account's swatch is stable across renders, sessions,
1024
- * and devices.
1265
+ * Labels a sidebar row while and only while — the desktop panel is collapsed
1266
+ * to the icon rail. Wrap it around a `Sidebar.ItemButton` or
1267
+ * `Sidebar.SwitcherTrigger`.
1025
1268
  *
1026
- * Accounts are rendered as squares to differentiate them visually from users,
1027
- * which use a circular `Sidebar.UserAvatar`.
1269
+ * The collapsed rail keeps every row's label in the accessibility tree (clipped,
1270
+ * not removed), which serves screen-reader users but leaves a sighted pointer
1271
+ * user with an unlabeled icon column. This restores the label for them without
1272
+ * duplicating it for anyone else: expanded rows already read their own text, and
1273
+ * the mobile sheet shows full labels, so the collapsed desktop rail is the only
1274
+ * state that shows a label at all.
1028
1275
  *
1029
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1276
+ * It opens the way any tooltip does — the pointer entering the row, or focus
1277
+ * reaching it — and the rail state vetoes it: the expanded panel and the mobile
1278
+ * sheet keep the row at `data-state="closed"` with no `aria-describedby`, and
1279
+ * toggling the rail dismisses whatever was showing, so collapsing the panel
1280
+ * cannot pop a label under a pointer that has already moved on.
1281
+ *
1282
+ * **Requires a `TooltipProvider` ancestor**, like any `Tooltip.Root` — mount one
1283
+ * at your app root. This part deliberately does not mount its own, so the
1284
+ * app-wide tooltip delay stays app-wide rather than being overridden per row.
1285
+ * The one provider setting it does override is hoverable content: a rail label
1286
+ * holds nothing to hover into, so the pointer leaving the row closes it.
1287
+ *
1288
+ * It composes with a menu trigger: nest `DropdownMenu.Root >
1289
+ * Sidebar.Tooltip > DropdownMenu.Trigger asChild > Sidebar.ItemButton` for a
1290
+ * row that opens a menu *and* labels itself in the rail. `DropdownMenu.Root` must
1291
+ * stay **outside** the tooltip — it is renderless, and `Tooltip.Trigger asChild`
1292
+ * needs a real element to clone.
1293
+ *
1294
+ * `children` is the row; `label` is what the tooltip says. Every other prop is
1295
+ * `Tooltip.Content`'s and lands on the tooltip surface — `className`, `style`,
1296
+ * `ref`, `data-*`, positioning props such as `align` and `sideOffset`, and
1297
+ * `asChild`, which Radix's `Tooltip.Content` implements itself. `side` defaults
1298
+ * to `"right"` so the tooltip opens away from the rail.
1299
+ *
1300
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebartooltip
1030
1301
  *
1031
1302
  * @example
1032
1303
  * ```tsx
1033
- * <Sidebar.Root>
1034
- * <Sidebar.Nav aria-label="Main">
1035
- * <Sidebar.Header>
1036
- * <DropdownMenu.Root>
1037
- * <DropdownMenu.Trigger asChild>
1038
- * <Sidebar.SwitcherTrigger>
1039
- * <GlobeIcon />
1040
- * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
1041
- * <CaretDownIcon className="text-muted size-4 shrink-0" />
1042
- * </Sidebar.SwitcherTrigger>
1043
- * </DropdownMenu.Trigger>
1044
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
1045
- * </DropdownMenu.Root>
1046
- * </Sidebar.Header>
1047
- * <Sidebar.Body>
1048
- * <Sidebar.Group>
1049
- * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
1050
- * <Sidebar.List>
1051
- * <Sidebar.Item>
1052
- * <Sidebar.ItemButton asChild current>
1053
- * <a href="/endpoints">
1054
- * <GraphIcon />
1055
- * Endpoints
1056
- * </a>
1057
- * </Sidebar.ItemButton>
1058
- * </Sidebar.Item>
1059
- * </Sidebar.List>
1060
- * </Sidebar.Group>
1061
- * </Sidebar.Body>
1062
- * <Sidebar.Footer>
1063
- * <Sidebar.Separator />
1064
- * <DropdownMenu.Root>
1065
- * <DropdownMenu.Trigger asChild>
1066
- * <Sidebar.SwitcherTrigger>
1067
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1068
- * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1069
- * <Sidebar.UserAvatar alt="Jane Doe" />
1070
- * </Sidebar.SwitcherTrigger>
1071
- * </DropdownMenu.Trigger>
1072
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
1073
- * </DropdownMenu.Root>
1074
- * </Sidebar.Footer>
1075
- * </Sidebar.Nav>
1076
- * <Sidebar.Trigger />
1077
- * </Sidebar.Root>
1304
+ * <TooltipProvider>
1305
+ * <Sidebar.Root>
1306
+ * <Sidebar.Nav aria-label="Main">
1307
+ * <Sidebar.Body>
1308
+ * <Sidebar.Group>
1309
+ * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
1310
+ * <Sidebar.List>
1311
+ * <Sidebar.Item>
1312
+ * <Sidebar.Tooltip label="Endpoints">
1313
+ * <Sidebar.ItemButton asChild current>
1314
+ * <a href="/endpoints">
1315
+ * <GraphIcon />
1316
+ * Endpoints
1317
+ * </a>
1318
+ * </Sidebar.ItemButton>
1319
+ * </Sidebar.Tooltip>
1320
+ * </Sidebar.Item>
1321
+ * </Sidebar.List>
1322
+ * </Sidebar.Group>
1323
+ * </Sidebar.Body>
1324
+ * <Sidebar.Footer>
1325
+ * <DropdownMenu.Root>
1326
+ * <Sidebar.Tooltip label="Help">
1327
+ * <DropdownMenu.Trigger asChild>
1328
+ * <Sidebar.ItemButton>
1329
+ * <QuestionIcon />
1330
+ * Help
1331
+ * </Sidebar.ItemButton>
1332
+ * </DropdownMenu.Trigger>
1333
+ * </Sidebar.Tooltip>
1334
+ * <DropdownMenu.Content>…</DropdownMenu.Content>
1335
+ * </DropdownMenu.Root>
1336
+ * </Sidebar.Footer>
1337
+ * </Sidebar.Nav>
1338
+ * <Sidebar.Trigger />
1339
+ * </Sidebar.Root>
1340
+ * </TooltipProvider>
1078
1341
  * ```
1079
1342
  */
1080
- declare const AccountAvatar: ({ accountId, accountName, className, ...props }: SidebarAccountAvatarProps) => import("react").JSX.Element;
1081
- type SidebarUserAvatarProps = Omit<ComponentProps<"div">, "children"> & {
1082
- /**
1083
- * Optional URL of the user's profile picture. When provided, the image is
1084
- * rendered to fill the avatar with `object-cover`. When omitted (or while
1085
- * loading), a neutral person silhouette is shown.
1086
- */
1087
- src?: string;
1088
- /**
1089
- * Accessible label for the avatar. Used as the image's `alt` text and as
1090
- * the container's `aria-label` when no image is rendered.
1091
- *
1092
- * @default "Your account"
1093
- */
1094
- alt?: string;
1095
- };
1343
+ declare const SidebarTooltip: ({ children, "data-slot": dataSlot, label, shortcut, side, ...props }: SidebarTooltipProps) => import("react").JSX.Element;
1344
+ type SidebarSeparatorProps = ComponentProps<typeof Separator> & WithDataSlot;
1096
1345
  /**
1097
- * A circular avatar that represents the currently signed-in user. Renders the
1098
- * user's profile picture when `src` is provided, otherwise falls back to a
1099
- * neutral, theme-aware person silhouette.
1100
- *
1101
- * Users are rendered as circles to differentiate them visually from accounts,
1102
- * which use a square `Sidebar.AccountAvatar`.
1346
+ * An inset hairline between sidebar regions. Composes the mantle `Separator`,
1347
+ * staying aligned with the `px-3` content padding of `Sidebar.Body` and
1348
+ * `Sidebar.Footer` (it deliberately does not run edge to edge) with `my-3`
1349
+ * breathing room above and below. When collapsed to the icon rail, it widens
1350
+ * to the same 36px chip width as `Sidebar.SwitcherTrigger`, balancing the
1351
+ * adjacent app-content gutter that sits outside the rail.
1103
1352
  *
1104
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1353
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarseparator
1105
1354
  *
1106
1355
  * @example
1107
1356
  * ```tsx
@@ -1139,9 +1388,10 @@ type SidebarUserAvatarProps = Omit<ComponentProps<"div">, "children"> & {
1139
1388
  * <DropdownMenu.Root>
1140
1389
  * <DropdownMenu.Trigger asChild>
1141
1390
  * <Sidebar.SwitcherTrigger>
1142
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1391
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1392
+ * <Avatar.Fallback name="Acme Corp" />
1393
+ * </Avatar.Root>
1143
1394
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1144
- * <Sidebar.UserAvatar alt="Jane Doe" />
1145
1395
  * </Sidebar.SwitcherTrigger>
1146
1396
  * </DropdownMenu.Trigger>
1147
1397
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1152,7 +1402,7 @@ type SidebarUserAvatarProps = Omit<ComponentProps<"div">, "children"> & {
1152
1402
  * </Sidebar.Root>
1153
1403
  * ```
1154
1404
  */
1155
- declare const UserAvatar: ({ alt, className, src, ...props }: SidebarUserAvatarProps) => import("react").JSX.Element;
1405
+ declare const SidebarSeparator: ({ className, "data-slot": dataSlot, ...props }: SidebarSeparatorProps) => import("react").JSX.Element;
1156
1406
  /**
1157
1407
  * A composable, collapsible app-navigation sidebar. `Sidebar.Root` owns the
1158
1408
  * state (no DOM); `Sidebar.Nav` renders the panel — inline on desktop,
@@ -1176,16 +1426,17 @@ declare const UserAvatar: ({ alt, className, src, ...props }: SidebarUserAvatarP
1176
1426
  * │ ├── Sidebar.Header
1177
1427
  * │ │ └── Sidebar.SwitcherTrigger
1178
1428
  * │ ├── Sidebar.Body
1429
+ * │ │ ├── Sidebar.SearchTrigger
1179
1430
  * │ │ └── Sidebar.Group
1180
1431
  * │ │ ├── Sidebar.GroupLabel
1181
1432
  * │ │ └── Sidebar.List
1182
1433
  * │ │ └── Sidebar.Item
1183
- * │ │ └── Sidebar.ItemButton
1434
+ * │ │ └── Sidebar.Tooltip
1435
+ * │ │ └── Sidebar.ItemButton
1184
1436
  * │ └── Sidebar.Footer
1437
+ * │ ├── Sidebar.ItemButton
1185
1438
  * │ ├── Sidebar.Separator
1186
1439
  * │ └── Sidebar.SwitcherTrigger
1187
- * │ ├── Sidebar.AccountAvatar
1188
- * │ └── Sidebar.UserAvatar
1189
1440
  * └── Sidebar.Trigger
1190
1441
  * ```
1191
1442
  *
@@ -1225,9 +1476,10 @@ declare const UserAvatar: ({ alt, className, src, ...props }: SidebarUserAvatarP
1225
1476
  * <DropdownMenu.Root>
1226
1477
  * <DropdownMenu.Trigger asChild>
1227
1478
  * <Sidebar.SwitcherTrigger>
1228
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1479
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1480
+ * <Avatar.Fallback name="Acme Corp" />
1481
+ * </Avatar.Root>
1229
1482
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1230
- * <Sidebar.UserAvatar alt="Jane Doe" />
1231
1483
  * </Sidebar.SwitcherTrigger>
1232
1484
  * </DropdownMenu.Trigger>
1233
1485
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1240,11 +1492,11 @@ declare const UserAvatar: ({ alt, className, src, ...props }: SidebarUserAvatarP
1240
1492
  */
1241
1493
  declare const Sidebar: {
1242
1494
  /**
1243
- * The state owner for a sidebar. Renders no DOM — provides expanded /
1495
+ * The state owner for a sidebar. Renders no DOM — carries expanded /
1244
1496
  * mobile-sheet state to every part below it so the trigger can live in the
1245
1497
  * app shell without coupling it to the sidebar.
1246
1498
  *
1247
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1499
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarroot
1248
1500
  *
1249
1501
  * @example
1250
1502
  * ```tsx
@@ -1282,9 +1534,10 @@ declare const Sidebar: {
1282
1534
  * <DropdownMenu.Root>
1283
1535
  * <DropdownMenu.Trigger asChild>
1284
1536
  * <Sidebar.SwitcherTrigger>
1285
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1537
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1538
+ * <Avatar.Fallback name="Acme Corp" />
1539
+ * </Avatar.Root>
1286
1540
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1287
- * <Sidebar.UserAvatar alt="Jane Doe" />
1288
1541
  * </Sidebar.SwitcherTrigger>
1289
1542
  * </DropdownMenu.Trigger>
1290
1543
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1302,7 +1555,16 @@ declare const Sidebar: {
1302
1555
  * `--sidebar-width` / `--sidebar-width-mobile` via its `className` or
1303
1556
  * `style`.
1304
1557
  *
1305
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1558
+ * **Data attributes:**
1559
+ *
1560
+ * | Data Attribute | Value | Description |
1561
+ * | --- | --- | --- |
1562
+ * | `data-state` | `"expanded"` \| `"collapsed"` | On the desktop panel surface. Mirrors the root's expanded state and drives the width collapse to the icon rail; descendant parts style off it with `group-data-[state=collapsed]/sidebar-nav:`. |
1563
+ * | `data-hydrated` | present after hydration | Presence-only, desktop panel surface. The CSS-side twin of the `isHydrated` gate: descendant collapse transitions are enabled only under `group-data-hydrated/sidebar-nav:`, so an SSR state correction snaps instead of animating on page load. |
1564
+ * | `data-mobile` | present in the mobile sheet | Presence-only. Marks the `Sheet.Content` presentation used below the root's `mobileBreakpoint`. |
1565
+ * | `data-state` | `"open"` \| `"closed"` | In the mobile sheet only, where the panel *is* the `Sheet`'s Radix dialog content element and Radix owns the attribute — the sheet's open/close animation state, not the desktop expanded state. Consumers style against it too. |
1566
+ *
1567
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarnav
1306
1568
  *
1307
1569
  * @example
1308
1570
  * ```tsx
@@ -1340,9 +1602,10 @@ declare const Sidebar: {
1340
1602
  * <DropdownMenu.Root>
1341
1603
  * <DropdownMenu.Trigger asChild>
1342
1604
  * <Sidebar.SwitcherTrigger>
1343
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1605
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1606
+ * <Avatar.Fallback name="Acme Corp" />
1607
+ * </Avatar.Root>
1344
1608
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1345
- * <Sidebar.UserAvatar alt="Jane Doe" />
1346
1609
  * </Sidebar.SwitcherTrigger>
1347
1610
  * </DropdownMenu.Trigger>
1348
1611
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1358,7 +1621,16 @@ declare const Sidebar: {
1358
1621
  * The `IconButton` that toggles the sidebar. Place it in the app shell's
1359
1622
  * header; it stays functional at every breakpoint.
1360
1623
  *
1361
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1624
+ * **Data attributes:**
1625
+ *
1626
+ * | Data Attribute | Value | Description |
1627
+ * | --- | --- | --- |
1628
+ * | `data-state` | `"expanded"` \| `"collapsed"` | Mirrors what the trigger toggles: the mobile sheet below the root's `mobileBreakpoint`, the desktop panel otherwise. Pairs with `aria-expanded`. |
1629
+ * | `data-appearance` | `"ghost"` \| `"outlined"` | Read, not stamped: the underlying `IconButton` reflects its `appearance`, which this part defaults to `"ghost"`. |
1630
+ * | `data-intent` | `"accent"` \| `"danger"` \| `"neutral"` | Read, not stamped: the underlying `IconButton` reflects its `intent`, which this part defaults to `"neutral"`. |
1631
+ * | `data-size` | `"xs"` \| `"sm"` \| `"md"` \| `"lg"` \| `"xl"` | Read, not stamped: the underlying `IconButton` reflects its `size` and its own `"md"` default. |
1632
+ *
1633
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebartrigger
1362
1634
  *
1363
1635
  * @example
1364
1636
  * ```tsx
@@ -1396,9 +1668,10 @@ declare const Sidebar: {
1396
1668
  * <DropdownMenu.Root>
1397
1669
  * <DropdownMenu.Trigger asChild>
1398
1670
  * <Sidebar.SwitcherTrigger>
1399
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1671
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1672
+ * <Avatar.Fallback name="Acme Corp" />
1673
+ * </Avatar.Root>
1400
1674
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1401
- * <Sidebar.UserAvatar alt="Jane Doe" />
1402
1675
  * </Sidebar.SwitcherTrigger>
1403
1676
  * </DropdownMenu.Trigger>
1404
1677
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1415,7 +1688,7 @@ declare const Sidebar: {
1415
1688
  * switcher (`Sidebar.SwitcherTrigger` + `DropdownMenu`/`Dialog`). Its
1416
1689
  * height vertically aligns the switcher with an `AppLayout.Header`.
1417
1690
  *
1418
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1691
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarheader
1419
1692
  *
1420
1693
  * @example
1421
1694
  * ```tsx
@@ -1453,9 +1726,10 @@ declare const Sidebar: {
1453
1726
  * <DropdownMenu.Root>
1454
1727
  * <DropdownMenu.Trigger asChild>
1455
1728
  * <Sidebar.SwitcherTrigger>
1456
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1729
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1730
+ * <Avatar.Fallback name="Acme Corp" />
1731
+ * </Avatar.Root>
1457
1732
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1458
- * <Sidebar.UserAvatar alt="Jane Doe" />
1459
1733
  * </Sidebar.SwitcherTrigger>
1460
1734
  * </DropdownMenu.Trigger>
1461
1735
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1470,7 +1744,7 @@ declare const Sidebar: {
1470
1744
  /**
1471
1745
  * The scrollable middle region holding the navigation groups.
1472
1746
  *
1473
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1747
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarbody
1474
1748
  *
1475
1749
  * @example
1476
1750
  * ```tsx
@@ -1508,9 +1782,10 @@ declare const Sidebar: {
1508
1782
  * <DropdownMenu.Root>
1509
1783
  * <DropdownMenu.Trigger asChild>
1510
1784
  * <Sidebar.SwitcherTrigger>
1511
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1785
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1786
+ * <Avatar.Fallback name="Acme Corp" />
1787
+ * </Avatar.Root>
1512
1788
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1513
- * <Sidebar.UserAvatar alt="Jane Doe" />
1514
1789
  * </Sidebar.SwitcherTrigger>
1515
1790
  * </DropdownMenu.Trigger>
1516
1791
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1526,7 +1801,7 @@ declare const Sidebar: {
1526
1801
  * The pinned bottom container, typically holding cross-product items and
1527
1802
  * the account/user switcher row.
1528
1803
  *
1529
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1804
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarfooter
1530
1805
  *
1531
1806
  * @example
1532
1807
  * ```tsx
@@ -1564,9 +1839,10 @@ declare const Sidebar: {
1564
1839
  * <DropdownMenu.Root>
1565
1840
  * <DropdownMenu.Trigger asChild>
1566
1841
  * <Sidebar.SwitcherTrigger>
1567
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1842
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1843
+ * <Avatar.Fallback name="Acme Corp" />
1844
+ * </Avatar.Root>
1568
1845
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1569
- * <Sidebar.UserAvatar alt="Jane Doe" />
1570
1846
  * </Sidebar.SwitcherTrigger>
1571
1847
  * </DropdownMenu.Trigger>
1572
1848
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1582,7 +1858,7 @@ declare const Sidebar: {
1582
1858
  * A grouping container pairing a `GroupLabel` with a `List`; wires the
1583
1859
  * label to the list via `aria-labelledby`.
1584
1860
  *
1585
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1861
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebargroup
1586
1862
  *
1587
1863
  * @example
1588
1864
  * ```tsx
@@ -1620,9 +1896,10 @@ declare const Sidebar: {
1620
1896
  * <DropdownMenu.Root>
1621
1897
  * <DropdownMenu.Trigger asChild>
1622
1898
  * <Sidebar.SwitcherTrigger>
1623
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1899
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1900
+ * <Avatar.Fallback name="Acme Corp" />
1901
+ * </Avatar.Root>
1624
1902
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1625
- * <Sidebar.UserAvatar alt="Jane Doe" />
1626
1903
  * </Sidebar.SwitcherTrigger>
1627
1904
  * </DropdownMenu.Trigger>
1628
1905
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1638,7 +1915,7 @@ declare const Sidebar: {
1638
1915
  * The muted label of a group. Renders a `<div>`; pass `asChild` to render
1639
1916
  * a heading at a level you control.
1640
1917
  *
1641
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1918
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebargrouplabel
1642
1919
  *
1643
1920
  * @example
1644
1921
  * ```tsx
@@ -1676,9 +1953,10 @@ declare const Sidebar: {
1676
1953
  * <DropdownMenu.Root>
1677
1954
  * <DropdownMenu.Trigger asChild>
1678
1955
  * <Sidebar.SwitcherTrigger>
1679
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1956
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
1957
+ * <Avatar.Fallback name="Acme Corp" />
1958
+ * </Avatar.Root>
1680
1959
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1681
- * <Sidebar.UserAvatar alt="Jane Doe" />
1682
1960
  * </Sidebar.SwitcherTrigger>
1683
1961
  * </DropdownMenu.Trigger>
1684
1962
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1693,7 +1971,7 @@ declare const Sidebar: {
1693
1971
  /**
1694
1972
  * The `<ul>` of navigation rows in a group.
1695
1973
  *
1696
- * @see https://mantle.ngrok.com/components/navigation/sidebar
1974
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarlist
1697
1975
  *
1698
1976
  * @example
1699
1977
  * ```tsx
@@ -1731,9 +2009,10 @@ declare const Sidebar: {
1731
2009
  * <DropdownMenu.Root>
1732
2010
  * <DropdownMenu.Trigger asChild>
1733
2011
  * <Sidebar.SwitcherTrigger>
1734
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2012
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2013
+ * <Avatar.Fallback name="Acme Corp" />
2014
+ * </Avatar.Root>
1735
2015
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1736
- * <Sidebar.UserAvatar alt="Jane Doe" />
1737
2016
  * </Sidebar.SwitcherTrigger>
1738
2017
  * </DropdownMenu.Trigger>
1739
2018
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1748,7 +2027,7 @@ declare const Sidebar: {
1748
2027
  /**
1749
2028
  * A single `<li>` row wrapper.
1750
2029
  *
1751
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2030
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebaritem
1752
2031
  *
1753
2032
  * @example
1754
2033
  * ```tsx
@@ -1786,9 +2065,10 @@ declare const Sidebar: {
1786
2065
  * <DropdownMenu.Root>
1787
2066
  * <DropdownMenu.Trigger asChild>
1788
2067
  * <Sidebar.SwitcherTrigger>
1789
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2068
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2069
+ * <Avatar.Fallback name="Acme Corp" />
2070
+ * </Avatar.Root>
1790
2071
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1791
- * <Sidebar.UserAvatar alt="Jane Doe" />
1792
2072
  * </Sidebar.SwitcherTrigger>
1793
2073
  * </DropdownMenu.Trigger>
1794
2074
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1804,7 +2084,15 @@ declare const Sidebar: {
1804
2084
  * The interactive navigation row (icon + truncating label). `asChild` for
1805
2085
  * router links; `current` for the active page.
1806
2086
  *
1807
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2087
+ * **Data attributes:**
2088
+ *
2089
+ * | Data Attribute | Value | Description |
2090
+ * | --- | --- | --- |
2091
+ * | `data-current` | present when `current` | Presence-only — never `"false"`, since the `data-current:` variant matches the attribute's existence. Styles the current row. |
2092
+ * | `aria-current` | `"page"` when `current` | Set alongside `data-current`. The current-row styling follows *either*, so a composed child that marks itself (react-router's `NavLink`) gets the treatment without the prop. |
2093
+ * | `data-state` | `"open"` | **Read, not stamped** — supplied by a composing `DropdownMenu.Trigger` / `Dialog.Trigger`. The row styles against it so it stays highlighted while its menu is open. |
2094
+ *
2095
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebaritembutton
1808
2096
  *
1809
2097
  * @example
1810
2098
  * ```tsx
@@ -1842,9 +2130,10 @@ declare const Sidebar: {
1842
2130
  * <DropdownMenu.Root>
1843
2131
  * <DropdownMenu.Trigger asChild>
1844
2132
  * <Sidebar.SwitcherTrigger>
1845
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2133
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2134
+ * <Avatar.Fallback name="Acme Corp" />
2135
+ * </Avatar.Root>
1846
2136
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1847
- * <Sidebar.UserAvatar alt="Jane Doe" />
1848
2137
  * </Sidebar.SwitcherTrigger>
1849
2138
  * </DropdownMenu.Trigger>
1850
2139
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1857,28 +2146,53 @@ declare const Sidebar: {
1857
2146
  */
1858
2147
  readonly ItemButton: typeof ItemButton;
1859
2148
  /**
1860
- * The styled switcher row for the header/footer. Not state-wired compose
1861
- * with `DropdownMenu.Trigger asChild` or `Dialog.Trigger asChild`.
2149
+ * The search row for `Sidebar.Body`: an item-shaped row whose `shortcut` hint
2150
+ * appears on hover or focus, and the same chip as any other row in the
2151
+ * collapsed icon rail. Not state-wired — compose with
2152
+ * `Command.SearchTrigger`.
2153
+ *
2154
+ * **Data attributes:**
1862
2155
  *
1863
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2156
+ * | Data Attribute | Value | Description |
2157
+ * | --- | --- | --- |
2158
+ * | `data-state` | `"open"` \| `"closed"` | **Read, not stamped** — supplied by the composing `Command.SearchTrigger` / `Dialog.Trigger`. Style the row while its palette is open with `data-state-open:`. |
2159
+ *
2160
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarsearchtrigger
1864
2161
  *
1865
2162
  * @example
1866
2163
  * ```tsx
1867
2164
  * <Sidebar.Root>
1868
2165
  * <Sidebar.Nav aria-label="Main">
1869
2166
  * <Sidebar.Header>
1870
- * <DropdownMenu.Root>
1871
- * <DropdownMenu.Trigger asChild>
1872
- * <Sidebar.SwitcherTrigger>
1873
- * <GlobeIcon />
1874
- * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
1875
- * <CaretDownIcon className="text-muted size-4 shrink-0" />
1876
- * </Sidebar.SwitcherTrigger>
1877
- * </DropdownMenu.Trigger>
1878
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
1879
- * </DropdownMenu.Root>
2167
+ * <Sidebar.SwitcherTrigger>
2168
+ * <GlobeIcon />
2169
+ * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
2170
+ * </Sidebar.SwitcherTrigger>
1880
2171
  * </Sidebar.Header>
1881
2172
  * <Sidebar.Body>
2173
+ * <Command.DialogRoot>
2174
+ * <Sidebar.Tooltip label="Search">
2175
+ * <Command.SearchTrigger>
2176
+ * <Sidebar.SearchTrigger
2177
+ * shortcut={
2178
+ * <>
2179
+ * <MetaKey />
2180
+ * <Kbd>K</Kbd>
2181
+ * </>
2182
+ * }
2183
+ * >
2184
+ * <MagnifyingGlassIcon />
2185
+ * <span className="min-w-0 flex-1 truncate">Search</span>
2186
+ * </Sidebar.SearchTrigger>
2187
+ * </Command.SearchTrigger>
2188
+ * </Sidebar.Tooltip>
2189
+ * <Command.DialogContent>
2190
+ * <Command.Input placeholder="Search endpoints, agents, and settings..." />
2191
+ * <Command.List>
2192
+ * <Command.Empty>No results found.</Command.Empty>
2193
+ * </Command.List>
2194
+ * </Command.DialogContent>
2195
+ * </Command.DialogRoot>
1882
2196
  * <Sidebar.Group>
1883
2197
  * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
1884
2198
  * <Sidebar.List>
@@ -1893,30 +2207,23 @@ declare const Sidebar: {
1893
2207
  * </Sidebar.List>
1894
2208
  * </Sidebar.Group>
1895
2209
  * </Sidebar.Body>
1896
- * <Sidebar.Footer>
1897
- * <Sidebar.Separator />
1898
- * <DropdownMenu.Root>
1899
- * <DropdownMenu.Trigger asChild>
1900
- * <Sidebar.SwitcherTrigger>
1901
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
1902
- * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1903
- * <Sidebar.UserAvatar alt="Jane Doe" />
1904
- * </Sidebar.SwitcherTrigger>
1905
- * </DropdownMenu.Trigger>
1906
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
1907
- * </DropdownMenu.Root>
1908
- * </Sidebar.Footer>
1909
2210
  * </Sidebar.Nav>
1910
2211
  * <Sidebar.Trigger />
1911
2212
  * </Sidebar.Root>
1912
2213
  * ```
1913
2214
  */
1914
- readonly SwitcherTrigger: typeof SwitcherTrigger;
2215
+ readonly SearchTrigger: typeof SearchTrigger;
1915
2216
  /**
1916
- * An inset hairline between sidebar regions, aligned with the content
1917
- * padding.
2217
+ * The styled switcher row for the header/footer. Not state-wired — compose
2218
+ * with `DropdownMenu.Trigger asChild` or `Dialog.Trigger asChild`.
1918
2219
  *
1919
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2220
+ * **Data attributes:**
2221
+ *
2222
+ * | Data Attribute | Value | Description |
2223
+ * | --- | --- | --- |
2224
+ * | `data-state` | `"open"` | **Read, not stamped** — supplied by the composing `DropdownMenu.Trigger` / `Dialog.Trigger`. The row styles against it so it stays highlighted while its menu is open. |
2225
+ *
2226
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarswitchertrigger
1920
2227
  *
1921
2228
  * @example
1922
2229
  * ```tsx
@@ -1954,9 +2261,10 @@ declare const Sidebar: {
1954
2261
  * <DropdownMenu.Root>
1955
2262
  * <DropdownMenu.Trigger asChild>
1956
2263
  * <Sidebar.SwitcherTrigger>
1957
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2264
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2265
+ * <Avatar.Fallback name="Acme Corp" />
2266
+ * </Avatar.Root>
1958
2267
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
1959
- * <Sidebar.UserAvatar alt="Jane Doe" />
1960
2268
  * </Sidebar.SwitcherTrigger>
1961
2269
  * </DropdownMenu.Trigger>
1962
2270
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -1967,67 +2275,77 @@ declare const Sidebar: {
1967
2275
  * </Sidebar.Root>
1968
2276
  * ```
1969
2277
  */
1970
- readonly Separator: typeof SidebarSeparator;
2278
+ readonly SwitcherTrigger: typeof SwitcherTrigger;
1971
2279
  /**
1972
- * A rounded-square account avatar with deterministic, WCAG-compliant
1973
- * swatch colors derived from the account id.
2280
+ * Labels a row while the panel is collapsed to the icon rail — wrap it
2281
+ * around a `Sidebar.ItemButton` or `Sidebar.SwitcherTrigger`. Requires a
2282
+ * `TooltipProvider` ancestor. Takes `Tooltip.Content`'s props (including
2283
+ * `asChild`) on the tooltip surface; `side` defaults to `"right"`.
1974
2284
  *
1975
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2285
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebartooltip
1976
2286
  *
1977
2287
  * @example
1978
2288
  * ```tsx
1979
- * <Sidebar.Root>
1980
- * <Sidebar.Nav aria-label="Main">
1981
- * <Sidebar.Header>
1982
- * <DropdownMenu.Root>
1983
- * <DropdownMenu.Trigger asChild>
1984
- * <Sidebar.SwitcherTrigger>
1985
- * <GlobeIcon />
1986
- * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
1987
- * <CaretDownIcon className="text-muted size-4 shrink-0" />
1988
- * </Sidebar.SwitcherTrigger>
1989
- * </DropdownMenu.Trigger>
1990
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
1991
- * </DropdownMenu.Root>
1992
- * </Sidebar.Header>
1993
- * <Sidebar.Body>
1994
- * <Sidebar.Group>
1995
- * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
1996
- * <Sidebar.List>
1997
- * <Sidebar.Item>
1998
- * <Sidebar.ItemButton asChild current>
1999
- * <a href="/endpoints">
2000
- * <GraphIcon />
2001
- * Endpoints
2002
- * </a>
2003
- * </Sidebar.ItemButton>
2004
- * </Sidebar.Item>
2005
- * </Sidebar.List>
2006
- * </Sidebar.Group>
2007
- * </Sidebar.Body>
2008
- * <Sidebar.Footer>
2009
- * <Sidebar.Separator />
2010
- * <DropdownMenu.Root>
2011
- * <DropdownMenu.Trigger asChild>
2012
- * <Sidebar.SwitcherTrigger>
2013
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2014
- * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
2015
- * <Sidebar.UserAvatar alt="Jane Doe" />
2016
- * </Sidebar.SwitcherTrigger>
2017
- * </DropdownMenu.Trigger>
2018
- * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
2019
- * </DropdownMenu.Root>
2020
- * </Sidebar.Footer>
2021
- * </Sidebar.Nav>
2022
- * <Sidebar.Trigger />
2023
- * </Sidebar.Root>
2289
+ * <TooltipProvider>
2290
+ * <Sidebar.Root>
2291
+ * <Sidebar.Nav aria-label="Main">
2292
+ * <Sidebar.Header>
2293
+ * <DropdownMenu.Root>
2294
+ * <DropdownMenu.Trigger asChild>
2295
+ * <Sidebar.SwitcherTrigger>
2296
+ * <GlobeIcon />
2297
+ * <span className="text-strong min-w-0 flex-1 truncate text-base">Universal Gateway</span>
2298
+ * <CaretDownIcon className="text-muted size-4 shrink-0" />
2299
+ * </Sidebar.SwitcherTrigger>
2300
+ * </DropdownMenu.Trigger>
2301
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
2302
+ * </DropdownMenu.Root>
2303
+ * </Sidebar.Header>
2304
+ * <Sidebar.Body>
2305
+ * <Sidebar.Group>
2306
+ * <Sidebar.GroupLabel>Traffic</Sidebar.GroupLabel>
2307
+ * <Sidebar.List>
2308
+ * <Sidebar.Item>
2309
+ * <Sidebar.Tooltip label="Endpoints">
2310
+ * <Sidebar.ItemButton asChild current>
2311
+ * <a href="/endpoints">
2312
+ * <GraphIcon />
2313
+ * Endpoints
2314
+ * </a>
2315
+ * </Sidebar.ItemButton>
2316
+ * </Sidebar.Tooltip>
2317
+ * </Sidebar.Item>
2318
+ * </Sidebar.List>
2319
+ * </Sidebar.Group>
2320
+ * </Sidebar.Body>
2321
+ * <Sidebar.Footer>
2322
+ * <Sidebar.Separator />
2323
+ * <DropdownMenu.Root>
2324
+ * <Sidebar.Tooltip label="Acme Corp">
2325
+ * <DropdownMenu.Trigger asChild>
2326
+ * <Sidebar.SwitcherTrigger>
2327
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2328
+ * <Avatar.Fallback name="Acme Corp" />
2329
+ * </Avatar.Root>
2330
+ * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
2331
+ * </Sidebar.SwitcherTrigger>
2332
+ * </DropdownMenu.Trigger>
2333
+ * </Sidebar.Tooltip>
2334
+ * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
2335
+ * </DropdownMenu.Root>
2336
+ * </Sidebar.Footer>
2337
+ * </Sidebar.Nav>
2338
+ * <Sidebar.Trigger />
2339
+ * </Sidebar.Root>
2340
+ * </TooltipProvider>
2024
2341
  * ```
2025
2342
  */
2026
- readonly AccountAvatar: typeof AccountAvatar;
2343
+ readonly Tooltip: typeof SidebarTooltip;
2027
2344
  /**
2028
- * A circular user avatar with a silhouette fallback.
2345
+ * An inset hairline between sidebar regions, aligned with the content
2346
+ * padding.
2029
2347
  *
2030
- * @see https://mantle.ngrok.com/components/navigation/sidebar
2348
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebarseparator
2031
2349
  *
2032
2350
  * @example
2033
2351
  * ```tsx
@@ -2065,9 +2383,10 @@ declare const Sidebar: {
2065
2383
  * <DropdownMenu.Root>
2066
2384
  * <DropdownMenu.Trigger asChild>
2067
2385
  * <Sidebar.SwitcherTrigger>
2068
- * <Sidebar.AccountAvatar accountId="acc_123" accountName="Acme Corp" />
2386
+ * <Avatar.Root appearance="square" colorSeed="acc_123">
2387
+ * <Avatar.Fallback name="Acme Corp" />
2388
+ * </Avatar.Root>
2069
2389
  * <span className="text-strong min-w-0 flex-1 truncate text-sm font-medium">Acme Corp</span>
2070
- * <Sidebar.UserAvatar alt="Jane Doe" />
2071
2390
  * </Sidebar.SwitcherTrigger>
2072
2391
  * </DropdownMenu.Trigger>
2073
2392
  * <DropdownMenu.Content width="trigger" className="min-w-(--sidebar-row-width)">…</DropdownMenu.Content>
@@ -2078,7 +2397,143 @@ declare const Sidebar: {
2078
2397
  * </Sidebar.Root>
2079
2398
  * ```
2080
2399
  */
2081
- readonly UserAvatar: typeof UserAvatar;
2400
+ readonly Separator: typeof SidebarSeparator;
2401
+ };
2402
+ //#endregion
2403
+ //#region src/components/sidebar/sidebar-state-cookie.d.ts
2404
+ /**
2405
+ * The cookie name {@link extractSidebarStateCookie} reads and
2406
+ * {@link serializeSidebarStateCookie} writes.
2407
+ *
2408
+ * Exported so an app can clear the cookie on sign-out, or read it with its own
2409
+ * cookie library, without hard-coding the name.
2410
+ *
2411
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#sidebar_state_cookie_name
2412
+ *
2413
+ * @example
2414
+ * ```ts
2415
+ * // clear the persisted rail state on sign-out
2416
+ * headers.append("Set-Cookie", `${SIDEBAR_STATE_COOKIE_NAME}=; Max-Age=0; Path=/`);
2417
+ * ```
2418
+ */
2419
+ declare const SIDEBAR_STATE_COOKIE_NAME = "mantle-sidebar-state";
2420
+ /**
2421
+ * Parse the sidebar's expanded state out of a raw `Cookie` header.
2422
+ *
2423
+ * This is the server half of cookie-backed persistence: unlike storage-backed
2424
+ * persistence, a cookie is available *before* the server renders, so the
2425
+ * server-rendered HTML already carries the right `data-state` and there is no
2426
+ * first-frame correction to hide. Pass the result straight to `defaultOpen` —
2427
+ * controlled `open` is not required.
2428
+ *
2429
+ * Returns `undefined` — not `false` — when the cookie is absent or holds a
2430
+ * value this helper does not recognize, so a first-time visitor is
2431
+ * distinguishable from one who deliberately collapsed the sidebar. Collapse the
2432
+ * state into your own default at the call site with `?? true`.
2433
+ *
2434
+ * Never throws: a header is client-controlled, and a value with a malformed
2435
+ * percent-escape (`mantle-sidebar-state=%E0%A4%A`) is unparseable rather than
2436
+ * fatal, so one hostile or corrupt cookie cannot fail the server render on
2437
+ * every page load.
2438
+ *
2439
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#persisting-the-collapsed-state
2440
+ *
2441
+ * @example
2442
+ * ```ts
2443
+ * // app/root.tsx loader
2444
+ * export const loader = ({ request }: Route.LoaderArgs) => ({
2445
+ * sidebarOpen: extractSidebarStateCookie(request.headers.get("Cookie")) ?? true,
2446
+ * });
2447
+ * ```
2448
+ *
2449
+ * @param cookieHeader - The raw `Cookie` header string from the request, or null/undefined.
2450
+ * @returns `true` when expanded, `false` when collapsed, `undefined` when unset, undecodable, or unparseable.
2451
+ */
2452
+ declare function extractSidebarStateCookie(cookieHeader: string | null | undefined): boolean | undefined;
2453
+ /**
2454
+ * Attributes for {@link serializeSidebarStateCookie}. Deliberately omits
2455
+ * `HttpOnly`: the browser writes this cookie from `onOpenChange`, so a
2456
+ * server-only cookie could never be updated when the user toggles the rail.
2457
+ *
2458
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#serializesidebarstatecookie
2459
+ *
2460
+ * @example
2461
+ * ```ts
2462
+ * serializeSidebarStateCookie(open, { maxAge: 60 * 60 * 24 * 365, sameSite: "Lax" });
2463
+ * ```
2464
+ */
2465
+ type SerializeSidebarStateCookieOptions = {
2466
+ /**
2467
+ * How long the preference survives, in seconds.
2468
+ *
2469
+ * @default 31_536_000 // one year
2470
+ */
2471
+ maxAge?: number;
2472
+ /**
2473
+ * The path the cookie applies to. Keep the default unless the sidebar only
2474
+ * exists under one route subtree.
2475
+ *
2476
+ * @default "/"
2477
+ */
2478
+ path?: string;
2479
+ /**
2480
+ * The domain the cookie applies to. Omitted by default, which scopes it to
2481
+ * the exact current host. Set it (e.g. `".example.com"`) to share the
2482
+ * preference across subdomains.
2483
+ */
2484
+ domain?: string;
2485
+ /**
2486
+ * `SameSite` policy. `"Lax"` is right for a UI preference — it survives
2487
+ * top-level navigations back to your app without riding along on
2488
+ * cross-site subrequests.
2489
+ *
2490
+ * @default "Lax"
2491
+ */
2492
+ sameSite?: "Lax" | "Strict" | "None";
2493
+ /**
2494
+ * Whether to add the `Secure` attribute. Omitted by default so the same call
2495
+ * works on `http://localhost` — a `Secure` cookie is silently rejected over
2496
+ * http, which would make the preference appear not to persist in local
2497
+ * development. Set it to `true` in production if your CSP or policy requires
2498
+ * it; this cookie holds no secret, only whether a rail is open.
2499
+ *
2500
+ * @default false
2501
+ */
2502
+ secure?: boolean;
2082
2503
  };
2504
+ /**
2505
+ * Serialize the sidebar's expanded state as a cookie string.
2506
+ *
2507
+ * Framework-agnostic by design: the returned string is valid for both
2508
+ * `document.cookie` on the client and a `Set-Cookie` response header on the
2509
+ * server, so the same helper covers whichever side of your app owns the write.
2510
+ *
2511
+ * @see https://mantle.ngrok.com/components/navigation/sidebar#persisting-the-collapsed-state
2512
+ *
2513
+ * @example
2514
+ * ```tsx
2515
+ * // client: persist as the user toggles, and render from the loader value
2516
+ * const { sidebarOpen } = useLoaderData<typeof loader>();
2517
+ * <Sidebar.Root
2518
+ * defaultOpen={sidebarOpen}
2519
+ * onOpenChange={(open) => {
2520
+ * document.cookie = serializeSidebarStateCookie(open);
2521
+ * }}
2522
+ * >
2523
+ * ```
2524
+ *
2525
+ * @example
2526
+ * ```ts
2527
+ * // server: set it from an action instead
2528
+ * return new Response(null, {
2529
+ * headers: { "Set-Cookie": serializeSidebarStateCookie(false, { secure: true }) },
2530
+ * });
2531
+ * ```
2532
+ *
2533
+ * @param open - Whether the sidebar is expanded.
2534
+ * @param options - Cookie attributes; see {@link SerializeSidebarStateCookieOptions}.
2535
+ * @returns A cookie string such as `mantle-sidebar-state=collapsed; Max-Age=31536000; Path=/; SameSite=Lax`.
2536
+ */
2537
+ declare function serializeSidebarStateCookie(open: boolean, options?: SerializeSidebarStateCookieOptions): string;
2083
2538
  //#endregion
2084
- export { Sidebar, type SidebarMobileBreakpoint, type SidebarState, useSidebar };
2539
+ export { SIDEBAR_STATE_COOKIE_NAME, type SerializeSidebarStateCookieOptions, Sidebar, type SidebarMobileBreakpoint, type SidebarState, extractSidebarStateCookie, serializeSidebarStateCookie, useSidebar };