Skip to content

Give a menu pressable its accessibility label and hint on iOS - #202

Open
techenby wants to merge 1 commit into
NativePHP:mainfrom
techenby:menu-accessibility-label
Open

techenby wants to merge 1 commit into
NativePHP:mainfrom
techenby:menu-accessibility-label

Conversation

@techenby

@techenby techenby commented Nov 5, 2026

Copy link
Copy Markdown

On iOS, a pressable with a :menu drops its a11y-label and a11y-hint.

Core's NodeAccessibility skips :menu pressables on purpose: the SwiftUI Menu owns the tap and is already a button, so it's "left to its renderer". But NativeUIPressableRenderer wraps the content in a Menu without applying either one. An icon-only menu, like an ellipsis "more" button, reads in VoiceOver as a bare "pop up button" with no name.

<pressable a11y-label="Retake or remove" :menu="$menu" class="h-12 w-12 items-center justify-center">
    <icon :ios="Ios::Ellipsis" :android="Android::MoreHoriz" :size="18" />
</pressable>

The fix

The Menu gets the label and hint through a small modifier, and only when each is set. A menu whose content shows text, like "+ Add", reads the same as before when it has no label. Android doesn't change.

Testing

  • A new test in tests/IosPressableMenuItemsTest.php checks that the renderer passes a11y_label and a11y_hint to the Menu, and that an empty value leaves the Menu alone. It fails without the change. composer test (487 passed) and composer lint:test pass.
  • In our app on an iPhone 18 Pro simulator (iOS 27.2), AXe reads the accessibility tree:
    • Before: an icon-only menu button is a PopUpButton with no label.
    • After: it's labeled "Retake or remove".
    • A menu with visible text ("+ Add", with a11y-label="Add") still reads "Add".
    • The menu still opens on tap.
  • Our app runs this as a patch on 0.9.

Core skips its accessibility modifier for a pressable with a :menu,
since the SwiftUI Menu owns the tap and is a button already, and leaves
it to the renderer. The renderer wrapped the content in a Menu without
the a11y-label or a11y-hint, so an icon-only menu (an ellipsis "more"
button) read as a bare "pop up button" in VoiceOver.

The Menu now carries both when they're set. A menu whose content shows
text, like "+ Add", reads the same as before when no label is given.
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.

1 participant