Skip to content

Radio group

A radio group lets users pick a single option from a small, fully visible set of choices. Each choice is a Radio, and the selected one is bound through v-model and reflects the value of the active radio.

TIP

Reach for a radio group when every option should stay visible at a glance. When the list is long or space is tight, prefer a Select instead. When wrapped in a required Form field, the group (role="radiogroup") automatically receives aria-required, and setting error exposes aria-invalid.

Props

model-value?: string | number | boolean
The value of the selected radio.

name?: string
The shared name of the underlying radio inputs. Generated automatically when omitted.

aria-label?: string
The accessible label of the radio group.

is-inline?: boolean
Lays the radios out horizontally instead of stacked.

is-connected?: boolean
Joins [Radio tiles](./tile) into a single block with shared borders and rounded outer corners. Not meant to be mixed with regular radios.

disabled?: boolean
If the entire radio group is disabled.

error?: string
The error message, marking every radio as invalid.

is-readonly?: boolean
If the radio group is read-only.

Emits

update:model-value: [string, number, boolean]
Triggered when the selected radio changes.

Slots

default
The radios of the group, rendered as [Radio](./) components.

Examples

Basic

A radio group inside a form field.

Plan

<template>
    <FluxPane style="max-width: 390px">
        <FluxForm>
            <FluxPaneBody>
                <FluxFormField
                    as="group"
                    label="Plan">
                    <FluxFormRadioGroup v-model="plan">
                        <FluxFormRadio
                            value="free"
                            label="Free"/>

                        <FluxFormRadio
                            value="pro"
                            label="Pro"/>

                        <FluxFormRadio
                            value="enterprise"
                            label="Enterprise"/>
                    </FluxFormRadioGroup>
                </FluxFormField>
            </FluxPaneBody>
        </FluxForm>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxForm, FluxFormField, FluxPane, FluxPaneBody, FluxFormRadio, FluxFormRadioGroup } from '@flux-ui/components';
    import { ref } from 'vue';

    const plan = ref('pro');
</script>

Inline

A radio group laid out horizontally.

<template>
    <FluxFormRadioGroup
        v-model="size"
        is-inline>
        <FluxFormRadio
            value="s"
            label="Small"/>

        <FluxFormRadio
            value="m"
            label="Medium"/>

        <FluxFormRadio
            value="l"
            label="Large"/>
    </FluxFormRadioGroup>
</template>

<script
    setup
    lang="ts">
    import { FluxFormRadio, FluxFormRadioGroup } from '@flux-ui/components';
    import { ref } from 'vue';

    const size = ref('m');
</script>

Disabled item

A radio group with a single disabled option.

<template>
    <FluxFormRadioGroup v-model="plan">
        <FluxFormRadio
            value="free"
            label="Free"/>

        <FluxFormRadio
            value="pro"
            label="Pro"/>

        <FluxFormRadio
            value="enterprise"
            label="Enterprise"
            disabled/>
    </FluxFormRadioGroup>
</template>

<script
    setup
    lang="ts">
    import { FluxFormRadio, FluxFormRadioGroup } from '@flux-ui/components';
    import { ref } from 'vue';

    const plan = ref('pro');
</script>

Tile

Card-style options through Radio tile, with an icon and description.

Payment method

<template>
    <FluxPane style="max-width: 411px">
        <FluxForm>
            <FluxPaneBody>
                <FluxFormField
                    as="group"
                    label="Payment method">
                    <FluxFormRadioGroup v-model="method">
                        <FluxFormRadioTile
                            value="card"
                            icon="money-bill"
                            label="Card"
                            sub-label="Pay with a saved or new card."/>

                        <FluxFormRadioTile
                            value="bank"
                            icon="building-columns"
                            label="Bank transfer"
                            sub-label="Pay directly from your bank."/>
                    </FluxFormRadioGroup>
                </FluxFormField>
            </FluxPaneBody>
        </FluxForm>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxForm, FluxFormField, FluxFormRadioGroup, FluxFormRadioTile, FluxPane, FluxPaneBody } from '@flux-ui/components';
    import { ref } from 'vue';

    const method = ref('card');
</script>

Mixed

Combine tiles with a regular radio for a less prominent option.

Payment method

<template>
    <FluxPane style="max-width: 411px">
        <FluxForm>
            <FluxPaneBody>
                <FluxFormField
                    as="group"
                    label="Payment method">
                    <FluxFormRadioGroup v-model="method">
                        <FluxFormRadioTile
                            value="card"
                            icon="money-bill"
                            label="Card"
                            sub-label="Pay with a saved or new card."/>

                        <FluxFormRadioTile
                            value="bank"
                            icon="building-columns"
                            label="Bank transfer"
                            sub-label="Pay directly from your bank."/>

                        <FluxFormRadio
                            value="invoice"
                            label="Pay later by invoice"/>
                    </FluxFormRadioGroup>
                </FluxFormField>
            </FluxPaneBody>
        </FluxForm>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxForm, FluxFormField, FluxFormRadio, FluxFormRadioGroup, FluxFormRadioTile, FluxPane, FluxPaneBody } from '@flux-ui/components';
    import { ref } from 'vue';

    const method = ref('card');
</script>

Connected

Join the tiles into a single block with is-connected.

Payment method

<template>
    <FluxPane style="max-width: 411px">
        <FluxForm>
            <FluxPaneBody>
                <FluxFormField
                    as="group"
                    label="Payment method">
                    <FluxFormRadioGroup
                        v-model="method"
                        is-connected>
                        <FluxFormRadioTile
                            value="card"
                            icon="money-bill"
                            label="Card"
                            sub-label="Pay with a saved or new card."/>

                        <FluxFormRadioTile
                            value="bank"
                            icon="building-columns"
                            label="Bank transfer"
                            sub-label="Pay directly from your bank."/>

                        <FluxFormRadioTile
                            value="paypal"
                            icon="bolt"
                            label="PayPal"
                            sub-label="Pay using your PayPal balance."/>
                    </FluxFormRadioGroup>
                </FluxFormField>
            </FluxPaneBody>
        </FluxForm>
    </FluxPane>
</template>

<script
    setup
    lang="ts">
    import { FluxForm, FluxFormField, FluxFormRadioGroup, FluxFormRadioTile, FluxPane, FluxPaneBody } from '@flux-ui/components';
    import { ref } from 'vue';

    const method = ref('card');
</script>

Used components