TakeoverPage replaces the shell for a single committed task. Because the shell is gone, the takeover is responsible for a lot of what the shell normally provides: clear heading order, a labelled close control, focus placement on open and close, and a graceful exit when the task errors. The component ships the header and close wiring; your app supplies the title, close handler, heading strategy, and any inner overlays' focus handling.
What the component handles
TakeoverPageHeader renders a labelled close control with a visible or tooltip-titled accessible name.
- Body region is a regular document flow; internal focus starts at the top of your rendered content.
- Stacking context for child overlays (modals, drawers, popovers) so they layer correctly above the takeover.
- A task-oriented, localizable title on
TakeoverPageHeader so screen readers announce purpose on entry.
- A real document heading inside the body (for example
<Heading level={1}>) when the visual title alone is emphasis text rather than an h1.
- Focus placement on mount—send focus to a meaningful anchor (the primary action, the first form field) rather than leaving it at the document start.
- An Escape or close handler that guards unsaved state; never close silently through a route change.
- Focus return on close: restore focus to the element that opened the takeover, or to a predictable anchor if it's no longer in the DOM.
- Error recovery copy and CTAs; the shell nav is gone, so errors must provide their own way out.
- Tab / Shift+Tab: reach every interactive control in the body and the close control in the header.
- Escape: close the takeover via the header's close handler when no child overlay is open; when a modal or drawer is stacked, Escape closes that first.
- Shortcut keys that rely on the app shell stop working inside takeover; validate hot paths and re-expose them in-page if they're critical.
- Use a real
<main> (or labelled <section>) as the takeover body so screen readers have a landmark to jump to. The takeover itself is not a dialog unless your product treats it as modal.
- Heading order inside the body should start at
h1; the TakeoverPageHeader title text does not supply this.
- The close control's accessible name should describe the action ("Close review", "Exit wizard"), not just "Close".
- On mount, set focus to the primary action or the first meaningful control in the body.
- On close, return focus to the element that triggered the takeover. If that element is gone (route change, deleted object), send focus to a predictable anchor such as the shell's page title.
- For multi-step flows, keep focus inside the active step when stepping forward; on step back, return focus to the control that advanced the step.
- When an inner overlay opens (modal, drawer), trap focus inside that overlay and restore it to the triggering control on close. Don't trap focus across the entire takeover body.
Screen reader announcements
- Announce the takeover's purpose via the
TakeoverPageHeader title plus the document h1 inside.
- For error states, render a
Callout with variant="error" and a retry action; this uses the Callout live-region pattern by default.
- For long-running operations inside takeover, use a polite live region to announce progress ("Reviewing 12 of 24").
- If your takeover animates in (slide, fade), respect
prefers-reduced-motion: reduce and drop the animation. The takeover should appear instantly when motion is disabled.
- Takeover is not a modal dialog; if your product treats it as one, add
role="dialog" and aria-modal="true" explicitly, and wire full focus trapping. Most dispatch takeovers are route-scoped full-screen surfaces, not dialogs.
- The shell's persistent nav and shortcuts disappear inside takeover. If operators rely on global shortcuts, either re-expose them or pre-warn via the launch UI.
- Nested takeovers are not supported: don't open a takeover from inside another.
- Header close is the primary exit. Hiding or removing it is a regression even if a back button exists in the body.