Files
TaskPool/web/src/components/ui/tabs.tsx
T
2026-07-26 20:14:42 +08:00

55 lines
1.5 KiB
TypeScript

import { cn } from '@/lib/utils'
export function Tabs({
value,
onValueChange,
items,
className,
size = 'md',
}: {
value: string
onValueChange: (v: string) => void
items: { value: string; label: string }[]
className?: string
size?: 'sm' | 'md' | 'lg'
}) {
const tabSizes = {
sm: 'px-2.5 py-1 text-[12px]',
md: 'px-3.5 py-1.5 text-[13px]',
lg: 'px-4 py-2 text-[14px]',
}
return (
<div
className={cn(
'flex max-w-full items-center gap-1.5 overflow-x-auto rounded-lg border border-[var(--border)] bg-[var(--bg-tertiary)] p-1.5',
'[scrollbar-width:thin]',
className,
)}
role="tablist"
>
{items.map((item) => {
const active = value === item.value
return (
<button
key={item.value}
type="button"
role="tab"
aria-selected={active}
className={cn(
'relative shrink-0 rounded-md font-medium whitespace-nowrap transition-colors',
tabSizes[size],
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]',
active
? 'bg-[var(--bg-secondary)] text-[var(--text-primary)] shadow-[var(--shadow-sm)] ring-1 ring-[var(--border)]'
: 'text-[var(--text-muted)] hover:bg-[var(--bg-hover)]/60 hover:text-[var(--text-secondary)]',
)}
onClick={() => onValueChange(item.value)}
>
{item.label}
</button>
)
})}
</div>
)
}