/** * A11y Tree — generic type definitions. * * The A11y Tree is a browser-agnostic description of the *semantic* a11y * structure of a component. Each node captures the intent (role, label, * description, level, etc.) and a stable `id` that the strategy layer * can use to project ARIA attributes onto the real DOM. * * ## Architecture overview * * ``` * Component (TSX) * ↓ builds semantic tree via DTO helpers (a11y-node-dto.ts) * A11yNode tree (this file) * ↓ compiled by an A11yTreeStrategy * AriaPatch[] * ↓ applied by a11y-tree-applier.ts * Shadow DOM (ARIA attributes on data-a11y-id elements) * ``` * * The A11y Tree is NOT rendered itself. It is consumed by an * `A11yTreeStrategy` that decides, per browser/AT, which ARIA attributes * to attach to which DOM nodes. * * ## Browser-engine strategy contract * * Assistive technology (AT) cannot be detected from JavaScript (by design, * for user privacy). The strategy resolver therefore branches on *browser * engine* as a coarse proxy for the most likely AT pairing: * * | Engine | Assumed AT | Confidence | * |-----------|-------------------|---------------------| * | WebKit | VoiceOver (macOS/iOS) | medium on Apple, low elsewhere | * | Gecko | NVDA (Windows), Orca (Linux) | medium on Win, low elsewhere | * | Chromium | JAWS / NVDA / TalkBack | high on non-Apple, medium on Apple | * * **Confidence semantics** (see `A11yStrategyConfidence`): * - `high` — direct signal (explicit override or confirmed UA). * - `medium` — plausible proxy; AT pairing is an assumption that covers the * majority of users on that engine+platform combination. * - `low` — unknown UA or atypical engine/platform combo; dev-mode warning * fires once per (strategy, reason) tuple via `resolveStrategy`. * * Consumers who know the AT environment (e.g. automated tests, a storybook * knob) can pin a strategy explicitly via `data-a11y-strategy` on the host * element — this is always treated as `high` confidence. */ export declare type A11yRole = 'heading' | 'group' | 'region' | 'img' | 'presentation' | 'none'; /** * Semantic kind — describes *what the content is*, independent of which * ARIA attribute it ultimately produces. Strategies may dispatch on `kind` * for fine-grained control beyond what `role` can express. * * Authoritative definition: `a11y-node-dto.ts`. Re-exported here so tree * literal authors can type-check without importing the DTO module. */ export declare type A11ySemanticKind = 'container' | 'landmark' | 'heading' | 'icon' | 'image' | 'button' | 'live'; /** * A single node in the semantic A11y Tree. * * Nodes are authored via the DTO helpers in `a11y-node-dto.ts` to avoid * hand-shaping ARIA field names. Raw literals are still accepted by all * APIs for backwards compatibility and quick inline use. */ export interface A11yNode { /** Stable identifier; DOM nodes opt in via `data-a11y-id`. */ id: string; /** Semantic role for this node. */ role: A11yRole; /** * Optional semantic discriminator emitted by the DTO layer. * Strategies that need to distinguish intent beyond `role` * (e.g. landmark vs plain container) dispatch on this first * and fall back to `role` when absent. */ kind?: A11ySemanticKind; /** Visible text label (used for aria-label / aria-labelledby). */ label?: string; /** Supplementary description (used for aria-describedby). */ description?: string; /** Heading level (1–6) when role === 'heading'. */ level?: 1 | 2 | 3 | 4 | 5 | 6; /** Whether this node is purely decorative. */ decorative?: boolean; /** Child semantic nodes. */ children?: A11yNode[]; } /** * A flat instruction emitted by the strategy: "on the DOM node carrying * `data-a11y-id=`, set this attribute to this value". * * `value === null` means the attribute should be removed. */ export interface AriaPatch { targetId: string; attribute: string; value: string | null; } /** * Strategy contract. Each strategy encapsulates the per-browser/AT quirks * needed to project an `A11yNode` tree onto real ARIA attributes. * * Strategies MUST be pure functions of the tree: same input → same output. * Side effects (DOM manipulation) belong in `a11y-tree-applier.ts`. */ export interface A11yTreeStrategy { /** Machine-readable name, used for `data-a11y-strategy` lookups. */ name: string; /** Convert a semantic A11y tree into a flat list of ARIA patches. */ compile(root: A11yNode): AriaPatch[]; } /** * Confidence level for the strategy-resolver's UA→AT mapping. * * - `high` : we observed a direct signal (explicit override, or a * UA the resolver has confirmed test coverage for). * - `medium` : UA pattern is a known proxy but the AT pairing is an * assumption (e.g. Firefox → NVDA on Windows; users on * Linux running Orca will also match this branch). * - `low` : we are falling back to baseline because we could not * recognise the UA at all. * * Low-confidence matches surface a dev-mode console warning (rate-limited * per strategy+reason tuple) so product teams know when to pin a strategy * explicitly via `data-a11y-strategy`. */ export declare type A11yStrategyConfidence = 'high' | 'medium' | 'low'; /** * Full resolution result including the strategy, how confident we are, * and a human-readable reason string for dev warnings. */ export interface A11yStrategyResolution { strategy: A11yTreeStrategy; confidence: A11yStrategyConfidence; /** Human-readable reason — surfaced in dev warnings. */ reason: string; }