WIP PWA for Grain
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add grain-image-carousel organism

+77
+77
src/components/organisms/grain-image-carousel.js
··· 1 + import { LitElement, html, css } from 'lit'; 2 + import '../atoms/grain-image.js'; 3 + import '../molecules/grain-carousel-dots.js'; 4 + 5 + export class GrainImageCarousel extends LitElement { 6 + static properties = { 7 + photos: { type: Array }, 8 + _currentIndex: { state: true } 9 + }; 10 + 11 + static styles = css` 12 + :host { 13 + display: block; 14 + position: relative; 15 + } 16 + .carousel { 17 + display: flex; 18 + overflow-x: auto; 19 + scroll-snap-type: x mandatory; 20 + scrollbar-width: none; 21 + -ms-overflow-style: none; 22 + } 23 + .carousel::-webkit-scrollbar { 24 + display: none; 25 + } 26 + .slide { 27 + flex: 0 0 100%; 28 + scroll-snap-align: start; 29 + } 30 + .dots { 31 + position: absolute; 32 + bottom: 0; 33 + left: 0; 34 + right: 0; 35 + } 36 + `; 37 + 38 + constructor() { 39 + super(); 40 + this.photos = []; 41 + this._currentIndex = 0; 42 + } 43 + 44 + #handleScroll(e) { 45 + const carousel = e.target; 46 + const index = Math.round(carousel.scrollLeft / carousel.offsetWidth); 47 + if (index !== this._currentIndex) { 48 + this._currentIndex = index; 49 + } 50 + } 51 + 52 + render() { 53 + return html` 54 + <div class="carousel" @scroll=${this.#handleScroll}> 55 + ${this.photos.map(photo => html` 56 + <div class="slide"> 57 + <grain-image 58 + src=${photo.url} 59 + alt=${photo.alt || ''} 60 + aspectRatio=${photo.aspectRatio || 1} 61 + ></grain-image> 62 + </div> 63 + `)} 64 + </div> 65 + ${this.photos.length > 1 ? html` 66 + <div class="dots"> 67 + <grain-carousel-dots 68 + total=${this.photos.length} 69 + current=${this._currentIndex} 70 + ></grain-carousel-dots> 71 + </div> 72 + ` : ''} 73 + `; 74 + } 75 + } 76 + 77 + customElements.define('grain-image-carousel', GrainImageCarousel);