mirror of
https://github.com/shoelace-style/shoelace.git
synced 2026-01-12 02:59:13 +00:00
chore(carousel): animation timeline poc
This commit is contained in:
@@ -17,6 +17,7 @@ import SlIcon from '../icon/icon.component.js';
|
||||
import styles from './carousel.styles.js';
|
||||
import type { CSSResultGroup, PropertyValueMap } from 'lit';
|
||||
import type SlCarouselItem from '../carousel-item/carousel-item.component.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
|
||||
/**
|
||||
* @summary Carousels display an arbitrary number of content slides along a horizontal or vertical axis.
|
||||
@@ -506,11 +507,11 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
id="scroll-container"
|
||||
part="scroll-container"
|
||||
class="${classMap({
|
||||
carousel__slides: true,
|
||||
'carousel__slides--horizontal': this.orientation === 'horizontal',
|
||||
'carousel__slides--vertical': this.orientation === 'vertical',
|
||||
'carousel__slides--dragging': this.dragging
|
||||
})}"
|
||||
carousel__slides: true,
|
||||
'carousel__slides--horizontal': this.orientation === 'horizontal',
|
||||
'carousel__slides--vertical': this.orientation === 'vertical',
|
||||
'carousel__slides--dragging': this.dragging
|
||||
})}"
|
||||
style="--slides-per-page: ${this.slidesPerPage};"
|
||||
aria-busy="${scrolling ? 'true' : 'false'}"
|
||||
aria-atomic="true"
|
||||
@@ -524,15 +525,15 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
</div>
|
||||
|
||||
${this.navigation
|
||||
? html`
|
||||
? html`
|
||||
<div part="navigation" class="carousel__navigation">
|
||||
<button
|
||||
part="navigation-button navigation-button--previous"
|
||||
class="${classMap({
|
||||
'carousel__navigation-button': true,
|
||||
'carousel__navigation-button--previous': true,
|
||||
'carousel__navigation-button--disabled': !prevEnabled
|
||||
})}"
|
||||
'carousel__navigation-button': true,
|
||||
'carousel__navigation-button--previous': true,
|
||||
'carousel__navigation-button--disabled': !prevEnabled
|
||||
})}"
|
||||
aria-label="${this.localize.term('previousSlide')}"
|
||||
aria-controls="scroll-container"
|
||||
aria-disabled="${prevEnabled ? 'false' : 'true'}"
|
||||
@@ -546,10 +547,10 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
<button
|
||||
part="navigation-button navigation-button--next"
|
||||
class=${classMap({
|
||||
'carousel__navigation-button': true,
|
||||
'carousel__navigation-button--next': true,
|
||||
'carousel__navigation-button--disabled': !nextEnabled
|
||||
})}
|
||||
'carousel__navigation-button': true,
|
||||
'carousel__navigation-button--next': true,
|
||||
'carousel__navigation-button--disabled': !nextEnabled
|
||||
})}
|
||||
aria-label="${this.localize.term('nextSlide')}"
|
||||
aria-controls="scroll-container"
|
||||
aria-disabled="${nextEnabled ? 'false' : 'true'}"
|
||||
@@ -561,19 +562,21 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
: ''}
|
||||
${this.pagination
|
||||
? html`
|
||||
<div part="pagination" role="tablist" class="carousel__pagination" aria-controls="scroll-container">
|
||||
? html`
|
||||
<div part="pagination" role="tablist" class="carousel__pagination" aria-controls="scroll-container" style="${styleMap({
|
||||
'--pages': pagesCount
|
||||
})}">
|
||||
${map(range(pagesCount), index => {
|
||||
const isActive = index === currentPage;
|
||||
return html`
|
||||
const isActive = index === currentPage;
|
||||
return html`
|
||||
<button
|
||||
part="pagination-item ${isActive ? 'pagination-item--active' : ''}"
|
||||
class="${classMap({
|
||||
'carousel__pagination-item': true,
|
||||
'carousel__pagination-item--active': isActive
|
||||
})}"
|
||||
class="carousel__pagination-item"
|
||||
style="${styleMap({
|
||||
'--index': index
|
||||
})}"
|
||||
role="tab"
|
||||
aria-selected="${isActive ? 'true' : 'false'}"
|
||||
aria-label="${this.localize.term('goToSlide', index + 1, pagesCount)}"
|
||||
@@ -582,10 +585,10 @@ export default class SlCarousel extends ShoelaceElement {
|
||||
@keydown=${this.handleKeyDown}
|
||||
></button>
|
||||
`;
|
||||
})}
|
||||
})}
|
||||
</div>
|
||||
`
|
||||
: ''}
|
||||
: ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export default css`
|
||||
}
|
||||
|
||||
.carousel {
|
||||
timeline-scope: --carousel;
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr min-content;
|
||||
grid-template-rows: 1fr min-content;
|
||||
@@ -33,7 +34,6 @@ export default css`
|
||||
|
||||
.carousel__slides {
|
||||
grid-area: slides;
|
||||
|
||||
display: grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -55,6 +55,7 @@ export default css`
|
||||
}
|
||||
|
||||
.carousel__slides--horizontal {
|
||||
scroll-timeline: --carousel x;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: var(--slide-size);
|
||||
grid-auto-rows: 100%;
|
||||
@@ -66,6 +67,7 @@ export default css`
|
||||
}
|
||||
|
||||
.carousel__slides--vertical {
|
||||
scroll-timeline: --carousel y;
|
||||
grid-auto-flow: row;
|
||||
grid-auto-columns: 100%;
|
||||
grid-auto-rows: var(--slide-size);
|
||||
@@ -140,9 +142,22 @@ export default css`
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.carousel__pagination-item--active {
|
||||
background-color: var(--sl-color-neutral-700);
|
||||
transform: scale(1.2);
|
||||
@keyframes pagination-item-active {
|
||||
0%,
|
||||
100% {
|
||||
background-color: var(--sl-color-neutral-700);
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
@supports (animation-timeline: view()) {
|
||||
.carousel__pagination-item {
|
||||
animation: pagination-item-active linear;
|
||||
animation-timeline: --carousel;
|
||||
animation-range:
|
||||
calc(var(--index) * calc(100% / var(--pages)))
|
||||
calc((var(--index) + 1) * calc(100% / var(--pages) + 1px));
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus styles */
|
||||
|
||||
Reference in New Issue
Block a user