) {
// Update checkbox element reference if needed
const currentCheckbox = this.querySelector('input[type="checkbox"]') as HTMLInputElement;
if (currentCheckbox) {
this.checkboxElement = currentCheckbox;
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');
}
}
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,
})
);
};
/**
* Public API: Reset checkbox to unchecked state
* Allows patterns to clear the checkbox without DOM manipulation
*/
reset(): void {
this.checked = false;
this.requestUpdate();
}
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() {
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.checkbox && typeof USWDS.checkbox.on === 'function') {
USWDS.checkbox.on(this);
return;
}
}
// Checkbox is a presentational component (USWDS Checkbox is CSS-only)
} catch {
// Initialization completed with basic behavior
}
}
override disconnectedCallback() {
// Clean up event listeners
if (this.checkboxElement) {
this.checkboxElement.removeEventListener('change', this.handleChange);
}
super.disconnectedCallback();
this.cleanupUSWDS();
}
/**
* Clean up USWDS module on component destruction
*/
private cleanupUSWDS() {
// Try cleanup with global USWDS (checkbox components are presentational)
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 {
// Cleanup failed silently
}
}
}
}
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)}
`;
}
}