<input-radiogroup value="other">
<fieldset>
<legend>Gender</legend>
<label>
<input type="radio" name="gender" value="female">
<span>Female</span>
</label>
<label>
<input type="radio" name="gender" value="male">
<span>Male</span>
</label>
<label class="selected">
<input type="radio" name="gender" value="other" checked>
<span>Other</span>
</label>
</fieldset>
</input-radiogroup>
<input-radiogroup value="all" class="split-button">
<fieldset>
<legend class="visually-hidden">Filter</legend>
<label class="selected">
<input type="radio" class="visually-hidden" name="filter" value="all" checked>
<span>All</span>
</label>
<label>
<input type="radio" class="visually-hidden" name="filter" value="active">
<span>Active</span>
</label>
<label>
<input type="radio" class="visually-hidden" name="filter" value="completed">
<span>Completed</span>
</label>
</fieldset>
</input-radiogroup>
input-radiogroup {
display: inline-block;
> fieldset {
display: flex;
gap: var(--space-m);
border: none;
margin: 0;
padding: var(--space-xs) 0 var(--space-s);
}
& legend,
& label {
font-size: var(--font-size-s);
}
& label {
border-radius: var(--space-xs);
&:focus-within {
box-shadow: 0 0 var(--space-xxs) 2px var(--color-selection);
}
& input:focus {
outline: none;
box-shadow: none;
}
}
&.split-button {
& fieldset {
gap: 0;
padding: 0;
}
& label {
display: inline-block;
box-sizing: border-box;
height: var(--input-height);
min-width: var(--input-height);
border: 1px solid var(--color-border);
border-radius: 0;
border-left-width: 0;
background-color: var(--color-secondary);
color: var(--color-text);
padding: var(--space-xs) var(--space-s);
cursor: pointer;
line-height: var(--line-height-s);
opacity: var(--opacity-dimmed);
transition: opacity var(--transition-short) var(--easing-inout);
&:hover {
background-color: var(--color-secondary-hover);
opacity: var(--opacity-solid);
}
&:active {
background-color: var(--color-secondary-active);
}
&.selected {
color: var(--color-text-inverted);
background-color: var(--color-primary);
border-color: var(--color-primary-active);
&:hover {
background-color: var(--color-primary-hover);
}
&:active {
background-color: var(--color-primary-active);
}
}
}
& legend + label {
border-radius: var(--space-xs) 0 0 var(--space-xs);
border-left-width: 1px;
}
& label:last-child {
border-radius: 0 var(--space-xs) var(--space-xs) 0;
}
}
}
import {
type SignalValueProvider,
asString, setAttribute, toggleClass, UIElement
} from '../../../'
export class InputRadiogroup extends UIElement<{ value: string }> {
static localName = 'input-radiogroup'
static observedAttributes = ['value']
init = {
value: asString()
}
connectedCallback() {
super.connectedCallback()
this.self.sync(setAttribute('value'))
this.all('input').on('change', (e: Event) => {
this.set('value', (e.target as HTMLInputElement)?.value)
})
const getSelectedByElement: SignalValueProvider<boolean> =
target => this.get('value') === target.querySelector('input')?.value
this.all('label')
.sync(toggleClass('selected', getSelectedByElement))
}
}
InputRadiogroup.define()