(
'change',
{
detail: {
checked: this.checked,
value: this.value,
name: this.name,
},
bubbles: true,
composed: true,
}
);
this.dispatchEvent(changeEvent);
if (this.onChange) {
this.onChange(changeEvent as RadioChangeEvent);
}
}
private uncheckOtherRadiosInGroup() {
const root = this.getRootNode() as Document | ShadowRoot;
const allRadios = root.querySelectorAll(`ag-radio[name="${this.name}"]`);
allRadios.forEach((radio) => {
if (radio !== this && radio instanceof AgRadio) {
radio.checked = false;
// If checked didn't actually change (was already false), Lit's updated() won't
// fire on the sibling, so _syncValidity() wouldn't be called. Force it so
// unchecked siblings correctly reflect the group's new validity state.
radio._syncValidity();
radio._syncStates();
}
});
}
/**
* Render optional external label (for groups or above radio)
*/
private _renderExternalLabel() {
if (!this.label || this.noLabel) return nothing;
return html`
`;
}
/**
* Render helper text
*/
private _renderHelper() {
if (!this.helpText) return nothing;
return html`
${this.helpText}
`;
}
/**
* Render error text
*/
private _renderError() {
return html`
${this.errorMessage || ''}
`;
}
/**
* Build ARIA describedby attribute
*/
private _getAriaDescribedBy(): string | undefined {
return buildAriaDescribedBy({
helperId: this._ids.helperId,
errorId: this._ids.errorId,
hasHelper: !!this.helpText,
hasError: this.invalid && !!this.errorMessage,
});
}
override render() {
const wrapperClasses = `
radio-wrapper
${this.labelPosition === 'start' ? 'radio-wrapper--label-start' : ''}
`;
const indicatorClasses = `
radio-indicator
radio-indicator--${this.size}
radio-indicator--${this.theme}
`;
const labelClasses = `
radio-label
radio-label--${this.size}
`;
// Build aria-describedby
const describedBy = this._getAriaDescribedBy();
// The radio control (internal label wrapper + input + indicator + text)
const radioControl = html`
`;
// If external label/helper/error are provided, wrap with them
if (this.label || this.helpText || this.errorMessage) {
return html`
${this._renderExternalLabel()}
${radioControl}
${this._renderHelper()}
${this._renderError()}
`;
}
// Otherwise just return the radio control
return radioControl;
}
}