Vitral 0.2
Form

RadioButton

Native radios under drawn rings, grouped by RadioGroup with one name and one v-model.

Import

main.ts
import { RadioButton } from '@vitral/vue';

Radio group

Tab into the group, then use the arrow keys.

Delivery
Value: standard
<script setup lang="ts">import { RadioButton, RadioGroup, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const delivery = ref('standard');</script> <template>    <StackPanel spacing="1rem">        <small id="rb-delivery" style="color: var(--vt-text-muted-color)">Delivery</small>        <RadioGroup v-model="delivery" aria-labelledby="rb-delivery">            <RadioButton value="standard" label="Standard (5–7 days)" />            <RadioButton value="express" label="Express (2 days)" />            <RadioButton value="pickup" label="Pick up in store" />            <RadioButton value="drone" label="Drone" disabled />        </RadioGroup>        <small style="color: var(--vt-text-muted-color)">Value: {{ delivery }}</small>    </StackPanel></template>

Horizontal, with object values

Plan
Value: { "id": "pro", "name": "Pro", "price": 12 }
<script setup lang="ts">import { RadioButton, RadioGroup, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const plans = [    { id: 'free', name: 'Free', price: 0 },    { id: 'pro', name: 'Pro', price: 12 },    { id: 'team', name: 'Team', price: 30 }];const plan = ref<(typeof plans)[number] | null>(plans[1]!);</script> <template>    <StackPanel spacing="1rem">        <small id="rb-plan" style="color: var(--vt-text-muted-color)">Plan</small>        <RadioGroup v-model="plan" orientation="horizontal" aria-labelledby="rb-plan">            <RadioButton v-for="p in plans" :key="p.id" :value="p">{{ p.name }} <small style="color: var(--vt-text-muted-color)">${{ p.price }}/mo</small></RadioButton>        </RadioGroup>        <small style="color: var(--vt-text-muted-color)">Value: {{ plan }}</small>    </StackPanel></template>

Invalid and sizes

Size (required)
<script setup lang="ts">import { RadioButton, RadioGroup, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const size = ref<string | null>(null);</script> <template>    <StackPanel spacing="1rem">        <small id="rb-size" style="color: var(--vt-text-muted-color)">Size (required)</small>        <RadioGroup v-model="size" orientation="horizontal" aria-labelledby="rb-size" :invalid="size === null">            <RadioButton value="s" label="Small" size="small" />            <RadioButton value="m" label="Medium" />            <RadioButton value="l" label="Large" size="large" />        </RadioGroup>    </StackPanel></template>

Without a group

Standalone radios share a group by their `name`.

<script setup lang="ts">import { RadioButton } from '@vitral/vue';import { ref } from 'vue'; const theme = ref('light');</script> <template>    <RadioButton v-model="theme" value="light" name="rb-theme" label="Light" />    <RadioButton v-model="theme" value="dark" name="rb-theme" label="Dark" />    <RadioButton model-value="on" value="on" name="rb-disabled" label="Disabled checked" disabled /></template>

API

Read from packages/vue/src/components/RadioButton/types.ts, so it says what the component actually accepts.

Props

NameTypeDescription
valueanyWhat v-model becomes when this radio is chosen; compared structurally, so objects work.
namestringRadios that share a name are one group to the browser. A RadioGroup provides it.
labelstringThe text beside the ring; the default slot takes richer content. Either becomes its `<label>`.
sizeSize—
invalidboolean—
disabledboolean—

Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.

Emits

EventPayloadDescription
changeevent: RadioButtonChangeEvent—
focusevent: FocusEvent—
blurevent: FocusEvent—

Slots

NameSlot propsDescription
default—The label's content.