Checkbox primitive wrapper
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
export default function CheckboxDemoExample() {
return (
<div class="grid gap-4">
<label class="flex items-center gap-2"><Checkbox id="terms" />Accept terms and conditions</label>
<label class="flex items-start gap-2"><Checkbox id="terms-description" defaultChecked /><span><strong>Accept terms and conditions</strong><small class="block text-muted-foreground">By clicking this checkbox, you agree to the terms.</small></span></label>
<label class="flex items-center gap-2"><Checkbox id="disabled" disabled />Enable notifications</label>
<label class="flex items-start gap-2"><Checkbox id="notifications" /><span><strong>Enable notifications</strong><small class="block text-muted-foreground">You can enable or disable notifications at any time.</small></span></label>
</div>
)
}
Installation
npx @fictjs/shadcn@latest add checkboxInstall the runtime dependencies:
npm install @fictjs/radix-uiCopy the Fict shadcn component into your project.
Source
components/ui/checkbox.tsx
src/components/ui/checkbox.tsx
import { Checkbox as CheckboxPrimitive } from '@fictjs/radix-ui'
import { cn } from '@/lib/cn'
type CheckboxProps = {
class?: string
indicatorClass?: string
children?: unknown
[key: string]: unknown
}
export function Checkbox(props: CheckboxProps) {
const { class: className, indicatorClass, children, ...rest } = props
return (
<CheckboxPrimitive.Root
class={cn(
'peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...rest}
>
<CheckboxPrimitive.Indicator class={cn('flex items-center justify-center text-[10px]', indicatorClass)}>
{children ?? '✓'}
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
)
}
Usage
Examples
Invalid
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
export default function CheckboxInvalidExample() {
return <label class="flex items-center gap-2 text-destructive"><Checkbox id="terms-invalid" aria-invalid="true" />Accept terms and conditions</label>
}
Basic
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
export default function CheckboxBasicExample() {
return <label class="flex items-center gap-2"><Checkbox id="terms-basic" />Accept terms and conditions</label>
}
Description
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
export default function CheckboxDescriptionExample() {
return <label class="flex items-start gap-2"><Checkbox id="terms-description" defaultChecked /><span><strong>Accept terms and conditions</strong><small class="block text-muted-foreground">By clicking this checkbox, you agree to the terms and conditions.</small></span></label>
}
Disabled
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
export default function CheckboxDisabledExample() {
return <label class="flex items-center gap-2 opacity-50"><Checkbox id="notifications-disabled" disabled />Enable notifications</label>
}
Group
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
const items = [['hard-disks', 'Hard disks', true], ['external-disks', 'External disks', true], ['cds', 'CDs, DVDs, and iPods', false], ['servers', 'Connected servers', false]] as const
export default function CheckboxGroupExample() {
return <fieldset class="grid gap-3"><legend>Show these items on the desktop:</legend><p class="text-sm text-muted-foreground">Select the items you want to show on the desktop.</p>{items.map(([id, label, checked]) => <label class="flex items-center gap-2"><Checkbox id={id} defaultChecked={checked} />{label}</label>)}</fieldset>
}
Table
| Name | Role | ||
|---|---|---|---|
| Sarah Chen | sarah.chen@example.com | Admin | |
| Marcus Rodriguez | marcus.rodriguez@example.com | User | |
| Priya Patel | priya.patel@example.com | User | |
| David Kim | david.kim@example.com | Editor |
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
const people = [['Sarah Chen', 'sarah.chen@example.com', 'Admin'], ['Marcus Rodriguez', 'marcus.rodriguez@example.com', 'User'], ['Priya Patel', 'priya.patel@example.com', 'User'], ['David Kim', 'david.kim@example.com', 'Editor']] as const
export default function CheckboxTableExample() {
let selected = $state(new Set([0]))
const toggle = (index: number) => { const next = new Set(selected); next.has(index) ? next.delete(index) : next.add(index); selected = next }
const toggleAll = () => { selected = selected.size === people.length ? new Set() : new Set(people.map((_, index) => index)) }
return <table><thead><tr><th><Checkbox checked={() => selected.size === people.length} onCheckedChange={toggleAll} aria-label="Select all rows" /></th><th>Name</th><th>Email</th><th>Role</th></tr></thead><tbody>{people.map((person, index) => <tr data-state={selected.has(index) ? 'selected' : undefined}><td><Checkbox checked={() => selected.has(index)} onCheckedChange={() => toggle(index)} aria-label={`Select ${person[0]}`} /></td><td>{person[0]}</td><td>{person[1]}</td><td>{person[2]}</td></tr>)}</tbody></table>
}
Rtl
import { Checkbox } from '@/components/ui/checkbox'
...import { Checkbox } from '@/components/ui/checkbox'
const translations = {
ar: { dir: 'rtl', terms: 'قبول الشروط والأحكام', termsDescription: 'بالنقر على هذا المربع، فإنك توافق على الشروط.', notifications: 'تفعيل الإشعارات', notificationsDescription: 'يمكنك تفعيل أو إلغاء تفعيل الإشعارات في أي وقت.' },
he: { dir: 'rtl', terms: 'קבל תנאים והגבלות', termsDescription: 'על ידי לחיצה על תיבת הסימון הזו, אתה מסכים לתנאים.', notifications: 'הפעל התראות', notificationsDescription: 'אתה יכול להפעיל או להשבית התראות בכל עת.' },
en: { dir: 'ltr', terms: 'Accept terms and conditions', termsDescription: 'By clicking this checkbox, you agree to the terms.', notifications: 'Enable notifications', notificationsDescription: 'You can enable or disable notifications at any time.' },
} as const
export default function CheckboxRtlExample() {
let language = $state<keyof typeof translations>('ar')
const text = () => translations[language]
return <div class="grid gap-4"><select value={language} onChange={event => { language = event.currentTarget.value as keyof typeof translations }}><option value="ar">Arabic (العربية)</option><option value="he">Hebrew (עברית)</option><option value="en">English</option></select><div class="grid gap-4" dir={text().dir}><label class="flex items-center gap-2"><Checkbox />{text().terms}</label><label class="flex items-start gap-2"><Checkbox defaultChecked /><span><strong>{text().terms}</strong><small class="block">{text().termsDescription}</small></span></label><label class="flex items-center gap-2"><Checkbox disabled />{text().notifications}</label><label class="flex items-start gap-2"><Checkbox /><span><strong>{text().notifications}</strong><small class="block">{text().notificationsDescription}</small></span></label></div></div>
}