Skip to content

♿️(frontend) limit share modal opening announcement for screen readers#2452

Open
Ovgodd wants to merge 3 commits into
mainfrom
fix/a11y-2334-share-modal-access-names
Open

♿️(frontend) limit share modal opening announcement for screen readers#2452
Ovgodd wants to merge 3 commits into
mainfrom
fix/a11y-2334-share-modal-access-names

Conversation

@Ovgodd

@Ovgodd Ovgodd commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Limit the screen reader announcement when opening the share modal without the search input.

Proposal

  • Autofocus the close button when the search input is hidden

@Ovgodd
Ovgodd requested a review from AntoLC June 22, 2026 14:03
@Ovgodd Ovgodd self-assigned this Jun 22, 2026
@Ovgodd Ovgodd added bug Something isn't working accessibility triage labels Jun 22, 2026
@Ovgodd
Ovgodd force-pushed the fix/a11y-2334-share-modal-access-names branch from 065c3b1 to 49c6f8e Compare June 22, 2026 14:03
@Ovgodd
Ovgodd marked this pull request as ready for review June 22, 2026 14:05
@Ovgodd Ovgodd moved this from Backlog to In review in LaSuite Docs A11y Jun 22, 2026
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Size Change: -1 B (0%)

Total Size: 4.37 MB

📦 View Changed
Filename Size Change
apps/impress/out/_next/static/343f0930/_buildManifest.js 695 B +695 B (new file) 🆕
apps/impress/out/_next/static/aa40a0b3/_buildManifest.js 0 B -696 B (removed) 🏆

compressed-size-action

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

DocShareModal adds timed accessibility gating for modal content when canShare is false, updates close-button autofocus, standardizes the search debounce delay, and records the behavior in CHANGELOG.md.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: antolc, antolc

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the accessibility-focused share modal change.
Description check ✅ Passed The description is directly related to the share modal screen reader accessibility update.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/a11y-2334-share-modal-access-names

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 87fbcba and 49c6f8e.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx

Autofocus close and hide modal body from SR when search input is hidden.
@Ovgodd
Ovgodd force-pushed the fix/a11y-2334-share-modal-access-names branch from 49c6f8e to 8f41648 Compare July 15, 2026 09:36

@coderabbitai coderabbitai Bot 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.

♻️ Duplicate comments (2)
src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx (2)

43-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Decouple search debounce timing from accessibility timing.

DEBOUNCE_MS currently 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 useEffect hook (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 win

Ensure isContentAccessible is reset on every canShare transition.

The effect only handles the canShare === false branch by scheduling true, but it does not reset isContentAccessible to false when canShare transitions 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

📥 Commits

Reviewing files that changed from the base of the PR and between 49c6f8e and 8f41648.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx

@Ovgodd
Ovgodd requested review from AntoLC and removed request for AntoLC July 15, 2026 09:39

@coderabbitai coderabbitai Bot 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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8f41648 and d40b395.

📒 Files selected for processing (1)
  • src/frontend/apps/impress/src/features/docs/doc-share/components/DocShareModal.tsx

Comment on lines +170 to +183
useEffect(() => {
if (canShare) {
setIsContentAccessible(true);
return;
}

setIsContentAccessible(false);

const id = window.setTimeout(() => {
setIsContentAccessible(true);
}, ACCESSIBILITY_REEXPOSURE_DELAY_MS);

return () => window.clearTimeout(id);
}, [canShare]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 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 -n

Repository: 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 -n

Repository: 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility bug Something isn't working triage

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

Share modal: spurious restitution of accessible names unrelated to the dialog window

1 participant