On this page
RadioButton
A styled radio button with group support, labels, filled/outlined variants, and validation. Radio buttons sharing the same name form a mutually exclusive group.
uwc-radiobutton is a styled radio button. Group several with the same
name attribute for mutually exclusive selection. It fires uwc-change with
{ value } when selected.
Import
All components
import '@uwc/components';
Selected component (Lit / Angular / Vue)
import { UwcRadioButton } from '@uwc/components/radiobutton';
customElements.define('uwc-radiobutton', UwcRadioButton);
React
import { UwcRadioButton } from '@uwc/components/react';
Usage
Lit
import { LitElement, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
@state() value = '';
render() {
return html`
<uwc-radiobutton name="city" value="NY" label="New York"
@uwc-change=${(e) => { this.value = e.detail.value; }}></uwc-radiobutton>
<uwc-radiobutton name="city" value="LA" label="Los Angeles"
@uwc-change=${(e) => { this.value = e.detail.value; }}></uwc-radiobutton>
`;
}
}
React
import React, { useState } from 'react';
import { UwcRadioButton } from '@uwc/components/react';
export default function App() {
const [value, setValue] = useState('');
return (
<>
<UwcRadioButton name="city" value="NY" label="New York"
onUwcChange={(e) => setValue(e.detail.value)} />
<UwcRadioButton name="city" value="LA" label="Los Angeles"
onUwcChange={(e) => setValue(e.detail.value)} />
</>
);
}
Angular
import { Component, signal } from '@angular/core';
import '@uwc/radiobutton';
@Component({
selector: 'app-root',
standalone: true,
template: `
<uwc-radiobutton name="city" value="NY" label="New York"
(uwc-change)="value.set($event.detail.value)"></uwc-radiobutton>
<uwc-radiobutton name="city" value="LA" label="Los Angeles"
(uwc-change)="value.set($event.detail.value)"></uwc-radiobutton>
`,
})
export class AppComponent {
readonly value = signal('');
}
Vue
import '@uwc/radiobutton';
export default {
data() {
return { value: '' };
},
template: `
<uwc-radiobutton name="city" value="NY" label="New York"
@uwc-change="value = $event.detail.value"></uwc-radiobutton>
<uwc-radiobutton name="city" value="LA" label="Los Angeles"
@uwc-change="value = $event.detail.value"></uwc-radiobutton>
`,
};
Basic Usage
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('app-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="demo" label="Unchecked"></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Checked" checked></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Disabled" disabled></uwc-radiobutton>
</div>
`;
}
}
import React from 'react';
import { UwcRadioButton } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '1.5rem', flexWrap: 'wrap' }}>
<UwcRadioButton name="demo" label="Unchecked" />
<UwcRadioButton name="demo" label="Checked" checked />
<UwcRadioButton name="demo" label="Disabled" disabled />
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="demo" label="Unchecked"></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Checked" checked></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Disabled" disabled></uwc-radiobutton>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="demo" label="Unchecked"></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Checked" checked></uwc-radiobutton>
<uwc-radiobutton name="demo" label="Disabled" disabled></uwc-radiobutton>
</div>
`
};
Basic group
Radio buttons sharing the same name form a mutually exclusive group. Listen to
uwc-change on each button to track the selected value.
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
@customElement('radio-basic-demo')
export class AppDemo extends LitElement {
static styles = css`
:host { display: block; }
.group { display: flex; gap: 1.5rem; flex-wrap: wrap; }
p { margin: .75rem 0 0; font-size: .875rem; color: #374151; }
strong { color: #6366f1; }
`;
@state() city = '';
render() {
return html`
<div class="group">
${['New York', 'London', 'Tokyo', 'Paris'].map(c => html`
<uwc-radiobutton
name="city"
value=${c}
label=${c}
?checked=${this.city === c}
@uwc-change=${() => { this.city = c; }}>
</uwc-radiobutton>
`)}
</div>
<p>Selected: <strong>${this.city || 'none'}</strong></p>
`;
}
}
import React, { useState } from 'react';
import { UwcRadioButton } from '@uwc/components/react';
export default function App() {
const [city, setCity] = useState('');
const cities = ['New York', 'London', 'Tokyo', 'Paris'];
return (
<>
<div style={{ display: 'flex', gap: '1.5rem', flexWrap: 'wrap' }}>
{cities.map(c => (
<UwcRadioButton
key={c}
name="city"
value={c}
label={c}
checked={city === c}
onUwcChange={() => setCity(c)}
/>
))}
</div>
<p style={{ marginTop: '.75rem', fontSize: '.875rem', color: '#374151' }}>
Selected: <strong style={{ color: '#6366f1' }}>{city || 'none'}</strong>
</p>
</>
);
}
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
@for (c of cities; track c) {
<uwc-radiobutton
name="city"
[value]="c"
[label]="c"
[checked]="city() === c"
(uwc-change)="city.set(c)">
</uwc-radiobutton>
}
</div>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong style="color:#6366f1">{{ city() || 'none' }}</strong>
</p>
`
})
export class AppComponent {
readonly city = signal('');
cities = ['New York', 'London', 'Tokyo', 'Paris'];
}
export default {
data() {
return {
city: '',
cities: ['New York', 'London', 'Tokyo', 'Paris'],
};
},
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton
v-for="c in cities"
:key="c"
name="city"
:value="c"
:label="c"
:checked="city === c"
@uwc-change="city = c">
</uwc-radiobutton>
</div>
<p style="margin:.75rem 0 0;font-size:.875rem;color:#374151">
Selected: <strong style="color:#6366f1">{{ city || 'none' }}</strong>
</p>
`
};
Filled variant
Set variant="filled" for a solid background instead of the default outlined circle.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('radio-filled-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:2rem;flex-wrap:wrap;">
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.05em">Outlined</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-out" value="a" label="Option A"></uwc-radiobutton>
<uwc-radiobutton name="r-out" value="b" label="Option B" checked></uwc-radiobutton>
</div>
</div>
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:.05em">Filled</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-fill" value="a" label="Option A" variant="filled"></uwc-radiobutton>
<uwc-radiobutton name="r-fill" value="b" label="Option B" variant="filled" checked></uwc-radiobutton>
</div>
</div>
</div>
`;
}
}
import React from 'react';
import { UwcRadioButton } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap' }}>
<div>
<p style={{ margin: '0 0 .75rem', fontSize: '.8rem', fontWeight: 600, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '.05em' }}>Outlined</p>
<div style={{ display: 'flex', flexDirection: 'column', gap: '.75rem' }}>
<UwcRadioButton name="r-out" value="a" label="Option A" />
<UwcRadioButton name="r-out" value="b" label="Option B" checked />
</div>
</div>
<div>
<p style={{ margin: '0 0 .75rem', fontSize: '.8rem', fontWeight: 600, color: '#6b7280', textTransform: 'uppercase', letterSpacing: '.05em' }}>Filled</p>
<div style={{ display: 'flex', flexDirection: 'column', gap: '.75rem' }}>
<UwcRadioButton name="r-fill" value="a" label="Option A" variant="filled" />
<UwcRadioButton name="r-fill" value="b" label="Option B" variant="filled" checked />
</div>
</div>
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:2rem;flex-wrap:wrap;">
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase">Outlined</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-out" value="a" label="Option A"></uwc-radiobutton>
<uwc-radiobutton name="r-out" value="b" label="Option B" checked></uwc-radiobutton>
</div>
</div>
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase">Filled</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-fill" value="a" label="Option A" variant="filled"></uwc-radiobutton>
<uwc-radiobutton name="r-fill" value="b" label="Option B" variant="filled" checked></uwc-radiobutton>
</div>
</div>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:2rem;flex-wrap:wrap;">
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase">Outlined</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-out" value="a" label="Option A"></uwc-radiobutton>
<uwc-radiobutton name="r-out" value="b" label="Option B" checked></uwc-radiobutton>
</div>
</div>
<div>
<p style="margin:0 0 .75rem;font-size:.8rem;font-weight:600;color:#6b7280;text-transform:uppercase">Filled</p>
<div style="display:flex;flex-direction:column;gap:.75rem;">
<uwc-radiobutton name="r-fill" value="a" label="Option A" variant="filled"></uwc-radiobutton>
<uwc-radiobutton name="r-fill" value="b" label="Option B" variant="filled" checked></uwc-radiobutton>
</div>
</div>
</div>
`
};
Outlined
Filled
Disabled
Set disabled on a radio button to prevent interaction.
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
@customElement('radio-disabled-demo')
export class AppDemo extends LitElement {
render() {
return html`
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="d" label="Enabled" value="a"></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled" value="b" disabled></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled checked" value="c" disabled checked></uwc-radiobutton>
</div>
`;
}
}
import React from 'react';
import { UwcRadioButton } from '@uwc/components/react';
export default function App() {
return (
<div style={{ display: 'flex', gap: '1.5rem', flexWrap: 'wrap' }}>
<UwcRadioButton name="d" label="Enabled" value="a" />
<UwcRadioButton name="d" label="Disabled" value="b" disabled />
<UwcRadioButton name="d" label="Disabled checked" value="c" disabled checked />
</div>
);
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
standalone: true,
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="d" label="Enabled" value="a"></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled" value="b" disabled></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled checked" value="c" disabled checked></uwc-radiobutton>
</div>
`
})
export class AppComponent {}
export default {
template: `
<div style="display:flex;gap:1.5rem;flex-wrap:wrap;">
<uwc-radiobutton name="d" label="Enabled" value="a"></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled" value="b" disabled></uwc-radiobutton>
<uwc-radiobutton name="d" label="Disabled checked" value="c" disabled checked></uwc-radiobutton>
</div>
`
};
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
checked |
— |
— |
Whether this radio is selected. |
value |
— |
— |
Value for this option. |
name |
— |
— |
Group name — radio buttons with same name form a group. |
label |
— |
— |
Label text rendered beside the radio. |
disabled |
— |
— |
Disable the radio button. |
invalid |
— |
— |
Mark as invalid (red border). |
variant |
— |
— |
outlined | filled. Default: outlined. |
Properties
| Name | Type | Default | Description |
|---|---|---|---|
styles |
CSSResultGroup |
[styles] |
— |
checked |
boolean |
false |
— |
value |
string | undefined |
— |
— |
name |
string | undefined |
— |
— |
label |
string | undefined |
— |
— |
disabled |
boolean |
false |
— |
invalid |
boolean |
false |
— |
variant |
RadioButtonVariant |
'outlined' |
— |
Slots
| Name | Description |
|---|---|
default |
Custom label content (overrides label attr). |
Events
| Name | Type | Description |
|---|---|---|
uwc-change |
CustomEvent |
Fired when this radio becomes selected. Detail: { value }. |
CSS Custom Properties
| Name | Default | Description |
|---|---|---|
--uwc-radio-size |
— |
Circle size. Default: 1.125rem. |
--uwc-radio-bg |
— |
Background color (unchecked). |
--uwc-radio-color |
— |
Accent color for dot and border. |
--uwc-radio-label-color |
— |
Label text color. |
--uwc-radio-font-size |
— |
Label font size. |
CSS Parts
| Name | Description |
|---|---|
circle |
The visual circle. |
label |
The label element. |