Vela UI Docsvenizia.ai

Checkbox

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

npx shadcn@latest add @velaui/checkbox
npx shadcn@latest add @velaui/checkbox

Examples

  • Default
  • Basic
  • With description
  • Disabled
  • Error
  • Group

View code

Checkbox · Default

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-default.tsx
import { Checkbox } from "@/components/ui/checkbox";

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox defaultChecked size="sm" />
      <Checkbox defaultChecked size="md" />
      <Checkbox defaultChecked size="lg" />
    </div>
  );
}

View code

Checkbox · Basic

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-basic.tsx
import { Checkbox } from '@/components/ui/checkbox';

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox id='agreeTerms'/>
      <label htmlFor="agreeTerms" className="text-sm font-medium" >Accept Terms & Conditions</label>
    </div>
  )
}

View code

Checkbox · With description

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-with-description.tsx
import { Checkbox } from '@/components/ui/checkbox';

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox id="agreeTermsConditons" className="shrink-0"/>
      <label htmlFor="agreeTermsConditons">
        <p className="text-sm font-medium">Accept Terms & Conditions</p>
        <p className="text-xs text-muted-foreground">By clicking this checkbox, you agree to the terms and conditions</p>
      </label>
    </div>
  )
}

View code

Checkbox · Disabled

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-disabled.tsx
import { Checkbox } from '@/components/ui/checkbox';

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox id='sendNoti' disabled/>
      <label htmlFor="sendNoti" className="text-sm font-medium text-muted-foreground">Enable notifications</label>
    </div>
  )
}

View code

Checkbox · Error

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-error.tsx
import { Checkbox } from '@/components/ui/checkbox';

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox id='error' aria-invalid />
      <label htmlFor="error" className="text-sm font-medium text-destructive" >Accept Terms & Conditions</label>
    </div>
  )
}

View code

Checkbox · Group

Installation

pnpm dlx velaui add @velaui/checkbox
pnpm dlx velaui add @velaui/checkbox

Code

checkbox-group.tsx
import { Checkbox } from '@/components/ui/checkbox';

const itemsOnDesktop = [
  { label: 'Hard Disks', value: 'hardDisks' },
  { label: 'External Disks', value: 'externalDisks' },
  { label: 'CDs, DVDs, and iPods', value: 'cdDvdIpod' },
  { label: 'Connected servers', value: 'connectedServers' },
]

export default function Example() {
  return (
    <div className='flex flex-col gap-y-2'>
      Show these items on the desktop:
      {itemsOnDesktop.map((item) => (
        <div key={item.value} className='flex items-center gap-x-2'>
          <Checkbox id={item.value} name={item.value} />
          <label htmlFor={item.value} className='text-sm'>{item.label}</label>
        </div>
      ))}
    </div>
  )
}

Usage

import { Checkbox } from "@/components/ui/checkbox";

export default function Example() {
  return (
    <div className="flex items-center gap-x-2">
      <Checkbox defaultChecked size="sm" />
      <Checkbox defaultChecked size="md" />
      <Checkbox defaultChecked size="lg" />
    </div>
  );
}

Props

Checkbox

PropTypeDefault
size"sm" | "md" | "lg""md"

Takes these and every prop of CheckboxProps.

CheckboxField

Takes every prop of CheckboxFieldProps.

CheckboxLabel

Takes every prop of CheckboxLabelProps.

CheckboxDescription

Takes every prop of CheckboxDescriptionProps.

Dependencies

npm
class-variance-authority@0.7.1radix-ui@1.6.0
Installs with it
1 icon
npm
@base-ui/react@1.6.0class-variance-authority@0.7.1
Installs with it
1 icon

Source

components/ui/checkbox.tsx
/* eslint-disable react-refresh/only-export-components */
import * as React from "react";
import {
  Checkbox as CheckboxPrimitive,
  Label as LabelPrimitive,
} from "radix-ui";
import { cva, type VariantProps } from "class-variance-authority";
import { Check01 } from "@/components/icons/check-01";

import { cn } from "@/lib/utils";

