Skip to main content
Raw GestureDetectors and bare InkWells don’t announce a button role, and widgets composed of several texts read as disjoint nodes. SemanticButton merges its subtree into one semantics node with button: true, so VoiceOver/TalkBack reads e.g. “Inspired by you, Your own definition of enough, button” and activates it with the standard double-tap. Source: semantic_button.dart.
Implementation is deliberately tiny: MergeSemantics ▸ Semantics(button: true, …) ▸ optionally ExcludeSemantics. No visuals, no tokens — purely semantics.

API

Usage rules (from the source doc comment)

1

Visible descriptive text → no label

The merge composes the announcement from the child’s text automatically.
2

Decorative or animated child → label + excludeChildSemantics

Custom paint or streaming text reads badly; provide a stable label and set excludeChildSemantics: true.
3

Never wrap other interactive controls

The merge swallows nested controls’ tap actions — one button per wrapper.
4

Pass onTap only when the child has no semantic tap

An InkWell/GestureDetector inside already merges its handler; duplicating it double-registers.

Used by

StyledFloatingActionButton and composite tappables like StyledListTile consumers. Reach for it any time you build a custom tappable that isn’t a Material button.