Skip to content

♿ Fix event handler accessibility parity on clickable divs#3959

Merged
clubanderson merged 4 commits intomainfrom
copilot/auto-qa-event-handler-a11y
Mar 31, 2026
Merged

♿ Fix event handler accessibility parity on clickable divs#3959
clubanderson merged 4 commits intomainfrom
copilot/auto-qa-event-handler-a11y

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

Auto-QA flagged 9 div elements with onClick but no ARIA role or onKeyDown, failing accessibility parity checks.


📌 Fixes


📝 Summary of Changes

Adds appropriate ARIA roles and accessible names to all 9 flagged clickable div elements across 6 files. No behavioral changes — purely semantic markup fixes.


Changes Made

Element type Fix Files
Modal backdrop overlays role="presentation" Deploy.tsx, CardWrapper.tsx, ClusterSelectionDialog.tsx, ClusterAssignmentPanel.tsx, PayloadCard.tsx
Modal content containers role="dialog" aria-modal="true" aria-labelledby Deploy.tsx, CardWrapper.tsx, ClusterSelectionDialog.tsx
Structural stopPropagation wrapper role="presentation" ClusterGrid.tsx
Icon-only close button aria-label="Close dialog" CardWrapper.tsx

Rationale: Backdrop overlays are visual-only — keyboard users close via the dedicated Close button, so role="presentation" is correct. Modal content containers get role="dialog" aria-modal="true" so screen readers announce them correctly. Each dialog is also given an accessible name via aria-labelledby pointing to its heading <h3>, and the icon-only close button in CardWrapper receives aria-label="Close dialog".

// Before
<div className="fixed inset-0 z-50 ..." onClick={() => setShowInstallGuide(null)}>
  <div className="bg-card ..." onClick={e => e.stopPropagation()}>
    <h3 className="text-lg font-semibold">...</h3>
    <button onClick={() => setShowInstallGuide(null)}><X /></button>

// After
<div className="fixed inset-0 z-50 ..." role="presentation" onClick={() => setShowInstallGuide(null)}>
  <div className="bg-card ..." role="dialog" aria-modal="true" aria-labelledby="install-guide-title" onClick={e => e.stopPropagation()}>
    <h3 id="install-guide-title" className="text-lg font-semibold">...</h3>
    <button onClick={() => setShowInstallGuide(null)} aria-label="Close dialog"><X /></button>
  • Fixed ClusterGrid.tsx:171 — structural wrapper → role="presentation"
  • Fixed ClusterAssignmentPanel.tsx:182 — dropdown backdrop → role="presentation"
  • Fixed PayloadCard.tsx:203 — dropdown backdrop → role="presentation"
  • Fixed Deploy.tsx:265,266 — modal backdrop role="presentation" + content role="dialog" aria-modal="true" aria-labelledby="group-picker-dialog-title"
  • Fixed CardWrapper.tsx:1261,1262 — modal backdrop role="presentation" + content role="dialog" aria-modal="true" aria-labelledby="install-guide-title"; icon-only close button aria-label="Close dialog"
  • Fixed ClusterSelectionDialog.tsx:90,91 — modal backdrop role="presentation" + content role="dialog" aria-modal="true" aria-labelledby="cluster-selection-dialog-title"

Checklist

  • I used a coding agent (Claude Code, Copilot, Gemini, or Codex) to generate/review this code
  • I have reviewed the project's contribution guidelines
  • New cards target console-marketplace, not this repo
  • isDemoData is wired correctly (cards show Demo badge when using demo data)
  • I have written unit tests for the changes (if applicable)
  • I have tested the changes locally and ensured they work as expected
  • All commits are signed with DCO (git commit -s)

Screenshots or Logs (if applicable)

N/A — markup-only changes with no visual impact.


👀 Reviewer Notes

No logic changes. All onClick handlers are unchanged — only ARIA roles and accessible names added. The three modal content wrappers (Deploy, CardWrapper, ClusterSelectionDialog) use role="dialog" aria-modal="true" with aria-labelledby pointing to their respective <h3> headings, ensuring screen readers can announce the dialog name when it opens.

@kubestellar-prow kubestellar-prow bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. dco-signoff: no Indicates the PR's author has not signed the DCO. labels Mar 31, 2026
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 31, 2026

Deploy Preview for kubestellarconsole ready!

