Files
CA/frontend/src/components/ui/Segmented.tsx

54 lines
1.3 KiB
TypeScript
Raw Normal View History

import { memo } from 'react';
export const Segmented = memo(function Segmented<T extends string>({
options,
value,
onChange,
size = 'md',
testid,
}: {
options: { value: T; label: string }[];
value: T;
onChange: (v: T) => void;
size?: 'sm' | 'md';
testid?: string;
}): JSX.Element {
const sizeClasses = size === 'sm'
? 'px-2.5 py-0.5 text-xs'
: 'px-3.5 py-1 text-[13px]';
return (
<div
data-testid={testid}
className="inline-flex items-center gap-0.5 rounded-full bg-bg-hover p-0.5"
>
{options.map((opt) => {
const isActive = opt.value === value;
return (
<button
key={opt.value}
type="button"
data-testid={testid ? `${testid}-${opt.value}` : undefined}
onClick={() => onChange(opt.value)}
className={[
'rounded-full font-medium transition-colors',
sizeClasses,
isActive
? 'bg-primary text-white shadow-sm'
: 'text-text-secondary hover:bg-bg-active',
].join(' ')}
>
{opt.label}
</button>
);
})}
</div>
);
}) as <T extends string>(props: {
options: { value: T; label: string }[];
value: T;
onChange: (v: T) => void;
size?: 'sm' | 'md';
testid?: string;
}) => JSX.Element;