- Spec files
npm-react-aria
Describes: pkg:npm/react-aria@3.43.x
- Description
- Comprehensive library of unstyled React hooks providing accessible UI primitives with full WAI-ARIA compliance and internationalization support.
- Author
- tessl
- Last updated
focus-management.md docs/
1# Focus Management23Advanced focus management including focus rings, focus scopes, focus restoration, and keyboard navigation. These hooks and components provide comprehensive focus control for accessible applications.45## Capabilities67### Focus Ring89Provides focus ring visualization with keyboard-only display and customizable styling.1011```typescript { .api }12/**13* Focus ring component that automatically shows/hides based on interaction method14* @param props - Focus ring configuration15* @returns Focus ring element16*/17function FocusRing(props: FocusRingProps): JSX.Element;1819/**20* Provides focus ring behavior and state21* @param props - Focus ring configuration22* @returns Focus ring result with state and props23*/24function useFocusRing(props?: AriaFocusRingProps): FocusRingAria;2526interface FocusRingProps {27/** Children render prop receiving focus ring state */28children: (states: { isFocusVisible: boolean; focusProps: DOMAttributes<Element> }) => ReactNode;29/** Whether focus ring is disabled */30isDisabled?: boolean;31/** Auto-focus behavior */32autoFocus?: boolean;33/** Focus ring class name when visible */34focusClass?: string;35/** Focus ring styles when visible */36focusStyle?: React.CSSProperties;37}3839interface AriaFocusRingProps {40/** Whether focus ring is disabled */41isDisabled?: boolean;42/** Auto-focus behavior */43autoFocus?: boolean;44/** Within focus scope */45within?: boolean;46}4748interface FocusRingAria {49/** Whether focus should be visible */50isFocusVisible: boolean;51/** Props to spread on the target element */52focusProps: DOMAttributes<Element>;53}54```5556### Focus Scope5758Provides focus containment and restoration for modal dialogs and other containers.5960```typescript { .api }61/**62* Focus scope component that contains focus within its children63* @param props - Focus scope configuration64* @returns Focus scope container65*/66function FocusScope(props: FocusScopeProps): JSX.Element;6768interface FocusScopeProps {69/** Children to contain focus within */70children: ReactNode;71/** Whether focus containment is active */72contain?: boolean;73/** Whether to restore focus when scope unmounts */74restoreFocus?: boolean;75/** Whether to auto-focus first element */76autoFocus?: boolean;77/** Element type to render as container */78elementType?: React.ElementType;79/** Whether focus should be contained */80isDisabled?: boolean;81}82```8384### Focus Manager8586Provides programmatic focus management within a focus scope.8788```typescript { .api }89/**90* Provides focus management within a focus scope91* @returns Focus manager with navigation methods92*/93function useFocusManager(): FocusManager;9495interface FocusManager {96/** Move focus to the next focusable element */97focusNext(opts?: FocusManagerOptions): HTMLElement | null;98/** Move focus to the previous focusable element */99focusPrevious(opts?: FocusManagerOptions): HTMLElement | null;100/** Move focus to the first focusable element */101focusFirst(opts?: FocusManagerOptions): HTMLElement | null;102/** Move focus to the last focusable element */103focusLast(opts?: FocusManagerOptions): HTMLElement | null;104}105106interface FocusManagerOptions {107/** Whether to wrap focus at boundaries */108wrap?: boolean;109/** Tabbable elements only */110tabbable?: boolean;111/** From element to start search */112from?: Element;113/** Accept function to filter elements */114accept?: (element: Element) => boolean;115}116```117118### Focusable119120Provides focusable element behavior with proper tab order management.121122```typescript { .api }123/**124* Provides focusable element behavior125* @param props - Focusable configuration126* @param ref - Ref to the focusable element127* @returns Focusable result with props and state128*/129function useFocusable(props: FocusableOptions, ref: RefObject<Element>): FocusableAria;130131interface FocusableOptions {132/** Whether element should be excluded from tab order */133excludeFromTabOrder?: boolean;134/** Whether element is disabled */135isDisabled?: boolean;136/** Auto-focus behavior */137autoFocus?: boolean;138}139140interface FocusableAria {141/** Props to spread on the focusable element */142focusableProps: DOMAttributes<Element>;143}144```145146**Usage Examples:**147148```typescript149import { useFocusable } from "react-aria";150151// Basic focusable element152function CustomButton(props) {153const ref = useRef();154const { focusableProps } = useFocusable(props, ref);155156return (157<button {...focusableProps} ref={ref}>158{props.children}159</button>160);161}162163// Focusable with auto-focus164function AutoFocusButton(props) {165const ref = useRef();166const { focusableProps } = useFocusable({167autoFocus: true,168isDisabled: props.isDisabled169}, ref);170171return (172<button {...focusableProps} ref={ref}>173{props.children}174</button>175);176}177178// Focusable excluded from tab order179function SkipTabButton(props) {180const ref = useRef();181const { focusableProps } = useFocusable({182excludeFromTabOrder: true183}, ref);184185return (186<button {...focusableProps} ref={ref}>187{props.children}188</button>189);190}191```192193### Focus Utilities194195Additional focus-related utilities for managing focus behavior.196197```typescript { .api }198/**199* Get all focusable elements within a container200* @param element - Container element to search within201* @param opts - Options for filtering focusable elements202* @returns Array of focusable elements203*/204function getFocusableElements(element: Element, opts?: {205/** Include only tabbable elements */206tabbable?: boolean;207/** Accept function to filter elements */208accept?: (element: Element) => boolean;209}): HTMLElement[];210211/**212* Check if an element is focusable213* @param element - Element to check214* @param opts - Options for focusability check215* @returns Whether element is focusable216*/217function isFocusable(element: Element, opts?: {218/** Check if tabbable instead of just focusable */219tabbable?: boolean;220}): boolean;221222/**223* Focus an element with appropriate timing224* @param element - Element to focus225* @param preventScroll - Whether to prevent scrolling to element226*/227function focusElement(element: HTMLElement | null, preventScroll?: boolean): void;228229/**230* Restore focus to a previously focused element231* @param element - Element to restore focus to232* @param opts - Options for focus restoration233*/234function restoreFocus(element: HTMLElement | null, opts?: {235/** Whether to prevent scrolling */236preventScroll?: boolean;237}): void;238```239240### Focus Visible Detection241242Provides focus-visible detection for styling keyboard-focused elements.243244```typescript { .api }245/**246* Get the current focus-visible state globally247* @returns Whether focus should be visible248*/249function isFocusVisible(): boolean;250251/**252* Set up global focus-visible detection253* This is called automatically by React Aria components254*/255function setupFocusVisible(): void;256257/**258* Determine if focus should be visible for an element259* @param element - Element to check260* @param modality - Current input modality261* @returns Whether focus should be visible262*/263function shouldShowFocusRing(element: Element, modality?: string): boolean;264```265266### Focus Event Handling267268Advanced focus event handling utilities.269270```typescript { .api }271/**272* Create a focus event handler that respects focus visible state273* @param onFocus - Handler to call when focus should be visible274* @param onBlur - Handler to call when focus is lost275* @returns Combined focus event handlers276*/277function createFocusHandler(278onFocus?: (e: FocusEvent) => void,279onBlur?: (e: FocusEvent) => void280): {281onFocus: (e: FocusEvent) => void;282onBlur: (e: FocusEvent) => void;283};284285/**286* Wrap focus events to handle focus-visible state287* @param target - Target element288* @param onFocusVisible - Handler for focus visible changes289* @returns Cleanup function290*/291function trackFocusVisible(292target: Element,293onFocusVisible: (isFocusVisible: boolean) => void294): () => void;295```296297**Usage Examples:**298299```typescript300import { FocusRing, FocusScope, useFocusManager } from "react-aria";301302// Focus ring with custom styling303function StyledButton(props) {304return (305<FocusRing focusClass="focus-visible">306{({ isFocusVisible, focusProps }) => (307<button308{...focusProps}309className={`btn ${isFocusVisible ? 'focus-visible' : ''}`}310>311{props.children}312</button>313)}314</FocusRing>315);316}317318// Modal dialog with focus containment319function Modal({ isOpen, onClose, children }) {320if (!isOpen) return null;321322return (323<div className="modal-backdrop">324<FocusScope contain restoreFocus autoFocus>325<div className="modal">326<button onClick={onClose}>×</button>327{children}328</div>329</FocusScope>330</div>331);332}333334// Custom navigation with focus manager335function CustomToolbar() {336const focusManager = useFocusManager();337338const handleKeyDown = (e) => {339switch (e.key) {340case 'ArrowRight':341focusManager.focusNext({ wrap: true });342break;343case 'ArrowLeft':344focusManager.focusPrevious({ wrap: true });345break;346case 'Home':347focusManager.focusFirst();348break;349case 'End':350focusManager.focusLast();351break;352}353};354355return (356<div role="toolbar" onKeyDown={handleKeyDown}>357<button>Cut</button>358<button>Copy</button>359<button>Paste</button>360</div>361);362}363```364365## Advanced Focus Patterns366367### Virtual Focus368369For complex widgets like grids and trees, React Aria supports virtual focus patterns.370371```typescript { .api }372/**373* Implement virtual focus for grid-like components374* @param props - Virtual focus configuration375* @returns Virtual focus state and handlers376*/377function useVirtualFocus<T>(props: VirtualFocusProps<T>): VirtualFocusResult<T>;378379interface VirtualFocusProps<T> {380/** Current collection */381collection: Collection<Node<T>>;382/** Currently focused key */383focusedKey?: Key;384/** Default focused key */385defaultFocusedKey?: Key;386/** Handler for focus changes */387onFocusChange?: (key: Key) => void;388/** Whether virtual focus is disabled */389isDisabled?: boolean;390}391392interface VirtualFocusResult<T> {393/** Currently focused key */394focusedKey: Key | null;395/** Set the focused key */396setFocusedKey(key: Key): void;397/** Focus the next item */398focusNext(): void;399/** Focus the previous item */400focusPrevious(): void;401/** Focus the first item */402focusFirst(): void;403/** Focus the last item */404focusLast(): void;405}406```407408### Focus Restoration409410Advanced focus restoration patterns for complex interactions.411412```typescript { .api }413/**414* Track and restore focus across component lifecycles415* @param props - Focus restoration configuration416* @returns Focus restoration handlers417*/418function useFocusRestoration(props: FocusRestorationProps): FocusRestorationResult;419420interface FocusRestorationProps {421/** Whether focus restoration is enabled */422isEnabled?: boolean;423/** Element to restore focus to */424restoreTarget?: HTMLElement | null;425/** Whether to restore focus on unmount */426restoreOnUnmount?: boolean;427}428429interface FocusRestorationResult {430/** Save the current focus */431saveFocus(): void;432/** Restore the saved focus */433restoreFocus(): void;434/** Clear the saved focus */435clearSavedFocus(): void;436}437```438439## Types440441```typescript { .api }442type FocusStrategy = 'first' | 'last' | 'restore';443444interface FocusableElement extends HTMLElement {445/** Whether element supports focus */446focus(options?: FocusOptions): void;447/** Tab index of the element */448tabIndex: number;449}450451interface FocusOptions {452/** Whether to prevent scrolling to the element */453preventScroll?: boolean;454}455456interface FocusEvent {457/** Type of focus event */458type: 'focus' | 'blur' | 'focusin' | 'focusout';459/** Target element */460target: Element;461/** Related target (element losing/gaining focus) */462relatedTarget: Element | null;463/** Whether event bubbles */464bubbles: boolean;465/** Whether event is cancelable */466cancelable: boolean;467}468469interface FocusState {470/** Whether element has focus */471isFocused: boolean;472/** Whether focus should be visible */473isFocusVisible: boolean;474/** Whether element is within a focused container */475isFocusWithin: boolean;476}477```