# Radio Primitive

Radio is a Starwind Runtime primitive in the single-boolean-control contract family.
Astro and React share one semantic component API. React coordinates reactive state through controlled and default props plus callbacks. Astro renders initial state and coordinates later changes through DOM events and Runtime methods. Raw HTML uses Runtime attributes, DOM events, and imperative methods.
## Anatomy
### Astro
Use the Astro primitive adapter to render Radio anatomy with the Runtime wiring included.
```astro
---
import { Radio } from "@starwind-ui/astro/radio";
---

<Radio.Root value="option-one">
  <Radio.Indicator />
</Radio.Root>
```

### React
Use the React primitive adapter when Radio state participates in React rendering.
```tsx
import { Radio } from "@starwind-ui/react/radio";

export function Example() {
  return (
    <Radio.Root value="option-one">
      <Radio.Indicator />
    </Radio.Root>
  );
}
```

### HTML
Render the Radio data-sw-* contract yourself, then initialize createRadio.
```html
<span data-sw-radio role="radio" data-value="option-one">
  <span data-sw-radio-indicator></span>
  <input data-sw-radio-input type="radio" aria-hidden="true" tabindex="-1" />
</span>

<script type="module">
  import { createRadio } from "@starwind-ui/runtime/radio";

  const root = document.querySelector("[data-sw-radio]");
  if (root) {
    createRadio(root);
  }
</script>
```

### Vue
Use the Vue 3.5 beta adapter to render Radio anatomy.
```vue
<script setup lang="ts">
import Radio from "@starwind-ui/vue/radio";
</script>

<template>
  <Radio.Root value="option-one">
    <Radio.Indicator />
  </Radio.Root>
</template>
```
## API Reference
### Root
The main element that owns the Radio Runtime instance.
| Fact | Value |
| --- | --- |
| Default element | `span` |
| Discovery hook | `data-sw-radio` |
| Role | `radio` |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| checked | `boolean` | - | control | Controls whether Radio is checked. | **React:** Use checked for controlled state and defaultChecked for default state, and onCheckedChange for change proposals.<br>**Astro:** Use checked or defaultChecked for initial state, listen for starwind:checked-change, and call setChecked for later updates.<br>**Runtime / HTML:** Use data-default-checked for initial state, listen for starwind:checked-change, and call setChecked for later updates. |
| defaultChecked | `boolean` | false | control | Sets whether Radio starts checked for uncontrolled usage. | **React:** Use checked for controlled state and defaultChecked for default state, and onCheckedChange for change proposals.<br>**Astro:** Use checked or defaultChecked for initial state, listen for starwind:checked-change, and call setChecked for later updates.<br>**Runtime / HTML:** Use data-default-checked for initial state, listen for starwind:checked-change, and call setChecked for later updates. |
| disabled | `boolean` | false | option | Disables the Root part. | - |
| form | `string` | - | option | Associates the control with a form element. | - |
| id | `string` | - | option | Sets the id used by the associated native control. | - |
| name | `string` | - | option | Sets the submitted form field name. | - |
| nativeButton | `boolean` | false | rendering | Renders the control as a native button element. | - |
| readOnly | `boolean` | false | option | Marks the control as read-only. | - |
| required | `boolean` | false | option | Marks the form control as required. | - |
| value | `string` | - | option | Controls the current Radio value. | - |
| onCheckedChange | `(checked: boolean, details: RadioCheckedChangeDetails) => void` | - | callback | Runs when the Radio checked state changes. | **React:** Use checked for controlled state and defaultChecked for default state, and onCheckedChange for change proposals.<br>**Astro:** Use checked or defaultChecked for initial state, listen for starwind:checked-change, and call setChecked for later updates.<br>**Runtime / HTML:** Use data-default-checked for initial state, listen for starwind:checked-change, and call setChecked for later updates. |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-radio` | runtime | - | Marks the Root part so Starwind Runtime can find it. |
| `data-checked` | state | - | Reflects the checked state on the Root part. |
| `data-default-checked` | prop | - | Reflects the default checked prop on the Root part. |
| `data-disabled` | prop | - | Reflects the disabled prop on the Root part. |
| `data-form` | prop | - | Reflects the form prop on the Root part. |
| `data-id` | prop | - | Reflects the id prop on the Root part. |
| `data-name` | prop | - | Reflects the name prop on the Root part. |
| `data-readonly` | prop | - | Reflects the readonly prop on the Root part. |
| `data-required` | prop | - | Reflects the required prop on the Root part. |
| `data-unchecked` | state | - | Reflects the unchecked state on the Root part. |
| `data-value` | prop | - | Reflects the value prop on the Root part. |
#### State
| State | Value Type | Controlled Prop | Default Prop | Initial Attribute | Runtime Getter | Runtime Setter | Description | State Control Support |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| checked | `boolean` | checked | defaultChecked | `data-default-checked` | `getChecked` | `setChecked` | Tracks whether Radio is checked. | **React:** Use checked for controlled state and defaultChecked for default state, and onCheckedChange for change proposals.<br>**Astro:** Use checked or defaultChecked for initial state, listen for starwind:checked-change, and call setChecked for later updates.<br>**Runtime / HTML:** Use data-default-checked for initial state, listen for starwind:checked-change, and call setChecked for later updates. |
#### Events
| Event | Callback | DOM Event | Value | Details | Timing | Cancelable | Description | Cancellation Sequence |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| checkedChange | onCheckedChange | starwind:checked-change | checked: `boolean` | RadioCheckedChangeDetails | before-state-commit | Yes | Fires when the checked state changes for Radio. | 1. Check internal eligibility and intent.<br>2. Create one details object for the proposal.<br>3. Call the Runtime callback with the details object when the controller exposes one.<br>4. Dispatch the cancelable DOM event with the same details object, including when the callback canceled it.<br>5. Read details.isCanceled, including cancellation caused by preventDefault().<br>6. Apply the accepted state.<br>7. Notify Runtime subscribers and other accepted-only observers. |
#### Runtime Setters
| Method | Target | Options | Suppresses Emit | Description |
| --- | --- | --- | --- | --- |
| `setChecked` | state: checked | emit: false | Yes | Updates whether Radio is checked from Runtime code. |
| `setDisabled` | prop: disabled | - | No | Updates whether Radio is disabled from Runtime code. |
| `setReadOnly` | prop: readOnly | - | No | Updates whether Radio is read-only from Runtime code. |
| `setFormOptions` | props: form, name, required, value | - | No | Updates Radio form-related options from Runtime code. |
#### Refs
| Part | Public |
| --- | --- |
| root | Yes |
#### Context
| Name | Direction | Values |
| --- | --- | --- |
| radio-group | consumes | disabled, form, name, readOnly, required, value |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-radio`, `role`, `aria-checked`, `data-checked`, `data-unchecked`, `data-default-checked`, `data-disabled` | The visible radio needs ARIA and state styling before the controller attaches. |
#### Form
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (radio) |

