Accessibility
Dockview ships a baseline of accessibility in core: WAI-ARIA roles and labels,
roving-tabindex navigation within the tab strip, screen-reader announcements of
layout changes, and keyboard-only focus indicators. These come with the
dockview package and the framework packages. No configuration is required
for the semantics below; the options on this page tune the announcements and the
opt-in keymap.
ARIA roles and labels
The tab headers are marked up as a WAI-ARIA Tabs widget, and groups and floating windows carry landmark roles, so assistive technology can describe the layout:
- The tab strip is a
role="tablist"(witharia-orientation), each tab arole="tab"carryingaria-selectedandaria-controls. Each tab has an explicit accessible name set from its panel title (falling back to the panel id), kept in sync withsetTitle, so a screen reader reads the title cleanly rather than absorbing the close button's label. - Panel content is a
role="tabpanel"labelled by its tab (aria-labelledby). - Each group is a
role="region"labelled by its active panel's title. - A floating group is a non-modal
role="dialog"named from its active panel, so the grid behind it stays reachable. - Close buttons expose an accessible name that includes the panel title (e.g. "Close Orders").
These roles are reactive: activating a tab, floating a group or calling
setTitle updates the relevant attributes.
Keyboard navigation
Within the tab strip, Dockview uses a roving tabindex: only one tab is a tab
stop, and the arrow keys move between tabs once the strip has focus. Home /
End jump to the first / last tab, and Enter / Space activate the focused
tab. This within-strip navigation is always on.
Broader keyboard operability (switching tabs, cycling groups with F6, jumping
focus to the tab strip, and keyboard-driven docking) is enabled with the
keyboardNavigation option and is documented in full on the
Keyboard page, including the rebindable keymap.
const options = {
keyboardNavigation: true,
};
Focus indicators
Keyboard focus is drawn with a :focus-visible outline, so the focus ring
appears when you tab to a control but is suppressed on plain mouse clicks. It is
themeable through the theme's CSS custom properties, and honours :has(:focus-visible)
so the ring still shows when a child control (such as a tab's close button) is
focused by keyboard.
Screen-reader announcements
Dockview narrates layout changes (panels opening/closing, groups floating, docking, popping out, maximising/restoring) through visually-hidden ARIA live regions (a polite region for routine status and an assertive one for cancellations). This is on by default.
Each window gets its own live region: the main document plus every popout window. Announcements are routed to the region of the window that currently has focus, so a screen-reader user working inside a popped-out group hears them in that window rather than the opener.
The announcement behaviour is configured with the following options:
Opt out entirely with:
const options = {
announcements: false,
};
Localising and overriding announcements
getAnnouncement runs per event and lets you override or localise the spoken
string. Return a string to use it, null / '' to suppress that announcement,
or undefined to fall through to the default:
const options = {
getAnnouncement: (event) => {
if (event.kind === 'maximize') {
return 'Panel maximised';
}
return undefined; // keep the default
},
};
For full translations, provide a messages catalog. Each entry is a function
that builds the string from the relevant context (e.g. the panel title); supply
any subset; unset entries keep the English defaults:
const options = {
messages: {
panelOpened: (title) => `${title} ouvert`,
panelClosed: (title) => `${title} fermé`,
groupMaximized: (title) => `${title} agrandi`,
},
};
Routing to your own announcer
If your app already manages a screen-reader live region, route Dockview's
announcements to it with announcer instead of using the built-in regions.
getAnnouncement (localisation) still applies first, and each event carries the
resolved message and a politeness of 'polite' or 'assertive':
const options = {
announcer: (event) =>
myLiveRegion.announce(event.message, event.politeness),
};
See also
- Focus navigation:
DockviewApimethods for moving focus between panels and groups - Keyboard: the opt-in keymap,
F6group cycling and keyboard-driven docking