• HTML

    input-radiogroup.html html

    <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>
    CSS

    input-radiogroup.css css

    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;
    		}
    	}
    }
    TS

    input-radiogroup.ts ts

    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()