Skip to content

Commit d714d25

Browse files
Merge pull request #40 from appwrite/carousel
2 parents 7c3ca1e + 4bbd2b5 commit d714d25

3 files changed

Lines changed: 554 additions & 88 deletions

File tree

src/lib/components/Carousel.svelte

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<script lang="ts">
2+
let carousel: HTMLElement;
3+
4+
export let gap = 32;
5+
let scroll = 0;
6+
let touchStart = 0;
7+
let touchEnd = 0;
8+
9+
function calculateScrollAmount(prev = false) {
10+
const direction = prev ? -1 : 1;
11+
const carouselSize = carousel?.clientWidth;
12+
const childSize = (carousel.childNodes[0] as HTMLUListElement)?.clientWidth + gap;
13+
14+
scroll = scroll || carouselSize;
15+
16+
const numberOfItems = Math.floor(carouselSize / childSize);
17+
const overflow = scroll % childSize;
18+
const amount = numberOfItems * childSize - overflow * direction;
19+
scroll += amount * direction;
20+
return amount * direction;
21+
}
22+
23+
function next() {
24+
carousel.scrollBy({
25+
left: calculateScrollAmount(),
26+
behavior: 'smooth'
27+
});
28+
}
29+
function prev() {
30+
carousel.scrollBy({
31+
left: calculateScrollAmount(true),
32+
behavior: 'smooth'
33+
});
34+
}
35+
36+
function handleTouchStart(e: TouchEvent) {
37+
touchStart = e.touches[0].clientX;
38+
}
39+
function handleTouchMove(e: TouchEvent) {
40+
touchEnd = e.touches[0].clientX;
41+
}
42+
43+
function handleTouchEnd() {
44+
if (touchEnd > touchStart) {
45+
prev();
46+
} else {
47+
next();
48+
}
49+
}
50+
</script>
51+
52+
<div class="u-flex u-main-space-between u-flex-wrap">
53+
<slot name="header" />
54+
<div class="u-flex u-gap-12 u-cross-end u-margin-block-start-8">
55+
<button class="aw-icon-button" aria-label="Move carousel backward" on:click={() => prev()}>
56+
<span class="icon-arrow-left" aria-hidden="true" />
57+
</button>
58+
<button class="aw-icon-button" aria-label="Move carousel forward" on:click={() => next()}>
59+
<span class="icon-arrow-right" aria-hidden="true" />
60+
</button>
61+
</div>
62+
</div>
63+
<ul
64+
class="aw-grid-articles aw-u-gap-32 u-margin-block-start-32 carousel"
65+
bind:this={carousel}
66+
on:touchstart={handleTouchStart}
67+
on:touchmove={handleTouchMove}
68+
on:touchend={handleTouchEnd}
69+
>
70+
<slot />
71+
</ul>
72+
73+
<style lang="scss">
74+
.carousel {
75+
grid-auto-flow: column;
76+
grid-auto-columns: minmax(17.5rem, 1fr);
77+
overflow-x: hidden;
78+
}
79+
</style>

src/lib/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export { default as Newsletter } from './Newsletter.svelte';
88
export { default as Tooltip } from './Tooltip.svelte';
99
export { default as Spline } from './Spline.svelte';
1010
export { default as Article } from './Article.svelte';
11+
export { default as Carousel } from './Carousel.svelte';

0 commit comments

Comments
 (0)