- Add AlertDialog.Description with sr-only text to satisfy Radix
aria-describedby requirement (fixes Radix console warning).
- Add eslint-disable for Discard button (AlertDialog.Action wires
keyboard events internally; no duplicate onKeyDown needed).
- Add explicit expect() assertion to overlay/ESC dismiss test (was
missing — test always passed regardless of behavior).
- Remove unnecessary vi.resetModules() from afterEach.
- Rewrite overlay test to click Keep editing button (Cancel) to
trigger onOpenChange(false) in jsdom, matching PR #708's pragmatic
pattern for asChild composite components.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cover RemoteBadge and WorkspacePill — the last two rendering components in
components.tsx that were missing direct tests.
- RemoteBadge: ★ REMOTE badge rendering, span element, border-radius 4px,
palette color/background application, dark/light difference
- WorkspacePill: brand text, count display, LIVE indicator, string count,
border-radius pill shape, dark/light background variants
Total mobile test count now: 104 passing (was 90).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Restructure SearchDialog so the backdrop div is separate from the dialog
container. The outer div previously served as both backdrop and centering
wrapper, which made it impossible to add accessibility attributes
(aria-hidden="true") without hiding the dialog content from screen
readers.
New structure mirrors ConfirmDialog and KeyboardShortcutsDialog:
- Backdrop: aria-hidden="true", cursor-pointer, click-to-dismiss
- Dialog: role="dialog", aria-modal, aria-label, relative z-[71]
Also removes the now-unnecessary stopPropagation() on the dialog div.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Discovered during WCAG audit: useKeyboardShortcuts.ts had an
isModalOpen() guard for Arrow-key move/resize shortcuts but NOT for
Escape, Enter, Cmd+]/[, or Z. When a modal dialog (role="dialog",
aria-modal="true") is open, pressing Escape cleared the canvas
selection (because the canvas handler fired before the dialog's own
Escape handler), and Enter/Cmd+[/]/Z could interfere with dialog
interactions.
Fix: add isModalOpen() guard to all four shortcut groups, extracted
as a shared helper. Also added 4 new test cases covering the
modal-dialog guard for Esc, Enter, Cmd+[/], and Z.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
+ form-inputs.test.tsx: 35 cases across TextInput, NumberInput, Toggle,
TagList, and Section — pure presentational components in the Config tab.
Uses vi.hoisted() patterns from established suite; no jest-dom matchers.
+ form-inputs.tsx (Section): add aria-expanded + aria-controls to the
collapsible toggle button for WCAG 2.1 AA compliance. The content div
gets a stable id derived from the title; aria-controls links button to
region. Indicator span gains aria-hidden="true" (decorative only).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- role=group with aria-label containing service label
- Service icon aria-hidden, correct emoji per service name
- Count label: "1 key" vs "N keys"
- Renders SecretRow for each secret
- Header and rows div structure
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds Vitest coverage for AttachmentImage — inline image thumbnail with
click-to-fullscreen lightbox. Covers: loading skeleton (240×180),
ready state with blob URL, tone=user/agent border classes, lightbox
open/close on click and Escape, AttachmentChip error fallback, img
onError transition to chip, external URI direct href (no fetch), and
blob URL cleanup on unmount.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
12 passing: loading spinner, empty state, token list rendering,
each token's prefix/age/Revoke button, API URL correctness, revoke
confirm + cancel dialogs, new-token creation + dismiss, create error,
network error banner.
Root bug fixed: confirm button search was unscoped — when the dialog
opened, two "Revoke" buttons existed (tok2's row + dialog confirm);
find() returned tok2's button first. Scoped the search to
document.querySelector('[role="dialog"]') to hit the correct target.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>