# All files / src/components/ui tabs.tsx

0% Statements 0/95
0% Branches 0/1
0% Functions 0/1
0% Lines 0/95

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96

     import { ComponentProps, forwardRef, createContext, useContext, useState } from "react"
    import { cn } from "@/lib/utils"

    interface TabsContextValue {
      value?: string
      onValueChange?: (value: string) => void
    }

    const TabsContext = createContext<TabsContextValue | null>(null)

    interface TabsProps extends ComponentProps<"div"> {
      value?: string
      onValueChange?: (value: string) => void
      defaultValue?: string
    }

    export const Tabs = forwardRef<HTMLDivElement, TabsProps>(
      ({ className, value: controlledValue, onValueChange, defaultValue, children, ...props }, ref) => {
        const [internalValue, setInternalValue] = useState(defaultValue)
        const value = controlledValue ?? internalValue

        const handleValueChange = (newValue: string) => {
          setInternalValue(newValue)
          onValueChange?.(newValue)
        }

        return (
          <TabsContext.Provider value={{ value, onValueChange: handleValueChange }}>
            <div ref={ref} className={cn("mat-mdc-tab-group", className)} {...props}>
              {children}
            </div>
          </TabsContext.Provider>
        )
      }
    )
    Tabs.displayName = "Tabs"

    export const TabsList = forwardRef<HTMLDivElement, ComponentProps<"div">>(
      ({ className, ...props }, ref) => (
        <div ref={ref} className={cn("mat-mdc-tab-header", className)} {...props} />
      )
    )
    TabsList.displayName = "TabsList"

    export const TabsTrigger = forwardRef<HTMLButtonElement, ComponentProps<"button"> & { value: string }>(
      ({ className, value, children, ...props }, ref) => {
        const context = useContext(TabsContext)
        const isActive = context?.value === value

        return (
          <button
            ref={ref}
            className={cn(
              "mdc-tab",
              "mat-mdc-tab",
              isActive && "mdc-tab--active",
              className
            )}
            onClick={() => context?.onValueChange?.(value)}
            {...props}
          >
            <span className="mdc-tab__content">
              <span className="mdc-tab__text-label">{children}</span>
            </span>
            <span className="mdc-tab-indicator">
              <span className="mdc-tab-indicator__content mdc-tab-indicator__content--underline" />
            </span>
            <span className="mdc-tab__ripple" />
          </button>
        )
      }
    )
    TabsTrigger.displayName = "TabsTrigger"

    export const TabsContent = forwardRef<HTMLDivElement, ComponentProps<"div"> & { value: string }>(
      ({ className, value, children, ...props }, ref) => {
        const context = useContext(TabsContext)
        const isActive = context?.value === value

        if (!isActive) return null

        return (
          <div
            ref={ref}
            className={cn("mat-mdc-tab-body", "mat-mdc-tab-body-active", className)}
            {...props}
          >
            <div className="mat-mdc-tab-body-content">
              {children}
            </div>
          </div>
        )
      }
    )
    TabsContent.displayName = "TabsContent"