Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Accessibility & Semantics Nodes

Accessibility in Voce IR is structurally required, not opt-in. Every interactive visual node must reference a SemanticNode. The validator rejects IR where interactive elements lack semantic annotations. Explicit opt-outs (decorative: true, presentation: true) are supported for valid exceptions.

SemanticNode

Parallel semantic tree entry for a visual node. Carries ARIA role, label, relationships, and keyboard focus configuration. Visual nodes reference SemanticNodes via the semantic_node_id field. All SemanticNodes live in a flat list on ViewRoot.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
rolestringyesARIA role (e.g., “button”, “heading”, “navigation”, “main”)
labelstringnoAccessible label announced by screen readers
labelled_bystringnoNode ID whose content labels this node (aria-labelledby)
described_bystringnoNode ID providing extended description (aria-describedby)
controlsstringnoNode ID this element controls (aria-controls)
owned_bystringnoNode ID that owns this element (aria-owns)
heading_levelint8noHeading level 1-6, only valid when role=“heading” (default 0)
tab_indexint32noKeyboard focus order (-2=unset, -1=programmatic, 0=natural, >0=explicit)
hiddenboolnoHidden from the accessibility tree (default false)
aria_expandedint8no-1=unset, 0=false, 1=true
aria_selectedint8no-1=unset, 0=false, 1=true
aria_checkedint8no-1=unset, 0=false, 1=true, 2=mixed
aria_disabledboolnoWhether element is disabled (default false)
aria_requiredboolnoWhether element is required (default false)
aria_invalidboolnoWhether element has invalid input (default false)
aria_value_minfloat32noMinimum value for range widgets
aria_value_maxfloat32noMaximum value for range widgets
aria_value_nowfloat32noCurrent value for range widgets
aria_value_textstringnoHuman-readable value for range widgets
custom_aria[KeyValue]noCustom ARIA attributes (escape hatch)

The validator enforces that interactive roles (“button”, “link”, “textbox”, etc.) have either label or labelled_by set.

{
  "node_id": "sem-cta-btn",
  "role": "button",
  "label": "Get started with Voce IR",
  "tab_index": 0
}

LiveRegion

Declares a region whose content changes are announced by screen readers. Used for toast notifications, form errors, cart updates, and status messages.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
target_node_idstringyesVisual node this live region is attached to
politenessLiveRegionPolitenessnoPolite (default) or Assertive or Off
atomicboolnoAnnounce entire region on change (default false)
relevantLiveRegionRelevantnoAdditions (default), Removals, Text, All
role_descriptionstringnoDescriptive label (e.g., “Shopping cart updates”)

Politeness values:

  • Polite – wait for the user to be idle before announcing
  • Assertive – interrupt current speech to announce immediately
  • Off – region is silent
{
  "node_id": "toast-live",
  "target_node_id": "toast-container",
  "politeness": "Assertive",
  "atomic": true,
  "role_description": "Notification"
}

FocusTrap

Constrains keyboard focus to a subtree. Used for modals, drawers, and dialogs. The compiler emits focus management JavaScript.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
container_node_idstringyesContainer node whose subtree traps focus
initial_focus_node_idstringnoNode to focus on activation (default: first focusable)
escape_behaviorFocusTrapEscapenoCloseOnEscape (default), NoEscape, FireEvent
escape_state_machinestringnoStateMachine for FireEvent escape behavior
escape_eventstringnoEvent to fire on Escape for FireEvent
restore_focusboolnoRestore previous focus on deactivation (default true)
{
  "node_id": "modal-trap",
  "container_node_id": "modal-container",
  "initial_focus_node_id": "modal-close-btn",
  "escape_behavior": "CloseOnEscape",
  "restore_focus": true
}

ReducedMotion

Every animation in the IR must reference a ReducedMotion alternative. The validator rejects any AnimationTransition, Sequence, or ScrollBinding that lacks one. See the Motion chapter for the full ReducedMotion reference.

Strategy values:

StrategyDescription
RemoveRemove animation entirely, snap to final state
SimplifyReplace with a simpler animation (e.g., opacity fade)
ReduceDurationKeep animation but reduce to near-instant duration
FunctionalAnimation is functional (spinner, progress bar); simplify only