Skip to content

Commit ef3e261

Browse files
authored
Merge pull request #19 from andriawan/15-landing-page
Landing page Improvement
2 parents c1cc46d + 2160d2e commit ef3e261

4 files changed

Lines changed: 92 additions & 42 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script module>
2+
import { defineMeta } from '@storybook/addon-svelte-csf';
3+
import HeroSlider from './HeroSlider.svelte';
4+
5+
const { Story } = defineMeta({
6+
title: 'Landing Page/HeroSlider',
7+
component: HeroSlider,
8+
tags: ['autodocs'],
9+
parameters: {
10+
layout: 'fullscreen'
11+
},
12+
args: {
13+
isStatic: false,
14+
intervalTime: 1000
15+
}
16+
});
17+
</script>
18+
19+
<Story name="Default">
20+
<HeroSlider />
21+
</Story>

src/lib/components/common/HeroSlider.svelte

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
import { onMount } from 'svelte';
33
import type { HeroSliderList } from '../../../contract/HeroSliderList';
44
5-
let currentSlide = 0;
6-
const totalSlides = 3;
5+
let { isStatic = false, intervalTime = 5000 } = $props();
6+
7+
let currentSlide = $state(0);
8+
const totalSlides = $state(3);
9+
let interval = $state<NodeJS.Timeout | null>(null);
710
let sliderItem: HeroSliderList[] = [
811
{
912
id: 1,
@@ -32,22 +35,42 @@
3235
];
3336
3437
onMount(() => {
35-
const interval = setInterval(() => {
36-
currentSlide = (currentSlide + 1) % totalSlides;
37-
}, 5000);
38+
setNewInterval();
39+
return () => interval && clearInterval(interval);
40+
});
3841
39-
return () => clearInterval(interval);
42+
$effect(() => {
43+
if (isStatic && interval) {
44+
clearInterval(interval);
45+
interval = null;
46+
return;
47+
} else {
48+
setTimeout(() => {
49+
setNewInterval();
50+
}, 0);
51+
}
4052
});
4153
54+
function setNewInterval() {
55+
if (isStatic) return;
56+
if (interval) clearInterval(interval);
57+
interval = setInterval(() => {
58+
currentSlide = (currentSlide + 1) % totalSlides;
59+
}, intervalTime);
60+
}
61+
4262
function goToSlide(index: number) {
63+
setNewInterval();
4364
currentSlide = index;
4465
}
4566
4667
function nextSlide() {
68+
setNewInterval();
4769
currentSlide = (currentSlide + 1) % totalSlides;
4870
}
4971
5072
function prevSlide() {
73+
setNewInterval();
5174
currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;
5275
}
5376
</script>
@@ -82,36 +105,37 @@
82105
</div>
83106
{/each}
84107

85-
<button
86-
aria-label="indicator previous slide"
87-
on:click={prevSlide}
88-
class="absolute top-1/2 left-4 z-10 flex h-12 w-12 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/80 transition-all hover:bg-white sm:left-8"
89-
>
90-
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
91-
<polyline points="15 18 9 12 15 6"></polyline>
92-
</svg>
93-
</button>
94-
<button
95-
aria-label="indicator next slide"
96-
on:click={nextSlide}
97-
class="absolute top-1/2 right-4 z-10 flex h-12 w-12 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/80 transition-all hover:bg-white sm:right-8"
98-
>
99-
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
100-
<polyline points="9 18 15 12 9 6"></polyline>
101-
</svg>
102-
</button>
103-
104-
<div class="absolute bottom-8 left-1/2 z-10 flex -translate-x-1/2 gap-4">
105-
{#each sliderItem as slider, i (slider.id)}
106-
<button
107-
aria-label="dot-{slider.id}"
108-
on:click={() => goToSlide(i)}
109-
class="h-3 cursor-pointer rounded-full transition-all {currentSlide === i
110-
? 'w-8'
111-
: 'w-3'} {currentSlide === i ? 'bg-white' : 'bg-white/50'}"
112-
>
113-
</button>
114-
{/each}
115-
</div>
108+
{#if !isStatic}
109+
<button
110+
aria-label="indicator previous slide"
111+
onclick={prevSlide}
112+
class="absolute top-1/2 left-4 z-10 flex h-12 w-12 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/80 transition-all hover:bg-white sm:left-8"
113+
>
114+
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
115+
<polyline points="15 18 9 12 15 6"></polyline>
116+
</svg>
117+
</button>
118+
<button
119+
aria-label="indicator next slide"
120+
onclick={nextSlide}
121+
class="absolute top-1/2 right-4 z-10 flex h-12 w-12 -translate-y-1/2 cursor-pointer items-center justify-center rounded-full bg-white/80 transition-all hover:bg-white sm:right-8"
122+
>
123+
<svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
124+
<polyline points="9 18 15 12 9 6"></polyline>
125+
</svg>
126+
</button>
127+
<div class="absolute bottom-8 left-1/2 z-10 flex -translate-x-1/2 gap-4">
128+
{#each sliderItem as slider, i (slider.id)}
129+
<button
130+
aria-label="dot-{slider.id}"
131+
onclick={() => goToSlide(i)}
132+
class="h-3 cursor-pointer rounded-full transition-all {currentSlide === i
133+
? 'w-8'
134+
: 'w-3'} {currentSlide === i ? 'bg-white' : 'bg-white/50'}"
135+
>
136+
</button>
137+
{/each}
138+
</div>
139+
{/if}
116140
</div>
117141
</section>
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<script module>
22
import { defineMeta } from '@storybook/addon-svelte-csf';
3-
import { fn } from 'storybook/test';
43
54
import Navbar from './Navbar.svelte';
65
@@ -9,11 +8,15 @@
98
component: Navbar,
109
tags: ['autodocs'],
1110
args: {
12-
onMenuClick: fn()
11+
fullWidth: true,
12+
maxWidthSizeClass: 'max-w-8xl'
1313
}
1414
});
1515
</script>
1616

17-
<Story name="Primary">
17+
<Story name="Default" args={{ fullWidth: false, maxWidthSizeClass: 'max-w-7xl' }}>
18+
<Navbar />
19+
</Story>
20+
<Story name="Full Width" args={{ fullWidth: true }}>
1821
<Navbar />
1922
</Story>

src/lib/components/common/Navbar.svelte

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<script lang="ts">
2+
let { fullWidth = false, maxWidthSizeClass = 'max-w-7xl' } = $props();
3+
let maxWidthClass = $derived(fullWidth ? 'max-w-full' : maxWidthSizeClass);
24
</script>
35

46
<nav
5-
class="fixed top-2.5 right-4 left-4 z-50 rounded-full bg-white/80 shadow-lg backdrop-blur-md md:right-8 md:left-8"
7+
class="fixed {maxWidthClass} top-2.5 right-4 left-4 z-50 mx-auto rounded-full bg-white/80 shadow-lg backdrop-blur-md md:right-8 md:left-8"
68
>
7-
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
9+
<div class="px-4 sm:px-6 lg:px-8">
810
<div class="flex h-16 items-center justify-between">
911
<button
1012
aria-label="Toggle mobile menu"

0 commit comments

Comments
 (0)