Skip to content

a11y

stable

Build and inspect accessibility trees with ARIA-style roles, labels, and properties for screen reader support.

use plugin a11y::{create_node, set_label, set_description, …}
19 functions UI
/ filter jk navigate Esc clear
Functions (19)
  1. create_node Create a new accessibility node
  2. set_label Set the accessible label property
  3. set_description Set the accessible description property
  4. set_value Set the current value property
  5. set_role Change the ARIA role of a node
  6. set_name Change the accessible name of a node
  7. set_property Set an arbitrary property by key
  8. get_property Read a property value by key
  9. get_role Read the node's role string
  10. get_name Read the node's accessible name
  11. get_children Return the node's children table
  12. child_count Return the number of children
  13. set_focusable Mark a node as focusable or not
  14. is_focusable Check whether a node is focusable
  15. screen_reader_text Generate screen reader announcement text
  16. validate_node Check for a11y issues on a node
  17. add_child Append a child node to a parent
  18. role_names Return all supported ARIA role names
  19. tree_to_string Render the accessibility tree as text

Overview

The a11y plugin lets you build and inspect an accessibility tree — the same kind of role/name/property model that screen readers and assistive technology consume. Every node is a plain table with role, name, children, and properties fields, so there are no opaque handles: you create a node with create_node, then thread it through the builder functions, each of which returns a new updated table. Use it to model the semantics of a UI (buttons, links, headings, lists), validate that interactive elements are correctly labelled and focusable, and render the tree for debugging or to preview what a screen reader would announce.

Because the builders are pure and return updated copies, the idiomatic style is to reassign the node on each step (let btn = set_label(btn, ...)). Roles follow ARIA conventions; call role_names() to see the full set of supported strings.

Common patterns

Build and announce a single node

Create a node, attach a label and value, then preview the screen reader announcement.

use plugin a11y::{create_node, set_label, set_value, screen_reader_text}

let slider = create_node("slider", "Brightness")
let slider = set_label(slider, "Screen brightness")
let slider = set_value(slider, "80%")
print(screen_reader_text(slider))

Assemble a tree and render it

Compose nested nodes with add_child, then dump the whole tree as indented text.

use plugin a11y::{create_node, add_child, child_count, tree_to_string}

let nav = create_node("navigation", "Main")
let nav = add_child(nav, create_node("link", "Home"))
let nav = add_child(nav, create_node("link", "Docs"))
let nav = add_child(nav, create_node("link", "About"))
print("links: {child_count(nav)}")
print(tree_to_string(nav, 2))

Validate interactive nodes

Mark interactive roles focusable and check the node passes a11y validation.

use plugin a11y::{create_node, set_focusable, validate_node}

let btn = create_node("button", "Submit")
let btn = set_focusable(btn, true)
let result = validate_node(btn)
print("valid: {result["valid"]}")

Create a new accessibility node

Creates a new accessibility node with the given ARIA role and accessible name. The returned table contains role, name, children, and properties fields.

use plugin a11y::{create_node, set_label, set_focusable}

let btn = create_node("button", "Submit")
let btn = set_label(btn, "Submit form")
let btn = set_focusable(btn, true)
print(btn["role"])

A freshly created node starts with empty children and properties tables, so you can read its fields immediately or pass it straight to add_child.

use plugin a11y::{create_node, get_role, get_name, child_count}

let heading = create_node("heading", "Welcome")
print(get_role(heading))
print(get_name(heading))
print(child_count(heading))

Set the accessible label property

Sets the accessible label in the node's properties. Use this to provide a human-readable label that screen readers announce instead of the raw name.

use plugin a11y::{create_node, set_label}

let img = create_node("img", "")
let img = set_label(img, "Company logo")

Set the accessible description property

Sets an extended accessible description in the node's properties. Use this for supplemental context that screen readers announce after the label and role.

use plugin a11y::{create_node, set_description}

let input = create_node("textbox", "Email")
let input = set_description(input, "Enter your work email address")

Set the current value property

Sets the current value property. Useful for range inputs, progress bars, or text boxes to convey the current state to assistive technology.

use plugin a11y::{create_node, set_value}

let slider = create_node("slider", "Volume")
let slider = set_value(slider, "75")

Change the ARIA role of a node

Replaces the node's ARIA role. Use role_names() to see all valid roles.

use plugin a11y::{create_node, set_role}

let node = create_node("button", "Toggle menu")
let node = set_role(node, "switch")

Change the accessible name of a node

Updates the accessible name of an existing node. The name is used when no label property is present.

use plugin a11y::{create_node, set_name}

let node = create_node("link", "Click here")
let node = set_name(node, "Go to homepage")

Set an arbitrary property by key

