@@ -2,24 +2,33 @@ import React, { useState, useEffect } from 'react';
22import { MemoizedRichText } from '../MemoizedComponents' ;
33import {
44 imageContainer ,
5+ imageWrapper ,
56 styledImage ,
67 placeholder ,
78 caption ,
89} from './styles.css' ;
910import { RichTextItem } from '../RichText/RichTexts' ;
1011
12+ export interface ImageFormat {
13+ block_width ?: number ;
14+ block_height ?: number ;
15+ block_aspect_ratio ?: number ;
16+ }
17+
1118export interface ImageProps {
1219 src : string ;
1320 alt : string ;
1421 caption ?: RichTextItem [ ] ;
1522 priority ?: boolean ;
23+ format ?: ImageFormat ;
1624}
1725
1826const Image : React . FC < ImageProps > = ( {
1927 src,
2028 alt,
2129 caption : imageCaption ,
2230 priority = false ,
31+ format,
2332} ) => {
2433 const [ isLoaded , setIsLoaded ] = useState ( false ) ;
2534 const [ error , setError ] = useState ( false ) ;
@@ -31,16 +40,124 @@ const Image: React.FC<ImageProps> = ({
3140
3241 return (
3342 < figure className = { imageContainer } >
34- < div >
35- { ! isLoaded && ! error && < div className = { placeholder } > Loading...</ div > }
36- { error && < div className = { placeholder } > Failed to load image</ div > }
43+ < div
44+ className = { imageWrapper ( {
45+ hasWidth : ! ! format ?. block_width ,
46+ } ) }
47+ style = {
48+ format ?. block_width
49+ ? {
50+ width :
51+ format . block_width > 900 ? '100%' : `${ format . block_width } px` ,
52+ }
53+ : undefined
54+ }
55+ >
56+ { ! isLoaded && ! error && (
57+ < div
58+ className = { placeholder }
59+ style = { {
60+ width : format ?. block_width
61+ ? format . block_width > 900
62+ ? '100%'
63+ : `${ format . block_width } px`
64+ : '100%' ,
65+ aspectRatio : format ?. block_aspect_ratio
66+ ? `${ format . block_aspect_ratio } `
67+ : 'auto' ,
68+ } }
69+ >
70+ < svg
71+ width = "38"
72+ height = "38"
73+ viewBox = "0 0 38 38"
74+ xmlns = "http://www.w3.org/2000/svg"
75+ stroke = "#888"
76+ >
77+ < g fill = "none" fillRule = "evenodd" >
78+ < g transform = "translate(1 1)" strokeWidth = "2" >
79+ < circle strokeOpacity = ".5" cx = "18" cy = "18" r = "18" />
80+ < path d = "M36 18c0-9.94-8.06-18-18-18" >
81+ < animateTransform
82+ attributeName = "transform"
83+ type = "rotate"
84+ from = "0 18 18"
85+ to = "360 18 18"
86+ dur = "1s"
87+ repeatCount = "indefinite"
88+ />
89+ </ path >
90+ </ g >
91+ </ g >
92+ </ svg >
93+ </ div >
94+ ) }
95+ { error && (
96+ < div
97+ className = { placeholder }
98+ style = { {
99+ width : format ?. block_width
100+ ? format . block_width > 900
101+ ? '100%'
102+ : `${ format . block_width } px`
103+ : '100%' ,
104+ aspectRatio : format ?. block_aspect_ratio
105+ ? `${ format . block_aspect_ratio } `
106+ : 'auto' ,
107+ } }
108+ >
109+ < svg
110+ width = "48"
111+ height = "48"
112+ viewBox = "0 0 24 24"
113+ fill = "none"
114+ xmlns = "http://www.w3.org/2000/svg"
115+ >
116+ < path
117+ d = "M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
118+ stroke = "#FF6B6B"
119+ strokeWidth = "2"
120+ strokeLinecap = "round"
121+ strokeLinejoin = "round"
122+ />
123+ < path
124+ d = "M15 9L9 15"
125+ stroke = "#FF6B6B"
126+ strokeWidth = "2"
127+ strokeLinecap = "round"
128+ strokeLinejoin = "round"
129+ />
130+ < path
131+ d = "M9 9L15 15"
132+ stroke = "#FF6B6B"
133+ strokeWidth = "2"
134+ strokeLinecap = "round"
135+ strokeLinejoin = "round"
136+ />
137+ </ svg >
138+ < div style = { { width : '10px' } } />
139+ < p style = { { color : '#FF6B6B' , fontSize : '14px' } } >
140+ Image Load failed
141+ </ p >
142+ </ div >
143+ ) }
37144 < img
38- className = { styledImage ( { loaded : isLoaded } ) }
145+ className = { styledImage ( {
146+ loaded : isLoaded ,
147+ hasAspectRatio : ! ! format ?. block_aspect_ratio ,
148+ } ) }
39149 src = { src }
40150 alt = { alt }
41151 loading = { priority ? 'eager' : 'lazy' }
42152 onLoad = { ( ) => setIsLoaded ( true ) }
43153 onError = { ( ) => setError ( true ) }
154+ width = { format ?. block_width }
155+ height = { format ?. block_height }
156+ style = {
157+ format ?. block_aspect_ratio
158+ ? { aspectRatio : `${ format . block_aspect_ratio } ` }
159+ : undefined
160+ }
44161 />
45162 </ div >
46163 { imageCaption && imageCaption . length > 0 && (
0 commit comments