Checkbox

A control that allows the user to toggle between checked and not checked.

As a private project, only admins could rewrite

import Checkbox from "@tailus-ui/Checkbox";
import Label from "@tailus-ui/Label";
import Aligner from "@tailus-ui/Aligner";
import { Caption } from "@tailus-ui/typography";
import { CheckIcon } from "lucide-react";

export const MyComponent = () => {
    return (
        <Aligner className="max-w-md">
            <Checkbox.Root id="c1">
                <Checkbox.Indicator asChild>
                    <CheckIcon className="size-3.5" strokeWidth={3} />
                </Checkbox.Indicator>
            </Checkbox.Root>
            <Label htmlFor="c1">
                Create a private project
            </Label>
            <Caption as="p" size="sm" className="row-start-2 col-start-2">As a private project, only admins could rewrite</Caption>
        </Aligner>
    );
}

Installation

Install the primitive and Copy-Paste the component code in a .tsx file.

npm install @radix-ui/react-checkbox
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import React, {forwardRef} from "react";
import { checkbox, fancyCheckbox, type CheckboxProps as CheckboxVariants } from "@tailus/themer"

export interface CheckboxProps extends CheckboxVariants {
  className?: string;
  fancy?: boolean;
}

const CheckboxRoot = forwardRef<
  React.ElementRef<typeof CheckboxPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & CheckboxProps
  >(({ className, intent, fancy, ...props }: CheckboxProps, forwardedRef) => {
    const classes = fancy ? fancyCheckbox({ intent, className }) : checkbox({ intent, className });
    return(
      <CheckboxPrimitive.Root
        ref={forwardedRef}
        className={classes}
        {...props}
      />
    )
});

const CheckboxIndicator = CheckboxPrimitive.Indicator;

export {
  CheckboxRoot,
  CheckboxIndicator,
};

export default {
  Root: CheckboxRoot,
  Indicator : CheckboxIndicator
}

Add Aligner component

Useful for aligning Checkbox, RadioGroup, and Switch components with their associated Label and Caption

import React from "react"
import { aligner, type AlignerProps as AlignerVariants } from "@tailus/themer"

export interface AlignerProps extends React.HTMLAttributes<HTMLDivElement>, AlignerVariants {}

export const Aligner = React.forwardRef<HTMLDivElement, AlignerProps>(
    ({className, children, fromRight, ...props }, forwardedRef) => {
        return (
            <div
                className={aligner({ fromRight, className})}
                ref={forwardedRef}
                children={children}
                {...props}
            />
        )
    })

export default Aligner;

Usage

Import all the parts and build your Checkbox.

import Checkbox from "@tailus-ui/Checkbox";
import Label from "@tailus-ui/Label";
const MyComponent = () => (
    <div>
        <Checkbox.Root id="c1">
            <Checkbox.Indicator asChild>
                <CheckIcon />
            </Checkbox.Indicator>
        </Checkbox.Root>
        <Label htmlFor="c1">Checkbox</Label>
    </div>
)

Reference

Checkbox

The Checkbox component has the following additional props.

Prop
Type
Default
intent
enum
primary
fancy
boolean
false

Aligner

The Aligner component has the following props.

Prop
Type
Default
fromRight
boolean
false

Examples

Disabled

As a private project, only admins could rewrite

import Checkbox from "@tailus-ui/Checkbox";
import Label from "@tailus-ui/Label";
import Aligner from "@tailus-ui/Aligner";
import { Caption } from "@tailus-ui/typography";
import { CheckIcon } from "lucide-react";

export const MyComponent = () => {
    return (
        <Aligner className="max-w-md">
            <Checkbox.Root id="c2" disabled>
                <Checkbox.Indicator asChild>
                    <CheckIcon className="size-3.5" strokeWidth={3} />
                </Checkbox.Indicator>
            </Checkbox.Root>
            <Label htmlFor="c2">
                Create a private project
            </Label>
            <Caption as="p" size="sm" className="row-start-2 col-start-2">As a private project, only admins could rewrite</Caption>
        </Aligner>
    );
}

Indeterminate

As a private project, only admins could rewrite

import { useState } from 'react';
import Checkbox from "@tailus-ui/Checkbox";
import Label from "@tailus-ui/Label";
import Aligner from "@tailus-ui/Aligner";
import { Caption } from "@tailus-ui/typography";
import { CheckIcon, Minus } from "lucide-react";

export const Indeterminate = () => {
    const [checked, setChecked] = useState<boolean | "indeterminate">('indeterminate');

    const handleCheckboxChange = () => {
        if (checked === "indeterminate") {
            setChecked(true);
        } else if (checked === true) {
            setChecked(false);
        } else if (checked === false) {
            setChecked(true);
        }
    };

    return (
        <Aligner className="max-w-md">
            <Checkbox.Root checked={checked} id="c3" onClick={handleCheckboxChange}>
                <Checkbox.Indicator asChild>
                    {
                        checked === "indeterminate" ?
                            <Minus className="size-3.5" strokeWidth={3} /> :
                            <CheckIcon className="size-3.5" strokeWidth={3} />
                    }
                </Checkbox.Indicator>
            </Checkbox.Root>
            <Label htmlFor="c3">
                Create a private project
            </Label>
            <Caption as="p" size="sm" className="row-start-2 col-start-2">As a private project, only admins could rewrite</Caption>
        </Aligner>
    );
}