📝(docs) add side panel focus pattern

Document trigger ref and panel ref focus workflow
This commit is contained in:
Cyril
2026-01-15 12:18:00 +01:00
committed by lebaudantoine
parent 17e5c31ee2
commit a863dedc6a
+33
View File
@@ -28,3 +28,36 @@ export default {
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
## Side Panel Focus Pattern
We use a consistent focus management pattern for side panels:
- **Open**: focus the first actionable element inside the panel.
- **Close**: restore focus to the button that opened the panel.
Implementation summary:
1. A provider stores a `panelRef` and a registry of trigger refs (`setTrigger/getTrigger`).
2. Each trigger button registers itself with `setTrigger("key", el)`.
3. Panel content uses `useRestoreFocus` with:
- `resolveTrigger` → returns `getTrigger("key")`.
- `onOpened` → finds the first actionable element inside `panelRef`.
Example:
```tsx
// Trigger button
;<ToggleButton ref={(el) => setTrigger('tools', el)} />
// Panel content
useRestoreFocus(isOpen, {
resolveTrigger: (activeEl) => getTrigger('tools') ?? activeEl,
onOpened: () => {
const first = panelRef.current?.querySelector(
'[data-attr="tools-list"] button'
)
;(first as HTMLElement | null)?.focus({ preventScroll: true })
},
})
```