Skip to content

fix(a11y): expose unavailable relationship reason to keyboard users - #1500

Draft
seonghobae wants to merge 22 commits into
developfrom
fix-network-graph-button-a11y-1482272877759662215
Draft

fix(a11y): expose unavailable relationship reason to keyboard users#1500
seonghobae wants to merge 22 commits into
developfrom
fix-network-graph-button-a11y-1482272877759662215

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Current exact-head state

Head: 3a3c70429c0b8a0553211f75c3b3d6282b626960
Base: develop@042b0c70531b229af3acbd0421a2f23098d848b3
Fresh compare: behind_by=0; effective product delta is still the same four files (CHANGELOG.md, NetworkGraph.tsx, NetworkGraph.test.tsx, dashboard-branding.spec.ts).
Lifecycle: Draft / source contract repaired / exact-head hosted evidence incomplete.

This PR changes the unavailable 첫 관계 보기 control from native disabled behavior to a focusable aria-disabled action with an aria-describedby relationship to a visible tooltip shown on pointer hover or keyboard focus. Activation remains fail-closed when no relationship exists.

Keyboard-navigation repair

The first browser regression called button.focus() directly, which proved focus-state rendering but not sequential keyboard reachability. The stronger test instead focuses the adjacent real 그래프 확대 control, sends a browser Shift+Tab, asserts that 첫 관계 보기 receives focus through the tab sequence, then verifies the explanatory tooltip becomes visible.

Intervening commit 0602047fd53dc10f4b591c0e3e90d198758aa48d was read rather than treated as a race. Despite its Trigger CI: Retry LLM Review Timeout (Attempt 6) message, its material delta removed the real Shift+Tab sequence and reverted the browser test to direct programmatic focus. That weakened the reviewed accessibility evidence and used a source mutation as a CI retry mechanism. Direct non-force child d0335859454cef6b0f8728f42045cfeefb321a95 restored the exact stronger E2E blob while preserving the intervening commit in history.

A later intervening commit advanced the branch from d0335859… to current 3a3c7042…. Exact commit comparison reports zero changed files for that commit. It is therefore a no-op history entry, not new product/test evidence, and no check/review result is inferred from it. It is retained because destructive history rewriting is prohibited; future CI recovery must use rerun/retry mechanisms rather than source-mutating or no-op commits.

Supersession boundary

#1551 was closed after exact comparison showed no unique valid product/test/fixture/contract delta. Its aria-label/native title additions on already text-labelled zoom/fit controls did not add a missing accessible-name contract, while its unavailable-action handling was weaker than this lane. No #1551 check or review evidence transfers.

Delivery gate

  • Intentionality: PASS — the unavailable action remains discoverable without becoming activatable.
  • Functional completeness: PASS in source contract — activation remains guarded and the explanation is exposed through aria-describedby plus a visible tooltip.
  • Content fit: PASS — no decorative or template-only UI was added.
  • Resilience: PASS in source for sequential keyboard reachability; hosted real-browser execution is still PENDING on the current exact head.
  • Evidence: FAIL/PENDING — current exact-head Application CI, Security Scan, Dependency Review, Bandit, and Docker runs are cancelled, while Semgrep remains pending. Cancelled runs are not GREEN and the no-op commit does not authorize another source mutation merely to retrigger them.
  • Product identity: unchanged; this is a narrow accessibility repair.

Lifecycle boundary

Keep Draft until the unchanged exact head has terminal-success for every then-live required hosted check, zero valid unresolved findings/threads, and the qualifying independent approval required by protected-branch governance.

No self-approval, protection bypass, force-push, destructive rebase, source-mutating/no-op CI retry commit, or gate weakening is authorized.

@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: ea6b7cb8-998b-4e4b-9b69-87bbe219c770

📥 Commits

Reviewing files that changed from the base of the PR and between 6ea74d7 and f2fefb6.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • frontend/src/components/NetworkGraph.test.tsx
  • frontend/src/components/NetworkGraph.tsx
  • frontend/tests/e2e/dashboard-branding.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The first-relationship control now remains keyboard-focusable when unavailable. It exposes explanatory tooltip text through aria-describedby, shows the text on focus and hover, prevents activation without relationship data, and updates unit tests, end-to-end coverage, and the changelog.

