diff --git a/app/katalog/[id]/page.tsx b/app/katalog/[id]/page.tsx index 33eedbe..6afd5ba 100644 --- a/app/katalog/[id]/page.tsx +++ b/app/katalog/[id]/page.tsx @@ -231,6 +231,19 @@ function DatasetView({ d, tab, setTab }: { d: Dataset; tab: TabKey; setTab: (k: const deposit = Math.round(d.price / 2); const remainder = d.price - deposit; + function handleTabKey(e: React.KeyboardEvent, idx: number) { + let next = -1; + if (e.key === "ArrowRight") next = (idx + 1) % TABS.length; + else if (e.key === "ArrowLeft") next = (idx - 1 + TABS.length) % TABS.length; + else if (e.key === "Home") next = 0; + else if (e.key === "End") next = TABS.length - 1; + if (next !== -1) { + e.preventDefault(); + setTab(TABS[next].key); + document.getElementById(`katalog-tab-${TABS[next].key}`)?.focus(); + } + } + return ( <> {/* breadcrumb */} @@ -279,6 +292,7 @@ function DatasetView({ d, tab, setTab }: { d: Dataset; tab: TabKey; setTab: (k: aria-selected={active} aria-controls={`katalog-panel-${tb.key}`} onClick={() => setTab(tb.key)} + onKeyDown={(e) => handleTabKey(e, TABS.findIndex((t) => t.key === tb.key))} className="flex-1 bg-background px-4 py-3.5 font-mono text-[11px] uppercase tracking-[0.1em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background" style={{ backgroundColor: active ? "var(--foreground)" : "var(--background)", diff --git a/app/order/[id]/validera/page.tsx b/app/order/[id]/validera/page.tsx index 4f0ddf2..3376b99 100644 --- a/app/order/[id]/validera/page.tsx +++ b/app/order/[id]/validera/page.tsx @@ -77,6 +77,19 @@ export default function ValidationPage() { const toggleDest = (d: string) => setDests((p) => (p.includes(d) ? p.filter((x) => x !== d) : [...p, d])); + function handleTabKey(e: React.KeyboardEvent, idx: number) { + let next = -1; + if (e.key === "ArrowRight") next = (idx + 1) % TABS.length; + else if (e.key === "ArrowLeft") next = (idx - 1 + TABS.length) % TABS.length; + else if (e.key === "Home") next = 0; + else if (e.key === "End") next = TABS.length - 1; + if (next !== -1) { + e.preventDefault(); + setTab(TABS[next].key); + document.getElementById(`validera-tab-${TABS[next].key}`)?.focus(); + } + } + async function approve() { try { const r = await fetch(`/api/orders/${id}`, { @@ -130,6 +143,7 @@ export default function ValidationPage() { aria-selected={tab === tb.key} aria-controls={`validera-panel-${tb.key}`} onClick={() => setTab(tb.key)} + onKeyDown={(e) => handleTabKey(e, i)} className="group relative -mb-px px-5 py-3.5 font-mono text-[11px] uppercase tracking-[0.12em] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background" style={{ color: tab === tb.key ? "var(--foreground)" : "var(--muted-foreground)" }} >