From 485e42374f20d96ca9b1af380dd542338fe1357a Mon Sep 17 00:00:00 2001 From: Diogo Soares <32431609+DiogoSoaress@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:39:32 +0100 Subject: [PATCH] feat: scroll based animation in VerticalStack --- src/components/Wallet/VerticalSlide/Table.tsx | 3 +- src/components/Wallet/VerticalStack/Table.tsx | 53 ++++++++++++++ src/components/Wallet/VerticalStack/index.tsx | 71 ++++++++----------- .../Wallet/VerticalStack/styles.module.css | 32 ++++++++- 4 files changed, 117 insertions(+), 42 deletions(-) create mode 100644 src/components/Wallet/VerticalStack/Table.tsx diff --git a/src/components/Wallet/VerticalSlide/Table.tsx b/src/components/Wallet/VerticalSlide/Table.tsx index 128f9ff6..fc2c0230 100644 --- a/src/components/Wallet/VerticalSlide/Table.tsx +++ b/src/components/Wallet/VerticalSlide/Table.tsx @@ -11,7 +11,8 @@ import useScrollProgress from '@/hooks/useScrollProgress' const icons = [, , ] -const selectIndex = (scrollYProgress: number) => { +// TODO: move to utils +export const selectIndex = (scrollYProgress: number) => { if (scrollYProgress >= 0 && scrollYProgress <= 0.4) { return 0 } else if (scrollYProgress > 0.4 && scrollYProgress <= 0.6) { diff --git a/src/components/Wallet/VerticalStack/Table.tsx b/src/components/Wallet/VerticalStack/Table.tsx new file mode 100644 index 00000000..d9b02091 --- /dev/null +++ b/src/components/Wallet/VerticalStack/Table.tsx @@ -0,0 +1,53 @@ +import type { BaseBlock } from '@/components/Home/types' +import { useEffect, useState, type ReactElement, type RefObject } from 'react' +import css from './styles.module.css' +import { Grid, Typography } from '@mui/material' +import useScrollProgress from '@/hooks/useScrollProgress' +import { selectIndex } from '@/components/Wallet/VerticalSlide/Table' + +export const GridItem = ({ + image, + title, + text, + isSelected, +}: Partial & { isSelected: boolean }): ReactElement => ( + + {image ? : null} + + {title} + + {text && ( + + {text} + + )} + +) + +const Table = ({ items = [], sectionRef }: { items: BaseBlock['items']; sectionRef: RefObject }) => { + const [selectedIndex, setSelectedIndex] = useState(0) + const { scrollYProgress } = useScrollProgress(sectionRef) + + useEffect(() => { + const handleScroll = () => { + const newIndex = selectIndex(scrollYProgress.get()) + setSelectedIndex(newIndex) + } + + const unsubscribe = scrollYProgress.on('change', handleScroll) + + return () => { + unsubscribe() + } + }, [scrollYProgress, items.length]) + + return ( +
+ {items.map((item, index) => ( + + ))} +
+ ) +} + +export default Table diff --git a/src/components/Wallet/VerticalStack/index.tsx b/src/components/Wallet/VerticalStack/index.tsx index 3122cc4a..1e7834f8 100644 --- a/src/components/Wallet/VerticalStack/index.tsx +++ b/src/components/Wallet/VerticalStack/index.tsx @@ -1,51 +1,42 @@ -import type { DetailedHTMLProps, ReactElement, SourceHTMLAttributes } from 'react' +import dynamic from 'next/dynamic' +import { useRef, type DetailedHTMLProps, type SourceHTMLAttributes } from 'react' import { Container, Grid, Typography } from '@mui/material' import type { BaseBlock } from '@/components/Home/types' import layoutCss from '@/components/common/styles.module.css' import css from './styles.module.css' +const Table = dynamic(() => import('./Table')) + type VideoEmbed = { sources: Array, HTMLSourceElement>> } -export const GridItem = ({ image, title, text }: Partial): ReactElement => ( - - {image ? : null} - - {title} - - {text && ( - - {text} - - )} - -) - -const VerticalStack = ({ title, video, items = [] }: BaseBlock & { video: VideoEmbed }) => ( - - - - {video && ( - - )} - - {title} - - - -
- {items.map((item, index) => ( - - ))} -
-
-
-
-) +const VerticalStack = ({ title, video, items = [] }: BaseBlock & { video: VideoEmbed }) => { + const sectionRef = useRef(null) + + return ( + +
+ + + {video && ( + + )} + + {title} + + + + + + + + + ) +} export default VerticalStack diff --git a/src/components/Wallet/VerticalStack/styles.module.css b/src/components/Wallet/VerticalStack/styles.module.css index 4dbc8ad5..8f194383 100644 --- a/src/components/Wallet/VerticalStack/styles.module.css +++ b/src/components/Wallet/VerticalStack/styles.module.css @@ -11,15 +11,45 @@ flex-direction: column; gap: 16px; align-items: flex-start; - padding: 48px 40px; + padding: 32px; text-align: left; + position: relative; } .video { width: 144px; } +.card.selected::before { + content: ''; + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 4px; + background-color: var(--mui-palette-primary-main); +} + +.selected { + color: var(--mui-palette-primary-main); +} + @media (min-width: 900px) { + .sectionContainer { + height: 240vh; + } + + .stickyContainer { + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + position: sticky; + top: 0; + overflow: hidden; + } + .titleWrapper { display: flex; flex-direction: column;