From 6645c2c636361ad37d34259e97068b55a4ca81b8 Mon Sep 17 00:00:00 2001 From: Molecule AI Core-FE Date: Sun, 17 May 2026 02:15:33 +0000 Subject: [PATCH] fix(canvas): WCAG focus-visible + aria-hidden decorative elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WCAG 2.4.7 (focus-visible) and WCAG 1.1.1 (decorative elements) on components not yet covered by prior accessibility sprints: Focus-visible rings: - AttachmentViews: Remove button + Download button - ChatTab: Enable agent-chat button aria-hidden on decorative emoji/icon spans: - BatchActionBar: ✕ close button - CommunicationOverlay: ↗↙ decorative chars (also adds role=complementary + aria-label) - ConversationTraceModal: ✕ close icon - OrgImportPreflightModal: ✓ checkmark indicators - WorkspaceNode: ↻ restart indicator - ActivityTab: filter icons, status icons, expand/collapse chevrons - MemoryTab: expand/collapse chevron - ScheduleTab: ⏲ clock emoji - FileEditor: 📄 placeholder emoji, file type icons - FileTree: directory chevrons (▼/▶), file type icons Keyboard navigation: - FileTree: role=button + tabIndex=0 + onKeyDown (Enter/Space) on directory and file rows Co-Authored-By: Claude Opus 4.7 --- canvas/src/components/BatchActionBar.tsx | 2 +- .../src/components/CommunicationOverlay.tsx | 6 ++++- .../src/components/ConversationTraceModal.tsx | 2 +- .../components/OrgImportPreflightModal.tsx | 4 ++-- canvas/src/components/WorkspaceNode.tsx | 2 +- canvas/src/components/tabs/ActivityTab.tsx | 6 ++--- canvas/src/components/tabs/ChatTab.tsx | 4 ++-- .../components/tabs/FilesTab/FileEditor.tsx | 4 ++-- .../src/components/tabs/FilesTab/FileTree.tsx | 24 ++++++++++++++++--- canvas/src/components/tabs/MemoryTab.tsx | 2 +- canvas/src/components/tabs/ScheduleTab.tsx | 2 +- .../components/tabs/chat/AttachmentViews.tsx | 5 ++-- 12 files changed, 43 insertions(+), 20 deletions(-) diff --git a/canvas/src/components/BatchActionBar.tsx b/canvas/src/components/BatchActionBar.tsx index 3a25c33b3..773ce9dae 100644 --- a/canvas/src/components/BatchActionBar.tsx +++ b/canvas/src/components/BatchActionBar.tsx @@ -149,7 +149,7 @@ export function BatchActionBar() { title="Clear selection (Escape)" className="p-1.5 rounded-lg text-[12px] text-ink-mid hover:text-ink hover:bg-surface-card/50 transition-colors disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/50" > - ✕ + ); diff --git a/canvas/src/components/CommunicationOverlay.tsx b/canvas/src/components/CommunicationOverlay.tsx index 11198d21e..80b111b0b 100644 --- a/canvas/src/components/CommunicationOverlay.tsx +++ b/canvas/src/components/CommunicationOverlay.tsx @@ -217,7 +217,11 @@ export function CommunicationOverlay() { } return ( -
+
Communications ({comms.length}) diff --git a/canvas/src/components/ConversationTraceModal.tsx b/canvas/src/components/ConversationTraceModal.tsx index 61a834c06..ccc874dde 100644 --- a/canvas/src/components/ConversationTraceModal.tsx +++ b/canvas/src/components/ConversationTraceModal.tsx @@ -125,7 +125,7 @@ export function ConversationTraceModal({ open, workspaceId: _workspaceId, onClos aria-label="Close conversation trace" className="text-ink-mid hover:text-ink-mid text-lg px-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-surface" > - ✕ +
diff --git a/canvas/src/components/OrgImportPreflightModal.tsx b/canvas/src/components/OrgImportPreflightModal.tsx index 6bc4ea480..4b5f8b830 100644 --- a/canvas/src/components/OrgImportPreflightModal.tsx +++ b/canvas/src/components/OrgImportPreflightModal.tsx @@ -406,7 +406,7 @@ function StrictEnvRow({ {envKey} {configured ? ( - ✓ set + ) : ( <> {isConfigured ? ( - ✓ set + ) : ( <> >) }} className="flex items-center gap-1.5 mt-1 w-full bg-accent/10 px-2 py-1 rounded-md border border-accent/40 hover:bg-accent/20 transition-colors text-left focus-visible:ring-2 focus-visible:ring-accent/70 focus-visible:outline-none" > - + Restart to apply changes )} diff --git a/canvas/src/components/tabs/ActivityTab.tsx b/canvas/src/components/tabs/ActivityTab.tsx index 092a58bc9..c34f1b8c5 100644 --- a/canvas/src/components/tabs/ActivityTab.tsx +++ b/canvas/src/components/tabs/ActivityTab.tsx @@ -145,7 +145,7 @@ export function ActivityTab({ workspaceId }: Props) { : "text-ink-mid hover:text-ink-mid hover:bg-surface-card/60" }`} > - {f.icon} {f.label} + {f.label} ))}
@@ -260,7 +260,7 @@ function ActivityRow({ )} - + @@ -274,7 +274,7 @@ function ActivityRow({ {formatTime(entry.created_at)} - +
diff --git a/canvas/src/components/tabs/ChatTab.tsx b/canvas/src/components/tabs/ChatTab.tsx index d6a9b85ca..5aa1410e7 100644 --- a/canvas/src/components/tabs/ChatTab.tsx +++ b/canvas/src/components/tabs/ChatTab.tsx @@ -383,7 +383,7 @@ function MyChatPanel({ workspaceId, data }: Props) { // ignore — user will see no change and can retry } }} - className="px-2 py-0.5 text-[10px] font-medium bg-accent/10 hover:bg-accent/20 text-accent rounded border border-accent/30 transition-colors shrink-0" + className="px-2 py-0.5 text-[10px] font-medium bg-accent/10 hover:bg-accent/20 text-accent rounded border border-accent/30 transition-colors shrink-0 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 focus-visible:ring-offset-zinc-900" > Enable @@ -582,7 +582,7 @@ function MyChatPanel({ workspaceId, data }: Props) {
Processing with {runtimeDisplayName(data.runtime)}...
{activityLog.map((line, i) => ( -
◇ {line}
+
{line}
))}
)} diff --git a/canvas/src/components/tabs/FilesTab/FileEditor.tsx b/canvas/src/components/tabs/FilesTab/FileEditor.tsx index db5301c5d..e757c41e2 100644 --- a/canvas/src/components/tabs/FilesTab/FileEditor.tsx +++ b/canvas/src/components/tabs/FilesTab/FileEditor.tsx @@ -35,7 +35,7 @@ export function FileEditor({ return (
-
📄
+

Select a file to edit

@@ -47,7 +47,7 @@ export function FileEditor({ {/* File header */}
- {getIcon(selectedFile, false)} + {selectedFile} {isDirty && modified}
diff --git a/canvas/src/components/tabs/FilesTab/FileTree.tsx b/canvas/src/components/tabs/FilesTab/FileTree.tsx index 0e32bc455..2c5800878 100644 --- a/canvas/src/components/tabs/FilesTab/FileTree.tsx +++ b/canvas/src/components/tabs/FilesTab/FileTree.tsx @@ -199,6 +199,9 @@ function TreeItem({ return (
onToggleDir(node.path)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onToggleDir(node.path); + } + }} onContextMenu={(e) => openContextMenu(e, node)} {...dragProps} > - {isLoading ? "…" : expanded ? "▼" : "▶"} - 📁 + + {node.name}
diff --git a/canvas/src/components/tabs/ScheduleTab.tsx b/canvas/src/components/tabs/ScheduleTab.tsx index b25fbf1d6..f0af58709 100644 --- a/canvas/src/components/tabs/ScheduleTab.tsx +++ b/canvas/src/components/tabs/ScheduleTab.tsx @@ -313,7 +313,7 @@ export function ScheduleTab({ workspaceId }: Props) {
{schedules.length === 0 && !showForm ? (
-
+
No schedules yet
Add a schedule to run tasks automatically — daily scans, periodic reports, standup reminders. diff --git a/canvas/src/components/tabs/chat/AttachmentViews.tsx b/canvas/src/components/tabs/chat/AttachmentViews.tsx index 0d01a425d..7a2a47ea2 100644 --- a/canvas/src/components/tabs/chat/AttachmentViews.tsx +++ b/canvas/src/components/tabs/chat/AttachmentViews.tsx @@ -33,7 +33,7 @@ export function PendingAttachmentPill({