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

38.94% Statements 37/95
100% Branches 0/0
100% Functions 0/0
38.94% Lines 37/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
    961x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x

    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x

    1x
    1x
    1x
    1x
    1x

    1x
    1x
     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"