geraete/components/ui/Tabs.tsx
2025-11-14 11:28:24 +01:00

63 lines
1.5 KiB
TypeScript

// /components/ui/Tabs.tsx
'use client'
import * as React from 'react'
export type TabItem = {
id: string
label: string
}
export type TabsProps = {
tabs: TabItem[]
defaultTabId?: string
onChange?(id: string): void
className?: string
}
export function Tabs({ tabs, defaultTabId, onChange, className }: TabsProps) {
const [activeId, setActiveId] = React.useState(
defaultTabId ?? (tabs[0]?.id ?? ''),
)
const handleClick = (id: string) => {
setActiveId(id)
onChange?.(id)
}
return (
<div
className={[
'border-b border-gray-200 dark:border-white/10',
className,
]
.filter(Boolean)
.join(' ')}
>
<nav className="-mb-px flex space-x-8" aria-label="Tabs">
{tabs.map((tab) => {
const isActive = tab.id === activeId
return (
<button
key={tab.id}
type="button"
onClick={() => handleClick(tab.id)}
className={[
'whitespace-nowrap border-b-2 px-1 pb-3 pt-2 text-sm/6 font-semibold transition-colors',
isActive
? 'border-indigo-500 text-indigo-600 dark:border-indigo-400 dark:text-indigo-300'
: 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200',
]
.filter(Boolean)
.join(' ')}
>
{tab.label}
</button>
)
})}
</nav>
</div>
)
}