) {
// Update the radio element if it exists
if (this.radioElement) {
this.updateRadioElement();
}
}
private updateRadioElement() {
if (!this.radioElement) return;
// Update radio properties
this.radioElement.name = this.name;
this.radioElement.value = this.value;
this.radioElement.checked = this.checked;
this.radioElement.disabled = this.disabled;
this.radioElement.required = this.required;
// Update classes
// Remove existing USWDS classes
const classesToRemove = Array.from(this.radioElement.classList).filter((className) =>
className.startsWith('usa-radio__input')
);
classesToRemove.forEach((className) => this.radioElement?.classList.remove(className));
// Always add base usa-radio__input class
this.radioElement.classList.add('usa-radio__input');
// Add tile class if needed
if (this.tile) {
this.radioElement.classList.add('usa-radio__input--tile');
}
// Add error class if error exists
if (this.error) {
this.radioElement.classList.add('usa-input--error');
}
// Update ARIA attributes
if (this.error) {
this.radioElement.setAttribute('aria-invalid', 'true');
} else {
this.radioElement.removeAttribute('aria-invalid');
}
}
private handleChange(e: Event) {
const radio = e.target as HTMLInputElement;
this.checked = radio.checked;
// Dispatch both change and input events for consistency with other form elements
this.dispatchEvent(
new CustomEvent('change', {
detail: {
checked: this.checked,
value: this.value,
name: this.name,
},
bubbles: true,
composed: true,
})
);
this.dispatchEvent(
new CustomEvent('input', {
detail: {
checked: this.checked,
value: this.value,
name: this.name,
},
bubbles: true,
composed: true,
})
);
}
private get radioId() {
// Always check for element id first, then use cached generated id
if (this.id) {
return this.id;
}
if (!this._radioId) {
this._radioId = `radio-${Math.random().toString(36).substring(2, 11)}`;
}
return this._radioId;
}
private async initializeUSWDSRadio() {
// Prevent multiple initializations
if (this.usingUSWDSEnhancement) {
console.log(`โ ๏ธ ${this.constructor.name}: Already initialized, skipping duplicate initialization`);
return;
}
console.log(`๐ Radio: Initializing (presentational component - no USWDS JavaScript needed)`);
try {
// Check if global USWDS is available for potential future enhancements
if (typeof window !== 'undefined' && typeof (window as any).USWDS !== 'undefined') {
const USWDS = (window as any).USWDS;
if (USWDS.radio && typeof USWDS.radio.on === 'function') {
USWDS.radio.on(this);
console.log(`๐ Radio: Enhanced with global USWDS JavaScript`);
return;
}
}
console.log(`๐ Radio: Using presentational component behavior (USWDS Radio is CSS-only)`);
} catch (error) {
console.warn(`๐ Radio: Initialization completed with basic behavior:`, error);
}
}
override disconnectedCallback() {
super.disconnectedCallback();
this.cleanupUSWDS();
}
/**
* Clean up USWDS module on component destruction
*/
private cleanupUSWDS() {
// Try cleanup with global USWDS (radio components are presentational)
if (typeof window !== 'undefined' && typeof (window as any).USWDS !== 'undefined') {
const USWDS = (window as any).USWDS;
if (USWDS.radio?.off) {
try {
USWDS.radio.off(this);
console.log(`๐งน Cleaned up USWDS radio`);
} catch (error) {
console.warn(`โ ๏ธ Error cleaning up USWDS:`, error);
}
}
}
}
private renderError(radioId: string) {
if (!this.error) return '';
return html`
Error: ${this.error}
`;
}
private renderLabelDescription(radioId: string) {
if (!this.description || !this.tile) return '';
return html`
${this.description}
`;
}
override render() {
const radioId = this.radioId;
const wrapperClasses = ['usa-radio', this.tile ? 'usa-radio--tile' : '']
.filter(Boolean)
.join(' ');
const describedByIds: string[] = [];
if (this.description && this.tile) {
describedByIds.push(`${radioId}-description`);
}
if (this.error) {
describedByIds.push(`${radioId}-error`);
}
return html`
${this.renderError(radioId)}
`;
}
}