Radio group
Choose one answer from a short list, cards or a segmented bar; the whole row or card is the click target.
<script setup lang="ts">import { ref } from 'vue'import { UiRadioGroup, UiRadio } from 'grani' const delivery = ref('door')</script> <template> <UiRadioGroup v-model="delivery" aria-label="Delivery" class="w-80"> <UiRadio value="door"> Leave the parcel at the door if nobody answers, and send a photo of where it was left </UiRadio> <UiRadio value="neighbor" description="The courier rings the flat next door"> Hand it to a neighbor </UiRadio> <UiRadio value="point" description="Not in your area yet" disabled> Take it to a pickup point </UiRadio> </UiRadioGroup></template>
Also called radio buttons, segmented control, option cards.
Usage
<UiRadioGroup v-model="value">…</UiRadioGroup> With GraniResolver in the Vite config, a template needs no import: set it up once.
API
| Name · type | Default | Description |
|---|---|---|
| Value | ||
| modelValue*SelectValue | null | The selected value (v-model). null when nothing is selected. | |
| Look | ||
| variantplain | card | card-check | segmented= "plain" | "plain" | plain rows with the mark first; card a card per radio with the mark at the end; card-check cards that show a check and a tint on the selected one only; segmented a bar with one segment pressed. |
| sizexs | sm | md | Step of the control ladder. A segmented bar is 36 or 44 px (xs is read as sm: a 24px segment is too small to hit); a plain mark is 16, 18 or 20 px. Unset, the app's size (createGrani({ size })). | |
| blockboolean= false | false | A segmented bar as wide as its row, segments sharing the width. |
| Form and access | ||
| namestring | Native name shared by every radio, for forms. Generated when omitted, stable across server and client; two apps on one page need their own app.config.idPrefix. | |
| disabledboolean= false | false | Prevents selecting in every radio. |
| invalidboolean= false | false | Marks the group as invalid: red marks. Inside UiField, the error state sets this automatically. |
| idstring | Own id of the group, for a reference from elsewhere (aria-controls, a link); a field names it by its legend. | |
| ariaLabelstring | Accessible name of the group when there is no visible legend. Inside a UiField group the legend names it. | |
| requiredboolean= false | false | One answer is needed: said to a reader on the group, and required on the radios for a form. Inside UiField group the legend says it instead. |
Attributes: class and style stay on the outer element; the rest (native attributes, aria-*, data-testid) reach the control inside it.
Radio
| Name · type | Default | Description |
|---|---|---|
| value*SelectValue | The value this radio stands for; the group's model takes it when selected. | |
| descriptionstring | A second line under the label. Read with the radio as its description. Not drawn in a segment. | |
| disabledboolean= false | false | Prevents selecting this radio; the group's disabled covers all of them. |
| idstring | Own id, for a label elsewhere. | |
| ariaLabelstring | Accessible name when the slot has no text: a glyph segment, a label outside the row. |
Attributes: class and style stay on the outer element; the rest (native attributes, aria-*, data-testid) reach the control inside it.
When to use another component
| When you need | Take |
|---|---|
| Several answers | Checkbox in a Field group |
| A mark from 1 to N | Scale input |
| A pick from a long list | Select |
| On or off | Switch |
| Sections of a page, each with its own content | Tabs |
| Actions side by side | Button group |