/** * Copyright (c) TonTech. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ import { createContext, useCallback, useContext, useState } from 'react'; import type { ComponentProps, FC, ReactNode } from 'react'; import clsx from 'clsx'; import styles from './tabs.module.css'; interface TabsContextValue { value: string; onValueChange: (value: string) => void; } const TabsContext = createContext({ value: '', onValueChange: () => {}, }); export interface TabsProps extends ComponentProps<'div'> { value?: string; defaultValue?: string; onValueChange?: (value: string) => void; children: ReactNode; } export const Tabs: FC = ({ value: controlledValue, defaultValue = '', onValueChange, children, className, ...props }) => { const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue); const isControlled = controlledValue !== undefined; const currentValue = isControlled ? controlledValue : uncontrolledValue; const handleValueChange = useCallback( (newValue: string) => { if (!isControlled) { setUncontrolledValue(newValue); } onValueChange?.(newValue); }, [isControlled, onValueChange], ); return (
{children}
); }; export interface TabsListProps extends ComponentProps<'div'> { children: ReactNode; } export const TabsList: FC = ({ children, className, ...props }) => { return (
{children}
); }; export interface TabsTriggerProps extends ComponentProps<'button'> { value: string; children: ReactNode; } export const TabsTrigger: FC = ({ value, children, className, ...props }) => { const ctx = useContext(TabsContext); const isActive = ctx.value === value; return ( ); }; export interface TabsContentProps extends ComponentProps<'div'> { value: string; children: ReactNode; } export const TabsContent: FC = ({ value, children, className, ...props }) => { const ctx = useContext(TabsContext); const isActive = ctx.value === value; if (!isActive) return null; return (
{children}
); };