Un interruptor para valores booleanos, utilizado individualmente para controles de opt-in o en grupos para selección múltiple. Construido con entradas de casilla de verificación nativas y estilo Tailwind para accesibilidad y consistencia.
Una casilla de verificación mínima con una etiqueta de texto. El callback onChange devuelve un booleano directamente, por lo que el componente padre no necesita desempaquetar e.target.checked. Envolver ambos elementos dentro de una <label> hace que toda la fila sea clickeable.
Una casilla de verificación independiente sin etiqueta, útil cuando la etiqueta se renderiza por separado (como en filas de tabla o diseños personalizados). El prop name permite que participe en envíos de formularios nativos.
Usa useId para generar un ID estable que vincula <label> e <input> a través de htmlFor. Este enfoque mantiene la etiqueta y la entrada como hermanas, dando más flexibilidad para el diseño que envolver la entrada dentro de la etiqueta.
Un grupo de casillas de verificación gestionado como un array de valores seleccionados. Los elementos <fieldset> y <legend> proporcionan agrupación semántica para lectores de pantalla. Alternar un valor lo añade a o lo elimina del array seleccionado.
El estado indeterminado es un tercer estado visual (un guión en lugar de una marca de verificación) que solo se puede configurar mediante JavaScript, no atributos HTML. Esto se usa típicamente para una casilla "seleccionar todo" cuando solo se marcan algunos elementos secundarios. El useEffect establece indeterminate directamente en el elemento DOM.
Añade una descripción secundaria debajo de la etiqueta para contexto adicional. La casilla de verificación se alinea en la parte superior del bloque de texto con items-start y mt-0.5. El atributo aria-describedby vincula la descripción a la entrada para lectores de pantalla.
Usa React 19 useActionState para manejar el envío del formulario. Las casillas de verificación no están controladas con atributos name para que el navegador las recopile en FormData. Una casilla marcada envía "on" como su valor; las casillas desmarcadas están completamente ausentes de los datos del formulario.
forwardRef -- permite que los componentes padre adjunten refs para gestión de foco, librerías de formularios o acceso imperativo a la entrada de casilla de verificación subyacente.
useId para accesibilidad -- genera un ID único estable para vincular la etiqueta, descripción y texto de error a la entrada sin requerir que el consumidor proporcione IDs.
Soporte para estado indeterminado -- el prop indeterminate se aplica a través de useEffect en el elemento DOM ya que HTML no tiene atributo indeterminate. Esto permite patrones de "seleccionar todo" en tablas de datos.
API dual onChange -- soporta tanto el manejador de eventos onChange nativo como una devolución de llamada booleana simplificada onCheckedChange, haciéndola compatible con librerías de formularios y estado simple por igual.
Encadenamiento de aria-describedby -- vincula la casilla de verificación tanto a descripción como a elementos de texto de error para que los lectores de pantalla anuncien información contextual en el orden correcto.
Variantes de tamaño -- tres tamaños ajustan las dimensiones de la casilla, el tamaño de la fuente de la etiqueta y el tamaño del texto de descripción juntos para consistencia visual.
Borde de error -- cuando hay un error, el borde de la casilla se vuelve rojo además de mostrar el mensaje de error, dando retroalimentación visual y textual.
El valor de la casilla en FormData es "on", no true -- Cuando se usa envío de formularios nativos, una casilla marcada envía "on" como su valor. Las casillas desmarcadas están completamente ausentes de FormData, no "off". Usa formData.has("name") para verificar la existencia.
indeterminate no es un atributo HTML -- No puedes configurar el estado indeterminado a través de props JSX. Debe configurarse a través de una ref con el.indeterminate = true. Olvidar esto lleva a que el estado indeterminado nunca aparezca.
La casilla controlada necesita tanto checked como onChange -- Proporcionar checked sin onChange hace que la casilla sea de solo lectura y dispara una advertencia de React. Si quieres una casilla de solo lectura, también pasa readOnly.
defaultChecked vs checked -- Usar defaultChecked hace que la casilla no esté controlada. Cambiar entre defaultChecked y checked en tiempo de ejecución causa comportamiento impredecible. Elige un enfoque por instancia de componente.
Serialización de grupo de casillas -- Cuando múltiples casillas comparten el mismo name, FormData.getAll("name") devuelve un array de strings "on". Dale a cada casilla un name único o usa un atributo value: <input type="checkbox" name="colors" value="red" />.
Área de clic demasiado pequeña -- Una casilla desnuda es un objetivo pequeño. Siempre envoltura en una <label> o usa suficiente padding alrededor de ella para cumplir con tamaños mínimos de objetivos táctiles (al menos 44x44px en móvil).