Files
svelte-headlessui/src/routes/docs/latest/radio-group.svx
2023-06-11 14:45:30 -07:00

241 lines
9.6 KiB
Plaintext

# Radio Group
<script>
import Preview from "./_Preview.svelte";
</script>
<Preview url="examples/radio-group" code="" class="h-[380px] bg-cyan-300"/>
## Basic example
Radio Groups are built using a combination of the `RadioGroup`, `RadioGroupOption`, `RadioGroupLabel`, and `RadioGroupDescription` components:
```svelte
<script>
import {
RadioGroup,
RadioGroupLabel,
RadioGroupOption,
RadioGroupDescription,
} from "@rgossiaux/svelte-headlessui";
let plan = "startup";
</script>
<RadioGroup bind:value={plan}>
<RadioGroupLabel>Plan</RadioGroupLabel>
<RadioGroupOption value="startup" let:checked>
<span class:checked>Startup</span>
</RadioGroupOption>
<RadioGroupOption value="business" let:checked>
<span class:checked>Business</span>
</RadioGroupOption>
<RadioGroupOption value="enterprise" let:checked>
<span class:checked>Enterprise</span>
</RadioGroupOption>
</RadioGroup>
<style>
.checked {
/* Your styles here */
}
</style>
```
## Styling
[See here](general-concepts#component-styling) for some general notes on styling the components in this library.
### Checked option
To style the selected `RadioGroupOption`, you can use the `checked` slot prop that it provides, which tells you whether or not that option is the currently selected one. You can use this state to conditionally apply whatever styles you wish.
```svelte
<script>
import {
RadioGroup,
RadioGroupLabel,
RadioGroupOption,
} from "@rgossiaux/svelte-headlessui";
let plan = "startup";
</script>
<RadioGroup bind:value={plan}>
<RadioGroupLabel>Plan</RadioGroupLabel>
<!-- Use the `checked` slot prop to conditionally style the checked item -->
<RadioGroupOption value="startup" let:checked>
<span class:checked>Startup</span>
</RadioGroupOption>
<!-- ... -->
</RadioGroup>
<style>
.checked {
/* Your styles here */
}
</style>
```
### Active options
`RadioGroupOption`s can also be in an `active` state if they are focused with either the mouse or the keyboard. It's a good idea to add styles specifically for this state.
```svelte
<script>
import {
RadioGroup,
RadioGroupLabel,
RadioGroupOption,
} from "@rgossiaux/svelte-headlessui";
let plan = "startup";
</script>
<RadioGroup bind:value={plan}>
<RadioGroupLabel>Plan</RadioGroupLabel>
<!-- Use both `active` and `checked` slot props
to differentiate between the active and checked states -->
<RadioGroupOption value="startup" let:active let:checked>
<span class:active class:checked>Startup</span>
</RadioGroupOption>
<!-- ... -->
</RadioGroup>
<style>
.active {
/* Your styles here */
}
.checked {
/* Your styles here */
}
</style>
```
## Using the Label and Description components
You can use the `RadioGroupLabel` and `RadioGroupDescription` components to label and describe each `RadioGroupOption`, as well as the `RadioGroup` itself. These components will automatically link with their relevant ancestor components via the `aria-labelledby` and `aria-describedby` attributes, improving the semantics and accessibility of your component.
By default, `RadioGroupLabel` renders a `<label>` element and `RadioGroupDescription` renders a `<p>`. These can be customized using the `as` prop, as described in the API docs below.
```svelte
<script>
import {
RadioGroup,
RadioGroupLabel,
RadioGroupOption,
RadioGroupDescription,
} from "@rgossiaux/svelte-headlessui";
let plan = "startup";
</script>
<RadioGroup bind:value={plan}>
<!-- This Label is for the `RadioGroup` -->
<RadioGroupLabel>Plan</RadioGroupLabel>
<RadioGroupOption value="startup" let:checked>
<RadioGroupLabel as="span" class:checked>Startup</span>
<RadioGroupDescription as="span" class:checked>
Up to 5 active job postings
</RadioGroupDescription>
</RadioGroupOption>
<!-- ... -->
</RadioGroup>
<style>
/* WARNING: This is just for demonstration.
Using :global() in this way can be risky. */
:global(.checked) {
/* Your styles here */
}
</style>
```
## Accessibility notes
### Mouse interaction
Clicking a `RadioGroupOption` will select it.
### Keyboard interaction
| Command | Description |
| ----------------------------------------------------------- | ------------------------------------------------------------------ |
| `<ArrowDown>` / `<ArrowRight>` when `RadioGroup` is focused | Focuses and checks the next `RadioGroupOption` |
| `<ArrowUp>` / `<ArrowLeft>` when `RadioGroup` is focused | Focuses and checks the previous `RadioGroupOption` |
| `<Space>` when `RadioGroup` is focused | Checks the current `RadioGroupOption` if it is not already checked |
### Other
All relevant ARIA attributes are automatically managed.
For a full reference on all accessibility features implemented in `RadioGroup`, see <a href="https://www.w3.org/TR/wai-aria-practices-1.2/#radiobutton">the ARIA spec on Radio Groups</a>.
## Component API
### RadioGroup
The main Radio Group component.
| Prop | Default | Type | Description |
| ---------- | ------- | ------------------ | ------------------------------------------------------------------------ |
| `as` | `div` | `string` | The element the `RadioGroup` should render as |
| `disabled` | `false` | `boolean` | Whether the `RadioGroup` and all of its `RadioGroupOption`s are disabled |
| `value` | -- | `T` \| `undefined` | The currently selected value in the `RadioGroup` |
This component also dispatches a custom event, which is listened to using the Svelte `on:` directive:
| Event name | Type of event `.detail` | Description |
| ---------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `change` | `T` | Dispatched when a `RadioGroupOption` is selected; the event `detail` contains the `value` of the selected option |
### RadioGroupOption
The wrapper component for each selectable option.
| Prop | Default | Type | Description |
| ---------- | ------- | ------------------ | ----------------------------------------------------------------------------------------------------------- |
| `as` | `div` | `string` | The element the `RadioGroupOption` should render as |
| `disabled` | `false` | `boolean` | Whether the `RadioGroupOption` is disabled |
| `value` | -- | `T` \| `undefined` | The value of the `RadioGroupOption`; the type should match the type of the `value` prop in the `RadioGroup` |
| Slot prop | Type | Description |
| ---------- | --------- | ---------------------------------------------------------- |
| `active` | `boolean` | Whether the option is active (using the mouse or keyboard) |
| `checked` | `boolean` | Whether the option is the checked option |
| `disabled` | `boolean` | Whether the option is disabled |
### RadioGroupLabel
Renders an element that is linked to its nearest `RadioGroup` or `RadioGroupOption` ancestor component via the `aria-labelledby` attribute and an autogenerated id.
| Prop | Default | Type | Description |
| ---- | ------- | -------- | -------------------------------------------------- |
| `as` | `label` | `string` | The element the `RadioGroupLabel` should render as |
If the `RadioGroupLabel` is labeling a `RadioGroupOption` (instead of the `RadioGroup`), it will also have these slot props available:
| Slot prop | Type | Description |
| ---------- | --------- | ------------------------------------------------------------------------ |
| `active` | `boolean` | Whether the corresponding option is active (using the mouse or keyboard) |
| `checked` | `boolean` | Whether the corresponding option is the checked option |
| `disabled` | `boolean` | Whether the corresponding option is disabled |
### RadioGroupDescription
Renders an element that is linked to its nearest `RadioGroup` or `RadioGroupOption` ancestor component via the `aria-describedby` attribute and an autogenerated id.
| Prop | Default | Type | Description |
| ---- | ------- | -------- | -------------------------------------------------------- |
| `as` | `a` | `string` | The element the `RadioGroupDescription` should render as |
If the `RadioGroupDescription` is describing a `RadioGroupOption` (instead of the `RadioGroup`), it will also have these slot props available:
| Slot prop | Type | Description |
| ---------- | --------- | ------------------------------------------------------------------------ |
| `active` | `boolean` | Whether the corresponding option is active (using the mouse or keyboard) |
| `checked` | `boolean` | Whether the corresponding option is the checked option |
| `disabled` | `boolean` | Whether the corresponding option is disabled |