Skip to content

Fix TextInput placeholder invisible to assistive technologies#1832

Open
Stasshe wants to merge 2 commits into
linebender:mainfrom
Stasshe:main
Open

Fix TextInput placeholder invisible to assistive technologies#1832
Stasshe wants to merge 2 commits into
linebender:mainfrom
Stasshe:main

Conversation

@Stasshe

@Stasshe Stasshe commented Jul 15, 2026

Copy link
Copy Markdown

Fix TextInput placeholder invisible to assistive technologies

Fixes #1701

Problem

TextInput's AccessKit representation exposed the placeholder text twice:

  1. As a visual Label child node (used only for painting).
  2. Via accesskit::Node::set_placeholder, called on the parent GenericContainer node instead of the TextArea node it actually describes.

Assistive technologies could not associate the placeholder with its text input, and screen readers announced the redundant label as a separate element.

Fix

  • TextArea gained a placeholder field and TextArea::set_placeholder, so the placeholder is set on the TextInput's inner AccessKit TextInput-role node (the TextArea), not its container.
  • TextInput::accessibility no longer calls node.set_placeholder on the container node.
  • Added NewWidget::accessibility_hidden(bool) (backed by a new accessibility_hidden flag on WidgetOptions/WidgetState), which omits a widget and its whole subtree from the AccessKit tree without touching layout, painting, or event handling.
  • TextInput's visual placeholder Label is now created with .accessibility_hidden(true), so it's no longer published to the accessibility tree at all.
  • run_accessibility_pass skips building nodes under a hidden subtree, filters hidden children out of set_children, drops the root widget's node when hidden, and redirects focus away from a hidden widget to the window node.

Testing

  • masonry::tests::accessibility::accessibility_hidden_omits_subtree — a hidden widget and its descendants are absent from the tree, and its parent has zero exposed children.
  • masonry::widgets::text_input::tests::placeholder_is_exposed_on_text_area_accessibility_node — the placeholder is set on the TextArea node (not the root TextInput node), the visual placeholder Label has no accessibility node, and the root exposes exactly one child. Updated after set_placeholder is called to confirm live updates propagate.
  • cargo test -p masonry --lib accessibility passes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TextInput placeholder invisible to assistive technologies

1 participant