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>