Name Link
🔨 Latest commit 7a504bc
🔍 Latest deploy log https://app.netlify.com/projects/kubestellarconsole/deploys/69cb31604b1d820008593f0d
😎 Deploy Preview https://deploy-preview-3959.console-deploy-preview.kubestellar.io
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown
Contributor

👋 Hey @Copilot — thanks for opening this PR!

🤖 This project is developed exclusively using AI coding assistants.

Please do not attempt to code anything for this project manually.
All contributions should be authored using an AI coding tool such as:

This ensures consistency in code style, architecture patterns, test coverage,
and commit quality across the entire codebase.


This is an automated message.

@kubestellar-prow kubestellar-prow bot added the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label Mar 31, 2026
@github-actions github-actions bot added dco-signoff: yes Indicates the PR's author has signed the DCO. and removed dco-signoff: no Indicates the PR's author has not signed the DCO. labels Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

❌ PR Title Verification Failed

Your PR title does not follow the required format.

Current title: ♿ Fix event handler accessibility parity on clickable divs

Required Format

PR titles must start with one of these emoji prefixes:

Emoji Meaning
⚠️ Breaking change
Non-breaking feature
🐛 Patch fix / Bug fix
📖 Documentation
🚀 Release
🌱 Infra/Tests/Other

How to Fix

Edit your PR title to start with the appropriate emoji. For example:

  • ✨ Add new feature for user authentication
  • 🐛 Fix crash when loading empty config
  • 📖 Update installation guide

You can edit the title by clicking the Edit button next to your PR title.


This comment was automatically posted by the PR Title Verifier workflow.

… clickable divs

Fixes #3577

Add role="presentation" to 9 clickable div elements that lacked proper
ARIA roles, resolving the Auto-QA accessibility parity findings:

- ClusterGrid.tsx:171 - container div with stopPropagation
- ClusterAssignmentPanel.tsx:182 - dropdown backdrop overlay
- PayloadCard.tsx:203 - dropdown backdrop overlay
- Deploy.tsx:265 - modal backdrop overlay
- Deploy.tsx:266 - modal content container (stopPropagation)
- CardWrapper.tsx:1261 - modal backdrop overlay
- CardWrapper.tsx:1262 - modal content container (stopPropagation)
- ClusterSelectionDialog.tsx:90 - modal backdrop overlay
- ClusterSelectionDialog.tsx:91 - modal content container (stopPropagation)

Using role="presentation" is semantically correct for these elements:
- Backdrop overlays are visual-only; keyboard users use the Close button
- StopPropagation containers are structural wrappers, not interactive

Signed-off-by: copilot <copilot@github.com>

Agent-Logs-Url: https://github.com/kubestellar/console/sessions/000497be-b91c-488a-a6a2-446abb9f4061

Co-authored-by: clubanderson <407614+clubanderson@users.noreply.github.com>
@kubestellar-prow kubestellar-prow bot added dco-signoff: no Indicates the PR's author has not signed the DCO. and removed dco-signoff: yes Indicates the PR's author has signed the DCO. labels Mar 31, 2026
@kubestellar-prow
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from clubanderson. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions github-actions bot removed the dco-signoff: no Indicates the PR's author has not signed the DCO. label Mar 31, 2026
@kubestellar-prow kubestellar-prow bot removed the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label Mar 31, 2026
@github-actions github-actions bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Mar 31, 2026
@kubestellar-prow kubestellar-prow bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Mar 31, 2026
Per code review feedback, modal content containers should use
role="dialog" aria-modal="true" rather than role="presentation" to
ensure screen readers announce modal content correctly.

Backdrop/overlay divs keep role="presentation" as they are visual-only.

Signed-off-by: copilot <copilot@github.com>

Agent-Logs-Url: https://github.com/kubestellar/console/sessions/000497be-b91c-488a-a6a2-446abb9f4061

Co-authored-by: clubanderson <407614+clubanderson@users.noreply.github.com>
@kubestellar-prow kubestellar-prow bot added dco-signoff: no Indicates the PR's author has not signed the DCO. and removed dco-signoff: yes Indicates the PR's author has signed the DCO. labels Mar 31, 2026
@github-actions github-actions bot added dco-signoff: yes Indicates the PR's author has signed the DCO. and removed dco-signoff: no Indicates the PR's author has not signed the DCO. labels Mar 31, 2026
@clubanderson clubanderson marked this pull request as ready for review March 31, 2026 02:18
Copilot AI review requested due to automatic review settings March 31, 2026 02:18
@clubanderson clubanderson changed the title [WIP] Fix event handler accessibility parity issues Fix event handler accessibility parity issues Mar 31, 2026
@clubanderson clubanderson removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Mar 31, 2026
Copilot AI changed the title Fix event handler accessibility parity issues ♿ Fix event handler accessibility parity on clickable divs Mar 31, 2026
Copilot AI requested a review from clubanderson March 31, 2026 02:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses accessibility lint/parity issues by adding ARIA roles to non-semantic elements that handle click interactions (e.g., modal backdrops, dropdown backdrops, and click-swallowing containers) across the React frontend.

