Checkbox
Hoja clienteA control that toggles a boolean or shows an indeterminate state.
Vista previa en vivo
Renderizado desde el código fuente instalado de VEXA — los mismos archivos que recibes.
Escritorio
Playground
Ajusta las props y copia el JSX equivalente.
Playground
checkbox.tsx
<Checkbox defaultChecked />Instalación
Añade el código del componente a tu proyecto. Las dependencias del registry se resuelven automáticamente.
npx shadcn@latest add https://vexa.valfiguer.com/r/checkbox.jsonSe instala en components/vexa/checkbox.tsx
Dependencias npm
- @radix-ui/react-checkbox
Dependencias del registry
- @vexa/utils
Otros items de VEXA que necesita este componente. Instálalos primero — la CLI los resuelve automáticamente.
Código
Cópialo a su ruta destino, o instálalo con el comando de arriba.
components/vexa/checkbox.tsx
"use client";
import type * as React from "react";
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { cn } from "@/lib/utils";
function CheckIcon({ className }: { className?: string }) {
return (
<svg
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
className={className}
>
<path
d="M4 12.5 9 17.5 20 6.5"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
function MinusIcon({ className }: { className?: string }) {
return (
<svg
viewBox="0 0 24 24"
fill="none"
aria-hidden="true"
className={className}
>
<path
d="M6 12h12"
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
/>
</svg>
);
}
/**
* Checkbox — a control that toggles a boolean, or represents an indeterminate
* (mixed) state. Built on Radix so the role, `aria-checked` (including
* `"mixed"`), keyboard model (Space toggles), and label association are handled.
*
* Client leaf: the `"use client"` boundary lives here. Pair with `<Label>` via
* a shared `id`, or wrap the label text so a click on it toggles the control.
* The checked/indeterminate state is conveyed by an icon, not color alone.
*/
export function Checkbox({
className,
...props
}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
return (
<CheckboxPrimitive.Root
data-slot="checkbox"
className={cn(
"group peer size-5 shrink-0 rounded-vexa-sm border border-vexa-input bg-vexa-surface-raised shadow-vexa-sm",
"transition-[color,background-color,border-color,box-shadow] duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)]",
"outline-none focus-visible:ring-2 focus-visible:ring-vexa-ring focus-visible:ring-offset-2 focus-visible:ring-offset-vexa-background",
"disabled:cursor-not-allowed disabled:opacity-50",
"data-[state=checked]:border-vexa-primary data-[state=checked]:bg-vexa-primary data-[state=checked]:text-vexa-primary-foreground",
"data-[state=indeterminate]:border-vexa-primary data-[state=indeterminate]:bg-vexa-primary data-[state=indeterminate]:text-vexa-primary-foreground",
"aria-[invalid=true]:border-vexa-danger",
className,
)}
{...props}
>
<CheckboxPrimitive.Indicator
data-slot="checkbox-indicator"
className="flex items-center justify-center text-current"
>
<CheckIcon className="size-3.5 group-data-[state=indeterminate]:hidden" />
<MinusIcon className="hidden size-3.5 group-data-[state=indeterminate]:block" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
);
}
JSON del registryr/checkbox.json
r/checkbox.json
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "checkbox",
"type": "registry:ui",
"title": "Checkbox",
"description": "A control that toggles a boolean or shows an indeterminate state.",
"dependencies": [
"@radix-ui/react-checkbox"
],
"registryDependencies": [
"@vexa/utils"
],
"files": [
{
"path": "registry/default/ui/checkbox.tsx",
"type": "registry:ui",
"target": "components/vexa/checkbox.tsx",
"content": "\"use client\";\n\nimport type * as React from \"react\";\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction CheckIcon({ className }: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={className}\n >\n <path\n d=\"M4 12.5 9 17.5 20 6.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction MinusIcon({ className }: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={className}\n >\n <path\n d=\"M6 12h12\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/**\n * Checkbox — a control that toggles a boolean, or represents an indeterminate\n * (mixed) state. Built on Radix so the role, `aria-checked` (including\n * `\"mixed\"`), keyboard model (Space toggles), and label association are handled.\n *\n * Client leaf: the `\"use client\"` boundary lives here. Pair with `<Label>` via\n * a shared `id`, or wrap the label text so a click on it toggles the control.\n * The checked/indeterminate state is conveyed by an icon, not color alone.\n */\nexport function Checkbox({\n className,\n ...props\n}: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"group peer size-5 shrink-0 rounded-vexa-sm border border-vexa-input bg-vexa-surface-raised shadow-vexa-sm\",\n \"transition-[color,background-color,border-color,box-shadow] duration-[var(--vexa-duration-fast)] ease-[var(--vexa-ease-standard)]\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-vexa-ring focus-visible:ring-offset-2 focus-visible:ring-offset-vexa-background\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"data-[state=checked]:border-vexa-primary data-[state=checked]:bg-vexa-primary data-[state=checked]:text-vexa-primary-foreground\",\n \"data-[state=indeterminate]:border-vexa-primary data-[state=indeterminate]:bg-vexa-primary data-[state=indeterminate]:text-vexa-primary-foreground\",\n \"aria-[invalid=true]:border-vexa-danger\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current\"\n >\n <CheckIcon className=\"size-3.5 group-data-[state=indeterminate]:hidden\" />\n <MinusIcon className=\"hidden size-3.5 group-data-[state=indeterminate]:block\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n"
}
],
"meta": {
"frameworks": [
"react",
"next"
],
"rsc": "client",
"cssVars": [
"--vexa-input",
"--vexa-surface-raised",
"--vexa-primary",
"--vexa-primary-foreground",
"--vexa-ring",
"--vexa-danger",
"--vexa-background"
],
"a11y": "Radix supplies role=checkbox, aria-checked (including \"mixed\"), and Space to toggle. Checked/indeterminate shown by an icon, not color alone. Associate a <Label>.",
"example": "<div className=\"flex items-center gap-2\"><Checkbox id=\"terms\" /><Label htmlFor=\"terms\">Accept terms</Label></div>",
"tests": "registry/tests/checkbox.test.tsx"
}
}Detalles
Accesibilidad
Radix supplies role=checkbox, aria-checked (including "mixed"), and Space to toggle. Checked/indeterminate shown by an icon, not color alone. Associate a <Label>.