Files
cv-maker/components/ui/Tabs.tsx
T
2026-09-16 21:34:09 +02:00

56 lines
1.7 KiB
TypeScript

"use client";
import { type KeyboardEvent } from "react";
export interface TabItem<T extends string> {
id: T;
label: string;
}
interface TabsProps<T extends string> {
items: TabItem<T>[];
activeId: T;
onChange: (id: T) => void;
}
export function Tabs<T extends string>({ items, activeId, onChange }: TabsProps<T>) {
function handleKeyDown(event: KeyboardEvent<HTMLButtonElement>) {
const currentIndex = items.findIndex((item) => item.id === activeId);
if (event.key === "ArrowRight") {
event.preventDefault();
const next = items.at((currentIndex + 1) % items.length);
if (next) onChange(next.id);
} else if (event.key === "ArrowLeft") {
event.preventDefault();
const prev = items.at((currentIndex - 1 + items.length) % items.length);
if (prev) onChange(prev.id);
}
}
return (
<div role="tablist" aria-label="Sections du CV" className="flex flex-wrap gap-1">
{items.map((item) => {
const selected = item.id === activeId;
return (
<button
key={item.id}
role="tab"
id={`tab-${item.id}`}
aria-selected={selected}
aria-controls={`panel-${item.id}`}
tabIndex={selected ? 0 : -1}
onClick={() => onChange(item.id)}
onKeyDown={handleKeyDown}
className={`rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent ${
selected
? "bg-accent text-white"
: "border border-border bg-white text-muted hover:text-ink"
}`}
>
{item.label}
</button>
);
})}
</div>
);
}