interface TabOption<T extends string> { id: T; label: string }

interface Props<T extends string> {
  tabs: Array<TabOption<T>>;
  active: T;
  onChange: (tab: T) => void;
  ariaLabel: string;
  className?: string;
}

export function TabList<T extends string>({ tabs, active, onChange, ariaLabel, className = "" }: Props<T>) {
  const move = (event: React.KeyboardEvent<HTMLDivElement>) => {
    if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
    event.preventDefault();
    const index = tabs.findIndex((entry) => entry.id === active);
    const next = (index + (event.key === "ArrowRight" ? 1 : -1) + tabs.length) % tabs.length;
    onChange(tabs[next].id);
    event.currentTarget.querySelectorAll<HTMLButtonElement>('[role="tab"]')[next]?.focus();
  };
  return <div className={className} role="tablist" aria-label={ariaLabel} onKeyDown={move}>
    {tabs.map((entry) => <button key={entry.id} type="button" role="tab" tabIndex={active === entry.id ? 0 : -1} aria-selected={active === entry.id} className={active === entry.id ? "active" : ""} onClick={() => onChange(entry.id)}>{entry.label}</button>)}
  </div>;
}
