From 7aa901a355bfa2d32518f1fd865afddfdbcc5e2d Mon Sep 17 00:00:00 2001 From: Benno Tielen Date: Tue, 26 Nov 2024 17:02:38 +0100 Subject: [PATCH] fix: make image slider more beautiful --- src/components/Arrow/Arrow.tsx | 14 +++-- src/components/ImageCard/styles.module.scss | 8 ++- .../ImageCardSlider.stories.tsx | 6 ++ .../ImageCardSlider/ImageCardSlider.tsx | 57 ++++++++++++++++--- .../ImageCardSlider/styles.module.scss | 22 ++++++- src/fetch/blog.ts | 3 +- 6 files changed, 94 insertions(+), 16 deletions(-) diff --git a/src/components/Arrow/Arrow.tsx b/src/components/Arrow/Arrow.tsx index 1c72b28..6190ebc 100644 --- a/src/components/Arrow/Arrow.tsx +++ b/src/components/Arrow/Arrow.tsx @@ -1,12 +1,18 @@ -import arrow from "./Arrow.svg" +import arrow from './Arrow.svg' import Image from 'next/image' type ArrowProps = { - direction: "left" | "right" + direction: 'left' | 'right', + onClick?: () => void } -export const Arrow = ({direction}: ArrowProps) => { +export const Arrow = ({ direction, onClick }: ArrowProps) => { return ( - {""} + {''} ) } \ No newline at end of file diff --git a/src/components/ImageCard/styles.module.scss b/src/components/ImageCard/styles.module.scss index f59153b..700b730 100644 --- a/src/components/ImageCard/styles.module.scss +++ b/src/components/ImageCard/styles.module.scss @@ -8,7 +8,8 @@ box-shadow: 3px 7px 26px -5px rgba(0, 0, 0, 0.15); cursor: pointer; overflow: hidden; - border-radius: $border-radius; + border-top-left-radius: $border-radius; + border-top-right-radius: $border-radius; position: relative; } @@ -17,12 +18,13 @@ text-align: center; font-size: 18px; position: absolute; - bottom: 0px; + bottom: 0; width: 100%; color: $base-color; padding: 10px 0; transition: padding 0.3s ease-out; - border-radius: $border-radius; + border-top-left-radius: $border-radius; + border-top-right-radius: $border-radius; } .container:hover .title { diff --git a/src/compositions/ImageCardSlider/ImageCardSlider.stories.tsx b/src/compositions/ImageCardSlider/ImageCardSlider.stories.tsx index 1d8d528..caf3cd2 100644 --- a/src/compositions/ImageCardSlider/ImageCardSlider.stories.tsx +++ b/src/compositions/ImageCardSlider/ImageCardSlider.stories.tsx @@ -32,6 +32,12 @@ export const Default: Story = { src: "https://i1.sndcdn.com/artworks-6CIZtxsNOaYIm98h-mL41yA-t500x500.jpg", title: "Erntedankfest", href: "https://somelink" + }, + { + id: "id4", + src: "https://i1.sndcdn.com/artworks-6CIZtxsNOaYIm98h-mL41yA-t500x500.jpg", + title: "Slide4", + href: "https://somelink" } ] }, diff --git a/src/compositions/ImageCardSlider/ImageCardSlider.tsx b/src/compositions/ImageCardSlider/ImageCardSlider.tsx index 02b714f..5566446 100644 --- a/src/compositions/ImageCardSlider/ImageCardSlider.tsx +++ b/src/compositions/ImageCardSlider/ImageCardSlider.tsx @@ -1,7 +1,11 @@ +"use client" + import { ImageCard } from '@/components/ImageCard/ImageCard' import styles from "./styles.module.scss" import { StaticImageData } from 'next/image' import { Arrow } from '@/components/Arrow/Arrow' +import { useEffect, useMemo, useState } from 'react' +import classNames from 'classnames' export type Slide = { id: string, @@ -15,20 +19,59 @@ type ImageCardSliderProps = { } export const ImageCardSlider = ({slides}: ImageCardSliderProps) => { + + const itemsPerPage = 3; + const [page, setPage] = useState(0) + const [prevDisabled, setPrevDisabled] = useState(true) + const [nextDisabled, setNextDisabled] = useState(true) + + useEffect(() => { + if (page === 0) { + setPrevDisabled(true) + } else { + setPrevDisabled(false) + } + + if ((page + 1) * itemsPerPage > slides.length) { + setNextDisabled(true) + } else { + setNextDisabled(false) + } + + }, [slides, page, setNextDisabled, setPrevDisabled]) + + const pagedSlides = useMemo(() => { + return slides.slice(page * itemsPerPage, (page + 1) * itemsPerPage) + }, [slides, page]) + return (
-
- +
+ setPage(page - 1)} + />
{ - slides.map(slide =>
- -
) + pagedSlides.map(slide => +
+ +
+ ) }
-
- +
+ setPage(page + 1)} + />
diff --git a/src/compositions/ImageCardSlider/styles.module.scss b/src/compositions/ImageCardSlider/styles.module.scss index 205ff91..7b73993 100644 --- a/src/compositions/ImageCardSlider/styles.module.scss +++ b/src/compositions/ImageCardSlider/styles.module.scss @@ -8,12 +8,14 @@ position: absolute; top: calc(50% - 25px); left: -50px; + cursor: pointer; } .arrowRight { position: absolute; right: -50px; top: calc(50% - 25px); + cursor: pointer; } .container { @@ -24,8 +26,24 @@ } .item { - flex: 1 1 calc(33.333% - 20px); + flex: 0 1 calc(33.333% - 20px); aspect-ratio: 1 / 1; + animation: fadein 0.3s ease-out; +} + +.disabled { + opacity: 0.6; + pointer-events: none; + cursor: inherit; +} + +@keyframes fadein { + from { + opacity: 0; + } + to { + opacity: 1; + } } @media screen and (max-width: 576px) { @@ -33,7 +51,9 @@ flex: 0 0 100%; margin-bottom: 20px; } +} +@media screen and (max-width: 1200px) { .arrowLeft, .arrowRight { display: none; } diff --git a/src/fetch/blog.ts b/src/fetch/blog.ts index 819a0b5..368ce85 100644 --- a/src/fetch/blog.ts +++ b/src/fetch/blog.ts @@ -10,7 +10,8 @@ export const fetchBlog = async (): Promise | undefined> => { title: true, date: true, photo: true - } + }, + limit: 18 }, { addQueryPrefix: true }, )