) {
super.updated(changedProperties);
// Update host classes when relevant properties change
if (
changedProperties.has('flagLayout') ||
changedProperties.has('headerFirst') ||
changedProperties.has('mediaPosition') ||
changedProperties.has('mediaType') ||
changedProperties.has('actionable')
) {
this.updateHostClasses();
}
}
private updateHostClasses() {
// Apply card classes directly to the host element following USWDS structure
const cardClasses = ['usa-card'];
// Media right requires flag layout, so enable it automatically
const shouldUseFlagLayout = this.flagLayout || this.mediaPosition === 'right';
if (shouldUseFlagLayout) cardClasses.push('usa-card--flag');
if (this.headerFirst) cardClasses.push('usa-card--header-first');
if (this.mediaPosition === 'right') cardClasses.push('usa-card--media-right');
// Apply classes to the host element (this becomes the card element)
this.className = cardClasses.join(' ');
// Handle actionable state
if (this.actionable) {
this.setAttribute('role', 'button');
this.setAttribute('tabindex', '0');
} else {
this.removeAttribute('role');
this.removeAttribute('tabindex');
}
}
// private async initializeUSWDSCard() {
// // Note: USWDS cards are purely presentational components with no JavaScript behavior
// // The card component only requires USWDS CSS for styling and layout
// console.log('📋 Card: Initialized as presentational component (no USWDS JavaScript required)');
// }
private renderBodyText() {
return html`${this.text}
`;
}
private renderFooterText() {
return html`${this.footerText}
`;
}
private hasSlotContent(slotName: string): boolean {
// Check if there are any elements with the specified slot attribute
const slottedElements = this.querySelectorAll(`[slot="${slotName}"]`);
return slottedElements.length > 0;
}
override render() {
const renderMedia = () => {
if (this.mediaType === 'none' || !this.mediaSrc) return '';
if (this.mediaType === 'image') {
return html`
`;
}
if (this.mediaType === 'video') {
return html`
`;
}
return '';
};
const renderHeader = () => {
if (!this.heading) return '';
const headingTag = `h${this.headingLevel}`;
return staticHtml`
`;
};
const renderBody = () => {
// Always render body if there's text property or body slot
if (!this.text && !this.hasSlotContent('body')) return '';
return html`
${this.text ? this.renderBodyText() : ''}
`;
};
const renderFooter = () => {
// Always render footer if there's footerText property or footer slot
if (!this.footerText && !this.hasSlotContent('footer')) return '';
return html`
`;
};
// Media right positioning is handled by CSS, not HTML order
// Follow USWDS standard: Header -> Media -> Body -> Footer (unless headerFirst is false)
const cardContent = this.headerFirst
? html` ${renderHeader()} ${renderMedia()} ${renderBody()} ${renderFooter()} `
: html` ${renderMedia()} ${renderHeader()} ${renderBody()} ${renderFooter()} `;
// USWDS Compliance: Only use official USWDS class 'usa-card__container'
// No custom modifier classes - actionable behavior is handled via role/tabindex attributes
return html`
${cardContent}
`;
}
}