Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Banner - pause/play #531

Merged
merged 2 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 46 additions & 45 deletions src/components/Marquee/Marquee.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -86,21 +68,25 @@ interface MarqueeProps {
* Default: null
*/
children?: React.ReactNode
sx?: SxProps<Theme>
onClick?: () => void
}

// tento komponent je z https://github.com/justin-chu/react-fast-marquee/blob/master/src/components/Marquee.tsx
// ale prepisali sme si ho MUI stylmi
export const Marquee: FC<MarqueeProps> = ({
play = true,
pauseOnHover = false,
pauseOnClick = false,
pauseOnHold = false,
direction = 'left',
speed = 20,
delay = 0,
gradient = true,
gradientColor = [255, 255, 255],
gradientWidth = 200,
children,
sx,
onClick,
}) => {
/* React Hooks */
const [containerWidth, setContainerWidth] = useState(0)
Expand Down Expand Up @@ -133,42 +119,57 @@ export const Marquee: FC<MarqueeProps> = ({
const rgbaGradientColor = `rgba(${gradientColor[0]}, ${gradientColor[1]}, ${gradientColor[2]}`

const element = (
<Box
<Stack
ref={marqueeRef}
direction="row"
sx={{
...marqueeSx,
'--play': play ? 'running' : 'paused',
'--direction': direction === 'left' ? 'normal' : 'reverse',
'--duration': `${duration}s`,
'--delay': `${delay}s`,
'--margin-right': `${marqueeWidth < containerWidth ? containerWidth - marqueeWidth : 0}px`,
'@keyframes scroll': {
'0%': {
transform: 'translateX(0)',
},
'100%': {
transform: 'translateX(calc(-100% - var(--margin-right)))',
},
},

// `animation` has to be defined first, next properties adjust its state
animation: 'scroll var(--duration) linear var(--delay) infinite',
animationDelay: 'var(--delay)',
animationDirection: 'var(--direction)',
marginRight: 'var(--margin-right)',

animationPlayState: 'var(--play)',
}}
>
{children}
</Box>
</Stack>
)

return (
<>
{!isMounted ? null : (
<Box
<Stack
ref={containerRef}
direction="row"
onClick={onClick}
sx={{
overflowX: 'hidden !important',
display: 'flex !important',
flexDirection: 'row !important',
overflowX: 'hidden',
position: 'relative',
height: '100%',
width: '100%',
animationPlayState: 'running',
'&:hover div': {
animationPlayState: 'var(--pause-on-hover)',
},
'&:active div': {
animationPlayState: 'var(--pause-on-click)',
},
'--pause-on-hover': pauseOnHover ? 'paused' : 'running',
'--pause-on-click': pauseOnClick ? 'paused' : 'running',
cursor: onClick ? 'pointer' : 'default',

// `toFixed` fixes a weird bug with `duration` infinitely changing on pause
'--duration': `${duration.toFixed(4)}s`,
'--delay': `${delay}s`,
'--direction': direction === 'left' ? 'normal' : 'reverse',
'--margin-right': `${marqueeWidth < containerWidth ? containerWidth - marqueeWidth : 0}px`,

'--play': play ? 'running' : 'paused',
'&:hover': pauseOnHover ? {'--play': 'paused'} : {},
'&:active': pauseOnHold ? {'--play': 'paused'} : {},

...sx,
}}
>
{gradient && (
Expand All @@ -180,7 +181,7 @@ export const Marquee: FC<MarqueeProps> = ({

'&::before, &::after': {
background: 'linear-gradient(to right, var(--gradient-color))',
content: '',
content: '""',
height: '100%',
position: 'absolute',
width: 'var(--gradient-width)',
Expand All @@ -205,7 +206,7 @@ export const Marquee: FC<MarqueeProps> = ({
)}
{element}
{element}
</Box>
</Stack>
)}
</>
)
Expand Down
21 changes: 13 additions & 8 deletions src/components/PageLayout/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -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 =
Expand All @@ -16,19 +19,21 @@ export const Banner: FC = () => {
}

return (
<Box
<Marquee
gradient={false}
speed={100}
play={play}
onClick={togglePlay}
sx={{
bgcolor: 'black',
color: 'white',
zIndex: 3,
py: '0.2rem',
}}
>
<Marquee gradient={false} speed={100}>
<Typography variant="h2" component="span" sx={{whiteSpace: 'nowrap'}}>
{bannerTextFormatted}
</Typography>
</Marquee>
</Box>
<Typography variant="h2" component="span" sx={{whiteSpace: 'nowrap'}}>
{bannerTextFormatted}
</Typography>
</Marquee>
)
}
13 changes: 8 additions & 5 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<PropsWithChildren> = ({children}) => {
Expand Down Expand Up @@ -91,11 +92,13 @@ const MyApp: FC<AppProps> = ({Component, pageProps}) => {
<ReactQueryDevtools />
<CookiesProvider>
<AuthContainer.Provider>
<ThemeProvider theme={theme}>
<CssBaseline />
<AlertBox />
<Component {...pageProps} />
</ThemeProvider>
<BannerAnimationContainer.Provider>
<ThemeProvider theme={theme}>
<CssBaseline />
<AlertBox />
<Component {...pageProps} />
</ThemeProvider>
</BannerAnimationContainer.Provider>
</AuthContainer.Provider>
</CookiesProvider>
</ReactQueryProvider>
Expand Down
11 changes: 11 additions & 0 deletions src/utils/BannerAnimationProvider.tsx
Original file line number Diff line number Diff line change
@@ -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)
Loading