Ir al contenido
Formularios

CheckboxGroup

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.

PropTipoPor defectoDescripción
classNamestring—Se fusiona con las clases del componente vía cn() (tailwind-merge): lo que pongas gana.
allValuesstring[]—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.
valuestring[]—Heredada de Base UI. Los valores tildados. Para dejarlo no controlado, defaultValue.

CheckboxGroupItem

Hereda las props de Checkbox.Root.

PropTipoPor defectoDescripción
checkboxClassNamestring—Clases de la casilla. En className van las de la fila entera.
descriptionReact.ReactNode—Ayuda debajo de la etiqueta. Describe a esa opción, no al grupo.
disabledbooleanfalseApaga la casilla y su etiqueta. El disabled del grupo o del Field le gana.
parentbooleanfalseConvierte al ítem en el «seleccionar todo» del grupo. Necesita allValues en el grupo.
valuestring—La identidad de la opción: es lo que entra y sale del array.
classNamestring—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: el FieldLabel del campo que lo envuelve. Cada casilla conserva el suyo.
  • El error del campo describe al grupo (aria-describedby sobre el role="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, y aria-controls con 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, el name del campo le gana al de la casilla y las tres opciones terminarían con el mismo valor.
  • «Seleccionar todo» necesita las dos piezas: allValues en el grupo —la lista completa, que es de donde sale la cuenta— y parent en 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 validate del Field, no en cada casilla. Un Fieldset no tiene dónde mostrarlo.
  • De 2 a 7 opciones visibles. Más que eso se busca, no se recorre: Combobox con multiple.
  • Para opciones excluyentes, RadioGroup. Para una sola casilla —aceptar los términos—, Checkbox solo.

Relacionados