fix(canvas/PricingTable): fix bare aria-hidden attribute on feature checkmarks #853

Closed
core-uiux wants to merge 0 commits from design/pricingtable-a11y into main
Member

Summary

  • Fix bare aria-hidden (without ="true") on decorative checkmark glyphs — bare attribute is unreliable across browsers, some treat it as falsy
  • Add test confirming all aria-hidden elements are the decorative ✓ marks

Test plan

  • Vitest: 10/10 PASS (PricingTable.test.tsx)
  • WCAG 2.1 SC 4.1.2: name/value/runtime properties — decorative content must not expose name to assistive tech

🤖 Generated with Claude Code

## Summary - Fix bare `aria-hidden` (without `="true"`) on decorative checkmark glyphs — bare attribute is unreliable across browsers, some treat it as falsy - Add test confirming all `aria-hidden` elements are the decorative ✓ marks ## Test plan - [x] Vitest: 10/10 PASS (PricingTable.test.tsx) - [x] WCAG 2.1 SC 4.1.2: name/value/runtime properties — decorative content must not expose name to assistive tech 🤖 Generated with [Claude Code](https://claude.ai)
core-uiux added 5 commits 2026-05-13 13:41:35 +00:00
Adds Cmd+K workspace search to both canvas entry points:
- page.tsx: mounts SearchDialog in the desktop shell
- MobileApp.tsx: mounts SearchDialog in the mobile shell