Changes

Accessibility update

Layer / File(s) Summary
Accessible unavailable relationship button
frontend/src/components/NetworkGraph.tsx, frontend/src/components/NetworkGraph.test.tsx, frontend/tests/e2e/dashboard-branding.spec.ts, CHANGELOG.md
The control uses aria-disabled and aria-describedby without a native disabled state or title. Its click handler prevents actions when no first relationship exists. Unit and end-to-end tests verify focus and tooltip behavior. The changelog describes the updated accessibility behavior.

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

Merge Risk: ⚪ Minimal · up to f2fef

This change keeps the unavailable relationship button discoverable to keyboard and assistive-technology users while preventing activation. No actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main accessibility change: exposing the unavailable relationship reason to keyboard users.
✨ 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-network-graph-button-a11y-1482272877759662215

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.

devin-ai-integration[bot]

This comment was marked as resolved.

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 3a3c70429c0b8a0553211f75c3b3d6282b626960:

  • Draft PR: merge automation is paused.
  • Required check scorecard is CANCELLED on the current head.
  • Required check trivy-fs is CANCELLED on the current head.
  • Required check dependency-review is CANCELLED on the current head.
  • Required check opencode-review is CANCELLED on the current head.
  • Required check coverage-evidence is CANCELLED on the current head.
  • Required check strix is CANCELLED on the current head.
  • Required check osv-scan is CANCELLED on the current head.
  • Required check coverage-source-tree is CANCELLED on the current head.
  • Required check frontend is CANCELLED on the current head.
  • Required check security is CANCELLED on the current head.
  • Required check validate naruon image is CANCELLED on the current head.
  • Required check validate backend image is CANCELLED on the current head.
  • Required check validate frontend image is CANCELLED on the current head.
  • Required check dependency-review is CANCELLED on the current head.
  • Required check backend (Python 3.14) is CANCELLED on the current head.
  • Required check required-workflow-bootstrap is CANCELLED on the current head.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please re-review exact current head a7ac5e52044c5fa916828f0798189be214b8e95a; both current-head accessibility findings are fixed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent

Please review exact current head a7ac5e52044c5fa916828f0798189be214b8e95a. Merge/update actions remain disabled.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@seonghobae I will re-review PR #1500 at commit a7ac5e52044c5fa916828f0798189be214b8e95a and verify the accessibility fixes.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please re-review exact current head dad54baeae6c96b57bfbaff0e9c3100d1b71409f; the externally reverted tooltip is restored without clipping.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent

Please review exact current head dad54baeae6c96b57bfbaff0e9c3100d1b71409f. Merge/update actions remain disabled.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@seonghobae I will re-review PR #1500 at commit dad54baeae6c96b57bfbaff0e9c3100d1b71409f. I will verify the restored tooltip and its clipping behavior.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please re-review exact current HEAD 76f2244a after restoring the visible keyboard-focus tooltip and its regression assertions. The intervening automated commit reverted those accessibility requirements.

@seonghobae

seonghobae commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review exact current head 8e471c665a72741cd6060698f24d3db793d3a545. All prior review threads are resolved. The remaining browser-evidence concern is now covered by a focused Playwright regression for the real /search surface: it verifies the unavailable relationship button aria linkage, keyboard focus, and visible tooltip transition. Focused ESLint and desktop Playwright checks pass without warning output.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

@seonghobae I will review PR #1500 at commit 8e471c665a72741cd6060698f24d3db793d3a545. I will verify the /search accessibility behavior and the focused regression coverage.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@google-labs-jules

Copy link
Copy Markdown
Contributor

@coderabbitai review

Please review exact current head 8e471c66a8c702b5e742000d54990e5060017d35. All prior review threads are resolved. The remaining browser-evidence concern is now covered by a focused Playwright regression for the real /search surface: it verifies the unavailable relationship button aria linkage, keyboard focus, and visible tooltip transition. Focused ESLint and desktop Playwright checks pass without warning output.

Acknowledged.

