'use client'; import { useRef, type KeyboardEvent, type ReactNode } from 'react'; import { cn } from './cn'; import { focusRing, motionColors } from './tokens'; export const segmentedGroupClass = 'grid gap-1 rounded-full border border-line bg-surface-sunken p-1'; export const segmentedButtonClass = (active: boolean) => cn( 'rounded-full px-2.5 py-1.5 text-xs font-medium', focusRing, motionColors, active ? 'bg-accent text-background' : 'text-soft hover:bg-accent-wash hover:text-foreground', ); export function SegmentedControl({ value, options, onChange, ariaLabel, className, }: { value: T; options: Array<{ value: T; label: ReactNode }>; onChange: (value: T) => void; ariaLabel: string; className?: string; }) { const buttonRefs = useRef>([]); const focusOption = (index: number) => { const option = options[index]; if (!option) return; onChange(option.value); buttonRefs.current[index]?.focus(); }; const handleKeyDown = (event: KeyboardEvent, index: number) => { switch (event.key) { case 'ArrowLeft': case 'ArrowUp': event.preventDefault(); focusOption((index - 1 + options.length) % options.length); break; case 'ArrowRight': case 'ArrowDown': event.preventDefault(); focusOption((index + 1) % options.length); break; case 'Home': event.preventDefault(); focusOption(0); break; case 'End': event.preventDefault(); focusOption(options.length - 1); break; default: break; } }; return (
{options.map((option, index) => { const active = value === option.value; return ( ); })}
); }