✨ feat(molecules): add ProjectSpotlight

This commit is contained in:
2024-02-14 17:51:30 +01:00
parent d2ce4f05ba
commit 660dc5d4ca
3 changed files with 176 additions and 0 deletions
@@ -0,0 +1,174 @@
import React from 'react'
import { ParallaxBanner, ParallaxProvider } from 'react-scroll-parallax'
import { Box, Grid, IconButton, Typography, useTheme } from '@mui/material'
import { ExpandMore } from '@mui/icons-material'
type AnchorType = 'left' | 'top' | 'right' | 'bottom'
type Props = {
image: string
title: string
caption: React.ReactNode
children: React.ReactNode
ref?: React.ForwardedRef<HTMLSelectElement>
anchor?: AnchorType
scrollTarget?: React.ForwardedRef<HTMLSelectElement>
}
const Description = (props: Props) => {
const theme = useTheme()
switch (props.anchor) {
case 'bottom':
return (
<Box
sx={{
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
bgcolor: 'background.default',
opacity: 0.9,
bottom: '0',
borderTopStyle: 'solid',
borderTopWidth: theme.spacing(0.5),
borderTopColor: theme.palette.primary.main,
p: `${theme.spacing(7)} ${theme.spacing(5)} ${theme.spacing(5.5)} ${theme.spacing(5)}`,
}}>
<Grid container spacing={2} maxWidth="xl">
<Grid item xs={12} md={4}>
<Typography variant="h4">{props.title}</Typography>
{props.caption}
</Grid>
<Grid item component={Typography} xs={12} md={8}>
{props.children}
</Grid>
</Grid>
</Box>
)
case 'top':
return (
<Box
sx={{
display: 'flex',
position: 'absolute',
bgcolor: 'background.default',
opacity: 0.9,
top: '0',
ml: 'auto',
borderBottomWidth: theme.spacing(0.5),
// borderTopWidth: '0.35em',
borderBottomStyle: 'solid',
borderBottomColor: theme.palette.primary.main,
p: `${theme.spacing(5)} ${theme.spacing(5)} ${theme.spacing(3)} ${theme.spacing(5)}`,
// p: '5.1em 3.1em 3.1em 3.1em',
}}>
<Grid container spacing={2} maxWidth="xl">
<Grid item xs={12} md={4}>
<Typography variant="h4">{props.title}</Typography>
{props.caption}
</Grid>
<Grid item component={Typography} xs={12} md={8}>
{props.children}
</Grid>
</Grid>
</Box>
)
case 'right':
return (
<Box
sx={{
height: '102%',
width: '28em',
position: 'absolute',
bgcolor: 'background.default',
opacity: 0.9,
right: '0',
borderLeftWidth: theme.spacing(0.5),
// borderLeftWidth: '0.35em',
borderLeftStyle: 'solid',
borderLeftColor: theme.palette.primary.main,
p: `${theme.spacing(3)} ${theme.spacing(5)} ${theme.spacing(5)} ${theme.spacing(5)}`,
// p: '5.1em 3.1em 3.1em 3.1em',
}}>
<Typography variant="h4">{props.title}</Typography>
{props.caption}
<Typography mt={3}>{props.children}</Typography>
</Box>
)
case 'left':
return (
<Box
sx={{
height: '102%',
width: '28em',
position: 'absolute',
bgcolor: 'background.default',
opacity: 0.9,
left: '0',
borderRightWidth: theme.spacing(0.5),
// borderLeftWidth: '0.35em',
borderRightStyle: 'solid',
borderRightColor: theme.palette.primary.main,
p: `${theme.spacing(3)} ${theme.spacing(5)} ${theme.spacing(5)} ${theme.spacing(5)}`,
// p: '5.1em 3.1em 3.1em 3.1em',
}}>
<Typography variant="h4">{props.title}</Typography>
{props.caption}
<Typography mt={3}>{props.children}</Typography>
</Box>
)
}
}
const ProjectSpotlight = React.forwardRef<HTMLSelectElement, Props>((props, ref) => {
const executeScroll = () => {
if (typeof props.scrollTarget !== 'undefined') {
const target = props.scrollTarget as React.MutableRefObject<HTMLSelectElement | null>
target.current?.scrollIntoView()
}
}
// run this function from an event handler or an effect to execute scroll
return (
<section ref={ref}>
<ParallaxProvider>
<ParallaxBanner
layers={[
{
// translateY: [0, 30],
// scale: [1, 0.5, 'easeOutCubic'],
// shouldAlwaysCompleteAnimation: true,
image: props.image,
expanded: false,
speed: -20,
},
]}
style={{
// width: '150%',
// marginLeft: '-25%',
minHeight: '100vh',
position: 'relative',
height: '100vh',
overflow: 'hidden',
}}>
<Description {...props} />
{props.scrollTarget && (
<IconButton
size="large"
onClick={executeScroll}
sx={{ position: 'absolute', p: 1, bottom: 2, left: '50%', transform: 'translate(-50%, 0)' }}>
<ExpandMore fontSize="large" />
</IconButton>
)}
</ParallaxBanner>
</ParallaxProvider>
</section>
)
})
export default ProjectSpotlight
@@ -0,0 +1 @@
export { default } from './ProjectSpotlight'
+1
View File
@@ -2,4 +2,5 @@ export { default as Toobar } from './Toobar'
export { default as Footer } from './Footer'
export { default as CurriculumItem } from './CurriculumItem'
export { default as ProjectSpotlight } from './ProjectSpotlight'
export { default as Project } from './Project'