# Fieldset

> Un grupo de campos con un título común, y un disabled que los apaga a todos.

```tsx
import { Fieldset, FieldsetLegend } from "sebs7n-ui/fieldset"
```

## Ejemplos

### Un grupo de campos

`Fieldset` le da un nombre común a varios campos. No es un título decorativo: es lo que hace que dos campos "Calle" en la misma pantalla se distingan para quien usa un lector de pantalla.

```tsx
import { Field, FieldDescription, FieldLabel } from "sebs7n-ui/field"
import { Fieldset, FieldsetLegend } from "sebs7n-ui/fieldset"
import { Form } from "sebs7n-ui/form"
import { Input } from "sebs7n-ui/input"
import { Textarea } from "sebs7n-ui/textarea"

function Grupo() {
  return (
    <Form className="w-full max-w-sm">
      <Fieldset>
        <FieldsetLegend>Domicilio fiscal</FieldsetLegend>
        <Field name="domicilio.calle">
          <FieldLabel>Calle y número</FieldLabel>
          <Input />
        </Field>
        <Field name="domicilio.localidad">
          <FieldLabel>Localidad</FieldLabel>
          <Input />
        </Field>
      </Fieldset>

      <Field name="notas">
        <FieldLabel>Notas para el repartidor</FieldLabel>
        <Textarea rows={3} />
        <FieldDescription>Opcional.</FieldDescription>
      </Field>
    </Form>
  )
}
```

### El error que es del grupo y no de un campo

"Tildá al menos un archivo" no pertenece a ninguna casilla suelta. `Fieldset` no tiene dónde mostrarlo —un `<fieldset>` no lleva un mensaje que el lector anuncie—, así que ese conjunto se declara como lo que es: un campo con `name`, valor y error. El `FieldError` queda atado al `role="group"` por `aria-describedby` y se limpia solo al tildar.

```tsx
import { Button } from "sebs7n-ui/button"
import { CheckboxGroup, CheckboxGroupItem } from "sebs7n-ui/checkbox-group"
import { Field, FieldError, FieldLabel } from "sebs7n-ui/field"
import { Fieldset, FieldsetLegend } from "sebs7n-ui/fieldset"
import { Form } from "sebs7n-ui/form"
import { Input } from "sebs7n-ui/input"

function ErrorDelGrupo() {
  return (
    <Form className="w-full max-w-sm">
      <Fieldset>
        <FieldsetLegend>Documentación del legajo</FieldsetLegend>

        <Field name="titular">
          <FieldLabel>Titular</FieldLabel>
          <Input placeholder="Apellido y nombre" />
        </Field>

        <Field
          name="adjuntos"
          validate={(valor) => ((valor as string[]).length > 0 ? null : "Tildá al menos un archivo")}
        >
          <FieldLabel required>Archivos que adjuntás</FieldLabel>
          <CheckboxGroup>
            <CheckboxGroupItem value="factura">Factura</CheckboxGroupItem>
            <CheckboxGroupItem value="remito">Remito</CheckboxGroupItem>
            <CheckboxGroupItem value="comprobante">Comprobante de pago</CheckboxGroupItem>
          </CheckboxGroup>
          <FieldError />
        </Field>
      </Fieldset>

      <Button type="submit">Guardar el legajo</Button>
    </Form>
  )
}
```

## Props

### Fieldset

Hereda las props de `Fieldset.Root`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

### FieldsetLegend

Hereda las props de `Fieldset.Legend`.

| Prop | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `className` | `string` | — | Se fusiona con las clases del componente vía `cn()` (tailwind-merge): lo que pongas gana. |

## Teclado

| Tecla | Qué hace |
|---|---|
| Tab | Recorre los campos del grupo en orden. El título no recibe foco. |

## Accesibilidad

- El grupo tiene nombre accesible: es lo que distingue dos campos "Calle" en la misma pantalla, uno en "Domicilio fiscal" y otro en "Dirección de entrega".
- El título va con `aria-labelledby` en vez de un `<legend>` nativo, que no se puede ubicar libremente sin pelear con el navegador.
- `disabled` en el grupo apaga todos los campos de adentro sin que haya que repetirlo campo por campo.

## Reglas de uso

- Para opciones excluyentes va `RadioGroup`, que ya trae su propia semántica de grupo.
- Un formulario de tres campos no necesita un `Fieldset`: agrupar de a uno agrega ruido, no estructura.
- **El error del grupo no va en el `Fieldset`.** No tiene parte de error a propósito: un `<fieldset>` no lleva un mensaje que el lector de pantalla anuncie —lo que anuncia al entrar es la leyenda—, así que sería un cartel rojo que media pantalla nunca escucha.
- **Cuando el error es de un conjunto de opciones ("tildá al menos un archivo"), ese conjunto es un campo**: un `Field` con `name` alrededor de un `CheckboxGroup`, y el `FieldError` adentro. Ahí sí queda atado al `role="group"` por `aria-describedby`, entra en el `errors` de `Form` por su `name` y se limpia solo al tildar. El `Fieldset` sigue siendo el que agrupa, si hace falta.
- Un error que cruza campos que siguen siendo distintos ("el domicilio no existe", sobre calle + localidad) va en el campo que se puede corregir, o arriba del formulario en un `Alert`.

## Relacionados

[field](/docs/components/field.md) · [checkbox-group](/docs/components/checkbox-group.md) · [form](/docs/components/form.md)
