♿️(frontend) limit share modal opening announcement for screen readers#2452
♿️(frontend) limit share modal opening announcement for screen readers#2452Ovgodd wants to merge 3 commits into
Conversation
065c3b1 to
49c6f8e
Compare
|
Size Change: -1 B (0%) Total Size: 4.37 MB 📦 View Changed
|
Walkthrough
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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: 2
🤖 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/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx`:
- Around line 43-44: The constant DEBOUNCE_MS is being used for two unrelated
purposes: query filtering and accessibility re-exposure delay. Create two
separate constants instead - one specifically for search query debouncing and
another for the accessibility re-exposure delay timing. This decouples these
independent concerns so each can be tuned separately without affecting the
other. Find where DEBOUNCE_MS is used at the query filtering location (around
line 125) and the accessibility re-exposure location (around line 176), then
replace the appropriate usages with their respective new constants.
- Around line 167-180: The useEffect hook in DocShareModal only handles the case
when `canShare` is false by scheduling `isContentAccessible` to true, but it
does not reset `isContentAccessible` to false when `canShare` transitions from
false to true. To fix this, add a branch in the useEffect that immediately sets
`isContentAccessible` to false when `canShare` becomes true, ensuring the
content is removed from the accessibility tree during the opening announcement
for every transition of the `canShare` state.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 06e60d43-e900-4cc3-9140-39504c2bd9d2
📒 Files selected for processing (2)
CHANGELOG.mdsrc/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx
Autofocus close and hide modal body from SR when search input is hidden.
49c6f8e to
8f41648
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx (2)
43-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDecouple search debounce timing from accessibility timing.
DEBOUNCE_MScurrently drives both query filtering and the accessibility re-exposure delay. This couples unrelated UX behaviors and makes future tuning risky.♻️ Suggested refactor
-const DEBOUNCE_MS = 300; +const SEARCH_DEBOUNCE_MS = 300; +const A11Y_CONTENT_REVEAL_DELAY_MS = 300;Update the usage in
useDebouncedCallback(around line 125):const onFilter = useDebouncedCallback((str: string) => { setUserQuery(str); }, SEARCH_DEBOUNCE_MS);Update the usage in the
useEffecthook (around line 176):const id = window.setTimeout(() => { setIsContentAccessible(true); }, A11Y_CONTENT_REVEAL_DELAY_MS);🤖 Prompt for 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. In `@src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx` around lines 43 - 44, Split the shared DEBOUNCE_MS constant into distinct SEARCH_DEBOUNCE_MS and A11Y_CONTENT_REVEAL_DELAY_MS constants in DocShareModal. Update onFilter’s useDebouncedCallback to use SEARCH_DEBOUNCE_MS and the accessibility useEffect timeout to use A11Y_CONTENT_REVEAL_DELAY_MS, preserving the existing timing values.
167-180: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winEnsure
isContentAccessibleis reset on everycanSharetransition.The effect only handles the
canShare === falsebranch by schedulingtrue, but it does not resetisContentAccessibletofalsewhencanSharetransitions from true to false after mount. In that transition, the content can remain exposed to assistive tech, bypassing the announcement-limiting behavior.🐛 Suggested fix
// When the search input is hidden, keep the modal content out of the // accessibility tree during the opening announcement, then restore it. useEffect(() => { - if (canShare) { - return; - } + setIsContentAccessible(canShare); + if (canShare) return; const id = window.setTimeout(() => { setIsContentAccessible(true); }, DEBOUNCE_MS); return () => window.clearTimeout(id); }, [canShare]);🤖 Prompt for 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. In `@src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx` around lines 167 - 180, Update the useEffect keyed by canShare to immediately reset isContentAccessible to false whenever canShare is false, then schedule restoring it to true after DEBOUNCE_MS. Preserve timeout cleanup and the existing canShare true behavior so every false transition re-applies the accessibility suppression.
🤖 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.
Duplicate comments:
In
`@src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx`:
- Around line 43-44: Split the shared DEBOUNCE_MS constant into distinct
SEARCH_DEBOUNCE_MS and A11Y_CONTENT_REVEAL_DELAY_MS constants in DocShareModal.
Update onFilter’s useDebouncedCallback to use SEARCH_DEBOUNCE_MS and the
accessibility useEffect timeout to use A11Y_CONTENT_REVEAL_DELAY_MS, preserving
the existing timing values.
- Around line 167-180: Update the useEffect keyed by canShare to immediately
reset isContentAccessible to false whenever canShare is false, then schedule
restoring it to true after DEBOUNCE_MS. Preserve timeout cleanup and the
existing canShare true behavior so every false transition re-applies the
accessibility suppression.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5f498e66-859f-465a-b7ec-6a85c64fa1d7
📒 Files selected for processing (2)
CHANGELOG.mdsrc/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx
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/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx`:
- Around line 170-183: Update the DocShareModal focus and visibility logic
around the canShare-driven useEffect: synchronously derive the
hidden/accessibility state from canShare, and when canShare transitions from
true to false, move focus to the close button before the share content becomes
aria-hidden. Preserve the delayed re-exposure behavior and cleanup for the
accessibility timeout.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 9cb9a398-c983-4d13-b5ab-8a4ac2fe2989
📒 Files selected for processing (1)
src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx
| useEffect(() => { | ||
| if (canShare) { | ||
| setIsContentAccessible(true); | ||
| return; | ||
| } | ||
|
|
||
| setIsContentAccessible(false); | ||
|
|
||
| const id = window.setTimeout(() => { | ||
| setIsContentAccessible(true); | ||
| }, ACCESSIBILITY_REEXPOSURE_DELAY_MS); | ||
|
|
||
| return () => window.clearTimeout(id); | ||
| }, [canShare]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file='src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx'
echo '== outline =='
ast-grep outline "$file" --view expanded || true
echo
echo '== line count =='
wc -l "$file"
echo
echo '== relevant ranges =='
sed -n '1,280p' "$file" | cat -nRepository: suitenumerique/docs
Length of output: 11433
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file='src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx'
nl -ba "$file" | sed -n '1,320p'Repository: suitenumerique/docs
Length of output: 197
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file='src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx'
echo '== focus-related symbols =='
grep -nE 'focus|autoFocus|ref=' "$file" || true
echo
echo '== canShare / isContentAccessible usage =='
grep -nE 'canShare|isContentAccessible|aria-hidden' "$file" || true
echo
echo '== lower half of file =='
sed -n '280,421p' "$file" | cat -nRepository: suitenumerique/docs
Length of output: 6166
Move focus out of the share content before canShare hides it. autoFocus={!canShare} only runs on mount, so a true → false transition can leave focus inside an aria-hidden subtree. Shift focus to the close button on that transition and make the hidden state update synchronously from canShare instead of waiting for the effect.
🤖 Prompt for 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.
In
`@src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx`
around lines 170 - 183, Update the DocShareModal focus and visibility logic
around the canShare-driven useEffect: synchronously derive the
hidden/accessibility state from canShare, and when canShare transitions from
true to false, move focus to the close button before the share content becomes
aria-hidden. Preserve the delayed re-exposure behavior and cleanup for the
accessibility timeout.
Purpose
Limit the screen reader announcement when opening the share modal without the search input.
Proposal