"use client" import { Check } from "lucide-react" import * as React from "react" import { cn } from "../../../lib/utils" // ───────────────────────────────────────────────────────────────────────────── // Types // ───────────────────────────────────────────────────────────────────────────── interface CheckboxGroupContextValue { value: string[] onValueChange: (value: string[]) => void disabled: boolean name?: string } const CheckboxGroupContext = React.createContext(null) function useCheckboxGroupContext(consumerName: string) { const context = React.useContext(CheckboxGroupContext) if (!context) { throw new Error(`\`${consumerName}\` must be used within \`CheckboxGroup\``) } return context } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroup Root // ───────────────────────────────────────────────────────────────────────────── interface CheckboxGroupProps extends React.ComponentProps<"div"> { value?: string[] defaultValue?: string[] onValueChange?: (value: string[]) => void disabled?: boolean name?: string } function CheckboxGroup({ className, value: valueProp, defaultValue, onValueChange, disabled = false, name, ...props }: CheckboxGroupProps) { const isControlled = valueProp !== undefined const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue ?? []) const value = isControlled ? valueProp : uncontrolledValue const handleValueChange = React.useCallback( (nextValue: string[]) => { if (!isControlled) { setUncontrolledValue(nextValue) } onValueChange?.(nextValue) }, [isControlled, onValueChange], ) const contextValue = React.useMemo( () => ({ value, onValueChange: handleValueChange, disabled, name, }), [value, handleValueChange, disabled, name], ) return (
) } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroupLabel // ───────────────────────────────────────────────────────────────────────────── function CheckboxGroupLabel({ className, ...props }: React.ComponentProps<"div">) { return (
) } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroupList // ───────────────────────────────────────────────────────────────────────────── interface CheckboxGroupListProps extends React.ComponentProps<"div"> { orientation?: "horizontal" | "vertical" } function CheckboxGroupList({ className, orientation = "vertical", ...props }: CheckboxGroupListProps) { return (
) } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroupItem // ───────────────────────────────────────────────────────────────────────────── interface CheckboxGroupItemProps extends Omit, "value"> { value: string disabled?: boolean } function CheckboxGroupItem({ className, children, value, disabled: disabledProp, onClick, ...props }: CheckboxGroupItemProps) { const context = useCheckboxGroupContext("CheckboxGroupItem") const isDisabled = disabledProp || context.disabled const isChecked = context.value.includes(value) const handleClick = React.useCallback( (event: React.MouseEvent) => { onClick?.(event) if (isDisabled) return const nextValue = isChecked ? context.value.filter((v) => v !== value) : [...context.value, value] context.onValueChange(nextValue) }, [onClick, isDisabled, isChecked, context, value], ) return ( ) } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroupDescription // ───────────────────────────────────────────────────────────────────────────── function CheckboxGroupDescription({ className, ...props }: React.ComponentProps<"div">) { return (
) } // ───────────────────────────────────────────────────────────────────────────── // CheckboxGroupMessage // ───────────────────────────────────────────────────────────────────────────── function CheckboxGroupMessage({ className, ...props }: React.ComponentProps<"div">) { return (
) } export { CheckboxGroup, CheckboxGroupDescription, CheckboxGroupItem, CheckboxGroupLabel, CheckboxGroupList, CheckboxGroupMessage, } export type { CheckboxGroupProps, CheckboxGroupItemProps, CheckboxGroupListProps }