import { LitElement, html, css, unsafeCSS } from 'lit'; import { property } from 'lit/decorators.js'; export class ImageList extends LitElement { @property({ type: String }) variant: 'masonry' | 'quilted' | 'standard' | 'woven' = 'standard'; @property({ type: Number }) cols = 2; @property({ type: Number }) gap = 4; @property({ type: Number }) rowHeight = 164; static styles = css` :host { display: block; } .image-list { display: grid; overflow-y: auto; list-style: none; margin: 0; padding: 0; } /* Standard variant */ .image-list.standard { grid-auto-rows: 1fr; } /* Masonry variant */ .image-list.masonry { grid-auto-rows: auto; } /* Quilted variant */ .image-list.quilted { grid-auto-rows: auto; } /* Woven variant */ .image-list.woven { grid-auto-rows: 1fr; } ::slotted(mui-image-list-item) { display: block; position: relative; overflow: hidden; } ::slotted(mui-image-list-item img) { width: 100%; height: 100%; object-fit: cover; display: block; } /* Standard layout - all items same size */ .image-list.standard ::slotted(mui-image-list-item) { aspect-ratio: 1; } /* Masonry layout - items maintain aspect ratio */ .image-list.masonry ::slotted(mui-image-list-item) { break-inside: avoid; } /* Quilted layout - featured items are larger */ .image-list.quilted ::slotted(mui-image-list-item[featured]) { grid-column: span 2; grid-row: span 2; } /* Woven layout - alternating pattern */ .image-list.woven ::slotted(mui-image-list-item:nth-child(odd)) { aspect-ratio: 1; } .image-list.woven ::slotted(mui-image-list-item:nth-child(even)) { aspect-ratio: 2 / 1; } `; private _getSpacingValue(value: number): string { return `${value * 8}px`; } private _generateDynamicStyles(): string { const styles: string[] = []; const gapValue = this._getSpacingValue(this.gap); // Grid template columns if (this.variant === 'masonry') { // Masonry uses CSS columns instead of grid styles.push(` column-count: ${this.cols}; column-gap: ${gapValue}; grid-template-columns: none; `); } else { styles.push(` grid-template-columns: repeat(${this.cols}, 1fr); gap: ${gapValue}; `); } // Row height for standard and woven variants if (this.variant === 'standard' || this.variant === 'woven') { styles.push(`grid-auto-rows: ${this.rowHeight}px;`); } return styles.join(' '); } private _getClasses(): string { const classes = ['image-list']; classes.push(this.variant); return classes.join(' '); } render() { const dynamicStyles = this._generateDynamicStyles(); return html`