@@ -8,17 +8,34 @@ Constrains focus within a subtree when active. Used by modals and overlays to pr
88ui .focusTrap (
99 { id: " modal-trap" , active: state .modalOpen },
1010 [
11- ui .text (" Are you sure?" ),
12- ui .button ({ id: " confirm" , label: " Confirm" }),
13- ui .button ({ id: " cancel" , label: " Cancel" }),
11+ ui .column ({ gap: 1 }, [
12+ ui .text (" Are you sure?" ),
13+ ui .row ({ gap: 1 }, [
14+ ui .button ({ id: " confirm" , label: " Confirm" }),
15+ ui .button ({ id: " cancel" , label: " Cancel" }),
16+ ]),
17+ ]),
1418 ]
1519)
1620```
1721
1822## Layout behavior
1923
20- ` focusTrap ` is layout-transparent and does not impose a hidden column layout.
21- Children keep their native layout semantics (` row ` , ` column ` , ` grid ` , etc.).
24+ ` focusTrap ` is layout-transparent when it wraps a single child.
25+ That child keeps its native layout semantics (` row ` , ` column ` , ` grid ` , etc.).
26+
27+ For legacy multi-child usage, direct children fall back to an implicit column layout.
28+ Prefer an explicit container inside the trap when you need more than one child:
29+
30+ ``` typescript
31+ ui .focusTrap (
32+ { id: " trap-legacy" , active: true },
33+ [
34+ ui .button ({ id: " a" , label: " A" }),
35+ ui .button ({ id: " b" , label: " B" }),
36+ ]
37+ )
38+ ```
2239
2340When you want explicit arrangement, compose a normal layout container inside the trap:
2441
@@ -48,12 +65,14 @@ ui.focusTrap(
4865
4966When ` active ` is ` true ` :
5067
51- - Tab/Shift+Tab cycles only through focusable elements inside the trap
52- - Focus cannot escape to elements outside the trap
68+ - If the trap contains focusable elements, Tab/Shift+Tab cycles only through those elements
69+ - Containment is focus-system based; ` focusTrap ` alone does not define an outside click boundary
5370- Attempting to Tab past the last element wraps to the first
5471- Attempting to Shift+Tab before the first element wraps to the last
5572- The trap is collected into the focus system (` CollectedTrap ` ) so modal overlays
5673 consistently block/contain background focus.
74+ - If the active trap has no focusable descendants, it preserves the current focus unless
75+ ` initialFocus ` names a valid nested target.
5776
5877When ` active ` becomes ` false ` :
5978
@@ -128,7 +147,8 @@ ui.focusTrap({ id: "outer", active: true }, [
128147
129148## Mouse Behavior
130149
131- When a focus trap is active, mouse clicks outside the trap region are blocked. Clicking widgets inside the trap works normally — the clicked widget receives focus.
150+ ` focusTrap ` does not block outside clicks by itself.
151+ Use it with ` ui.modal() ` or a layer-backed overlay when you need pointer containment as well as Tab containment.
132152
133153## Related
134154
0 commit comments