This component is deprecated and will be removed in the next major release.
use NRadio to create a radio input.
| Attribute | Description |
|---|
v-model | Reactive value of radio if checked or not. |
value | The value of the radio. |
label | The label of the radio. |
To view the full list of attributes, see the Props section.
<script setup lang="ts">
const radio = ref('a')
</script>
<template>
<div class="flex gap-4">
<NRadio
v-model="radio"
value="a"
label="Radio A"
/>
<NRadio
v-model="radio"
value="b"
label="Radio B"
/>
<NRadio
v-model="radio"
value="c"
label="Radio C"
/>
</div>
</template>
radio="{color}" - change the color of the radio.
You can use breakpoints such as sm:red, xs:green to change color based on screen size.
You can use any color provided by the Tailwind CSS color palette, the default is primary. You can also add your own colors to the palette through the Configuration section.
<script setup lang="ts">
const radio = ref('')
const colors = [
{
radio: 'red sm:primary',
},
{
radio: 'info',
},
{
radio: 'error',
},
{
radio: 'warning',
},
{
radio: 'success',
},
{
radio: 'purple',
},
{
radio: 'pink',
},
{
radio: 'violet',
},
{
radio: 'fuchsia',
},
{
radio: 'indigo',
},
]
</script>
<template>
<div class="flex flex-wrap gap-4">
<NRadio
v-for="color in colors"
:key="color.radio"
v-model="radio"
:label="color.radio"
:radio="color.radio"
:value="color.radio"
/>
</div>
</template>
disabled - disable the radio.
<script setup lang="ts">
const radio = ref()
</script>
<template>
<div class="flex gap-4">
<NRadio
v-model="radio"
value="a"
label="Disabled"
disabled
/>
<NRadio
v-model="radio"
value="b"
label="Not disabled"
/>
</div>
</template>
You can use the NFormGroup component to create a radio group for the radio,
Read more about the NFormGroup component here.
Remember to set for to false to disable for behavior on the label since we have a custom implementation for the radio input.
<script setup lang="ts">
const gender = ref('digital ocean')
const options = [
{
label: 'Digital Ocean',
value: 'digital ocean',
radio: 'blue',
},
{
label: 'AWS',
value: 'aws',
radio: 'amber',
},
{
label: 'Google Cloud',
value: 'google cloud',
radio: 'red',
},
{
label: 'Heroku',
value: 'heroku',
radio: 'purple',
},
]
</script>
<template>
<div class="flex flex-col space-y-6">
<!-- Vertical -->
<NFormGroup
:for="false"
label="Service Provider"
description="Please select your service provider"
>
<NRadio v-for="option in options" :key="option.value" v-model="gender" v-bind="option" />
</NFormGroup>
<NSeparator />
<!-- Horizontal -->
<NFormGroup
:for="false"
label="Service Provider"
description="Please select your service provider"
required
status="error"
message="Service provider is required"
>
<div class="flex flex-wrap gap-8">
<NRadio v-for="option in options" :key="option.value" v-model="gender" v-bind="option" />
</div>
</NFormGroup>
</div>
</template>
reverse - Switch the position of the radio and the label.
<script setup lang="ts">
const radio = ref('a')
const choices = [
{ label: 'Radio A', value: 'a' },
{ label: 'Radio B', value: 'b' },
{ label: 'Radio C', value: 'c' },
]
</script>
<template>
<div class="flex flex-wrap space-x-8">
<NRadio
v-for="choice in choices"
:key="choice.value"
v-bind="choice"
v-model="radio"
reverse
/>
</div>
</template>
size="{size}" - change the size of the radio.
🚀 You can freely adjust the size of the radio using any size imaginable. No limits exist, and you can use breakpoints such as sm:sm, xs:lg to change size based on screen size.
<script setup lang="ts">
const radio = ref()
const items = [
{
label: '0.8cm',
size: '0.8cm',
},
{
label: 'xs md:2xl',
size: 'xs md:2xl',
},
{
label: 'sm',
size: 'sm',
},
]
</script>
<template>
<div class="flex gap-4">
<NRadio
v-for="item in items"
:key="item.size"
v-model="radio"
:value="item.size"
v-bind="item"
/>
</div>
</template>
You can use the following rules to customize the radio if it is checked.
You can also globally customize the radio preset if you want to have a different default style. See Configuration section for more details.
| Rule Name | Description | Example |
|---|
n-checked | Only apply the class if the radio is checked. | n-checked:bg-red |
<script setup lang="ts">
const radio = ref('a')
const options = [
{
value: 'vue',
radio: 'green',
class: 'n-checked:bg-green-500/30 n-checked:border-green-500',
},
{
value: 'react',
radio: 'blue',
class: 'n-checked:bg-blue-500/30 n-checked:border-blue-500',
},
{
value: 'angular',
radio: 'red',
class: 'n-checked:bg-red-500/30 n-checked:border-red-500',
},
]
</script>
<template>
<div class="flex flex-wrap gap-4">
<NRadio
v-for="option in options"
v-bind="option"
:key="option.value"
v-model="radio"
:label="option.value"
/>
</div>
</template>
You can customize the radio using the una prop and utility classes.
<script setup lang="ts">
const radio = ref()
const options = [
{
value: 'vue',
class: 'n-checked:bg-green-500/30 n-checked:border-green-500',
radio: 'green',
una: {
radioIcon: 'i-logos-vue n-checked:scale-200 transition-transform duration-1000',
},
},
{
value: 'react',
class: 'n-checked:bg-blue-500/30 n-checked:border-blue-500',
radio: 'blue',
una: {
radioIcon: 'i-logos-react n-checked:rotate-360 transition-transform duration-1000',
},
},
{
value: 'angular',
class: 'n-checked:bg-red-500/30 n-checked:border-red-500',
radio: 'red',
una: {
radioIcon: 'i-logos-angular-icon n-checked:scale-150 transition-transform duration-1000',
},
},
]
</script>
<template>
<div class="flex flex-col space-y-6">
<span>
Value: {{ radio }}
</span>
<div class="flex flex-wrap gap-4">
<NRadio
v-for="option in options"
:key="option.value"
v-model="radio"
:value="option.value"
:radio="option.radio"
:label="option.value"
:class="option.class"
size="15"
class="rounded-md"
:una="{
radioLabel: 'capitalize',
...option.una,
}"
/>
</div>
</div>
</template>
| Name | Description |
|---|
label | Use this slot to customize the label of the radio. |
icon | Use this slot to customize the icon of the radio when it is checked |
import type { RuleContext } from '@unocss/core'
import type { Theme } from '@unocss/preset-uno'
import { parseColor } from '@unocss/preset-mini/utils'
type RadioPrefix = 'radio'
export const staticRadio: Record<`${RadioPrefix}-${string}` | RadioPrefix, string> = {
// base
'radio': 'radio-primary flex items-center transition-base border border-$c-ring rounded-full p-0.12em h-1em w-1em n-checked:border-brand n-checked:bg-brand',
'radio-disabled': 'n-disabled',
'radio-label': 'block text-sm font-medium leading-6',
'radio-input': 'absolute w-full opacity-0',
'radio-reverse': 'flex-row-reverse',
'radio-peer-focus': 'peer-focus-(ring-2 ring-brand ring-offset-2 ring-offset-base)',
// wrappers
'radio-wrapper': 'gap-x-3 relative inline-flex items-center hover:cursor-pointer',
// icon
'radio-icon-base': 'm-auto opacity-0 text-inverted w-full h-full transition-base n-checked:opacity-100',
'radio-icon': 'i-dot', // refer to general.ts
}
export const dynamicRadio = [
[/^radio-(.*)$/, ([, body]: string[], { theme }: RuleContext<Theme>) => {
const color = parseColor(body, theme)
if ((color?.cssColor?.type === 'rgb' || color?.cssColor?.type === 'rgba') && color.cssColor.components)
return `n-${body}-600 dark:n-${body}-500`
}],
]
export const radio = [
...dynamicRadio,
staticRadio,
]
export interface NRadioProps {
/**
* Disable the radio.
*
* @default false
*/
disabled?: boolean
/**
* Switch the position of label and radio.
*
* @default false
*/
reverse?: boolean
/**
* Allows you to add `UnaUI` radio preset properties,
* Think of it as a shortcut for adding options or variants to the preset if available.
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/radio.ts
* @example
* radio="green"
*/
radio?: string
/**
* v-model binding value if the radio is checked.
*
* @default null
*/
modelValue?: string | number | boolean | Record<string, any>
/**
* Add name attribute to the radio.
*
* @default null
*/
name?: string
/**
* Manually set the id attribute.
*
* By default, the id attribute is generated randomly for accessibility reasons.
*
* @default randomId
* @example
* id="options"
*/
id?: string
/**
* Manually set the for attribute.
*
* By default, the for attribute is synced with the id attribute for accessibility reasons.
*
* @default randomId
* @example
* for="options"
*/
for?: string
/**
* Value of the radio.
*
* @example
* value="1"
*/
value?: string
/**
* Display label of the radio.
*
* @default null
*/
label?: string
/**
* Allows you to change the size of the radio.
*
* @default size="sm"
*
* @example
* size="sm" | size="2cm" | size="2rem" | size="2px"
*/
size?: string
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/radio.ts
*/
una?: {
radio?: string
radioWrapper?: string
radioLabel?: string
radioIconBase?: string
radioIcon?: string
}
}
<script setup lang="ts">
import type { NRadioProps } from '../../types'
import { useVModel } from '@vueuse/core'
import { computed } from 'vue'
import { randomId } from '../../utils'
import NIcon from '../elements/Icon.vue'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(
defineProps<NRadioProps>(),
{
modelValue: '',
disabled: false,
una: () => ({
radioIcon: 'radio-icon',
}),
},
)
const emit = defineEmits<{ (...args: any): void }>()
const slots = defineSlots<{
default?: void
icon?: any
}>()
const id = computed(() => props.id ?? randomId('radio'))
const model = useVModel(props, 'modelValue', emit, { passive: true })
</script>
<template>
<label
radio="wrapper"
:for="props.for ?? id"
:class="[
una?.radioWrapper,
{
'radio-reverse': reverse,
'radio-disabled': disabled,
},
]"
:checked="model === value || null"
:disabled="disabled || null"
>
<input
:id="id"
v-model="model"
type="radio"
class="peer"
radio="input"
:disabled="disabled"
:name="name"
:value="value"
@keypress.enter="model = value!"
>
<span
:radio="radio"
:size="size"
class="radio radio-peer-focus"
v-bind="$attrs"
>
<slot name="icon">
<NIcon
:class="[
una.radioIconBase,
]"
radio="icon-base icon-checked"
:name="una.radioIcon!"
/>
</slot>
</span>
<div
v-if="slots.default || label"
radio="label"
:class="una?.radioLabel"
>
<slot>
{{ label }}
</slot>
</div>
</label>
</template>