feat(a11y): label post action-row + overflow-menu controls for screen readers#3288
Conversation
… readers Extends the upvote a11y work (#3286) across the whole post action surface so VoiceOver/TalkBack announce every interactive control with a meaningful, count-aware name and role. Central (optional, additive props): TextWithIcon and IconButton now forward accessibilityLabel/accessibilityHint and expose accessibilityRole="button" when interactive (gated on a press handler), plus accessibilityState. Call sites labeled: - Feed card (postCardActionsPanel): votes / reblog / comment / tip - Single post bar (postDisplayView): votes / reblog / comment / tip / view-stats - Comment & wave row (commentView): votes / reply / tip / edit / delete / show-hide replies - Overflow menus: post options on feed cards (postCardHeader) and on comments/waves (postHeaderDescription) Counts are interpolated ({count} votes/reblogs/comments/tips/views) and every formatMessage carries a defaultMessage so non-English locales fall back to English instead of raw message IDs. 16 new post.a11y_* strings (en-US).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e7c7b2b084
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1 @@ | |||
| /root/ecency-mobile/node_modules No newline at end of file | |||
There was a problem hiding this comment.
Remove the tracked node_modules symlink
This commit tracks node_modules as a symlink to /root/ecency-mobile/node_modules. In any fresh checkout that is not running with that exact machine-local path, the dependency directory is dangling or points outside the repo, so install/test scripts that dereference node_modules/... can fail or write under /root instead of the workspace. Since node_modules/ is already ignored, this should stay untracked.
Useful? React with 👍 / 👎.
| accessibilityRole={onPress ? 'button' : undefined} | ||
| accessibilityLabel={accessibilityLabel} | ||
| accessibilityHint={accessibilityHint} | ||
| accessibilityState={{ disabled: !!disabled }} |
There was a problem hiding this comment.
Mark loading icon buttons as disabled for a11y
For callers that pass isLoading without also setting disabled (for example the edit-avatar/profile-cover and snippet delete buttons), onPress is suppressed while loading but this new accessibility state still reports the control as enabled. Screen-reader users can focus an enabled button that does nothing while the spinner is shown; include isLoading in the disabled state or disable the touchable consistently.
Useful? React with 👍 / 👎.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughAdds React Native accessibility props ( ChangesAccessibility Support
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/comment/view/commentView.tsx`:
- Around line 218-225: The accessibilityHint with the message "View voters" (id:
post.a11y_voters_hint) is shown regardless of whether the voters control is
actually interactive. Since the control only functions when _totalVotes is
greater than 0 (as checked on Line 214), make the accessibilityHint conditional
so it only renders when _totalVotes > 0. This ensures screen readers don't
mislead users by suggesting they can view voters when the control is
non-interactive. The accessibilityLabel reporting the vote count can remain
unconditional.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5d6bc9ce-1b6d-4ac0-b306-9de19d1c96a7
📒 Files selected for processing (9)
node_modulessrc/components/basicUIElements/view/textWithIcon/textWithIconView.tsxsrc/components/comment/view/commentView.tsxsrc/components/iconButton/view/iconButtonView.tsxsrc/components/postCard/children/postCardActionsPanel.tsxsrc/components/postCard/children/postCardHeader.tsxsrc/components/postElements/headerDescription/view/postHeaderDescription.tsxsrc/components/postView/view/postDisplayView.tsxsrc/config/locales/en-US.json
Greptile SummaryThis PR adds screen-reader labels (
Confidence Score: 5/5Safe to merge — all changes are purely additive a11y metadata with no behavioural side-effects on sighted users. Every new prop is optional, guarded by an interactivity check, and the locale fallbacks ensure no raw key IDs leak to users. The useMemo dep fix is correct, and the isClickable conditional on the votes button in commentView tightens behaviour that was already implicit. No logic paths that affect data, navigation, or rendering have changed. No files require special attention — the shared-component changes to TextWithIcon and IconButton are the widest-impact surface but both are correctly guarded. Important Files Changed
Reviews (2): Last reviewed commit: "fix(a11y): address review — plural count..." | Re-trigger Greptile |
…ode_modules - Remove the accidentally-committed node_modules symlink (it broke CI's yarn install --frozen-lockfile; node_modules stays gitignored/untracked). - Use ICU plural for count labels (votes/reblogs/comments/tips/views) so a count of 1 reads "1 vote" not "1 votes". en-US strings + inline defaultMessage fallbacks both updated. - TextWithIcon: set accessibilityState only on interactive instances so decorative/display-only ones don't announce as "dimmed". - IconButton: report disabled while isLoading, since onPress is suppressed then. - commentView votes: gate isClickable + the "View voters" hint on _totalVotes > 0 so a zero-vote control isn't announced as an actionable button.
|
Pushed 9751612 addressing the review + the Lint CI failure:
Prettier 2.8.8 ✓, eslint 0 errors ✓. |
What
Follows up the upvote a11y fix (#3286) with a broad pass over the rest of the post action surface so screen-reader users (VoiceOver / TalkBack) can find, identify, and operate every interactive control — not just the upvote arrow.
How
Central, additive change to two shared components — both rendered a touchable with no accessibility metadata:
TextWithIcon(votes / reblog / comment / tip / stats / replies-toggle) andIconButton(tip / edit / delete / overflow menu) now forward optionalaccessibilityLabel/accessibilityHint, exposeaccessibilityRole="button"only when interactive (gated on a press handler, mirroring each component's existingdisabledlogic), and setaccessibilityState. Props are optional → every existing call site is unaffected.Labels added at the call sites (count-aware, via
intl.formatMessage(..., { count })):postCardActionsPanelpostDisplayViewcommentViewpostCardHeader) + on comments/waves (postHeaderDescription)UpvoteButtonwas already done in #3286. Waves are covered transitively (the waves screen renders throughCommentView), and all feed/profile/community/search/bookmark lists route throughPostCardActionsPanel— so no duplicate surfaces.16 new
post.a11y_*strings inen-US.json. EveryformatMessagecarries adefaultMessage, so the ~37 non-English locales fall back to readable English instead of raw IDs (the lesson from #3286 review).Validation
intlis in scope (incl. theuseMemodep inpostDisplayView), and counts match what each control displays.Deliberately deferred
buttonrole (functionally accessible); reblog-by indicator has an implicit text label. Both are low-priority and left as-is.Summary by CodeRabbit