) {
super.updated(changedProperties);
// Update CSS custom property when containerHeight changes
if (changedProperties.has('containerHeight')) {
this.style.setProperty('--usa-collection-container-height', `${this.containerHeight}px`);
}
if (changedProperties.has('items') && this.virtual) {
this.updateVirtualData();
}
if (changedProperties.has('virtual') && this.virtual && !this.virtualScroller) {
this.setupVirtualScrolling();
}
}
private setupVirtualScrolling() {
if (!this.virtual || this.items.length === 0) return;
// Find or create scrollable container
const scrollContainer =
(this.querySelector('.usa-collection__virtual-container') as HTMLElement) ||
this.createVirtualContainer();
this.virtualScroller = new USWDSVirtualScroller(scrollContainer, {
itemHeight: this.itemHeight,
containerHeight: this.containerHeight,
overscan: 3,
onRender: (start: number, end: number) => {
this.visibleRange = { start, end };
this.requestUpdate(); // Trigger re-render with new visible range
},
});
this.virtualScroller.setTotalItems(this.items.length);
// Listen for virtual render events
scrollContainer.addEventListener(
'virtual-render',
this.handleVirtualRender.bind(this) as EventListener
);
}
private createVirtualContainer(): HTMLElement {
const container = document.createElement('div');
container.className = 'usa-collection__virtual-container';
return container;
}
private updateVirtualData() {
if (!this.virtualScroller) return;
this.virtualScroller.setTotalItems(this.items.length);
}
private handleVirtualRender(event: CustomEvent) {
const { startIndex, endIndex } = event.detail;
this.visibleRange = { start: startIndex, end: endIndex };
this.requestUpdate(); // Trigger re-render with new visible range
}
private renderMedia(media: CollectionMedia) {
if (!media) return '';
return html`
`;
}
private renderTag(tag: string) {
return html`${tag}`;
}
private renderTags(tags: string[]) {
if (!tags || tags.length === 0) return '';
return html`
`;
}
private renderAuthorItem(author: string) {
return html`By ${author}`;
}
private renderDateItem(date: string) {
return html`
`;
}
private renderAuthorAndDate(item: CollectionItem) {
const hasAuthor = item.author;
const hasDate = item.date;
if (!hasAuthor && !hasDate) return '';
return html`
`;
}
private renderMetadataItem(meta: CollectionMetadata) {
return html`${meta.label}: ${meta.value}`;
}
private renderMetadata(metadata: CollectionMetadata[]) {
if (!metadata || metadata.length === 0) return '';
return html`
`;
}
private renderTitle(item: CollectionItem) {
if (item.href) {
return html`${item.title}`;
}
return item.title;
}
private renderDescription(description: string) {
return html`${description}
`;
}
private renderItem(item: CollectionItem) {
return html`
${item.media ? this.renderMedia(item.media) : ''}
${this.renderTitle(item)}
${item.description ? this.renderDescription(item.description) : ''}
${this.renderAuthorAndDate(item)}
${this.renderMetadata(item.metadata || [])}
${this.renderTags(item.tags || [])}
`;
}
private async initializeUSWDSCollection() {
// Prevent multiple initializations
if (this.usingUSWDSEnhancement) {
console.log(`โ ๏ธ ${this.constructor.name}: Already initialized, skipping duplicate initialization`);
return;
}
console.log(
`๐๏ธ Collection: 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.collection && typeof USWDS.collection.on === 'function') {
USWDS.collection.on(this);
console.log(`๐๏ธ Collection: Enhanced with global USWDS JavaScript`);
return;
}
}
console.log(
`๐๏ธ Collection: Using presentational component behavior (USWDS Collection is CSS-only)`
);
} catch (error) {
console.warn(`๐๏ธ Collection: Initialization completed with basic behavior:`, error);
}
}
private renderVirtualCollection() {
const collectionClasses = ['usa-collection'];
return html`
${this.visibleItems.map(item => this.renderItem(item))}
`;
}
private renderStandardCollection() {
const collectionClasses = ['usa-collection'];
return html`
${this.items.map(item => this.renderItem(item))}
`;
}
override render() {
return this.virtual ? this.renderVirtualCollection() : this.renderStandardCollection();
}
}