Checkbox Group
Varias casillas que son un solo dato: el valor sale como array y el error es del grupo.
import { CheckboxGroup, CheckboxGroupItem } from "sebs7n-ui/checkbox-group"Ejemplos
Un dato que son varias casillas
Los tres checkboxes son un solo campo: un `name`, un array como valor y un error que es del grupo, no de una casilla. El `FieldLabel` nombra al grupo entero; cada `CheckboxGroupItem` trae su propia etiqueta.
import { Button } from "sebs7n-ui/button"
import { CheckboxGroup, CheckboxGroupItem } from "sebs7n-ui/checkbox-group"
import { Field, FieldDescription, FieldError, FieldLabel } from "sebs7n-ui/field"
import { Form } from "sebs7n-ui/form"
import { useState } from "react"
function ServiciosDelPaquete() {
const [enviado, setEnviado] = useState<string[] | null>(null)
return (
<Form
className="w-full max-w-sm"
onFormSubmit={(valores) => setEnviado(valores.servicios as string[])}
>
<Field
name="servicios"
validate={(valor) => ((valor as string[]).length > 0 ? null : "Elegí al menos un servicio")}
>
<FieldLabel required>Servicios incluidos</FieldLabel>
<CheckboxGroup>
<CheckboxGroupItem value="soporte">Soporte</CheckboxGroupItem>
<CheckboxGroupItem value="capacitacion">Capacitación</CheckboxGroupItem>
<CheckboxGroupItem value="migracion">Migración de los datos anteriores</CheckboxGroupItem>
</CheckboxGroup>
<FieldDescription>Se cotizan por separado.</FieldDescription>
<FieldError />
</Field>
<Button type="submit">Cotizar</Button>
{enviado && <p className="text-mono-callout text-label-secondary">servicios: {JSON.stringify(enviado)}</p>}
</Form>
)
}Seleccionar todo
El motivo principal por el que existe el componente. El padre lleva `parent` y el grupo, `allValues`: con algunos tildados queda indeterminado, y de un click pasa a todos o a ninguno. No aporta valor propio al array ni viaja en el submit.
import { CheckboxGroup, CheckboxGroupItem } from "sebs7n-ui/checkbox-group"
import { Field, FieldDescription, FieldLabel } from "sebs7n-ui/field"
import { useState } from "react"
function PermisosDelOperador() {
const permisos = ["reservas", "pagos", "clientes", "reportes"]
const [valor, setValor] = useState<string[]>(["reservas", "clientes"])
return (
<Field className="w-full max-w-sm" name="permisos">
<FieldLabel>Permisos del operador</FieldLabel>
<CheckboxGroup allValues={permisos} onValueChange={setValor} value={valor}>
<CheckboxGroupItem parent>Acceso total</CheckboxGroupItem>
<div className="flex flex-col gap-3 border-l border-separator pl-4">
<CheckboxGroupItem value="reservas">Crear y editar reservas</CheckboxGroupItem>
<CheckboxGroupItem value="pagos">Registrar pagos</CheckboxGroupItem>
<CheckboxGroupItem value="clientes">Ver la ficha del cliente</CheckboxGroupItem>
<CheckboxGroupItem value="reportes">Descargar reportes</CheckboxGroupItem>
</div>
</CheckboxGroup>
<FieldDescription>
{valor.length} de {permisos.length} habilitados.
</FieldDescription>
</Field>
)
}Opciones con ayuda y opciones apagadas
La ayuda de un ítem describe solo a ese ítem: el lector la anuncia al entrar en esa casilla y no en las otras. `disabled` apaga la casilla y su etiqueta juntas.
import { CheckboxGroup, CheckboxGroupItem } from "sebs7n-ui/checkbox-group"
import { Field, FieldLabel } from "sebs7n-ui/field"
function AvisosDeLaCuenta() {
return (
<Field className="w-full max-w-sm" name="avisos">
<FieldLabel>Avisos por email</FieldLabel>
<CheckboxGroup defaultValue={["reserva"]}>
<CheckboxGroupItem description="Al confirmar y al cancelar." value="reserva">
Movimientos de una reserva
</CheckboxGroupItem>
<CheckboxGroupItem description="Un resumen los lunes a la mañana." value="resumen">
Resumen semanal
</CheckboxGroupItem>
<CheckboxGroupItem description="Necesita un plan con facturación electrónica." disabled value="facturas">
Facturas emitidas
</CheckboxGroupItem>
</CheckboxGroup>
</Field>
)
}Props
Generadas del TypeScript del paquete. Las propias del componente, más las heredadas del primitivo que tienen algo que explicar —marcadas «heredada de Base UI»—. El resto está en la línea «hereda de».
CheckboxGroup
Hereda las props de CheckboxGroup.
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
className | string | — | Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana. |
allValues | string[] | — | Heredada de Base UI. La lista completa de valores. Solo hace falta si hay un ítem parent. |
onValueChange | ((value: string[], eventDetails: CheckboxGroupChangeEventDetails) => void) | — | Heredada de Base UI. Recibe el array nuevo cada vez que se tilda o destilda una casilla. |
value | string[] | — | Heredada de Base UI. Los valores tildados. Para dejarlo no controlado, defaultValue. |
CheckboxGroupItem
Hereda las props de Checkbox.Root.
| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
checkboxClassName | string | — | Clases de la casilla. En className van las de la fila entera. |
description | React.ReactNode | — | Ayuda debajo de la etiqueta. Describe a esa opción, no al grupo. |
disabled | boolean | false | Apaga la casilla y su etiqueta. El disabled del grupo o del Field le gana. |
parent | boolean | false | Convierte al ítem en el «seleccionar todo» del grupo. Necesita allValues en el grupo. |
value | string | — | La identidad de la opción: es lo que entra y sale del array. |
className | string | — | Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana. |
Teclado
- Tab
- Una parada por casilla. No es un
RadioGroup: acá no hay flechas, porque las opciones no compiten entre sí. - Espacio
- Tilda y destilda la casilla que tiene el foco.
- Espacio en el padre
- Pasa de indeterminado a todos, y de todos a ninguno.
Accesibilidad
- El grupo es
role="group"con un solo nombre accesible: elFieldLabeldel campo que lo envuelve. Cada casilla conserva el suyo. - El error del campo describe al grupo (
aria-describedbysobre elrole="group"), así que se anuncia al entrar en el grupo y no hace falta moverle el foco. - El padre emite
aria-checked="mixed"cuando hay selección parcial, yaria-controlscon los ids de las casillas que gobierna. - La ayuda de un ítem describe solo a ese ítem: por dentro cada opción es un
Field.Item, que abre su propio ámbito de etiquetado. - La etiqueta de la opción es el
<label>nativo de su casilla: clickear el texto tilda, que es la mitad del área útil de una lista de opciones.
Reglas de uso
- Va adentro de un `Field`, aunque no haya formulario. De ahí salen el nombre del grupo, el error y el estado; un grupo suelto —los filtros de una lista— se envuelve igual en un
<Field>pelado, que es un<div>con contexto. - El `value` de cada ítem es lo que termina en el array, y no se reemplaza por `name`: adentro de un
Field, elnamedel campo le gana al de la casilla y las tres opciones terminarían con el mismo valor. - «Seleccionar todo» necesita las dos piezas:
allValuesen el grupo —la lista completa, que es de donde sale la cuenta— yparenten el ítem. El padre no aporta valor propio ni viaja en el submit. - El error de "tildá al menos uno" es del grupo: va en el
validatedelField, no en cada casilla. UnFieldsetno tiene dónde mostrarlo. - De 2 a 7 opciones visibles. Más que eso se busca, no se recorre:
Comboboxconmultiple. - Para opciones excluyentes,
RadioGroup. Para una sola casilla —aceptar los términos—,Checkboxsolo.