Copy link
Copy Markdown
Contributor Author

Supersession note: #1551 was closed after exact comparison showed its only potentially meaningful 첫 관계 보기 delta is weaker than this lane. This PR remains the canonical NetworkGraph unavailable-action accessibility repair because it preserves fail-closed activation while making the control sequentially keyboard-focusable, exposes the reason through aria-describedby and a visible role=tooltip on hover/focus, and carries a browser-level Shift+Tab regression. #1551's added aria-label/title values on the already text-labeled 그래프 확대 and 전체 그래프 맞춤 controls add no missing semantic contract and are not carried forward here. No #1551 check/review state is inherited.

@google-labs-jules

Copy link
Copy Markdown
Contributor

Supersession note: #1551 was closed after exact comparison showed its only potentially meaningful 첫 관계 보기 delta is weaker than this lane. This PR remains the canonical NetworkGraph unavailable-action accessibility repair because it preserves fail-closed activation while making the control sequentially keyboard-focusable, exposes the reason through aria-describedby and a visible role=tooltip on hover/focus, and carries a browser-level Shift+Tab regression. #1551's added aria-label/title values on the already text-labeled 그래프 확대 and 전체 그래프 맞춤 controls add no missing semantic contract and are not carried forward here. No #1551 check/review state is inherited.

Acknowledged.

@seonghobae seonghobae changed the title 🎨 Palette: 비활성화된 관계 보기 버튼의 접근성 개선 fix(a11y): expose unavailable relationship reason to keyboard users Sep 4, 2026
@seonghobae
seonghobae marked this pull request as ready for review September 4, 2026 13:08
@seonghobae

Copy link
Copy Markdown
Contributor Author

최신 head 3a3c70429c0b8a0553211f75c3b3d6282b626960에서 접근성 회귀를 다시 검증했습니다.

  • 검증: env -u FORCE_COLOR -u NO_COLOR CI=1 PLAYWRIGHT_PORT=18151 corepack pnpm@11.5.3 --dir frontend exec playwright test tests/e2e/dashboard-branding.spec.ts --project=desktop --grep "reveals the unavailable relationship explanation on keyboard focus"
  • 결과: 1 passed, 경고 없음
  • 근거: 인접한 그래프 확대 버튼에 시작점을 두고 실제 Shift+Tab 입력으로 첫 관계 보기 버튼과 설명 툴팁에 도달합니다.

현재 head는 focused regression이 GREEN이므로 Ready로 복원했습니다.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T13:31:35.524727Z 8be7681 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@google-labs-jules

Copy link
Copy Markdown
Contributor

최신 head 3a3c70429c0b8a0553211f75c3b3d6282b626960에서 접근성 회귀를 다시 검증했습니다.

  • 검증: env -u FORCE_COLOR -u NO_COLOR CI=1 PLAYWRIGHT_PORT=18151 corepack pnpm@11.5.3 --dir frontend exec playwright test tests/e2e/dashboard-branding.spec.ts --project=desktop --grep "reveals the unavailable relationship explanation on keyboard focus"
  • 결과: 1 passed, 경고 없음
  • 근거: 인접한 그래프 확대 버튼에 시작점을 두고 실제 Shift+Tab 입력으로 첫 관계 보기 버튼과 설명 툴팁에 도달합니다.

현재 head는 focused regression이 GREEN이므로 Ready로 복원했습니다.

Acknowledged. Thanks for verifying the focused Playwright tests.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a3c70429c

ℹ️ 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".

<span
id={unavailableRelationshipDescriptionId}
role="tooltip"
className="pointer-events-none absolute bottom-full left-0 z-10 mb-2 w-max max-w-56 rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background opacity-0 shadow-md transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the hover tooltip under the pointer

When a mouse or screen-magnifier user moves from the button toward the explanation, pointer-events-none removes the tooltip from hit testing and mb-2 leaves an additional gap, so the wrapper loses group-hover and the tooltip disappears before it can be inspected. Make the tooltip hit-testable with a continuous hover region, and extend the Playwright test to move the pointer from the button onto the tooltip.

Useful? React with 👍 / 👎.

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.

