/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
import {LitElement, html, css, unsafeCSS} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import { breakpoints } from '../../breakpoints';
import Swiper from 'swiper';
import { EffectFade, Navigation, Pagination } from 'swiper/modules';
import swiperStyles from 'swiper/css/bundle?raw';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
@customElement('iu-carousel')
export class Carousel extends LitElement {
static override styles = [
css([swiperStyles]),
css`
.img{
aspect-ratio: 3/2;
height: auto;
}
.img img{
width: 100%;
height: 100%;
object-fit: cover;
}
.caption p{
font: var(--iu-f-0);
background: #fff;
margin-bottom: 0;
margin-top: 1.75rem;
height: 100%;
}
:host .swiper-button-prev, :host .swiper-button-next{
width: 50%;
height: var(--carousel-img-height);
top: 0;
margin-top: 0;
}
:host .swiper-button-prev::after, :host .swiper-button-next::after{
content: none;
}
:host .swiper-pagination{
display: flex;
gap: 0.625rem;
position: absolute;
top: calc(var(--carousel-img-height) + 0.625rem);
}
:host .swiper-pagination .swiper-pagination-bullet{
width:100%;
border-radius: 0;
height: 1px;
margin: 0;
background: var(--iu-color-grey-300);
opacity: 1;
}
:host .swiper-pagination .swiper-pagination-bullet-active{
background: var(--iu-color-black);
height: 3px;
}
:host .swiper-slide{
opacity: 0;
}
:host .swiper-slide-active, :host .swiper.slide-duplicate-active{
opacity: 1;
}
`
];
@property({ type: Array }) items: Array<{ path: string; caption?: string }> = [];
override firstUpdated() {
// Initialize Swiper once the component is rendered
new Swiper(this.shadowRoot.querySelector('.swiper'), {
modules: [EffectFade, Navigation, Pagination],
loop: true,
effect: 'fade',
crossFade: true,
pagination: {
el: this.shadowRoot.querySelector('.swiper-pagination')
},
navigation: {
nextEl: this.shadowRoot.querySelector('.swiper-button-next'),
prevEl: this.shadowRoot.querySelector('.swiper-button-prev')
},
});
requestAnimationFrame(() => {
const height = Math.floor(this.clientWidth / 1.5)
this.style.setProperty('--carousel-img-height', `${height}px`);
});
}
override render() {
return html`
<div class="swiper">
<div class="swiper-wrapper">
${this.items.map(
(item) => html`
<div class="swiper-slide">
<div class="img">
<img src="${item.path}" alt="${item.caption || 'Image'}" />
${item.caption
? html`
<div class="caption"><p>${unsafeHTML(item.caption)}</p></div>`
: ''
}
</div>
</div>
`
)}
</div>
<div class="swiper-pagination"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'iu-carousel': Carousel;
}
}