Changes:

  • Add role="presentation" to several backdrop / container <div> elements with onClick.
  • Add role="dialog" and aria-modal="true" to a few modal content containers.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
web/src/components/missions/ClusterSelectionDialog.tsx Adds role="presentation" to the overlay and role="dialog" aria-modal="true" to the dialog container.
web/src/components/mission-control/PayloadCard.tsx Adds role="presentation" to the priority dropdown backdrop.
web/src/components/mission-control/ClusterAssignmentPanel.tsx Adds role="presentation" to the cluster picker backdrop.
web/src/components/deploy/Deploy.tsx Adds role="presentation" to the modal backdrop and role="dialog" aria-modal="true" to the modal container.
web/src/components/clusters/components/ClusterGrid.tsx Adds role="presentation" to a click-swallowing controls wrapper.
web/src/components/cards/CardWrapper.tsx Adds role="presentation" to the modal backdrop and role="dialog" aria-modal="true" to the modal container.

Comment on lines +90 to 94
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-2xl" role="presentation" onClick={onCancel}>
<div className="w-full max-w-lg rounded-lg border border-border bg-card shadow-xl flex flex-col max-h-[80vh]" role="dialog" aria-modal="true" onClick={e => e.stopPropagation()}>
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-border flex-shrink-0">
<div>
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

role="dialog" elements should have an accessible name. This dialog currently lacks aria-label/aria-labelledby, so screen readers will announce it as an unnamed dialog. Consider adding aria-labelledby pointing to the header <h3> (and giving the <h3> a stable id, e.g. via useId()).

Copilot uses AI. Check for mistakes.
Comment on lines 266 to 267
<div className="bg-card border border-border rounded-xl shadow-2xl w-full max-w-sm mx-4 p-5" role="dialog" aria-modal="true" onClick={e => e.stopPropagation()}>
<h3 className="text-base font-medium text-foreground mb-1">
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

This modal uses role="dialog" aria-modal="true" but does not provide an accessible name (aria-label or aria-labelledby). Add aria-labelledby referencing the modal heading (or an aria-label) so assistive tech can announce what dialog opened.

Suggested change
<div className="bg-card border border-border rounded-xl shadow-2xl w-full max-w-sm mx-4 p-5" role="dialog" aria-modal="true" onClick={e => e.stopPropagation()}>
<h3 className="text-base font-medium text-foreground mb-1">
<div
className="bg-card border border-border rounded-xl shadow-2xl w-full max-w-sm mx-4 p-5"
role="dialog"
aria-modal="true"
aria-labelledby="group-picker-dialog-title"
onClick={e => e.stopPropagation()}
>
<h3 id="group-picker-dialog-title" className="text-base font-medium text-foreground mb-1">

Copilot uses AI. Check for mistakes.
Comment on lines 1262 to 1265
<div className="bg-card border border-border rounded-xl shadow-2xl max-w-lg w-full mx-4 max-h-[80vh] overflow-y-auto p-6" role="dialog" aria-modal="true" onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold">{showInstallGuide.mission.mission?.title ?? `Install ${installInfo?.project ?? 'Component'}`}</h3>
<button onClick={() => setShowInstallGuide(null)} className="p-1 hover:bg-secondary rounded"><X className="w-4 h-4" /></button>
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

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

The dialog container has role="dialog" aria-modal="true" but no accessible name, and the icon-only close <button> lacks an accessible label. Add aria-labelledby (or aria-label) for the dialog, and add an aria-label (or visible text) to the close button so screen readers can announce it correctly.

