Componentes · Ola 1 · Formularios
Checkbox
Marca o desmarca una opción independiente, con estado mixto para las listas.
import { Checkbox } from '@archeblack/ui';
Ejemplos
Con label
El uso más común: opciones independientes, cada una con su texto. bind:checked sigue el estado.
<script lang="ts">
import { Checkbox } from '@archeblack/ui';
let weekly = $state(true);
let deploys = $state(false);
</script>
<div style:display="grid" style:gap="var(--arche-spacing-1)">
<Checkbox bind:checked={weekly} label="Enviar un resumen semanal" />
<Checkbox bind:checked={deploys} label="Notificar cada despliegue" />
</div> Con descripción
description explica la opción en text-muted, debajo del label.
<script lang="ts">
import { Checkbox } from '@archeblack/ui';
</script>
<Checkbox
label="Notificar cada despliegue"
description="Un correo por cada despliegue a producción, con el autor y el resultado."
/> Estado mixto
Una casilla que agrupa a otras: indeterminate mientras solo algunas están marcadas.
<script lang="ts">
import { Checkbox } from '@archeblack/ui';
const projects = $state([
{ name: 'Portal de clientes', selected: true },
{ name: 'API de pagos', selected: false },
{ name: 'Motor de búsqueda', selected: false }
]);
const count = $derived(projects.filter((project) => project.selected).length);
</script>
<div style:display="grid" style:gap="var(--arche-spacing-1)">
<!-- Mixta mientras solo algunos están marcados. El clic marca o desmarca todos. -->
<Checkbox
label="Seleccionar todos"
checked={count === projects.length}
indeterminate={count > 0 && count < projects.length}
onchange={(event) => {
for (const project of projects) project.selected = event.currentTarget.checked;
}}
/>
<div style:display="grid" style:gap="var(--arche-spacing-1)" style:padding-inline-start="1.75rem">
{#each projects as project (project.name)}
<Checkbox bind:checked={project.selected} label={project.name} />
{/each}
</div>
</div> Deshabilitada
disabled apaga la casilla y su texto, marcada o no.
<script lang="ts">
import { Checkbox } from '@archeblack/ui';
</script>
<div style:display="grid" style:gap="var(--arche-spacing-1)">
<Checkbox label="Copias de seguridad diarias" disabled />
<Checkbox label="Registro de auditoría" checked disabled />
<Checkbox label="Plan de empresa" indeterminate disabled />
</div> Sin texto visible
En una fila de tabla la casilla va sola: el nombre accesible va en aria-label.
<script lang="ts">
import { Checkbox } from '@archeblack/ui';
</script>
<!-- Sin texto visible (una fila de tabla, por ejemplo): el nombre va en aria-label. -->
<Checkbox aria-label="Seleccionar Portal de clientes" />
<Checkbox aria-label="Seleccionar API de pagos" checked /> Props
| Prop | Descripción |
|---|---|
bind:checked? boolean Por defecto false | Si la casilla está marcada. |
bind:indeterminate? boolean Por defecto false | Estado mixto: una casilla que agrupa a otras y solo algunas están marcadas. Se dibuja como una raya. El navegador lo apaga cuando el usuario hace clic. |
label? string | Texto de la casilla y su nombre accesible. |
description? string | Texto de ayuda debajo del label, en text-muted. Se asocia al input con aria-describedby. |
children? Snippet | Contenido del label cuando hace falta marcado, como un link. Tiene prioridad sobre label. |
aria-label? string | Nombre accesible cuando no hay texto visible. Si otro texto de la página ya la nombra, aria-labelledby con su id. Hace falta uno de label, children, aria-label o aria-labelledby: TypeScript rechaza una casilla sin nombre. |
disabled? boolean Por defecto false | Deshabilita la casilla. El texto pasa a text-disabled. |
class? ClassValue | Clases del producto; se suman a arche-checkbox, el <label> que envuelve al control y su texto. |
...rest HTMLInputAttributes | Todo lo demás va al <input>: name, value, required, aria-invalid, onchange… El tipo lo fija el componente. |
Accesibilidad
- Es un
<input type="checkbox">nativo dibujado conappearance: none: el rol, el estado, el envío del formulario y la barra espaciadora son los del navegador. - El foco es el de Arche y se dibuja sobre la propia casilla.
- Un
<label>envuelve la casilla y su texto: toda la fila es clickeable y mide al menos 24 × 24 px, también sin texto. - El nombre accesible es solo el label; la descripción se anuncia aparte, con
aria-describedby. - El estado mixto se anuncia como «mixto» (
indeterminatees la propiedad nativa del input). - El borde de la casilla llega a 3:1 contra todas las superficies (
border-control). - En colores forzados, la casilla marcada se pinta con
Highlighty la marca conHighlightText: el estado no depende de un fondo que el navegador reemplaza. - Sin texto visible, el nombre va en
aria-labeloaria-labelledby. Los tipos exigen uno de los cuatro: TypeScript rechaza una casilla sin nombre.
Qué evitar
- Una casilla para una acción que tiene efecto inmediato, como activar un servicio. Un
Switch. La casilla es para opciones que se confirman después, al guardar o enviar. - Casillas para elegir una sola opción entre varias. Un
RadioGroup: comunica que las opciones son excluyentes. - Un label negativo («No enviar correos»). El label dice lo que pasa al marcarla: «Enviar un resumen semanal».
- Una casilla sin texto y sin
aria-label. Siempre un nombre: el label, oaria-labelsi no hay texto visible. - Un
<input type="checkbox">suelto con estilos propios.<Checkbox>: el foco, el tamaño del objetivo y los colores forzados ya están resueltos.