const checkboxVariants = cva(
  [
    "peer relative flex shrink-0 items-center justify-center border-[1.5px] border-border-default text-icon-inverse transition-colors outline-none after:absolute after:-inset-x-3 after:-inset-y-2",
    // Hover
    "hover:border-border-hover hover:bg-bg-surface-1",
    // Focus — the design draws it as an outside stroke, so it must be a ring
    // (a border would eat into the box and shift the indicator).
    "focus-visible:ring-2 focus-visible:ring-border-default focus-visible:border-ring-neutral-outline",
    // Checked — the fill replaces the stroke; a transparent border of the same
    // width keeps the box model identical across states.
    "data-checked:border-transparent data-checked:bg-bg-foreground data-checked:hover:border-transparent data-checked:hover:bg-primary-hover",
    // Disabled
    "disabled:cursor-not-allowed disabled:border-border-disabled disabled:bg-input-default disabled:text-icon-disabled disabled:hover:border-border-disabled disabled:hover:bg-input-default disabled:data-checked:border-transparent disabled:data-checked:bg-bg-disabled",
    // Alert
    "aria-invalid:border-negative-middle aria-invalid:hover:border-negative-middle aria-invalid:data-checked:border-transparent aria-invalid:data-checked:bg-negative-middle aria-invalid:data-checked:hover:bg-negative-middle",
    // Alert focus
    "aria-invalid:focus-visible:bg-bg-main aria-invalid:focus-visible:ring-2 aria-invalid:focus-visible:ring-negative-middle/25 aria-invalid:data-checked:focus-visible:bg-negative-middle",
  ],
  {
    variants: {
      size: {
        sm: "size-4 rounded-sm [&_svg]:size-2.5",
        md: "size-[18px] rounded-[5px] [&_svg]:size-2.75",
        lg: "size-[22px] rounded-md [&_svg]:size-3.25",
      },
    },
    defaultVariants: {
      size: "md",
    },
  },
);

export type CheckboxProps = React.ComponentProps<typeof CheckboxPrimitive.Root> &
  VariantProps<typeof checkboxVariants>;

function Checkbox({
  className,
  size = "md",
  ...props
}: CheckboxProps) {
  return (
    <CheckboxPrimitive.Root
      data-slot="checkbox"
      data-size={size}
      className={cn(checkboxVariants({ size }), className)}
      {...props}
    >
      <CheckboxPrimitive.Indicator
        data-slot="checkbox-indicator"
        className="grid place-content-center text-current transition-none"
      >
        <Check01 />
      </CheckboxPrimitive.Indicator>
    </CheckboxPrimitive.Root>
  );
}

export type CheckboxFieldProps = React.ComponentProps<"div">;

function CheckboxField({ className, ...props }: CheckboxFieldProps) {
  return (
    <div
      data-slot="checkbox-field"
      className={cn(
        "group/checkbox-field flex flex-col items-start justify-center gap-2",
        className,
      )}
      {...props}
    />
  );
}

export type CheckboxLabelProps = React.ComponentProps<typeof LabelPrimitive.Root>;

function CheckboxLabel({
  className,
  ...props
}: CheckboxLabelProps) {
  return (
    <LabelPrimitive.Root
      data-slot="checkbox-label"
      className={cn(
        "flex items-center gap-2 text-sm leading-[1.4] font-normal text-text-muted select-none has-disabled:cursor-not-allowed has-disabled:text-text-note",
        className,
      )}
      {...props}
    />
  );
}

export type CheckboxDescriptionProps = React.ComponentProps<"p">;

function CheckboxDescription({
  className,
  ...props
}: CheckboxDescriptionProps) {
  return (
    <p
      data-slot="checkbox-description"
      className={cn(
        "text-xs leading-[1.3] text-text-note group-has-aria-invalid/checkbox-field:text-negative-middle",
        className,
      )}
      {...props}
    />
  );
}

export {
  Checkbox,
  CheckboxField,
  CheckboxLabel,
  CheckboxDescription,
  checkboxVariants,
};
components/ui/checkbox.tsx
/* eslint-disable react-refresh/only-export-components */
import * as React from "react";
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
import { cva, type VariantProps } from "class-variance-authority";
import { Check01 } from "@/components/icons/check-01";

