) {
super.updated(changedProperties);
// CRITICAL: Do NOT sync value changes to USWDS-created inputs!
// The USWDS behavior (setCalendarValue) handles ALL input synchronization.
// The internal input uses YYYY-MM-DD format, external input uses MM/DD/YYYY.
// Syncing here would overwrite the external input's formatted value with the internal format.
// The component's value property is only used for the initial render.
// Handle minDate/maxDate changes - update data attributes
// These changes require re-initialization because USWDS caches these values during enhancement
if (changedProperties.has('minDate') || changedProperties.has('maxDate')) {
const datePickerWrapper = this.querySelector('.usa-date-picker') as HTMLElement;
if (datePickerWrapper) {
// Update data attributes - the behavior will read these on next calendar render
if (this.minDate) {
datePickerWrapper.dataset.minDate = this.minDate;
} else {
delete datePickerWrapper.dataset.minDate;
}
if (this.maxDate) {
datePickerWrapper.dataset.maxDate = this.maxDate;
} else {
delete datePickerWrapper.dataset.maxDate;
}
}
}
}
override disconnectedCallback() {
super.disconnectedCallback();
this.cleanup?.();
}
private handleInputChange(e: Event) {
const input = e.target as HTMLInputElement;
// Update component value from input
this.value = input.value;
// Dispatch web component events
this.dispatchEvent(new CustomEvent('date-change', {
detail: {
value: this.value,
date: this.value ? new Date(this.value) : null
},
bubbles: true,
composed: true
}));
}
private handleKeydown(_e: KeyboardEvent) {
// Keyboard navigation is handled by USWDS behavior file
// This handler is kept minimal for basic input functionality
}
private renderLabel() {
if (!this.label) return '';
return html`
`;
}
private renderHint() {
if (!this.hint) return '';
return html`${this.hint}
`;
}
private renderError() {
if (!this.error) return '';
return html`
Error: ${this.error}
`;
}
override render() {
const formGroupClasses = [
'usa-form-group',
this.error || this.errorState ? 'usa-form-group--error' : '',
this.required ? 'usa-form-group--required' : '',
]
.filter(Boolean)
.join(' ');
const ariaDescribedBy = [
this.hint ? `${this.inputId}-hint` : '',
this.error ? `${this.inputId}-error` : '',
]
.filter(Boolean)
.join(' ');
// USWDS Progressive Enhancement: Provide minimal structure that USWDS transforms
// CRITICAL USWDS Pattern for Initial Values:
// 1. Set value attribute on input (USWDS reads this during initialization)
// 2. Set data-default-value on wrapper (USWDS uses this to restore after clearing)
// Why both? USWDS clears input.value at line 908, but needs it initially to read format
return html`
`;
}
// Public API methods
override focus() {
const input = this.querySelector(`#${this.inputId}`) as HTMLInputElement;
input?.focus();
}
clear() {
this.value = '';
const input = this.querySelector(`#${this.inputId}`) as HTMLInputElement;
if (input) {
input.value = '';
}
}
toggleCalendar() {
// Find the USWDS-created toggle button and click it to open/close calendar
const toggleButton = this.querySelector('.usa-date-picker__button') as HTMLButtonElement;
if (toggleButton) {
toggleButton.click();
}
}
isValid(): boolean {
const input = this.querySelector(`#${this.inputId}`) as HTMLInputElement;
return input ? input.checkValidity() : true;
}
}