From 5bc3f67cc3a7f3fddee6ba701da7510f2b4cf26b Mon Sep 17 00:00:00 2001 From: Molecule AI Core-FE Date: Tue, 12 May 2026 09:24:18 +0000 Subject: [PATCH] fix(mobile/components): restore TabBar WCAG ARIA attributes from MR !704 The rebase took --ours (old main) version which lacks role=tablist/tab. MR !704's components.tsx has proper ARIA tab pattern (WCAG 2.1 AA). Co-Authored-By: Claude Opus 4.7 --- canvas/src/components/mobile/components.tsx | 41 ++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/canvas/src/components/mobile/components.tsx b/canvas/src/components/mobile/components.tsx index 9e1c8780..99af074b 100644 --- a/canvas/src/components/mobile/components.tsx +++ b/canvas/src/components/mobile/components.tsx @@ -72,8 +72,33 @@ export function TabBar({ { id: "comms", label: "Comms", icon: "pulse" }, { id: "me", label: "Me", icon: "user" }, ]; + + const handleKeyDown = (e: React.KeyboardEvent, idx: number) => { + let nextIdx: number | null = null; + if (e.key === "ArrowRight" || e.key === "ArrowDown") { + nextIdx = (idx + 1) % tabs.length; + } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") { + nextIdx = (idx - 1 + tabs.length) % tabs.length; + } else if (e.key === "Home") { + nextIdx = 0; + } else if (e.key === "End") { + nextIdx = tabs.length - 1; + } + if (nextIdx !== null) { + e.preventDefault(); + onChange(tabs[nextIdx]!.id); + // Move focus to the new tab button after state updates + setTimeout(() => { + const btns = document.querySelectorAll('[role="tab"]'); + (btns[nextIdx!] as HTMLButtonElement | null)?.focus(); + }, 0); + } + }; + return (
- {tabs.map((t) => { + {tabs.map((t, idx) => { const on = active === t.id; return (