Accessibility & IME
Glyx draws its entire UI to a GPU canvas, so unlike a DOM-based framework
there's no free accessibility tree for the OS to enumerate. Glyx builds one
explicitly via AccessKit (opens in a new tab) and wires IME composition
into TextInput, so screen readers and CJK input both work.
Both are live-tested — accessibility against Windows Narrator, confirmed working across the full role set below.
Accessibility
Every committed layout pass walks the node tree into an
accesskit::TreeUpdate, pushed to the OS accessibility API (Windows UIA,
macOS NSAccessibility, AT-SPI on Linux) via accesskit_winit. This is
compiled in behind the a11y Cargo feature — check __glyx_hasA11y() from
JS if your app needs to detect whether a build has it.
Props
| Prop | Type | Description |
|---|---|---|
role | string | Explicit AccessKit role — see the table below. Overrides the inferred default. |
ariaLabel | string | Accessible name announced by the screen reader. |
<Pressable role="button" ariaLabel="Close dialog" onPress={onClose}>
<Icon name="x" />
</Pressable>Role mapping
role value | AccessKit role |
|---|---|
'button' | Button |
'textbox' | TextInput |
'checkbox' | CheckBox |
'radio' | RadioButton |
'switch' | Switch |
'link' | Link |
'image' | Image |
'heading' | Heading |
'list' | List |
'listitem' | ListItem |
'combobox' | ComboBox |
'slider' | Slider |
'none' / 'presentation' | GenericContainer (filtered from the platform tree, same as ARIA none) |
Without an explicit role, Glyx infers one: <Text> → Label, <Image> →
Image, any node with a visible caret → TextInput, any pressable node →
Button, everything else → GenericContainer.
Actions
Wired: Focus, Click, Increment/Decrement (e.g. Slider), and
SetValue for numeric values.
Known gaps: Expand/Collapse, ScrollIntoView, and text-selection
actions aren't wired yet. There's also no keyboard Tab-key focus
cycling implementation — focus can be set programmatically and screen
readers can navigate their own virtual cursor, but there's no built-in
Tab/Shift+Tab traversal across focusable nodes yet.
IME / CJK text input
TextInput handles IME composition end-to-end — not just receiving the OS
events, but actually rendering the preedit string inline and committing it
into the field's value.
- Composition (preedit) text renders inline in the field as you type, before you've committed a character.
- On commit, the composed text is inserted into the real value at the caret — a proper two-phase insertion, not a naive append.
- The OS candidate window is positioned automatically against the caret.
This covers Chinese, Japanese, Korean, and any other script that needs a
composition window — no extra setup required beyond using <TextInput>.
What's genuinely still missing
- Tab-key focus cycling (keyboard-only navigation between focusable nodes).
Expand/Collapse,ScrollIntoView, and text-selection AccessKit actions.- An
ariaLabel-adjacent "hint" prop (e.g. a longer description alongside the accessible name) — not implemented. - Right-to-left
TextInputcursor/selection directionality, and bidirectional text mixing within a single field.
See the remaining accessibility gaps roadmap page for more detail on the first two.