Sets an arbitrary property on the node's properties table. Use this for custom ARIA attributes or any extra metadata.

use plugin a11y::{create_node, set_property}

let node = create_node("checkbox", "Accept terms")
let node = set_property(node, "checked", true)
let node = set_property(node, "required", true)

Property values are not limited to strings — store numbers or booleans for ARIA state attributes and read them back with get_property.

use plugin a11y::{create_node, set_property, get_property}

let slider = create_node("slider", "Volume")
let slider = set_property(slider, "valuemin", 0)
let slider = set_property(slider, "valuemax", 100)
print(get_property(slider, "valuemax"))

Read a property value by key

Reads a property value from the node's properties table. Returns nil if the property is not set.

use plugin a11y::{create_node, set_property, get_property}

let node = create_node("checkbox", "Accept terms")
let node = set_property(node, "checked", true)
let checked = get_property(node, "checked")
print(checked)

Read the node's role string

Returns the ARIA role string of the node, or nil if no role is set.

use plugin a11y::{create_node, get_role}

let node = create_node("button", "OK")
print(get_role(node))

Read the node's accessible name

Returns the accessible name of the node, or nil if no name is set.

use plugin a11y::{create_node, get_name}

let node = create_node("link", "Read more")
print(get_name(node))

Return the node's children table

Returns the table of child nodes appended via add_child.

use plugin a11y::{create_node, add_child, get_children}

let list = create_node("list", "Items")
let item = create_node("listitem", "First")
let list = add_child(list, item)
let kids = get_children(list)
print(kids[0]["name"])

Return the number of children

Returns the number of direct children of the node.

use plugin a11y::{create_node, add_child, child_count}

let nav = create_node("navigation", "Main nav")
let nav = add_child(nav, create_node("link", "Home"))
let nav = add_child(nav, create_node("link", "About"))
print(child_count(nav))

Mark a node as focusable or not

Marks the node as focusable (true) or not (false). Defaults to true if no second argument is passed. Interactive roles such as button, link, and textbox should always be focusable.

use plugin a11y::{create_node, set_focusable, is_focusable}

let btn = create_node("button", "Save")
let btn = set_focusable(btn, true)
print(is_focusable(btn))

Check whether a node is focusable

Returns true if the node has focusable: true in its properties.

use plugin a11y::{create_node, set_focusable, is_focusable}

let node = create_node("heading", "Section title")
print(is_focusable(node))

Generate screen reader announcement text

Generates the text a screen reader would announce for the node, combining label (or name), role, value, and description in order.

use plugin a11y::{create_node, set_label, set_value, screen_reader_text}

let slider = create_node("slider", "Brightness")
let slider = set_label(slider, "Brightness")
let slider = set_value(slider, "80%")
print(screen_reader_text(slider))

When no label is set, the announcement falls back to the node's name, followed by its role and any description.

use plugin a11y::{create_node, set_description, screen_reader_text}

let link = create_node("link", "Pricing")
let link = set_description(link, "opens in a new tab")
print(screen_reader_text(link))

Check for a11y issues on a node

Checks the node for accessibility issues. Returns a table with valid: bool and issues: table. Flags missing role/name and interactive roles that are not marked focusable.

use plugin a11y::{create_node, set_focusable, validate_node}

let btn = create_node("button", "Submit")
let btn = set_focusable(btn, true)
let result = validate_node(btn)
print(result["valid"])

A node missing a name, or an interactive role that is not focusable, reports valid: false and lists the problems in issues.

use plugin a11y::{create_node, validate_node}

let bad = create_node("button", "")
let result = validate_node(bad)
print(result["valid"])
print(result["issues"][0])

Append a child node to a parent

Appends a child node to the parent's children list and returns the updated parent table.

use plugin a11y::{create_node, add_child, child_count}

let nav = create_node("navigation", "Sidebar")
let link = create_node("link", "Dashboard")
let nav = add_child(nav, link)
print(child_count(nav))

Return all supported ARIA role names

Returns a table of all 36 supported ARIA role strings (button, checkbox, dialog, heading, link, etc.).

use plugin a11y::{role_names}

let roles = role_names()
print(roles[0])

Iterate the table to discover every role the plugin recognises.

use plugin a11y::{role_names}

let roles = role_names()
for role in roles {
  print(role)
}

Render the accessibility tree as text

Renders the entire accessibility tree as an indented text string, useful for debugging. The optional indent argument sets spaces per level (default 2).

use plugin a11y::{create_node, add_child, tree_to_string}

let root = create_node("navigation", "Main")
let root = add_child(root, create_node("link", "Home"))
let root = add_child(root, create_node("link", "About"))
print(tree_to_string(root, 4))
enespt-br