You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/sidebar/sidebar.mdx
+29-1Lines changed: 29 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,8 @@ styles the real elements while the provider holds state and behavior.
35
35
| Part | Renders | Owns |
36
36
| --- | --- | --- |
37
37
| \`Sidebar\` | the modal backdrop only (a sibling of the panel) | All controlled state and behavior: open, overlay, width and bounds, dismiss; derives the overlay state; provides context |
38
-
| \`SidebarContent\` | the panel element (a neutral \`<div>\` with \`role="dialog"\` when needed) | Positioning, the slide / collapse transition, dialog semantics, the committed width, the focus trap and assistive-tech hiding while modal, and panel-scoped Escape-to-dismiss |
38
+
| \`SidebarContent\` | the panel element (a neutral \`<div>\` with \`role="dialog"\` when needed) | Positioning, the slide / collapse transition, dialog semantics, the committed width, the focus trap and assistive-tech hiding while modal, making its contents \`inert\` while closed, and panel-scoped Escape-to-dismiss |
39
+
| \`SidebarPersistentContent\` | an optional slot inside the panel | A control that stays live while the sidebar is closed (e.g. a collapse toggle): kept out of the closed-state \`inert\`, while it rides the collapse transition and joins the focus trap |
39
40
| \`SidebarResizeHandle\` | a \`role="separator"\` | The pointer and keyboard resize affordance and its ARIA; self-positions on the inner edge from \`align\` |
40
41
`}</Markdown>
41
42
@@ -187,6 +188,27 @@ provider. Set the same `id` on `Sidebar` that the trigger points its
187
188
</button>
188
189
```
189
190
191
+
## A control that stays live while closed
192
+
193
+
While a sidebar is closed, its contents are made `inert`, so off-screen controls leave the tab order and the accessibility tree. `SidebarPersistentContent` is the exception: a control placed in it stays usable while the sidebar is closed, the canonical case being a collapse toggle that peeks out of the slid-off panel and reopens it. Unlike the external trigger above, this is for a toggle that belongs _in_ the panel.
194
+
195
+
<Canvasof={SidebarStories.CollapsibleNav} />
196
+
197
+
Its children render inside the panel, so they ride the collapse transition and join the focus trap when modal, but outside the closed-state `inert`. It works at any nesting depth, so a toggle already living deep in the content does not need hoisting.
<navaria-label="Main navigation">{/* nav content */}</nav>
207
+
</SidebarContent>
208
+
```
209
+
210
+
When the panel opens as a modal, the trap's initial focus goes to the first focusable, often the persistent control. Whether that is wanted is the consumer's call: add `data-no-autofocus` to your control (a react-focus-lock attribute) to keep a toggle from grabbing it, the way `Modal` opts its close button out, or `data-autofocus` to send initial focus to a specific element; the control stays tabbable either way. The consumer owns the control, its `aria-*`, and its positioning (e.g. a peek offset while collapsed).
211
+
190
212
## Left and right sidebars
191
213
192
214
A left nav and a right pane around the main absorber is the full shell contract.
@@ -256,3 +278,9 @@ CSS custom properties, set on `SidebarContent` (or any ancestor).
256
278
or tooltip) keeps it.
257
279
- The resize handle is a focusable `separator` while open, and leaves the tab
258
280
order and the accessibility tree while closed.
281
+
- While closed, the panel's contents are made `inert`, so off-screen controls
282
+
leave the tab order and the accessibility tree. A control in
283
+
`SidebarPersistentContent` is exempt and stays interactive. When the panel opens
284
+
as a modal it receives initial focus by default (it is first in the trap), so add
285
+
`data-no-autofocus` to it if it should not grab focus, as `Modal` does for its
0 commit comments