first commit
This commit is contained in:
131
docs/ui/react/react-ui/src/components/field-set/field-set.md
Normal file
131
docs/ui/react/react-ui/src/components/field-set/field-set.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# FieldSet (suaveplan-only)
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - field-set.variants — `fieldSetVariants` and `fieldL…
|
||||
- [field-set.variants](./field-set.variants.md) — `fieldSetVariants` and `fieldLegendVariants` are the cva (class-variance-authority) configurations powering `<FieldSet>…
|
||||
- field-set.variants — `fieldSetVariants` and `fieldL…
|
||||
|
||||
- [field-set.variants](./field-set.variants.md) — `fieldSetVariants` and `fieldLegendVariants` are the cva (class-variance-authority) configurations powering `<FieldSet>…
|
||||
|
||||
- field-set.variants — `fieldSetVariants` and `fieldL…
|
||||
|
||||
- [field-set.variants](./field-set.variants.md) — `fieldSetVariants` and `fieldLegendVariants` are the cva (class-variance-authority) configurations powering `<FieldSet>…
|
||||
|
||||
- field-set.variants — `fieldSetVariants` and `fieldL…
|
||||
|
||||
- [field-set.variants](./field-set.variants.md) — `fieldSetVariants` and `fieldLegendVariants` are the cva (class-variance-authority) configurations powering `<FieldSet>…
|
||||
- [field-set.variants](./field-set.variants.md) — `fieldSetVariants` and `fieldLegendVariants` are the cva (class-variance-authority) configurations powering `<FieldSet>…
|
||||
|
||||
## Purpose
|
||||
|
||||
`<FieldSet>` and `<FieldLegend>` are chassis primitives that wrap related controls (typically Checkbox / RadioGroup / Switch groups) inside the native `<fieldset>` + `<legend>` HTML5 elements. The native `<fieldset disabled>` attribute propagates to every contained form control automatically, which `<Field>` (a `<div>`) cannot replicate. Pair `<FieldLegend>` with `<FieldSet>` to provide an accessible grouping heading announced by screen readers when navigating into any contained control.
|
||||
|
||||
**Suaveplan addition** — shadcn does not ship a `FieldSet` registry item upstream. The chassis adds these primitives because the cross-cutting reconciliation note (#1) flagged the gap: `<Field>` is a `<div>` and cannot carry the native `<fieldset>` semantics. Documented as suaveplan-only so consumers know the source of truth lives in this package, not upstream shadcn.
|
||||
|
||||
## Features
|
||||
|
||||
- `<FieldSet>` renders the native `<fieldset>` so `disabled` propagates to every contained control via HTML5 semantics.
|
||||
- `<FieldLegend>` renders the native `<legend>` so screen readers announce the grouping when navigating into any contained control.
|
||||
- `data-invalid="true"` on `<FieldSet>` flips descendant `<FieldLegend>` colour to destructive via the cva `data-[invalid=true]:` selector.
|
||||
- `data-disabled="true"` mirrors the native `disabled` so sibling cva selectors can react.
|
||||
- Refs forwarded on both primitives.
|
||||
- Theme-driven variant overrides via `useThemedVariants("FieldSet" | "FieldLegend")`.
|
||||
- Layout uses `flex flex-col gap-3` (NOT `space-y-*` per shadcn skill rule).
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import { FieldSet, FieldLegend, Checkbox } from "@suaveplan/react-ui";
|
||||
|
||||
export function PermissionsFieldSet() {
|
||||
return (
|
||||
<FieldSet>
|
||||
<FieldLegend>Permissions</FieldLegend>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox id="read" defaultChecked />
|
||||
<label htmlFor="read">Read</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Checkbox id="write" />
|
||||
<label htmlFor="write">Write</label>
|
||||
</div>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import {
|
||||
FieldSet,
|
||||
FieldLegend,
|
||||
RadioGroup,
|
||||
RadioGroupItem,
|
||||
} from "@suaveplan/react-ui";
|
||||
import { useState } from "react";
|
||||
|
||||
export function NotificationFrequency() {
|
||||
const [enabled, setEnabled] = useState(true);
|
||||
const [freq, setFreq] = useState("daily");
|
||||
|
||||
// Disabling the entire fieldset propagates `disabled` to every
|
||||
// contained <RadioGroupItem> via HTML5 fieldset semantics.
|
||||
return (
|
||||
<FieldSet disabled={!enabled}>
|
||||
<FieldLegend>Notification frequency</FieldLegend>
|
||||
<RadioGroup value={freq} onValueChange={setFreq}>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="daily" id="freq-daily" />
|
||||
<label htmlFor="freq-daily">Daily digest</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="weekly" id="freq-weekly" />
|
||||
<label htmlFor="freq-weekly">Weekly summary</label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `<FieldSet>`
|
||||
|
||||
`forwardRef<HTMLFieldSetElement, FieldSetProps>` — renders the native `<fieldset>`.
|
||||
|
||||
#### `FieldSetProps`
|
||||
|
||||
Inherits every prop from `FieldsetHTMLAttributes<HTMLFieldSetElement>`. Adds:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `invalid` | `boolean` | `false` | Drives `data-invalid="true"` on the container so descendant `<FieldLegend>` flips to destructive colour. |
|
||||
|
||||
The native `disabled` attribute is forwarded as-is and additionally drives `data-disabled="true"` for cva selectors.
|
||||
|
||||
### `<FieldLegend>`
|
||||
|
||||
`forwardRef<HTMLLegendElement, FieldLegendProps>` — renders the native `<legend>`.
|
||||
|
||||
#### `FieldLegendProps`
|
||||
|
||||
Inherits every prop from `HTMLAttributes<HTMLLegendElement>`. Adds:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `invalid` | `boolean` | `false` | Drives `data-invalid="true"` on the legend itself so the destructive colour activates without depending on a parent `<FieldSet invalid>`. |
|
||||
|
||||
#### Cva resolvers
|
||||
|
||||
`fieldSetVariants` and `fieldLegendVariants` are exported as bare cva resolvers for external composition.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- This is a suaveplan-only addition — shadcn does not ship a `field-set` registry item upstream. The chassis adds it because `<Field>` (a `<div>`) cannot carry the native `<fieldset>` semantics, and the cross-cutting reconciliation note (#1) flagged the gap.
|
||||
- The native `<fieldset disabled>` attribute propagates `disabled` to every contained form control automatically. The chassis preserves this semantic by rendering the actual HTML5 element rather than wrapping in a `<div role="group">`.
|
||||
- The `<FieldLegend>` `invalid` prop is exposed independently of `<FieldSet>` so consumers can render a legend in error state outside a fieldset (e.g. a custom layout that uses the chassis legend styling without the fieldset wrapper).
|
||||
- Per the shadcn skill rule, the cva NEVER uses `space-y-*` — `gap-3` flows the same in RTL.
|
||||
- Refs target the native `<fieldset>` / `<legend>` so consumers can measure or scroll-into-view programmatically.
|
||||
Reference in New Issue
Block a user