From 66315d14312ed7ba0d965dae88009b5e2103d3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Trembeck=C3=BD?= Date: Sun, 15 Dec 2024 12:06:37 +0100 Subject: [PATCH] Banner - pause/play (#531) * pause/play on Banner * fix bug with `duration` infinitely changing on pause --- src/components/Marquee/Marquee.tsx | 91 +++++++++++---------- src/components/PageLayout/Banner/Banner.tsx | 21 +++-- src/pages/_app.tsx | 13 +-- src/utils/BannerAnimationProvider.tsx | 11 +++ 4 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 src/utils/BannerAnimationProvider.tsx diff --git a/src/components/Marquee/Marquee.tsx b/src/components/Marquee/Marquee.tsx index 6e3bc7f2..97262ada 100644 --- a/src/components/Marquee/Marquee.tsx +++ b/src/components/Marquee/Marquee.tsx @@ -1,24 +1,6 @@ -import {Box} from '@mui/material' +import {Box, Stack, SxProps, Theme} from '@mui/material' import {FC, useEffect, useRef, useState} from 'react' -const marqueeSx = { - display: 'flex', - flexDirection: 'row', - marginRight: 'var(--margin-right)', - animation: 'scroll var(--duration) linear var(--delay) infinite', - animationPlayState: 'var(--play)', - animationDelay: 'var(--delay)', - animationDirection: 'var(--direction)', - '@keyframes scroll': { - '0%': { - transform: 'translateX(0)', - }, - '100%': { - transform: 'translateX(calc(-100% - var(--margin-right)))', - }, - }, -} - interface MarqueeProps { /** * Inline style for the container div @@ -39,11 +21,11 @@ interface MarqueeProps { */ pauseOnHover?: boolean /** - * Whether to pause the marquee when clicked + * Whether to pause the marquee when clicked and held * Type: boolean * Default: false */ - pauseOnClick?: boolean + pauseOnHold?: boolean /** * The direction the marquee is sliding * Type: "left" or "right" @@ -86,6 +68,8 @@ interface MarqueeProps { * Default: null */ children?: React.ReactNode + sx?: SxProps + onClick?: () => void } // tento komponent je z https://github.com/justin-chu/react-fast-marquee/blob/master/src/components/Marquee.tsx @@ -93,7 +77,7 @@ interface MarqueeProps { export const Marquee: FC = ({ play = true, pauseOnHover = false, - pauseOnClick = false, + pauseOnHold = false, direction = 'left', speed = 20, delay = 0, @@ -101,6 +85,8 @@ export const Marquee: FC = ({ gradientColor = [255, 255, 255], gradientWidth = 200, children, + sx, + onClick, }) => { /* React Hooks */ const [containerWidth, setContainerWidth] = useState(0) @@ -133,42 +119,57 @@ export const Marquee: FC = ({ const rgbaGradientColor = `rgba(${gradientColor[0]}, ${gradientColor[1]}, ${gradientColor[2]}` const element = ( - {children} - + ) return ( <> {!isMounted ? null : ( - {gradient && ( @@ -180,7 +181,7 @@ export const Marquee: FC = ({ '&::before, &::after': { background: 'linear-gradient(to right, var(--gradient-color))', - content: '', + content: '""', height: '100%', position: 'absolute', width: 'var(--gradient-width)', @@ -205,7 +206,7 @@ export const Marquee: FC = ({ )} {element} {element} - + )} ) diff --git a/src/components/PageLayout/Banner/Banner.tsx b/src/components/PageLayout/Banner/Banner.tsx index 6c1dc63f..22d4f1e2 100644 --- a/src/components/PageLayout/Banner/Banner.tsx +++ b/src/components/PageLayout/Banner/Banner.tsx @@ -1,11 +1,14 @@ -import {Box, Typography} from '@mui/material' +import {Typography} from '@mui/material' import {FC} from 'react' import {Marquee} from '@/components/Marquee/Marquee' +import {BannerAnimationContainer} from '@/utils/BannerAnimationProvider' import {BannerContainer} from '@/utils/BannerContainer' export const Banner: FC = () => { const {bannerMessages} = BannerContainer.useContainer() + const {play, togglePlay} = BannerAnimationContainer.useContainer() + const divider = ' - ' const bannerTextFormatted = @@ -16,7 +19,11 @@ export const Banner: FC = () => { } return ( - { py: '0.2rem', }} > - - - {bannerTextFormatted} - - - + + {bannerTextFormatted} + + ) } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 0a79ccab..6d2ff0d3 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -12,6 +12,7 @@ import {AlertBox} from '@/components/Alert/AlertBox' import {theme} from '@/theme' import {AlertContainer} from '@/utils/AlertContainer' import {AuthContainer} from '@/utils/AuthContainer' +import {BannerAnimationContainer} from '@/utils/BannerAnimationProvider' import {useAlert} from '@/utils/useAlert' const ReactQueryProvider: FC = ({children}) => { @@ -91,11 +92,13 @@ const MyApp: FC = ({Component, pageProps}) => { - - - - - + + + + + + + diff --git a/src/utils/BannerAnimationProvider.tsx b/src/utils/BannerAnimationProvider.tsx new file mode 100644 index 00000000..09169053 --- /dev/null +++ b/src/utils/BannerAnimationProvider.tsx @@ -0,0 +1,11 @@ +import {useState} from 'react' +import {createContainer} from 'unstated-next' + +const useBannerAnimation = () => { + const [play, setPlay] = useState(true) + const togglePlay = () => setPlay((prev) => !prev) + + return {play, setPlay, togglePlay} +} + +export const BannerAnimationContainer = createContainer(useBannerAnimation)