first commit
This commit is contained in:
147
docs/ui/react/react-ui/src/components/radio-group/radio-group.md
Normal file
147
docs/ui/react/react-ui/src/components/radio-group/radio-group.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# RadioGroup
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - radio-group.variants — `radioGroupVariants` and `ra…
|
||||
- [radio-group.variants](./radio-group.variants.md) — `radioGroupVariants` and `radioGroupItemVariants` are the cva (class-variance-authority) configurations powering `<Radi…
|
||||
- radio-group.variants — `radioGroupVariants` and `ra…
|
||||
|
||||
- [radio-group.variants](./radio-group.variants.md) — `radioGroupVariants` and `radioGroupItemVariants` are the cva (class-variance-authority) configurations powering `<Radi…
|
||||
|
||||
- radio-group.variants — `radioGroupVariants` and `ra…
|
||||
|
||||
- [radio-group.variants](./radio-group.variants.md) — `radioGroupVariants` and `radioGroupItemVariants` are the cva (class-variance-authority) configurations powering `<Radi…
|
||||
|
||||
- radio-group.variants — `radioGroupVariants` and `ra…
|
||||
|
||||
- [radio-group.variants](./radio-group.variants.md) — `radioGroupVariants` and `radioGroupItemVariants` are the cva (class-variance-authority) configurations powering `<Radi…
|
||||
- [radio-group.variants](./radio-group.variants.md) — `radioGroupVariants` and `radioGroupItemVariants` are the cva (class-variance-authority) configurations powering `<Radi…
|
||||
|
||||
## Purpose
|
||||
|
||||
`<RadioGroup>` and `<RadioGroupItem>` are the chassis radio-group primitives built on `@radix-ui/react-radio-group`. Radix supplies the a11y semantics (`role="radiogroup"` on the container, `role="radio"` on each item, roving tabindex across items, arrow-key navigation, native `Space` activation, controlled `value` propagation); the chassis layers a vertical-stack flex/gap layout via cva and a circular indicator dot rendered with `<CircleIcon fill-current>` from `lucide-react`.
|
||||
|
||||
Per the shadcn convention, items always sit inside the group via `<RadioGroupItem>` — rendering an item without a group is unsupported. Both components forward refs to their underlying Radix elements so consumers can focus / measure / drive animations.
|
||||
|
||||
## Features
|
||||
|
||||
- Container renders a `<div role="radiogroup">` with `grid gap-2` so items stack vertically with a small uniform gap (NOT `space-y-*` per the shadcn skill rule).
|
||||
- Items render a `<button role="radio">` with the circular `border-primary` outline.
|
||||
- Three sizes for items (`sm`, `default`, `lg`) scaling the radio circle.
|
||||
- Indicator dot rendered via `<CircleIcon fill-current text-current>` so the dot inherits the surrounding text colour and the chassis switches it without an extra theme prop.
|
||||
- Controlled and uncontrolled use via Radix `value` / `defaultValue` / `onValueChange`.
|
||||
- `disabled` per-item or per-group blocks pointer + keyboard input.
|
||||
- Refs forwarded on both `<RadioGroup>` and `<RadioGroupItem>`.
|
||||
- `motion-reduce:transition-none` collapses transitions for `prefers-reduced-motion: reduce`.
|
||||
- Theme-driven variant overrides via `useThemedVariants("RadioGroup" | "RadioGroupItem")`.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import { RadioGroup, RadioGroupItem } from "@suaveplan/react-ui";
|
||||
|
||||
export function PlanPicker() {
|
||||
return (
|
||||
<RadioGroup defaultValue="pro">
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="free" id="plan-free" />
|
||||
<label htmlFor="plan-free">Free</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="pro" id="plan-pro" />
|
||||
<label htmlFor="plan-pro">Pro</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<RadioGroupItem value="team" id="plan-team" />
|
||||
<label htmlFor="plan-team">Team</label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import { RadioGroup, RadioGroupItem, FieldSet, FieldLegend } from "@suaveplan/react-ui";
|
||||
import { useState } from "react";
|
||||
|
||||
interface DeliverySpeed {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
readonly description: string;
|
||||
readonly disabled?: boolean;
|
||||
}
|
||||
|
||||
export function DeliveryPicker({ options }: { options: readonly DeliverySpeed[] }) {
|
||||
const [speed, setSpeed] = useState("standard");
|
||||
|
||||
return (
|
||||
<FieldSet>
|
||||
<FieldLegend>Delivery speed</FieldLegend>
|
||||
<RadioGroup value={speed} onValueChange={setSpeed}>
|
||||
{options.map((opt) => (
|
||||
<div key={opt.id} className="flex items-start gap-2">
|
||||
<RadioGroupItem
|
||||
value={opt.id}
|
||||
id={`delivery-${opt.id}`}
|
||||
disabled={opt.disabled}
|
||||
className="mt-1"
|
||||
/>
|
||||
<div>
|
||||
<label htmlFor={`delivery-${opt.id}`}>{opt.label}</label>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{opt.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</RadioGroup>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `<RadioGroup>`
|
||||
|
||||
`forwardRef<ComponentRef<typeof RadioGroupPrimitive.Root>, RadioGroupProps>` — renders the Radix Root.
|
||||
|
||||
#### `RadioGroupProps`
|
||||
|
||||
Inherits every prop from Radix `RadioGroupPrimitive.Root` except `asChild`. Common props:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `value` | `string` | _uncontrolled_ | Currently selected value. |
|
||||
| `defaultValue` | `string` | _none_ | Initial value for uncontrolled use. |
|
||||
| `onValueChange` | `(value: string) => void` | _none_ | Fires on value change. |
|
||||
| `disabled` | `boolean` | `false` | Disables every item. |
|
||||
| `name` | `string` | _none_ | Native form-field name. |
|
||||
| `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Arrow-key navigation axis. |
|
||||
|
||||
### `<RadioGroupItem>`
|
||||
|
||||
`forwardRef<ComponentRef<typeof RadioGroupPrimitive.Item>, RadioGroupItemProps>` — renders a Radix Item containing the indicator dot.
|
||||
|
||||
#### `RadioGroupItemProps`
|
||||
|
||||
Inherits every prop from Radix `RadioGroupPrimitive.Item` except `asChild`. Adds:
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `size` | `"sm" \| "default" \| "lg"` | `"default"` | Visual variant scaling the radio circle. |
|
||||
| `value` | `string` | _required_ | Unique value within the surrounding group. |
|
||||
|
||||
#### `radioGroupVariants` / `radioGroupItemVariants`
|
||||
|
||||
Both bare cva resolvers exported for external composition.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The container uses `grid gap-2` rather than `flex flex-col gap-2` because `grid` collapses cross-axis layout in a way that keeps the items column-aligned even when they have wildly different content lengths (label + description blocks).
|
||||
- Per the shadcn skill rule, the chassis NEVER uses `space-y-*` — `grid gap-*` flows the same in RTL.
|
||||
- The indicator dot uses `fill-current text-current` so it inherits the surrounding text colour automatically; theme overrides do not need to special-case the dot.
|
||||
- Refs target the Radix Root + Item. The Item ref attaches to the rendered `<button>` so consumers can `.focus()` programmatically.
|
||||
- Items that require a description/help text typically wrap the radio + content in `<div className="flex items-start gap-2">` with `mt-1` on the radio so the dot aligns with the first line of text.
|
||||
Reference in New Issue
Block a user