Skip to content

fix: expose overlay dismissal as an empty accessibility container - #23

Open
RoyalPineapple wants to merge 3 commits into
mainfrom
RoyalPineapple/overlay-a11y-container
Open

RoyalPineapple wants to merge 3 commits into
mainfrom
RoyalPineapple/overlay-a11y-container

Conversation

@RoyalPineapple

@RoyalPineapple RoyalPineapple commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

The overlay's "Dismiss popup" target was a leaf accessibility element, so VoiceOver put it in the swipe order alongside the modal content. This brings the implementation in line with the default dimming view behavior.

OverlayView now reports isAccessibilityElement = false and, when overlay-tap dismissal is enabled, accessibilityContainerType = .semanticGroup. It stays behind the content with no children. Label, hint, and activation are unchanged. VoiceOver focuses the empty group when the user touches outside the content, and double-tap still dismisses; the escape gesture is unaffected.

Verified on device with VoiceOver against Market popovers.

Checklist

  • Unit Tests
  • Documentation
  • Pull request title follows conventional commits

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RoyalPineapple
RoyalPineapple marked this pull request as ready for review October 15, 2026 14:17
@RoyalPineapple
RoyalPineapple requested review from a team as code owners October 15, 2026 14:17
override var isAccessibilityElement: Bool {
get { onAccessibilityActivate != nil }
get { false }
set { fatalError("Not settable") }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe not fatalerror,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Changed both setters (isAccessibilityElement and accessibilityContainerType) to no-ops, so external writes are ignored instead of crashing. Added test coverage that writes don't change either value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Switched both setters to assertionFailure("Not settable"): catches writes in debug, ignored in release. Dropped the write-ignoring test since it would now trap in debug.

…ping

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@soroushsq soroushsq left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question, no blocker

Comment on lines +1853 to +1859
get { onAccessibilityActivate != nil }
set { fatalError("Not settable") }
get { false }
set {}
}

override var accessibilityContainerType: UIAccessibilityContainerType {
get { onAccessibilityActivate != nil ? .semanticGroup : .none }
set {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have any concerns here? Have we done this anywhere else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no this is the sole place we set a dismissal overlay. or at least we don't do it within market.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

2 participants