You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.0 KiB
74 lines
2.0 KiB
import { Image, Box, BoxProps, SystemStyleObject } from '@chakra-ui/react'
|
|
|
|
type ResponsiveImageProps = {
|
|
url: string | null
|
|
avatar?: boolean
|
|
alt: string
|
|
imageStyle?: SystemStyleObject
|
|
filter?: string
|
|
}
|
|
|
|
// const defaultSizes = 'sizes[]=300,sizes[]=600,sizes[]=900,sizes[]=1200,sizes[]=1800'
|
|
|
|
const ResponsiveImage: React.FC<ResponsiveImageProps & BoxProps> = ({
|
|
url,
|
|
avatar,
|
|
alt,
|
|
children,
|
|
imageStyle,
|
|
w,
|
|
h,
|
|
...rest
|
|
}) => {
|
|
if (url === null) return null
|
|
|
|
let placeholder
|
|
let responsiveImage
|
|
let responsiveImageWebp
|
|
|
|
// The sizes are hardcoded because of a bug with webpack that impedes parametrization string interpolation
|
|
// after the question mark
|
|
// see https://github.com/cyrilwanner/next-optimized-images/issues/16
|
|
if (avatar) {
|
|
placeholder = require(`../assets/${url}?lqip`)
|
|
responsiveImage = require(`../assets/${url}?resize&sizes[]=96,sizes[]=128,sizes[]=256&format=jpg`)
|
|
responsiveImageWebp = require(`../assets/${url}?resize&sizes[]=96,sizes[]=128,sizes[]=256&format=webp`)
|
|
} else {
|
|
placeholder = require(`../assets/${url}?lqip`)
|
|
responsiveImage = require(`../assets/${url}?resize&sizes[]=300,sizes[]=600,sizes[]=900,sizes[]=1200,sizes[]=1800&format=jpg`)
|
|
responsiveImageWebp = require(`../assets/${url}?resize&sizes[]=300,sizes[]=600,sizes[]=900,sizes[]=1200,sizes[]=1800&format=webp`)
|
|
}
|
|
|
|
return (
|
|
<Box
|
|
width={w ?? responsiveImage.width}
|
|
height={h ?? responsiveImage.height}
|
|
background={`url(${placeholder})`}
|
|
backgroundSize="cover"
|
|
position="relative"
|
|
overflow="hidden"
|
|
objectFit="cover"
|
|
sx={{
|
|
'& picture img': imageStyle,
|
|
}}
|
|
{...rest}
|
|
>
|
|
{children}
|
|
<picture>
|
|
<source srcSet={responsiveImageWebp.srcSet} type="image/webp" />
|
|
<Image
|
|
objectFit="cover"
|
|
w="100%"
|
|
h="100%"
|
|
alt={alt}
|
|
src={responsiveImage.src}
|
|
srcSet={responsiveImage.srcSet}
|
|
loading="lazy"
|
|
/>
|
|
</picture>
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
export default ResponsiveImage
|