import type { BoxProps } from '@mui/material/Box'; import type { UseClientRectReturn } from 'minimal-shared/hooks'; import { useRef, useState } from 'react'; import { varAlpha } from 'minimal-shared/utils'; import { useClientRect } from 'minimal-shared/hooks'; import { m, useSpring, useScroll, useTransform, useMotionValueEvent } from 'framer-motion'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import SvgIcon from '@mui/material/SvgIcon'; import Container from '@mui/material/Container'; import Typography from '@mui/material/Typography'; import { styled, useTheme } from '@mui/material/styles'; import { CONFIG } from 'src/global-config'; import { primaryColorPresets } from 'src/theme/with-settings'; import { Iconify } from 'src/components/iconify'; import { varFade, MotionViewport } from 'src/components/animate'; import { SectionTitle } from './components/section-title'; import { FloatLine, FloatPlusIcon } from './components/svg-elements'; // ---------------------------------------------------------------------- const renderLines = () => ( <> ); export function HomeHighlightFeatures({ sx, ...other }: BoxProps) { const containerRoot = useClientRect(); return ( {renderLines()} ); } // ---------------------------------------------------------------------- const ITEMS = [ { title: 'Dark mode', subtitle: 'A dark theme that feels easier on the eyes.', icon: 'solar:cloudy-moon-bold-duotone', imgUrl: [`${CONFIG.assetsDir}/assets/images/home/highlight-darkmode.webp`], }, { title: 'Color presets', subtitle: 'Express your own style with just one click.', icon: 'solar:pallete-2-bold-duotone', imgUrl: [ `${CONFIG.assetsDir}/assets/images/home/highlight-presets-1.webp`, `${CONFIG.assetsDir}/assets/images/home/highlight-presets-2.webp`, `${CONFIG.assetsDir}/assets/images/home/highlight-presets-3.webp`, `${CONFIG.assetsDir}/assets/images/home/highlight-presets-4.webp`, `${CONFIG.assetsDir}/assets/images/home/highlight-presets-5.webp`, ], }, { title: 'Right-to-left', subtitle: 'Support languages such as Arabic, Persian, and Hebrew.', icon: 'solar:align-right-bold-duotone', imgUrl: [`${CONFIG.assetsDir}/assets/images/home/highlight-rtl.webp`], }, ] as const; type ScrollContentProps = { containerRoot: UseClientRectReturn; }; function ScrollableContent({ containerRoot }: ScrollContentProps) { const theme = useTheme(); const isRtl = theme.direction === 'rtl'; const containerRef = useRef(null); const containeRect = useClientRect(containerRef); const scrollRef = useRef(null); const scrollRect = useClientRect(scrollRef); const { scrollYProgress } = useScroll({ target: containerRef }); const [startScroll, setStartScroll] = useState(false); const physics = { damping: 16, mass: 0.12, stiffness: 80 }; const scrollRange = (-scrollRect.scrollWidth + containeRect.width / 2) * (isRtl ? -1 : 1); const x = useSpring(useTransform(scrollYProgress, [0, 1], [0, scrollRange]), physics); const background = useTransform( scrollYProgress, [0, 0.12, 0.28, 0.48, 0.58, 0.62, 0.72, 0.92], [ `transparent`, `linear-gradient(180deg, ${theme.palette.primary.light}, ${theme.palette.primary.dark})`, `linear-gradient(180deg, ${primaryColorPresets.preset1.light}, ${primaryColorPresets.preset1.dark})`, `linear-gradient(180deg, ${primaryColorPresets.preset2.light}, ${primaryColorPresets.preset2.dark})`, `linear-gradient(180deg, ${primaryColorPresets.preset3.light}, ${primaryColorPresets.preset3.dark})`, `linear-gradient(180deg, ${primaryColorPresets.preset4.light}, ${primaryColorPresets.preset4.dark})`, `linear-gradient(180deg, ${primaryColorPresets.preset5.light}, ${primaryColorPresets.preset5.dark})`, `linear-gradient(180deg, ${theme.palette.background.neutral}, ${theme.palette.background.neutral})`, ] ); useMotionValueEvent(scrollYProgress, 'change', (latest) => { if (latest !== 0 && latest !== 1) { setStartScroll(true); } else { setStartScroll(false); } }); return ( {ITEMS.map((item) => ( ))} ); } // ---------------------------------------------------------------------- const ScrollRoot = styled(m.div)(({ theme }) => ({ zIndex: 9, position: 'relative', paddingTop: theme.spacing(5), [theme.breakpoints.up('md')]: { paddingTop: theme.spacing(8) }, })); const ScrollContainer = styled(m.div)(({ theme }) => ({ top: 0, height: '100vh', display: 'flex', position: 'sticky', overflow: 'hidden', flexDirection: 'column', alignItems: 'flex-start', transition: theme.transitions.create(['background-color']), '&[data-scrolling="true"]': { justifyContent: 'center' }, })); const ScrollContent = styled(m.div)(({ theme }) => ({ display: 'flex', gap: theme.spacing(5), paddingLeft: theme.spacing(3), transition: theme.transitions.create(['margin-left', 'margin-top']), [theme.breakpoints.up('md')]: { gap: theme.spacing(8), paddingLeft: theme.spacing(0) }, })); // ---------------------------------------------------------------------- type ItemProps = BoxProps & { item: (typeof ITEMS)[number]; }; function Item({ item, sx, ...other }: ItemProps) { return ( {item.title} {item.subtitle} {item.imgUrl.map((url) => ( ({ borderRadius: 2, overflow: 'hidden', boxShadow: `-40px 40px 80px 0px ${varAlpha(theme.vars.palette.grey['500Channel'], 0.16)}`, ...theme.applyStyles('dark', { boxShadow: `-40px 40px 80px 0px ${varAlpha(theme.vars.palette.common.blackChannel, 0.16)}`, }), }), ]} > ))} ); }