diff --git a/apps/public-docsite-v9-headless/.storybook/manager-head.html b/apps/public-docsite-v9-headless/.storybook/manager-head.html index 11beec81c25d49..730b487ec19bf7 100644 --- a/apps/public-docsite-v9-headless/.storybook/manager-head.html +++ b/apps/public-docsite-v9-headless/.storybook/manager-head.html @@ -140,4 +140,12 @@ [id*='accessibility-stories'] { display: none !important; } + + /* Target the brand image container */ + .sidebar-header a::after { + content: ' Headless Components'; + display: block; + font-size: 12px; + margin-left: 34px; + } diff --git a/apps/public-docsite-v9-headless/.storybook/preview.js b/apps/public-docsite-v9-headless/.storybook/preview.js index 3cdce74a824fb4..5185ce7b232f73 100644 --- a/apps/public-docsite-v9-headless/.storybook/preview.js +++ b/apps/public-docsite-v9-headless/.storybook/preview.js @@ -8,7 +8,7 @@ export const parameters = { options: { storySort: { method: 'alphabetical', - order: ['Introduction', 'Headless Components'], + order: ['Overview', ['Introduction', 'Getting Started', 'Accessibility'], 'Guides', 'Components', 'Concepts'], }, }, reactStorybookAddon: { diff --git a/apps/public-docsite-v9-headless/src/Accessibility.mdx b/apps/public-docsite-v9-headless/src/Accessibility.mdx new file mode 100644 index 00000000000000..b2e01e69edbeb2 --- /dev/null +++ b/apps/public-docsite-v9-headless/src/Accessibility.mdx @@ -0,0 +1,136 @@ +import { Meta } from '@storybook/addon-docs/blocks'; + + + +# Accessibility + +Fluent UI Headless provides accessible, interactive React components without opinionated styling. Headless components implement WAI-ARIA authoring practices, keyboard navigation patterns, and focus management across a broad range of browsers and assistive technologies. + +**Important:** Headless components provide accessibility infrastructure: ARIA attributes, roles, keyboard event handling, and focus management. They **do not provide visual styling**, so your design system must supply visible focus indicators, sufficient color contrast, and clear interactive state feedback. + +## Built In, And What You Own + +When building custom components with Fluent UI Headless, you own the visual accessibility layer: + +- **Visible focus indicators** — Use CSS to style `:focus-visible` with sufficient contrast and size +- **Color contrast** — Ensure text and interactive elements meet WCAG AA (or AAA) color contrast ratios +- **Visual feedback** — Provide clear indication of hover, active, disabled, and error states +- **Touch targets** — Make interactive elements at least 44×44px for mobile accessibility +- **Motion considerations** — Respect `prefers-reduced-motion` media query for users with vestibular disorders + +## WAI-ARIA Patterns + +Headless components implement standard WAI-ARIA patterns and apply appropriate roles, states, and properties: + +| Component | ARIA Pattern | Key Attributes | +| -------------- | ------------- | ---------------------------------------------------------------- | +| Button | Button / Link | `role="button"`, `aria-pressed` (toggle), `aria-disabled` | +| Checkbox | Checkbox | `role="checkbox"`, `aria-checked` | +| Radio Group | Radio Group | `role="radiogroup"`, `role="radio"`, `aria-checked` | +| Switch | Switch | `role="switch"`, `aria-checked` | +| Accordion | Accordion | `role="button"`, `aria-expanded`, `aria-controls` | +| Dialog | Dialog | `role="dialog"`, `aria-modal`, `aria-labelledby` | +| Tooltip | Tooltip | `role="tooltip"` | +| Tabs | Tab List | `role="tablist"`, `role="tab"`, `aria-selected`, `aria-controls` | +| Menu / Popover | Menu | `role="menu"`, `role="menuitem"` | + +**Note:** When a component is disabled but should remain focusable (for context), headless components set `aria-disabled="true"` while keeping the element keyboard-accessible. Style both `:disabled` pseudo-classes and `[aria-disabled="true"]` states. + +## Keyboard Navigation + +Fluent UI Headless components support keyboard interaction patterns consistent with WAI-ARIA authoring practices: + +- **Tab/Shift+Tab** — Move focus between components; focus management respects `tabindex` +- **Enter/Space** — Activate buttons, checkboxes, switches, and toggle buttons +- **Arrow Keys** — Navigate within components like radio groups, tab lists, menus, and sliders +- **Home/End** — Jump to first/last item in lists, tabs, and menus (where applicable) +- **Escape** — Close overlays (dialogs, popovers, menus, tooltips) + +Each component's keyboard behavior is identical to its styled counterpart in `@fluentui/react-components`. Check individual component docs for pattern-specific details, like arrow key direction for horizontal versus vertical components. + +## Accessible Labels + +Form controls and custom UI patterns require accessible names so screen readers can identify them: + +### Form Controls + +Use the native HTML `