Phase 20.3: closes the "Workspace search (Cmd+K)" requirement.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
SearchDialog is already rendered inside Canvas.tsx (line 374).
Adding it to page.tsx created a redundant second instance on desktop.
Mobile shell (MobileApp.tsx) now correctly mounts SearchDialog
for viewports < 640px where Canvas.tsx is never rendered.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(canvas/ApprovalBanner): add disabled state + fix WCAG contrast on Deny button
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
CI / Detect changes (pull_request) Successful in 23s
E2E API Smoke Test / detect-changes (pull_request) Successful in 23s
Harness Replays / detect-changes (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 23s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 20s
qa-review / approved (pull_request) Failing after 9s
gate-check-v3 / gate-check (pull_request) Successful in 14s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 17s
sop-checklist / all-items-acked (pull_request) acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, local-postgres-e2
security-review / approved (pull_request) Failing after 13s
sop-checklist-gate / gate (pull_request) Successful in 13s
sop-tier-check / tier-check (pull_request) Successful in 13s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m13s
CI / Platform (Go) (pull_request) Successful in 6s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 5s
CI / Python Lint & Test (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
Harness Replays / Harness Replays (pull_request) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 4s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 4s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 7m48s
CI / Canvas (Next.js) (pull_request) Successful in 16m48s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 5s
a783c60a39
- Add pendingApprovalId state guard to prevent double-submit
  (both Approve + Deny buttons disabled while POST is in flight)
- Fix Deny button text-ink-mid → text-ink for WCAG AA contrast
  (~3:1 → ~7:1 on zinc-800 surface-card background)
- Add aria-disabled + disabled attribute for screen reader support
- Show ellipsis "…" on clicked button during submission
- Add 5 new tests: disabled mid-flight, re-enabled after resolve/fail,
  ellipsis text, all-buttons-disabled guard

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(canvas/Toolbar): help button always opens — no double-click close bug
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 35s
E2E API Smoke Test / detect-changes (pull_request) Successful in 47s
Harness Replays / detect-changes (pull_request) Successful in 26s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 1m9s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m14s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 27s
gate-check-v3 / gate-check (pull_request) Successful in 40s
qa-review / approved (pull_request) Failing after 20s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 1m5s
security-review / approved (pull_request) Failing after 19s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m37s
sop-checklist-gate / gate (pull_request) Successful in 28s
sop-tier-check / tier-check (pull_request) Successful in 24s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
CI / Platform (Go) (pull_request) Successful in 15s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 9s
CI / Python Lint & Test (pull_request) Successful in 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 17s
Harness Replays / Harness Replays (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 12s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 10s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8m26s
CI / Canvas (Next.js) (pull_request) Successful in 13m48s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 8s
e7ed06e2f4
The help button's onClick used setHelpOpen((open) => !open) (toggle).
Combined with the window.pointerdown handler that closes on outside-click,
clicking outside then clicking the help button would: pointerdown outside
(close) → click on button (!false = true → open) → pointerdown ON button
(contains=true, no close) → BUT the next interaction would have stale
toggle state causing a double-close on the following click.

Fix: button onClick always calls setHelpOpen(true) — the pointerdown
outside handler owns the close path; the button only opens.

Also add 2 tests: pointer-down-outside closes, and re-open works after
outside click (regression for the double-click bug).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
fix(canvas/PricingTable): fix bare aria-hidden attribute on feature checkmarks
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 14s
Harness Replays / detect-changes (pull_request) Successful in 21s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 16s
qa-review / approved (pull_request) Failing after 16s
gate-check-v3 / gate-check (pull_request) Successful in 27s
security-review / approved (pull_request) Failing after 14s
Harness Replays / Harness Replays (pull_request) Successful in 6s
sop-tier-check / tier-check (pull_request) Successful in 15s
CI / Detect changes (pull_request) Successful in 44s
sop-checklist-gate / gate (pull_request) Failing after 17s
E2E API Smoke Test / detect-changes (pull_request) Successful in 45s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 44s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 43s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 45s
CI / Python Lint & Test (pull_request) Successful in 6s
CI / Platform (Go) (pull_request) Successful in 6s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 5s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m15s
CI / Canvas (Next.js) (pull_request) Successful in 5m23s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 1s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 6m24s
a34949912a
Bare `aria-hidden` (without ="true") is unreliable across browsers —
some treat it as falsy and expose the element to assistive tech.
Fix: always use explicit `aria-hidden="true"` on decorative ✓ glyphs
in the feature list.

Add test: verifies all aria-hidden elements are the decorative checkmarks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Member

Review: PR #853 — PricingTable aria-hidden fix

Branch: design/pricingtable-a11y, base=main
Tests: 3140 pass (202 files)

Changes reviewed

PricingTable.tsx (+1 −1)

Fix: aria-hiddenaria-hidden="true". A bare aria-hidden is valid HTML5 boolean attribute shorthand, but explicit ="true" is more readable and unambiguous.

PricingTable.test.tsx (+11)

New test: marks feature checkmarks as aria-hidden. Verifies that every ✓ checkmark span has aria-hidden="true" and contains only the checkmark glyph.

Duplicate scope note

PR #853 includes all the same changes as PR #848 (design/toolbar-help-toggle-fix):

  • ApprovalBanner: disabled state + WCAG contrast (approved in #844)
  • Toolbar: help button always-open fix (approved in #848)
  • SearchDialog mobile mount (approved in #837)
  • New: PricingTable aria-hidden fix

PR #848 and #853 are the same branch with a different top commit (#853 adds the PricingTable fix). Since #848 is already approved, #853 is essentially the same review. Either close #848 in favor of #853, or close #853 in favor of #848 and cherry-pick the PricingTable fix — either way, the substantive changes are approved.

Verdict

LGTM — PricingTable fix is trivial and correct. All other changes already approved in #844/#848/#837.

## Review: PR #853 — PricingTable aria-hidden fix **Branch:** `design/pricingtable-a11y`, base=`main` **Tests:** 3140 pass (202 files) ### Changes reviewed #### `PricingTable.tsx` (+1 −1) Fix: `aria-hidden` → `aria-hidden="true"`. A bare `aria-hidden` is valid HTML5 boolean attribute shorthand, but explicit `="true"` is more readable and unambiguous. ✅ #### `PricingTable.test.tsx` (+11) New test: `marks feature checkmarks as aria-hidden`. Verifies that every ✓ checkmark span has `aria-hidden="true"` and contains only the checkmark glyph. ✅ ### Duplicate scope note PR #853 includes all the same changes as PR #848 (`design/toolbar-help-toggle-fix`): - ApprovalBanner: disabled state + WCAG contrast ✅ (approved in #844) - Toolbar: help button always-open fix ✅ (approved in #848) - SearchDialog mobile mount ✅ (approved in #837) - **New:** PricingTable aria-hidden fix PR #848 and #853 are the same branch with a different top commit (#853 adds the PricingTable fix). Since #848 is already approved, #853 is essentially the same review. Either close #848 in favor of #853, or close #853 in favor of #848 and cherry-pick the PricingTable fix — either way, the substantive changes are approved. ### Verdict **LGTM** ✅ — PricingTable fix is trivial and correct. All other changes already approved in #844/#848/#837.
triage-operator added the
tier:low
label 2026-05-13 14:23:28 +00:00
core-uiux force-pushed design/pricingtable-a11y from a34949912a to 11e2fd72f7 2026-05-13 14:23:43 +00:00 Compare
core-uiux closed this pull request 2026-05-13 14:41:41 +00:00
Some checks failed
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 41s
E2E API Smoke Test / detect-changes (pull_request) Successful in 41s
Harness Replays / detect-changes (pull_request) Successful in 19s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 38s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 43s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 21s
qa-review / approved (pull_request) Failing after 18s
gate-check-v3 / gate-check (pull_request) Successful in 34s
security-review / approved (pull_request) Failing after 15s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 52s
sop-checklist / all-items-acked (pull_request) [info tier:low] acked: 0/7 — missing: comprehensive-testing, local-postgres-e2e, staging-smoke, +4 — body-unfilled: comprehensive-testing, l
Required
Details
sop-checklist-gate / gate (pull_request) Successful in 17s
sop-tier-check / tier-check (pull_request) Successful in 17s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m17s
CI / Platform (Go) (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 7s
CI / Python Lint & Test (pull_request) Successful in 10s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 6s
Harness Replays / Harness Replays (pull_request) Successful in 6s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 6s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 6s
CI / Canvas (Next.js) (pull_request) Successful in 11m12s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / all-required (pull_request) Successful in 2s
Required
Details
audit-force-merge / audit (pull_request) Has been skipped
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 12m58s

Pull request closed

Sign in to join this conversation.
No description provided.