f5b632ed89
Reviewed-on: #397 Co-authored-by: miteruzo <miteruzo@naver.com> Co-committed-by: miteruzo <miteruzo@naver.com>
57 行
1.3 KiB
TypeScript
57 行
1.3 KiB
TypeScript
import type { FC } from 'react'
|
|
|
|
import React, { useState } from 'react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
type TabProps = { name: string
|
|
init?: boolean
|
|
children: React.ReactNode }
|
|
|
|
type Props = {
|
|
children: React.ReactNode
|
|
rightAddon?: React.ReactNode
|
|
}
|
|
|
|
export const Tab = ({ children }: TabProps) => <>{children}</>
|
|
|
|
|
|
const TabGroup: FC<Props> = ({ children, rightAddon }) => {
|
|
const tabs = React.Children.toArray (children) as React.ReactElement<TabProps>[]
|
|
|
|
const [current, setCurrent] = useState<number> (() => {
|
|
const i = tabs.findIndex (tab => tab.props.init)
|
|
return i >= 0 ? i : 0
|
|
})
|
|
|
|
return (
|
|
<div className="mt-4">
|
|
<div className="flex items-center justify-between gap-4">
|
|
<div className="flex min-w-0 gap-4">
|
|
{tabs.map ((tab, i) => (
|
|
<button
|
|
key={i}
|
|
type="button"
|
|
className={cn (
|
|
'bg-transparent p-0 text-left text-[hsl(var(--theme-link))] hover:opacity-85',
|
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
i === current && 'font-bold',
|
|
)}
|
|
onClick={() => {
|
|
setCurrent (i)
|
|
}}>
|
|
{tab.props.name}
|
|
</button>))}
|
|
</div>
|
|
{rightAddon && (
|
|
<div className="shrink-0">
|
|
{rightAddon}
|
|
</div>)}
|
|
</div>
|
|
<div className="mt-2">
|
|
{tabs[current]}
|
|
</div>
|
|
</div>)
|
|
}
|
|
|
|
export default TabGroup
|