{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "checkbox", "type": "registry:ui", "title": "Checkbox", "description": "A customizable checkbox component", "dependencies": [ "tailwind-variants", "clsx", "tailwind-merge", "@base-ui/react" ], "registryDependencies": [ "classes" ], "files": [ { "path": "src/registry/pure-ui/ui/checkbox/index.tsx", "content": "\"use client\";\r\n\r\nimport React, { createContext, useContext, useEffect, useState } from \"react\";\r\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react\";\r\nimport { tv, type VariantProps } from \"tailwind-variants\";\r\n\r\nimport { cn } from \"@/lib/classes\";\r\n\r\nconst checkboxRootStyles = tv({\r\n base: [\r\n `group size-7 relative inline-flex items-center justify-center shrink-0 overflow-hidden outline-hidden focus:outline-hidden focus-visible:outline-hidden cursor-pointer focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-ring focus-visible:ring-offset-background`,\r\n `data-disabled:cursor-not-allowed data-disabled:grayscale data-disabled:scale-100 data-disabled:opacity-50`,\r\n `before:content-[''] before:absolute before:border-2 before:inset-0 before:border-border not-data-disabled:hover:before:bg-secondary/60`,\r\n `after:content-[''] after:absolute after:inset-0 after:bg-primary data-unchecked:after:scale-50 data-unchecked:after:opacity-0 after:origin-center data-checked:after:scale-100 data-checked:after:opacity-100`,\r\n ``,\r\n ],\r\n variants: {\r\n size: {\r\n sm: \"size-4.5\",\r\n default: \"size-5\",\r\n lg: \"size-6\",\r\n },\r\n radius: {\r\n none: \"rounded-none before:rounded-none after:rounded-none\",\r\n sm: \"rounded-[6px] before:rounded-[6px] after:rounded-[6px]\",\r\n default: \"rounded-[7.2px] before:rounded-[7.2px] after:rounded-[7.2px]\",\r\n lg: \"rounded-[8.4px] before:rounded-[8.4px] after:rounded-[8.4px]\",\r\n full: \"rounded-full before:rounded-full after:rounded-full\",\r\n },\r\n reduceMotion: {\r\n true: \"transition-none before:transition-none after:transition-none\",\r\n false:\r\n \"before:transition-colors transition-transform after:[transition:0.2s_linear] after:[transition-property:opacity,scale,transform]\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"default\",\r\n radius: \"default\",\r\n reduceMotion: false,\r\n },\r\n});\r\n\r\nconst checkboxIndicatorStyles = tv({\r\n base: [\r\n `relative z-10 flex items-center justify-center data-unchecked:opacity-0 data-checked:opacity-100 text-primary-foreground transition-opacity pointer-events-none`,\r\n ],\r\n variants: {\r\n size: {\r\n sm: \"w-2.5 h-2.5\",\r\n default: \"w-3 h-3\",\r\n lg: \"w-4 h-4\",\r\n },\r\n reduceMotion: {\r\n true: \"transition-none\",\r\n false: \"transition-opacity\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"default\",\r\n reduceMotion: false,\r\n },\r\n});\r\n\r\ninterface CheckboxRootProps\r\n extends React.ComponentProps,\r\n VariantProps {\r\n reduceMotion?: boolean;\r\n}\r\n\r\ninterface CheckboxContextType {\r\n checked: boolean;\r\n onCheckedChange: CheckboxRootProps[\"onCheckedChange\"];\r\n indeterminate: boolean | undefined;\r\n size: VariantProps[\"size\"];\r\n reduceMotion?: boolean; // Add this\r\n}\r\n\r\nconst CheckboxContext = createContext(\r\n undefined\r\n);\r\n\r\nconst useCheckbox = () => {\r\n const context = useContext(CheckboxContext);\r\n if (!context) {\r\n throw new Error(\"useCheckbox must be used within a CheckboxProvider\");\r\n }\r\n return context;\r\n};\r\n\r\nfunction CheckboxRoot({\r\n checked,\r\n defaultChecked,\r\n onCheckedChange,\r\n indeterminate,\r\n className,\r\n reduceMotion = false,\r\n size = \"default\",\r\n radius = \"default\",\r\n ...rest\r\n}: CheckboxRootProps) {\r\n const [isChecked, setIsChecked] = useState(\r\n checked ?? defaultChecked ?? false\r\n );\r\n\r\n useEffect(() => {\r\n if (checked !== undefined) setIsChecked(checked);\r\n }, [checked]);\r\n\r\n const handleCheckedChange: CheckboxRootProps[\"onCheckedChange\"] = (\r\n checked,\r\n eventDetails\r\n ) => {\r\n if (indeterminate && !onCheckedChange) {\r\n return;\r\n }\r\n\r\n setIsChecked(checked);\r\n onCheckedChange?.(checked, eventDetails);\r\n };\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface CheckboxIconProps extends React.ComponentProps<\"svg\"> {\r\n checked: boolean;\r\n indeterminate: boolean | undefined;\r\n reduceMotion?: boolean;\r\n}\r\n\r\nfunction CheckboxIcon(props: CheckboxIconProps) {\r\n const { checked, indeterminate, reduceMotion, ...rest } = props;\r\n\r\n if (indeterminate) {\r\n return (\r\n \r\n \r\n \r\n );\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\ninterface CheckboxIndicatorProps\r\n extends React.ComponentProps {\r\n icon?: React.ReactNode | ((props: CheckboxIconProps) => React.ReactNode);\r\n}\r\n\r\nfunction CheckboxIndicator({\r\n className,\r\n icon = CheckboxIcon,\r\n children,\r\n ...rest\r\n}: CheckboxIndicatorProps) {\r\n const { checked, indeterminate, size, reduceMotion = false } = useCheckbox();\r\n\r\n return (\r\n \r\n {children ?? (\r\n \r\n )}\r\n \r\n );\r\n}\r\n\r\ninterface CheckboxProps\r\n extends React.ComponentProps,\r\n VariantProps {\r\n reduceMotion?: boolean;\r\n}\r\n\r\nfunction Checkbox({\r\n className,\r\n reduceMotion,\r\n children,\r\n ...rest\r\n}: CheckboxProps) {\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n}\r\n\r\nexport { Checkbox, CheckboxRoot, CheckboxIndicator };\r\n", "type": "registry:ui", "target": "components/ui/checkbox.tsx" } ] }