Radio Group
One of these. Every option on screen, each with room to explain itself.
import { RadioGroup, Radio } from "@dede-style/ui/radio", then <RadioGroup label="Delivery" value={v} onChange={setV}> holding a Radio per option. It is controlled — the selected value lives with whoever owns it — and it renders a real <fieldset> with the label as its <legend>.
| Prop | Description | Default | Control |
|---|---|---|---|
| label | the group's name, shown above the options. Required | ||
| hide | hide the name visually but keep it for screen readers, when a heading already says it | false | |
| is | disables every option | false | |
| required | requires a choice before the form submits (browser validation) | false |
Tokens
What a theme can move, where the props above are what an instance can move.
RadioGroup has none, and that is a decision rather than an omission. Every value it renders already resolves through a foundation token or a role, so a theme moves it by moving those. A component token earns its place only when a theme needs to change one component without changing the role beneath it.
These are public and overridable — there is no private custom property, because anything on :root is reachable by any stylesheet. What replaces privacy is a stability contract: primitives may move, roles are the guarantee, and these are the per-component escape from both.