Use a component for carousel dots
- Show 5 dots by default - First and last one from current index are smaller - Other ones are hidden
This commit is contained in:
21
src/molecules/PaginationDots.svelte
Normal file
21
src/molecules/PaginationDots.svelte
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
// Props
|
||||||
|
export let photos
|
||||||
|
export let currentIndex
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ol class="carousel__dots">
|
||||||
|
{#each photos as dot, index}
|
||||||
|
<li
|
||||||
|
class:active={index === currentIndex}
|
||||||
|
class:small={index < currentIndex - 2 || index > currentIndex + 2}
|
||||||
|
class:hidden={index < currentIndex - 3 || index > currentIndex + 3}
|
||||||
|
on:click={() => dispatch('goToIndex', { index })}
|
||||||
|
>
|
||||||
|
<button aria-label="Go to photo #{index + 1}"></button>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ol>
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
// Components
|
// Components
|
||||||
import IconArrow from '../atoms/IconArrow'
|
import IconArrow from '../atoms/IconArrow'
|
||||||
import Counter from '../atoms/Counter'
|
import Counter from '../atoms/Counter'
|
||||||
|
import PaginationDots from '../molecules/PaginationDots'
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
export let photos
|
export let photos
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
|
currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
|
||||||
} else {
|
} else {
|
||||||
currentIndex = direction
|
currentIndex = direction
|
||||||
console.log('Go to photo', direction, currentIndex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send current photo to event
|
// Send current photo to event
|
||||||
@@ -203,12 +203,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ol class="carousel__dots">
|
<PaginationDots {photos} {currentIndex}
|
||||||
{#each photos as page, index}
|
on:goToIndex={event => currentIndex = event.detail.index}
|
||||||
<li class:active={page === currentPhoto} on:click={() => goToPhoto(index)}>
|
/>
|
||||||
<button aria-label="Go to photo #{index + 1}"></button>
|
|
||||||
</li>
|
|
||||||
{/each}
|
|
||||||
</ol>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -252,16 +252,37 @@
|
|||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: block;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&, button {
|
||||||
|
transition: all 0.6s $ease-quart;
|
||||||
|
will-change: transform, width, height, padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active
|
||||||
&.active button {
|
&.active button {
|
||||||
background-color: $color-secondary;
|
background-color: $color-secondary;
|
||||||
transform: scale(1.25);
|
transform: scale(1.25);
|
||||||
will-change: scale, background-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Small dot
|
||||||
|
&.small button {
|
||||||
|
transform: scale(0.6);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
// Hidden
|
||||||
|
&.hidden {
|
||||||
|
padding: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hover
|
||||||
&:hover:not(.active) {
|
&:hover:not(.active) {
|
||||||
button {
|
button {
|
||||||
background-color: lighten($color-lightpurple, 10);
|
background-color: lighten($color-lightpurple, 10);
|
||||||
@@ -277,7 +298,6 @@
|
|||||||
background-color: $color-lightpurple;
|
background-color: $color-lightpurple;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all 600ms $ease-quart;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user