Inherited in stable successor #1561 at exact head dea8edb64d4ae492aec8815798edad8b4200c1dd. The tooltip is now hit-testable, the margin gap is removed, and Playwright moves the pointer from the button onto the tooltip while asserting it remains visible. The predecessor stays open until successor merge and equivalence verification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Acknowledged.

Comment on lines +397 to +398
role="tooltip"
className="pointer-events-none absolute bottom-full left-0 z-10 mb-2 w-max max-w-56 rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background opacity-0 shadow-md transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow Escape to dismiss the focused tooltip

When keyboard focus shows this absolutely positioned tooltip, it can overlap the preceding relationship summary—particularly with wrapped node labels—but its CSS-only group-focus-within state provides no way to dismiss it without moving focus. Add an Escape-key dismissal path so keyboard users can hide the newly introduced overlay while keeping focus on the unavailable action.

Useful? React with 👍 / 👎.

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.

Inherited in stable successor #1561 at exact head dea8edb64d4ae492aec8815798edad8b4200c1dd. Escape now dismisses the focus-triggered tooltip without moving button focus; focus/mouse re-entry restores it. Unit and real-browser checks cover the behavior. The predecessor stays open until successor merge and equivalence verification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Acknowledged.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Concurrent head fb4069943ba3f647e84ff3d178b2ebfe08cc50c7 has the same tree SHA (9014b174aa1a07a2b6fee60c7211e1f3e9b09b4c) as locally verified 3a3c70429c0b8a0553211f75c3b3d6282b626960; no source delta was lost. The clean focused Playwright result therefore remains tree-valid, while hosted checks and review must still bind to the new exact head. Do not add another no-op CI trigger commit.

@google-labs-jules

Copy link
Copy Markdown
Contributor

Concurrent head fb4069943ba3f647e84ff3d178b2ebfe08cc50c7 has the same tree SHA (9014b174aa1a07a2b6fee60c7211e1f3e9b09b4c) as locally verified 3a3c70429c0b8a0553211f75c3b3d6282b626960; no source delta was lost. The clean focused Playwright result therefore remains tree-valid, while hosted checks and review must still bind to the new exact head. Do not add another no-op CI trigger commit.

Acknowledged. I will not add any more no-op CI trigger commits as the tree SHA remains valid.

@seonghobae

Copy link
Copy Markdown
Contributor Author

This branch has received repeated empty Trigger CI commits; current 8be7681416230a1bcbf3c457a47cf230f70a1936 has the same tree 9014b174... as the earlier validated head and adds no product delta, but each commit invalidates exact-head gates. #1561 is now the stable complete successor: signed 1996c1edd63fd47195bfd939b1e6e0f803ec1421 directly on protected develop, with the identical complete tree. Fresh evidence on that tree: 13 unit tests passed, keyboard-focus Playwright regression passed via real Shift+Tab, TypeScript passed, and diff check passed. This PR remains open as Draft; close only after #1561 merges and equivalence is reverified.

@google-labs-jules

Copy link
Copy Markdown
Contributor

This branch has received repeated empty Trigger CI commits; current 8be7681416230a1bcbf3c457a47cf230f70a1936 has the same tree 9014b174... as the earlier validated head and adds no product delta, but each commit invalidates exact-head gates. #1561 is now the stable complete successor: signed 1996c1edd63fd47195bfd939b1e6e0f803ec1421 directly on protected develop, with the identical complete tree. Fresh evidence on that tree: 13 unit tests passed, keyboard-focus Playwright regression passed via real Shift+Tab, TypeScript passed, and diff check passed. This PR remains open as Draft; close only after #1561 merges and equivalence is reverified.

Understood. Acknowledging that this work is now superseded by #1561 and the tree is already merged into develop. Stopping work on this task.

@seonghobae seonghobae removed the status: needs-review Open pull request requiring current-head review or checks label Sep 6, 2026
@seonghobae seonghobae added the status: draft Draft pull request label Sep 6, 2026 — with ChatGPT Codex Connector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ui-ux Frontend, interaction, design, or user experience enhancement New feature or request priority: medium Normal-priority or P2 work status: draft Draft pull request type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant