FocusScope
FocusScope marks a subtree as its own focus region.
In practical terms, it tells the runtime that keyboard focus inside this part of the interface should be treated as one grouped area. When is_barrier is true, it also acts as a barrier that stops focus traversal from leaking through to surrounding content.
This is most useful for dialogs, popovers, menus, and embedded editing surfaces. It is not a general-purpose layout widget. If the only problem is spacing or stacking, use normal layout primitives instead.
Example
use fission::prelude::*;
let widget: Widget = FocusScope {
is_barrier: true,
children: vec![
TextInput {
value: String::new(),
placeholder: Some("To".into()),
..Default::default()
}
.into(),
],
..Default::default()
}
.into();
This is the kind of structure you want inside a modal, where keyboard users should stay inside the dialog while it is open.
Field table
| | | |
|---|
| | | |
| | The subtree inside the focus scope. | Defaults to an empty list. |
| | Whether focus traversal should be contained by this scope. | Defaults to false. Set true for modal-style focus containment. |
Focus and semantics behavior
FocusScope lowers its children under a semantics node marked as a focus scope. It is primarily about focus behavior and accessibility structure, not about visuals. The children are wrapped together so the runtime can treat them as one focus region.
When is_barrier is true, this becomes the right tool for modal flows where tabbing or keyboard focus should not fall through to controls behind the overlay.
Specific advice
Use FocusScope deliberately. Overusing focus barriers can make keyboard navigation feel trapped in the wrong places. The barrier mode is excellent for real dialogs and overlays, but it is usually wrong for ordinary in-page sections.
Pair FocusScope with clear visible structure, such as a titled modal or panel, so the accessibility structure matches what the user sees.
Production checklist
For FocusScope, review the fields that change behavior before treating the widget as finished: id, children, is_barrier. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
When child widgets are generated from data, give reordered or filtered rows an explicit WidgetId so retained local state and scroll behavior do not drift between items.
Set id only when identity must be stable across filtering, reordering, diagnostics, or tests; otherwise let Fission derive identity from structure.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same FocusScope setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
Overlay, Positioned, SafeArea, and TextInput.