) {
// Update the checkbox element if it exists
if (this.checkboxElement) {
this.updateCheckboxElement();
}
}
private updateCheckboxElement() {
if (!this.checkboxElement) return;
// Update checkbox properties
this.checkboxElement.name = this.name;
this.checkboxElement.value = this.value;
this.checkboxElement.checked = this.checked;
this.checkboxElement.disabled = this.disabled;
this.checkboxElement.required = this.required;
this.checkboxElement.indeterminate = this.indeterminate;
// Update classes
// Remove existing USWDS classes
const classesToRemove = Array.from(this.checkboxElement.classList).filter((className) =>
className.startsWith('usa-checkbox__input')
);
classesToRemove.forEach((className) => this.checkboxElement?.classList.remove(className));
// Always add base usa-checkbox__input class
this.checkboxElement.classList.add('usa-checkbox__input');
// Add tile class if needed
if (this.tile) {
this.checkboxElement.classList.add('usa-checkbox__input--tile');
}
// Add error class if error exists
if (this.error) {
this.checkboxElement.classList.add('usa-input--error');
}
// Update ARIA attributes
if (this.error) {
this.checkboxElement.setAttribute('aria-invalid', 'true');
} else {
this.checkboxElement.removeAttribute('aria-invalid');
}
// Update data-indeterminate attribute for USWDS CSS compatibility
// USWDS CSS supports both :indeterminate pseudo-class and [data-indeterminate] attribute
if (this.indeterminate) {
this.checkboxElement.setAttribute('data-indeterminate', 'true');
} else {
this.checkboxElement.removeAttribute('data-indeterminate');
}
}
private handleChange(e: Event) {
const checkbox = e.target as HTMLInputElement;
this.checked = checkbox.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 checkboxId() {
// Always check for element id first, then use cached generated id
if (this.id) {
return this.id;
}
if (!this._checkboxId) {
this._checkboxId = `checkbox-${Math.random().toString(36).substring(2, 11)}`;
}
return this._checkboxId;
}
private async initializeUSWDSCheckbox() {
// Prevent multiple initializations
if (this.usingUSWDSEnhancement) {
return;
}
try {
if (typeof window !== 'undefined' && typeof (window as any).USWDS !== 'undefined') {
const USWDS = (window as any).USWDS;
if (USWDS.checkbox && typeof USWDS.checkbox.on === 'function') {
USWDS.checkbox.on(this);
return;
}
}
} catch (error) {
// Silently continue with CSS-only behavior
}
}
override disconnectedCallback() {
super.disconnectedCallback();
this.cleanupUSWDS();
}
/**
* Clean up USWDS module on component destruction
*/
private cleanupUSWDS() {
if (typeof window !== 'undefined' && typeof (window as any).USWDS !== 'undefined') {
const USWDS = (window as any).USWDS;
if (USWDS.checkbox?.off) {
try {
USWDS.checkbox.off(this);
} catch (error) {
// Silently handle cleanup errors
}
}
}
}
private renderError(checkboxId: string) {
if (!this.error) return '';
return html`
Error: ${this.error}
`;
}
private renderDescription(checkboxId: string) {
if (!this.description) return '';
return html`
${this.description}
`;
}
override render() {
const checkboxId = this.checkboxId;
const describedByIds: string[] = [];
if (this.description) {
describedByIds.push(`${checkboxId}-description`);
}
if (this.error) {
describedByIds.push(`${checkboxId}-error`);
}
// Build wrapper classes
const wrapperClasses = ['usa-checkbox', this.tile ? 'usa-checkbox--tile' : '']
.filter(Boolean)
.join(' ');
const ariaDescribedby = describedByIds.length > 0 ? describedByIds.join(' ') : undefined;
return html`
${this.renderError(checkboxId)}
`;
}
}