Suggested change
<div className="bg-card border border-border rounded-xl shadow-2xl max-w-lg w-full mx-4 max-h-[80vh] overflow-y-auto p-6" role="dialog" aria-modal="true" onClick={e => e.stopPropagation()}>
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold">{showInstallGuide.mission.mission?.title ?? `Install ${installInfo?.project ?? 'Component'}`}</h3>
<button onClick={() => setShowInstallGuide(null)} className="p-1 hover:bg-secondary rounded"><X className="w-4 h-4" /></button>
<div
className="bg-card border border-border rounded-xl shadow-2xl max-w-lg w-full mx-4 max-h-[80vh] overflow-y-auto p-6"
role="dialog"
aria-modal="true"
aria-labelledby="install-guide-title"
onClick={e => e.stopPropagation()}
>
<div className="flex items-center justify-between mb-4">
<h3
id="install-guide-title"
className="text-lg font-semibold"
>
{showInstallGuide.mission.mission?.title ?? `Install ${installInfo?.project ?? 'Component'}`}
</h3>
<button
onClick={() => setShowInstallGuide(null)}
className="p-1 hover:bg-secondary rounded"
aria-label="Close dialog"
>
<X className="w-4 h-4" />
</button>

Copilot uses AI. Check for mistakes.
@clubanderson
Copy link
Copy Markdown
Collaborator

🔄 Auto-Applying Copilot Code Review

Copilot code review found 2 code suggestion(s) and 1 general comment(s).

@copilot Please apply all of the following code review suggestions:

  • web/src/components/deploy/Deploy.tsx (line 267): <div className="bg-card border border-border rounded-xl shadow-2xl w...
  • web/src/components/cards/CardWrapper.tsx (line 1265): <div className="bg-card border border-border rounded-xl shadow-2...

Also address these general comments:

  • web/src/components/missions/ClusterSelectionDialog.tsx (line 94): role="dialog" elements should have an accessible name. This dialog currently lacks aria-label/aria-labelledby, so

Push all fixes in a single commit. Run cd web && npm run build && npm run lint before committing.


Auto-generated by copilot-review-apply workflow.

- Deploy.tsx: add aria-labelledby="group-picker-dialog-title" to dialog,
  add id="group-picker-dialog-title" to h3
- CardWrapper.tsx: add aria-labelledby="install-guide-title" to dialog,
  add id="install-guide-title" to h3, add aria-label="Close dialog" to
  icon-only close button
- ClusterSelectionDialog.tsx: add aria-labelledby="cluster-selection-dialog-title"
  to dialog, add id="cluster-selection-dialog-title" to h3

Signed-off-by: copilot <copilot@github.com>

Agent-Logs-Url: https://github.com/kubestellar/console/sessions/679eab4c-3066-439b-95c7-ec47afc42084

Co-authored-by: clubanderson <407614+clubanderson@users.noreply.github.com>
@kubestellar-prow kubestellar-prow bot added dco-signoff: no Indicates the PR's author has not signed the DCO. and removed dco-signoff: yes Indicates the PR's author has signed the DCO. labels Mar 31, 2026
@kubestellar-prow
Copy link
Copy Markdown
Contributor

Thanks for your pull request. Before we can look at it, you'll need to add a 'DCO signoff' to your commits.

📝 Please follow instructions in the contributing guide to update your commits with the DCO

Full details of the Developer Certificate of Origin can be found at developercertificate.org.

The list of commits missing DCO signoff:

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@github-actions github-actions bot added dco-signoff: yes Indicates the PR's author has signed the DCO. and removed dco-signoff: no Indicates the PR's author has not signed the DCO. labels Mar 31, 2026
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 31, 2026

🔄 Auto-Applying Copilot Code Review

Copilot code review found 2 code suggestion(s) and 1 general comment(s)....

Applied all suggestions in commit 7a504bc:

  • Deploy.tsx: Added aria-labelledby="group-picker-dialog-title" to the dialog div and id="group-picker-dialog-title" to the <h3>.
  • CardWrapper.tsx: Added aria-labelledby="install-guide-title" to the dialog div, id="install-guide-title" to the <h3>, and aria-label="Close dialog" to the icon-only close button.
  • ClusterSelectionDialog.tsx: Added aria-labelledby="cluster-selection-dialog-title" to the dialog div and id="cluster-selection-dialog-title" to the <h3>.

All three dialogs now have accessible names that screen readers will announce when the dialog opens.

@clubanderson clubanderson merged commit 874721b into main Mar 31, 2026
20 of 28 checks passed
@kubestellar-prow kubestellar-prow bot deleted the copilot/auto-qa-event-handler-a11y branch March 31, 2026 11:27
@github-actions
Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

Check out what's new:

Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey

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

Labels

copilot dco-signoff: yes Indicates the PR's author has signed the DCO. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Auto-QA] Event handler accessibility parity issues

3 participants