---
## RadioGroup
Accessible radio group for single-option selection with semantic intents and form integration.
Uses native radio inputs for correct form behavior and ARIA semantics with keyboard navigation.
**Import:** `import { RadioGroup } from '@urbicon-ui/blocks';`
### Examples
```svelte
```
### Variants
- disabled: true (default: false)
- error: true (default: false)
- orientation: horizontal, vertical (default: vertical)
- required: true (default: false)
### Api
| Prop | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| children | `Snippet` | yes | | RadioItem children to render inside the group. |
| ...HTMLAttributes | `HTMLAttributes` | no | | HTML attributes (excluding: 'children' | 'class') |
| class | `string` | no | | Extra classes merged onto the root wrapper element. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| disabled | `boolean` | no | | Disable all radio items in the group. |
| error | `string` | no | | Error message below the group. Replaces `helper` and sets `aria-invalid`. |
| helper | `string` | no | | Hint text below the group. Hidden when `error` is set. |
| id | `string` | no | | Explicit `id` for the group element. Auto-generated if omitted. |
| intent | `RadioItemVariants['intent']` | no | 'primary' | Semantic color propagated to all child RadioItems. |
| label | `string` | no | | Group label displayed above the radio items. |
| mint | `MintProp` | no | 'none' | Micro-interaction preset applied to each RadioItem (per-item via context). Only applies while the item is not disabled. |
| name | `string` | no | | Shared `name` attribute for all radio inputs. Auto-generated if omitted. |
| onValueChange | `(value: string) => void` | no | | Fired after the selected value changes. Receives the new value. |
| orientation | `'horizontal' | 'vertical'` | no | 'vertical' | Stack direction for the radio items. |
| preset | `string` | no | | Apply a named preset registered via ``. Prefer this over `class` overrides when the requested look falls outside the semantic intent palette — presets keep hover/active/dark-mode logic coherent and make the custom look reusable across the project. |
| required | `boolean` | no | | Require a selection: marks the label with an asterisk, sets `aria-required` on the group, and puts the constraint on the radios themselves — so an empty group blocks the form's submit like a native required control. |
| size | `RadioItemVariants['size']` | no | 'md' | Visual size propagated to all child RadioItems. |
| slotClasses | `Partial>` | no | | Per-slot class overrides merged with tv() styles. Slots: root (what `class` also targets) | group | label | requiredMark | message. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| tier | `InteractiveTier` | no | 'commit' | Semantic radius tier propagated to every RadioItem. Default `commit` — radio indicators read as identity circles. Set to `modify` (or inherit via TierContext from a wrapping ``) for inline-toolbar contexts where a circle feels oversized. |
| unstyled | `boolean` | no | | Remove all default tv() classes. Only user-provided classes apply. |
| value | `string` | no | | Currently selected value. Supports two-way binding via `bind:value`. |
| variant | `RadioItemVariants['variant']` | no | 'outlined' | Visual weight propagated to all child RadioItems. |
Inherited from:
- Omit, 'children' | 'class'> (omit-pattern)
### Types
```ts
interface RadioGroupContext {
readonly name: string;
readonly size: NonNullable;
readonly intent: NonNullable;
readonly variant: NonNullable;
readonly tier: InteractiveTier;
readonly disabled: boolean;
readonly error: boolean;
readonly value: string | undefined;
readonly mint: MintProp;
/**
* Passed to every radio input, which is what makes the group's `required`
* real: HTML treats a radio group as required when any radio of the `name`
* carries the attribute, so the browser blocks an empty submit itself.
*/
readonly required: boolean;
select: (value: string) => void;
}
```
```ts
type MintProp = | MintName
| { name: MintName; config?: MintConfig & Record }
| Array
| Array }>
```
```ts
type InteractiveTier = 'commit' | 'modify'
```
```ts
type MintName = BuiltinMintName | 'none' | (string & {})
```
```ts
interface MintConfig {
/**
* `hover` and `focus` hold the effect while the pointer/visible focus stays
* on the element; `click` and `load` run it once.
*/
trigger?: 'hover' | 'click' | 'focus' | 'load';
/**
* Effect duration in ms. Written as an inline per-effect custom property
* (`--blocks-mint--duration`), so the CSS transition/animation
* actually runs at this speed; unset, the theme duration tokens apply.
*/
duration?: number;
/** Delay in ms before the effect applies. */
delay?: number;
/**
* CSS easing for the effect (`--blocks-mint--easing` inline);
* unset, the per-effect theme default applies.
*/
easing?: string;
disabled?: boolean;
}
```
```ts
type SlotNames = keyof ReturnType & string
```
```ts
type VariantProps = Omit<
Exclude[0], undefined>,
'class'
>
```
```ts
type BuiltinMintName = (typeof BUILTIN_MINT_NAMES)[number]
```
### Slots (slotClasses keys)
`root`, `group`, `label`, `requiredMark`, `message`