### Indicator
Visual state indicator rendered by Radio.
| Fact | Value |
| --- | --- |
| Default element | `span` |
| Discovery hook | `data-sw-radio-indicator` |
| Role | - |
#### Props
| Prop | Type | Default | Kind | Description | Framework Behavior |
| --- | --- | --- | --- | --- | --- |
| keepMounted | `boolean` | false | rendering | Keeps the Indicator part in the DOM when hidden. | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-radio-indicator` | runtime | - | Marks the Indicator part so Starwind Runtime can find it. |
| `data-keep-mounted` | prop | - | Reflects the keep mounted prop on the Indicator part. |
| `data-unchecked` | state | - | Reflects the unchecked state on the Indicator part. |
#### Refs
| Part | Public |
| --- | --- |
| indicator | Yes |
#### Presence
| Fact | Value |
| --- | --- |
| Initial hidden | Yes |
| Unmount policy | runtime-owned |
| Keep mounted prop | keepMounted |

### Input
The native input synchronized by Radio.
| Fact | Value |
| --- | --- |
| Default element | `input` |
| Discovery hook | `data-sw-radio-input` |
| Role | - |
#### Data Attributes
| Attribute | Source | Value | Description |
| --- | --- | --- | --- |
| `data-sw-radio-input` | runtime | - | Marks the Input part so Starwind Runtime can find it. |
#### Initial Markup
| Attributes | Reason |
| --- | --- |
| `data-sw-radio-input` | The runtime needs the hidden input placeholder so it can attach form state after hydration; native button roots place it as a sibling after the visible button. |
#### Form
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (radio) |
## Runtime API
| Fact | Value |
| --- | --- |
| Factory | [`createRadio`](/docs/runtime/#create-radio) |
| Import | `@starwind-ui/runtime/radio` |
| Root part | root |
| Option props | checked, defaultChecked, disabled, form, id, name, readOnly, required, value |
| Option lifecycles | - |
## Form Participation
| Fact | Value |
| --- | --- |
| Form props | form, id, name, required, value |
| Hidden input | input (radio) |
| Field integration | Yes |
## Related Styled Components
| Component | Relationship |
| --- | --- |
| [Radio Group](/docs/components/radio-group/) | Composite |
## Exports
| Group | Import | Exports |
| --- | --- | --- |
| Runtime | `@starwind-ui/runtime/radio` | `createRadio` |
| Astro Primitive | `@starwind-ui/astro/radio` | `Radio`, `RadioRoot`, `RadioIndicator` |
| React Primitive | `@starwind-ui/react/radio` | `Radio`, `RadioRoot`, `RadioIndicator` |
## Canonical Names
| Kind | Name |
| --- | --- |
| namespace | `Radio` |
| runtime-factory | `createRadio` |
| part | `Radio.Root` |
| part | `Radio.Indicator` |
## Changelog
### v1.0.1
- Removed obsolete private-release warnings from generated Vue adapters and normalized the resulting blank line in vendored Primitive indexes.
### v1.0.0
- Promoted this Primitive's vendoring version to the stable 1.0.0 baseline. Its existing API and Runtime behavior carry forward from the previous release.
### v0.1.2
- Marked generated React Primitive files as client modules so vendored installs preserve client boundaries in React server frameworks.
- Kept generated React state-change callbacks and DOM events cancelable until the Runtime accepts the proposed state, then synchronized rendered state.
### v0.1.1
- Synchronized vendored React Radio state after accepted Runtime transitions and external state changes.
### v0.1.0
- Introduced radio item checked state, disabled behavior, and native form participation.