# GroupBox

**Maturity:** experimental

Wrap a related cluster of content — account details, a terms toggle, a storage meter — behind one titled, visually-distinct card, so a screen reads as sections rather than an undifferentiated list.

## Import

```tsx
import { GroupBox } from "@liquidify/react/group-box"
```

## Props

- `children`: `ReactNode` (required). The grouped content (SwiftUI `{ … }` content closure, children role: `content`) — content-agnostic: hosts `LabeledContent` rows, a `Toggle`, a `ProgressIndicator`, or a nested `GroupBox`.
- `className`: `string | undefined`. Optional additional CSS class merged into the glass surface class. The supported per-instance customisation seam: override any `--lq-*` custom property from this class's CSS — the token cascade the engine reads (ADR-0004). No raw inline style is involved, so this stays ADR-0003 clean.
- `label`: `ReactNode`. The card's title (SwiftUI `GroupBox(_:content:)` / `GroupBox(content:label:)`). A `string` routes through the `TextLabel` guard into an internal `Text` (`variant="headline"`, `weight="semibold"`, `color="secondary"` by default, overridable per-instance via `labelProps`) carrying the id the root's `aria-labelledby` targets. A `ReactNode` (e.g. an icon+text composite) passes through unwrapped so the caller keeps ownership of its own typography and icon (`labelProps` has no effect on this shape). Omitted, or supplied as a non-renderable value (`false` / `null` / `true` / `""`), renders no label region and no `aria-labelledby` — an intentionally unnamed group.
- `labelProps`: `LabelProps | undefined`. Per-instance typography override for a `string` `label` (ADR-0028, charter §2) — spread last onto the internal `Text` so an explicit value wins over the `headline`/`semibold`/`secondary` default. No effect when `label` is a `ReactNode` (passes through `TextLabel` unwrapped) or omitted/non-renderable.
- `ref`: `Ref<HTMLDivElement> | undefined`. Forwarded ref to the rendered element — the component's native root (or the merged child element on a component that opts into {@link SlottableProps}). Generic over `E` (charter `docs/api-conventions.md` §4 rule 1, default `HTMLElement`) so a component with a polymorphic root (Link's navigation / action mode union, Text's `as`) can instantiate the concrete element per variant instead of leaving every consumer with a widened `Ref<HTMLElement>`. A component that does not narrow simply inherits the `HTMLElement` default — source-compatible with every pre-existing non-generic `extends ControlProps`.

## SwiftUI mapping

- ``GroupBox(_:content:)` — `String`/`LocalizedStringKey` title` → ``label?: string`` (direct): Routed through the `TextLabel` guard into an internal `Text` (ADR-0028).
- ``GroupBox(content:label:)` — custom `label` view` → ``label?: ReactNode`` (direct): Same `label` prop, union `string | ReactNode`; a node label renders verbatim — the caller composes its own icon+text pairing.
- ``GroupBox(content:)` — label-less` → ``label` omitted (or `false`/`null`/`true`/`""`)` (direct): No label region emitted; `children` is the only slot.
- ``GroupBox(label:content:)` (deprecated)` → `—` (direct): Not surfaced; superseded by `content:label:` in the demo and in SwiftUI's own docs.
- ``{ … }` content closure` → ``children: ReactNode` (required, children role: `content`)` (direct): Content slot, content-agnostic — hosts `LabeledContent`, `VStack`-equivalent layout, `Toggle`, `ProgressView`, or a nested `GroupBox`.
- ``init(_ configuration: GroupBoxStyleConfiguration)` / `.groupBoxStyle(_:)` / `GroupBoxStyle` protocol` → `— (Out of scope v1)` (direct): Only the default (`.automatic`/`DefaultGroupBoxStyle`) is exercised by the demo; no custom-style plumbing ships in v1.
- ``controlSize`` → `—` (direct): Non-sizable; no size prop (see Sizes).
- ``.tint(_:)`` → `—` (direct): GroupBox has no tint surface; no `tint` prop.
- ``.font(_:)` / `.foregroundStyle(_:)` on a `string` title` → ``labelProps?: LabelProps`` (direct): Per-instance typography override seam (ADR-0028, charter §2), spread **last** onto the string-`label` path's internal `Text` so an explicit consumer value wins over the `headline`/`semibold`/`secondary` default. No effect when `label` is a `ReactNode` (passes through `TextLabel` unwrapped) or omitted/non-renderable.
- `*(no analogue — web-only)*` → ``ref?: Ref<HTMLDivElement>`` (web-only): `GroupBoxProps extends ControlProps<HTMLDivElement>` (charter §4) — forwarded to the concrete `role="group"` root `<div>` (the shared `Card` primitive's rendered element), not a bare `Ref<HTMLElement>`.