import { cn } from "@/lib/utils";

const checkboxVariants = cva(
  [
    "peer relative flex shrink-0 items-center justify-center border-[1.5px] border-border-default text-icon-inverse transition-colors outline-none after:absolute after:-inset-x-3 after:-inset-y-2",
    // Hover
    "hover:border-border-hover hover:bg-bg-surface-1",
    // Focus — the design draws it as an outside stroke, so it must be a ring
    // (a border would eat into the box and shift the indicator).
    "focus-visible:ring-2 focus-visible:ring-border-default focus-visible:border-ring-neutral-outline",
    // Checked — the fill replaces the stroke; a transparent border of the same
    // width keeps the box model identical across states.
    "data-checked:border-transparent data-checked:bg-bg-foreground data-checked:hover:border-transparent data-checked:hover:bg-primary-hover",
    // Disabled — Base UI renders a span (not a button), so disabled styling
    // keys off its data-disabled attribute instead of :disabled.
    "data-disabled:cursor-not-allowed data-disabled:border-border-disabled data-disabled:bg-input-default data-disabled:text-icon-disabled data-disabled:hover:border-border-disabled data-disabled:hover:bg-input-default data-disabled:data-checked:border-transparent data-disabled:data-checked:bg-bg-disabled",
    // Alert
    "aria-invalid:border-negative-middle aria-invalid:hover:border-negative-middle aria-invalid:data-checked:border-transparent aria-invalid:data-checked:bg-negative-middle aria-invalid:data-checked:hover:bg-negative-middle",
    // Alert focus
    "aria-invalid:focus-visible:bg-bg-main aria-invalid:focus-visible:ring-2 aria-invalid:focus-visible:ring-negative-middle/25 aria-invalid:data-checked:focus-visible:bg-negative-middle",
  ],
  {
    variants: {
      size: {
        sm: "size-4 rounded-sm [&_svg]:size-2.5",
        md: "size-[18px] rounded-[5px] [&_svg]:size-2.75",
        lg: "size-[22px] rounded-md [&_svg]:size-3.25",
      },
    },
    defaultVariants: {
      size: "md",
    },
  },
);

export type CheckboxProps = CheckboxPrimitive.Root.Props & VariantProps<typeof checkboxVariants>;

function Checkbox({
  className,
  size = "md",
  ...props
}: CheckboxProps) {
  return (
    <CheckboxPrimitive.Root
      data-slot="checkbox"
      data-size={size}
      className={cn(checkboxVariants({ size }), className)}
      {...props}
    >
      <CheckboxPrimitive.Indicator
        data-slot="checkbox-indicator"
        className="grid place-content-center text-current transition-none"
      >
        <Check01 />
      </CheckboxPrimitive.Indicator>
    </CheckboxPrimitive.Root>
  );
}

export type CheckboxFieldProps = React.ComponentProps<"div">;

function CheckboxField({ className, ...props }: CheckboxFieldProps) {
  return (
    <div
      data-slot="checkbox-field"
      className={cn(
        "group/checkbox-field flex flex-col items-start justify-center gap-2",
        className,
      )}
      {...props}
    />
  );
}

export type CheckboxLabelProps = React.ComponentProps<"label">;

function CheckboxLabel({
  className,
  ...props
}: CheckboxLabelProps) {
  return (
    <label
      data-slot="checkbox-label"
      className={cn(
        "flex items-center gap-2 text-sm leading-[1.4] font-normal text-text-muted select-none has-disabled:cursor-not-allowed has-disabled:text-text-note",
        className,
      )}
      {...props}
    />
  );
}

export type CheckboxDescriptionProps = React.ComponentProps<"p">;

function CheckboxDescription({
  className,
  ...props
}: CheckboxDescriptionProps) {
  return (
    <p
      data-slot="checkbox-description"
      className={cn(
        "text-xs leading-[1.3] text-text-note group-has-aria-invalid/checkbox-field:text-negative-middle",
        className,
      )}
      {...props}
    />
  );
}

export {
  Checkbox,
  CheckboxField,
  CheckboxLabel,
  CheckboxDescription,
  checkboxVariants,
};