| 1 | export type ImageProps = { |
| 2 | src: string |
| 3 | alt: string |
| 4 | [attr: string]: string |
| 5 | } |
| 6 | |
| 7 | export const Image = ({ src, alt, ...rest }: ImageProps) => { |
| 8 | const isVideo = src.endsWith('.mp4') |
| 9 | |
| 10 | if (isVideo) { |
| 11 | let autoplay: boolean | undefined |
| 12 | let controls: boolean | undefined |
| 13 | let poster: string | undefined |
| 14 | |
| 15 | const normalizedAlt = (alt || '') |
| 16 | .replace( |
| 17 | /\b(?:autoplay|controls|poster=([^\s]+))\s*\b/g, |
| 18 | (matched, value) => { |
| 19 | if (matched.startsWith('autoplay')) autoplay = true |
| 20 | if (matched.startsWith('controls')) controls = true |
| 21 | if (matched.startsWith('poster')) poster = value |
| 22 | |
| 23 | return '' |
| 24 | } |
| 25 | ) |
| 26 | .trim() |
| 27 | |
| 28 | return ( |
| 29 | <video |
| 30 | className="markdown-video" |
| 31 | src={src} |
| 32 | playsInline |
| 33 | controls={controls} |
| 34 | loop |
| 35 | preload="metadata" |
| 36 | poster={poster} |
| 37 | autoPlay={autoplay} |
| 38 | muted={autoplay} |
| 39 | {...rest} |
| 40 | > |
| 41 | <a href={src} target="_blank" rel="noopener noreferrer"> |
| 42 | {normalizedAlt} |
| 43 | </a> |
| 44 | <style jsx>{` |
| 45 | .markdown-video { |
| 46 | @apply mx-auto block w-full max-w-xl shadow-md; |
| 47 | @apply my-6 !important; |
| 48 | } |
| 49 | `}</style> |
| 50 | </video> |
| 51 | ) |
| 52 | } |
| 53 | |
| 54 | return <img src={src} alt={alt} {...rest} /> |
| 55 | } |
| 56 |