UNPKG

@patreon/studio

Version:

Patreon Studio Design System

54 lines (52 loc) 1.89 kB
'use client'; import React from 'react'; import styled, { css } from 'styled-components'; import { useSources } from './hooks/useSources'; export function Image({ src: inputSrc, alt, sizing = 'cover', height: inputHeight, ratio = 1, loading = 'eager', id, 'data-tag': dataTag, onError, placeholder, blurDataUrl, ...props }) { const { src, sources } = useSources(inputSrc); const height = typeof inputHeight === 'number' ? `${inputHeight}px` : inputHeight; const [loaded, setLoaded] = React.useState(false); return (<Container height={height} ratio={ratio} id={id} data-tag={dataTag}> {!loaded && (!!placeholder || !!blurDataUrl) && (<AbsolutePlaceholder> {blurDataUrl ? (<img src={blurDataUrl} alt={alt} style={{ width: '100%', height: '100%', objectFit: sizing, }}/>) : (placeholder)} </AbsolutePlaceholder>)} <picture> {sources.map(({ media, srcSet }) => (<source key={srcSet} media={media} srcSet={srcSet}/>))} <StyledImage src={src} alt={alt} loading={loading} sizing={sizing} onError={onError} onLoad={() => { if (placeholder || blurDataUrl) { setLoaded(true); } }} {...props}/> </picture> </Container>); } const Container = styled.div.withConfig({ shouldForwardProp: (prop) => !['height', 'ratio'].includes(prop), }) ` position: relative; width: 100%; overflow: hidden; ${({ height, ratio }) => height ? css ` height: ${height}; ` : css ` aspect-ratio: ${ratio}; `} `; const AbsolutePlaceholder = styled.div ` position: absolute; inset: 0; `; const StyledImage = styled.img ` display: block; height: 100%; width: 100%; object-fit: ${({ sizing }) => sizing}; object-position: center; `; //# sourceMappingURL=index.jsx.map