react-datocms 5.0.3 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -13
- package/dist/cjs/Image/index.js +38 -138
- package/dist/cjs/Image/index.js.map +1 -1
- package/dist/cjs/Image/utils.js +52 -0
- package/dist/cjs/Image/utils.js.map +1 -0
- package/dist/cjs/SRCImage/index.js +43 -0
- package/dist/cjs/SRCImage/index.js.map +1 -0
- package/dist/cjs/SRCImage/utils.js +82 -0
- package/dist/cjs/SRCImage/utils.js.map +1 -0
- package/dist/cjs/VideoPlayer/index.js +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/useSiteSearch/index.js.map +1 -1
- package/dist/cjs/useVideoPlayer/index.js.map +1 -1
- package/dist/esm/Image/index.js +30 -110
- package/dist/esm/Image/index.js.map +1 -1
- package/dist/esm/Image/utils.js +46 -0
- package/dist/esm/Image/utils.js.map +1 -0
- package/dist/esm/SRCImage/index.js +36 -0
- package/dist/esm/SRCImage/index.js.map +1 -0
- package/dist/esm/SRCImage/utils.js +52 -0
- package/dist/esm/SRCImage/utils.js.map +1 -0
- package/dist/esm/VideoPlayer/index.js +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/useSiteSearch/index.js.map +1 -1
- package/dist/esm/useVideoPlayer/index.js.map +1 -1
- package/dist/types/Image/index.d.ts +3 -4
- package/dist/types/Image/utils.d.ts +7 -0
- package/dist/types/SRCImage/index.d.ts +33 -0
- package/dist/types/SRCImage/utils.d.ts +6 -0
- package/dist/types/index.d.ts +2 -1
- package/package.json +3 -4
- package/src/Image/__tests__/__snapshots__/index.test.tsx.snap +387 -60
- package/src/Image/__tests__/index.test.tsx +55 -8
- package/src/Image/index.tsx +64 -177
- package/src/Image/utils.ts +58 -0
- package/src/SRCImage/__tests__/__snapshots__/index.test.tsx.snap +268 -0
- package/src/SRCImage/__tests__/index.test.tsx +91 -0
- package/src/SRCImage/index.tsx +98 -0
- package/src/SRCImage/utils.tsx +95 -0
- package/src/VideoPlayer/index.tsx +1 -1
- package/src/index.ts +2 -1
- package/src/useSiteSearch/index.tsx +27 -27
- package/src/useVideoPlayer/index.ts +1 -4
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Image explicit sizes renders correctly 1`] = `
|
|
4
|
+
<SRCImage
|
|
5
|
+
data={
|
|
6
|
+
{
|
|
7
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
8
|
+
"height": 421,
|
|
9
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
10
|
+
"width": 750,
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
sizes="(max-width: 600px) 200px, 50vw"
|
|
14
|
+
>
|
|
15
|
+
<picture>
|
|
16
|
+
<source
|
|
17
|
+
sizes="(max-width: 600px) 200px, 50vw"
|
|
18
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750 750w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
19
|
+
/>
|
|
20
|
+
<img
|
|
21
|
+
loading="lazy"
|
|
22
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
23
|
+
style={
|
|
24
|
+
{
|
|
25
|
+
"aspectRatio": "750 / 421",
|
|
26
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
27
|
+
"backgroundPosition": "50% 50%",
|
|
28
|
+
"backgroundRepeat": "no-repeat",
|
|
29
|
+
"backgroundSize": "cover",
|
|
30
|
+
"color": "transparent",
|
|
31
|
+
"height": "auto",
|
|
32
|
+
"maxWidth": "750px",
|
|
33
|
+
"width": "100%",
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/>
|
|
37
|
+
</picture>
|
|
38
|
+
</SRCImage>
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
exports[`Image full data renders correctly 1`] = `
|
|
42
|
+
<SRCImage
|
|
43
|
+
data={
|
|
44
|
+
{
|
|
45
|
+
"alt": "DatoCMS swag",
|
|
46
|
+
"aspectRatio": 1.7777777777777777,
|
|
47
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
48
|
+
"height": 421,
|
|
49
|
+
"sizes": "(max-width: 750px) 100vw, 750px",
|
|
50
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
51
|
+
"srcSet": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.25&fit=crop&w=750 187w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.5&fit=crop&w=750 375w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.75&fit=crop&w=750 562w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1&fit=crop&w=750 750w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1.5&fit=crop&w=750 1125w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=2&fit=crop&w=750 1500w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=3&fit=crop&w=750 2250w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=4&fit=crop&w=750 3000w",
|
|
52
|
+
"title": "These are awesome, we know that.",
|
|
53
|
+
"width": 750,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
>
|
|
57
|
+
<picture>
|
|
58
|
+
<source
|
|
59
|
+
sizes="(max-width: 750px) 100vw, 750px"
|
|
60
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.25&fit=crop&w=750 187w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.5&fit=crop&w=750 375w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.75&fit=crop&w=750 562w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1&fit=crop&w=750 750w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1.5&fit=crop&w=750 1125w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=2&fit=crop&w=750 1500w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=3&fit=crop&w=750 2250w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=4&fit=crop&w=750 3000w"
|
|
61
|
+
/>
|
|
62
|
+
<img
|
|
63
|
+
alt="DatoCMS swag"
|
|
64
|
+
loading="lazy"
|
|
65
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
66
|
+
style={
|
|
67
|
+
{
|
|
68
|
+
"aspectRatio": "750 / 421",
|
|
69
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
70
|
+
"backgroundPosition": "50% 50%",
|
|
71
|
+
"backgroundRepeat": "no-repeat",
|
|
72
|
+
"backgroundSize": "cover",
|
|
73
|
+
"color": "transparent",
|
|
74
|
+
"height": "auto",
|
|
75
|
+
"maxWidth": "750px",
|
|
76
|
+
"width": "100%",
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
title="These are awesome, we know that."
|
|
80
|
+
/>
|
|
81
|
+
</picture>
|
|
82
|
+
</SRCImage>
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
exports[`Image minimal data renders correctly 1`] = `
|
|
86
|
+
<SRCImage
|
|
87
|
+
data={
|
|
88
|
+
{
|
|
89
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
90
|
+
"height": 421,
|
|
91
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
92
|
+
"width": 750,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
>
|
|
96
|
+
<picture>
|
|
97
|
+
<source
|
|
98
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750 750w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
99
|
+
/>
|
|
100
|
+
<img
|
|
101
|
+
loading="lazy"
|
|
102
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
103
|
+
style={
|
|
104
|
+
{
|
|
105
|
+
"aspectRatio": "750 / 421",
|
|
106
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
107
|
+
"backgroundPosition": "50% 50%",
|
|
108
|
+
"backgroundRepeat": "no-repeat",
|
|
109
|
+
"backgroundSize": "cover",
|
|
110
|
+
"color": "transparent",
|
|
111
|
+
"height": "auto",
|
|
112
|
+
"maxWidth": "750px",
|
|
113
|
+
"width": "100%",
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/>
|
|
117
|
+
</picture>
|
|
118
|
+
</SRCImage>
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
exports[`Image minimalDataWithRelativeUrl renders correctly 1`] = `
|
|
122
|
+
<SRCImage
|
|
123
|
+
data={
|
|
124
|
+
{
|
|
125
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
126
|
+
"height": 421,
|
|
127
|
+
"src": "/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
128
|
+
"width": 750,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
>
|
|
132
|
+
<picture>
|
|
133
|
+
<source
|
|
134
|
+
srcSet="/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,/205/image.png?ar=16%3A9&fit=crop&w=750 750w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
135
|
+
/>
|
|
136
|
+
<img
|
|
137
|
+
loading="lazy"
|
|
138
|
+
src="/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
139
|
+
style={
|
|
140
|
+
{
|
|
141
|
+
"aspectRatio": "750 / 421",
|
|
142
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
143
|
+
"backgroundPosition": "50% 50%",
|
|
144
|
+
"backgroundRepeat": "no-repeat",
|
|
145
|
+
"backgroundSize": "cover",
|
|
146
|
+
"color": "transparent",
|
|
147
|
+
"height": "auto",
|
|
148
|
+
"maxWidth": "750px",
|
|
149
|
+
"width": "100%",
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/>
|
|
153
|
+
</picture>
|
|
154
|
+
</SRCImage>
|
|
155
|
+
`;
|
|
156
|
+
|
|
157
|
+
exports[`Image passing className and/or style renders correctly 1`] = `
|
|
158
|
+
<SRCImage
|
|
159
|
+
className="class-name"
|
|
160
|
+
data={
|
|
161
|
+
{
|
|
162
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
163
|
+
"height": 421,
|
|
164
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
165
|
+
"width": 750,
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
style={
|
|
169
|
+
{
|
|
170
|
+
"border": "1px solid red",
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
>
|
|
174
|
+
<picture>
|
|
175
|
+
<source
|
|
176
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750 750w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
177
|
+
/>
|
|
178
|
+
<img
|
|
179
|
+
className="class-name"
|
|
180
|
+
loading="lazy"
|
|
181
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
182
|
+
style={
|
|
183
|
+
{
|
|
184
|
+
"aspectRatio": "750 / 421",
|
|
185
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
186
|
+
"backgroundPosition": "50% 50%",
|
|
187
|
+
"backgroundRepeat": "no-repeat",
|
|
188
|
+
"backgroundSize": "cover",
|
|
189
|
+
"border": "1px solid red",
|
|
190
|
+
"color": "transparent",
|
|
191
|
+
"height": "auto",
|
|
192
|
+
"maxWidth": "750px",
|
|
193
|
+
"width": "100%",
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/>
|
|
197
|
+
</picture>
|
|
198
|
+
</SRCImage>
|
|
199
|
+
`;
|
|
200
|
+
|
|
201
|
+
exports[`Image priority=true renders correctly 1`] = `
|
|
202
|
+
<SRCImage
|
|
203
|
+
data={
|
|
204
|
+
{
|
|
205
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
206
|
+
"height": 421,
|
|
207
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
208
|
+
"width": 750,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
priority={true}
|
|
212
|
+
>
|
|
213
|
+
<picture>
|
|
214
|
+
<source
|
|
215
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750 750w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
216
|
+
/>
|
|
217
|
+
<img
|
|
218
|
+
fetchpriority="high"
|
|
219
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
220
|
+
style={
|
|
221
|
+
{
|
|
222
|
+
"aspectRatio": "750 / 421",
|
|
223
|
+
"backgroundImage": "url(data:image/jpeg;base64,<IMAGE-DATA>)",
|
|
224
|
+
"backgroundPosition": "50% 50%",
|
|
225
|
+
"backgroundRepeat": "no-repeat",
|
|
226
|
+
"backgroundSize": "cover",
|
|
227
|
+
"color": "transparent",
|
|
228
|
+
"height": "auto",
|
|
229
|
+
"maxWidth": "750px",
|
|
230
|
+
"width": "100%",
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/>
|
|
234
|
+
</picture>
|
|
235
|
+
</SRCImage>
|
|
236
|
+
`;
|
|
237
|
+
|
|
238
|
+
exports[`Image usePlaceholder=false renders correctly 1`] = `
|
|
239
|
+
<SRCImage
|
|
240
|
+
data={
|
|
241
|
+
{
|
|
242
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
243
|
+
"height": 421,
|
|
244
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
245
|
+
"width": 750,
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
usePlaceholder={false}
|
|
249
|
+
>
|
|
250
|
+
<picture>
|
|
251
|
+
<source
|
|
252
|
+
srcSet="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.25 187w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.5 375w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=0.75 562w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750 750w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=1.5 1125w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=2 1500w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=3 2250w,https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750&dpr=4 3000w"
|
|
253
|
+
/>
|
|
254
|
+
<img
|
|
255
|
+
loading="lazy"
|
|
256
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
257
|
+
style={
|
|
258
|
+
{
|
|
259
|
+
"aspectRatio": "750 / 421",
|
|
260
|
+
"height": "auto",
|
|
261
|
+
"maxWidth": "750px",
|
|
262
|
+
"width": "100%",
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/>
|
|
266
|
+
</picture>
|
|
267
|
+
</SRCImage>
|
|
268
|
+
`;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { mount } from 'enzyme';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { SRCImage } from '../index.js';
|
|
4
|
+
|
|
5
|
+
const data = {
|
|
6
|
+
alt: 'DatoCMS swag',
|
|
7
|
+
aspectRatio: 1.7777777777777777,
|
|
8
|
+
base64: 'data:image/jpeg;base64,<IMAGE-DATA>',
|
|
9
|
+
height: 421,
|
|
10
|
+
sizes: '(max-width: 750px) 100vw, 750px',
|
|
11
|
+
src: 'https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750',
|
|
12
|
+
srcSet:
|
|
13
|
+
'https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.25&fit=crop&w=750 187w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.5&fit=crop&w=750 375w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=0.75&fit=crop&w=750 562w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1&fit=crop&w=750 750w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=1.5&fit=crop&w=750 1125w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=2&fit=crop&w=750 1500w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=3&fit=crop&w=750 2250w,↵https://www.datocms-assets.com/205/image.png?ar=16%3A9&dpr=4&fit=crop&w=750 3000w',
|
|
14
|
+
title: 'These are awesome, we know that.',
|
|
15
|
+
width: 750,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const minimalData = {
|
|
19
|
+
base64: 'data:image/jpeg;base64,<IMAGE-DATA>',
|
|
20
|
+
height: 421,
|
|
21
|
+
src: 'https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750',
|
|
22
|
+
width: 750,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const minimalDataWithRelativeUrl = {
|
|
26
|
+
base64: 'data:image/jpeg;base64,<IMAGE-DATA>',
|
|
27
|
+
height: 421,
|
|
28
|
+
src: '/205/image.png?ar=16%3A9&fit=crop&w=750',
|
|
29
|
+
width: 750,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
describe('Image', () => {
|
|
33
|
+
describe('full data', () => {
|
|
34
|
+
it('renders correctly', () => {
|
|
35
|
+
const wrapper = mount(<SRCImage data={data} />);
|
|
36
|
+
expect(wrapper).toMatchSnapshot();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('minimal data', () => {
|
|
41
|
+
it('renders correctly', () => {
|
|
42
|
+
const wrapper = mount(<SRCImage data={minimalData} />);
|
|
43
|
+
expect(wrapper).toMatchSnapshot();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('minimalDataWithRelativeUrl', () => {
|
|
48
|
+
it('renders correctly', () => {
|
|
49
|
+
const wrapper = mount(<SRCImage data={minimalDataWithRelativeUrl} />);
|
|
50
|
+
expect(wrapper).toMatchSnapshot();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('passing className and/or style', () => {
|
|
55
|
+
it('renders correctly', () => {
|
|
56
|
+
const wrapper = mount(
|
|
57
|
+
<SRCImage
|
|
58
|
+
data={minimalData}
|
|
59
|
+
className="class-name"
|
|
60
|
+
style={{ border: '1px solid red' }}
|
|
61
|
+
/>,
|
|
62
|
+
);
|
|
63
|
+
expect(wrapper).toMatchSnapshot();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('priority=true', () => {
|
|
68
|
+
it('renders correctly', () => {
|
|
69
|
+
const wrapper = mount(<SRCImage data={minimalData} priority={true} />);
|
|
70
|
+
expect(wrapper).toMatchSnapshot();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('usePlaceholder=false', () => {
|
|
75
|
+
it('renders correctly', () => {
|
|
76
|
+
const wrapper = mount(
|
|
77
|
+
<SRCImage data={minimalData} usePlaceholder={false} />,
|
|
78
|
+
);
|
|
79
|
+
expect(wrapper).toMatchSnapshot();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('explicit sizes', () => {
|
|
84
|
+
it('renders correctly', () => {
|
|
85
|
+
const wrapper = mount(
|
|
86
|
+
<SRCImage data={minimalData} sizes="(max-width: 600px) 200px, 50vw" />,
|
|
87
|
+
);
|
|
88
|
+
expect(wrapper).toMatchSnapshot();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ResponsiveImageType } from '../Image';
|
|
3
|
+
import { buildRegularSource, buildWebpSource, priorityProp } from './utils.js';
|
|
4
|
+
|
|
5
|
+
export type SRCImagePropTypes = {
|
|
6
|
+
/** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */
|
|
7
|
+
data: ResponsiveImageType;
|
|
8
|
+
/** Additional CSS className for root node */
|
|
9
|
+
className?: string;
|
|
10
|
+
/** Additional CSS rules to add to the root node */
|
|
11
|
+
style?: React.CSSProperties;
|
|
12
|
+
/**
|
|
13
|
+
* When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
|
|
14
|
+
* You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
|
|
15
|
+
* Should only be used when the image is visible above the fold.
|
|
16
|
+
**/
|
|
17
|
+
priority?: boolean;
|
|
18
|
+
/** Whether the component should use a blurred image placeholder */
|
|
19
|
+
usePlaceholder?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The HTML5 `sizes` attribute for the image
|
|
22
|
+
*
|
|
23
|
+
* Learn more about srcset and sizes:
|
|
24
|
+
* -> https://web.dev/learn/design/responsive-images/#sizes
|
|
25
|
+
* -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
|
|
26
|
+
**/
|
|
27
|
+
sizes?: HTMLImageElement['sizes'];
|
|
28
|
+
/**
|
|
29
|
+
* If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
|
|
30
|
+
*
|
|
31
|
+
* Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
32
|
+
**/
|
|
33
|
+
srcSetCandidates?: number[];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function SRCImage({
|
|
37
|
+
className,
|
|
38
|
+
style,
|
|
39
|
+
data,
|
|
40
|
+
usePlaceholder = true,
|
|
41
|
+
priority = false,
|
|
42
|
+
sizes,
|
|
43
|
+
srcSetCandidates = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4],
|
|
44
|
+
}: SRCImagePropTypes) {
|
|
45
|
+
const webpSource = buildWebpSource(data, sizes);
|
|
46
|
+
const regularSource = buildRegularSource(data, sizes, srcSetCandidates);
|
|
47
|
+
|
|
48
|
+
const placeholderStyle: React.CSSProperties | undefined =
|
|
49
|
+
usePlaceholder && data.base64
|
|
50
|
+
? {
|
|
51
|
+
backgroundImage: `url(${data.base64})`,
|
|
52
|
+
backgroundSize: 'cover',
|
|
53
|
+
backgroundRepeat: 'no-repeat',
|
|
54
|
+
backgroundPosition: '50% 50%',
|
|
55
|
+
color: 'transparent',
|
|
56
|
+
}
|
|
57
|
+
: usePlaceholder && data.bgColor
|
|
58
|
+
? { backgroundColor: data.bgColor ?? undefined, color: 'transparent' }
|
|
59
|
+
: undefined;
|
|
60
|
+
|
|
61
|
+
const { width } = data;
|
|
62
|
+
|
|
63
|
+
const height =
|
|
64
|
+
data.height ?? Math.round(data.aspectRatio ? width / data.aspectRatio : 0);
|
|
65
|
+
|
|
66
|
+
const sizingStyle = {
|
|
67
|
+
aspectRatio: `${width} / ${height}`,
|
|
68
|
+
width: '100%',
|
|
69
|
+
maxWidth: `${width}px`,
|
|
70
|
+
height: 'auto',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const loadingBehaviourProps = priority
|
|
74
|
+
? priorityProp(priority ? 'high' : undefined)
|
|
75
|
+
: { loading: 'lazy' };
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<picture>
|
|
79
|
+
{webpSource}
|
|
80
|
+
{regularSource}
|
|
81
|
+
{data.src && (
|
|
82
|
+
// biome-ignore lint/a11y/useAltText: We do with alt the best we can
|
|
83
|
+
<img
|
|
84
|
+
src={data.src}
|
|
85
|
+
alt={data.alt ?? undefined}
|
|
86
|
+
title={data.title ?? undefined}
|
|
87
|
+
{...loadingBehaviourProps}
|
|
88
|
+
className={className}
|
|
89
|
+
style={{
|
|
90
|
+
...placeholderStyle,
|
|
91
|
+
...sizingStyle,
|
|
92
|
+
...style,
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
)}
|
|
96
|
+
</picture>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, { version } from 'react';
|
|
2
|
+
import { ResponsiveImageType } from '../Image';
|
|
3
|
+
|
|
4
|
+
export function priorityProp(
|
|
5
|
+
fetchPriority?: string,
|
|
6
|
+
): Record<string, string | undefined> {
|
|
7
|
+
const [majorStr, minorStr] = version.split('.');
|
|
8
|
+
const major = parseInt(majorStr, 10);
|
|
9
|
+
const minor = parseInt(minorStr, 10);
|
|
10
|
+
if (major > 18 || (major === 18 && minor >= 3)) {
|
|
11
|
+
// In React 18.3.0 or newer, we must use camelCase
|
|
12
|
+
// prop to avoid "Warning: Invalid DOM property".
|
|
13
|
+
// See https://github.com/facebook/react/pull/25927
|
|
14
|
+
return { fetchPriority };
|
|
15
|
+
}
|
|
16
|
+
// In React 18.2.0 or older, we must use lowercase prop
|
|
17
|
+
// to avoid "Warning: Invalid DOM property".
|
|
18
|
+
return { fetchpriority: fetchPriority };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const bogusBaseUrl = 'https://example.com/';
|
|
22
|
+
|
|
23
|
+
export const buildSrcSetFromSrc = (
|
|
24
|
+
src: string | null | undefined,
|
|
25
|
+
width: number | undefined,
|
|
26
|
+
candidateMultipliers: number[],
|
|
27
|
+
) => {
|
|
28
|
+
if (!(src && width)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return candidateMultipliers
|
|
33
|
+
.map((multiplier) => {
|
|
34
|
+
const url = new URL(src, bogusBaseUrl);
|
|
35
|
+
|
|
36
|
+
if (multiplier !== 1) {
|
|
37
|
+
url.searchParams.set('dpr', `${multiplier}`);
|
|
38
|
+
const maxH = url.searchParams.get('max-h');
|
|
39
|
+
const maxW = url.searchParams.get('max-w');
|
|
40
|
+
if (maxH) {
|
|
41
|
+
url.searchParams.set(
|
|
42
|
+
'max-h',
|
|
43
|
+
`${Math.floor(parseInt(maxH) * multiplier)}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (maxW) {
|
|
47
|
+
url.searchParams.set(
|
|
48
|
+
'max-w',
|
|
49
|
+
`${Math.floor(parseInt(maxW) * multiplier)}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const finalWidth = Math.floor(width * multiplier);
|
|
55
|
+
|
|
56
|
+
if (finalWidth < 50) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return `${url.toString().replace(bogusBaseUrl, '/')} ${finalWidth}w`;
|
|
61
|
+
})
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
.join(',');
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export function buildWebpSource(
|
|
67
|
+
data: ResponsiveImageType,
|
|
68
|
+
sizes: HTMLImageElement['sizes'] | undefined,
|
|
69
|
+
) {
|
|
70
|
+
return (
|
|
71
|
+
data.webpSrcSet && (
|
|
72
|
+
<source
|
|
73
|
+
srcSet={data.webpSrcSet}
|
|
74
|
+
sizes={sizes ?? data.sizes ?? undefined}
|
|
75
|
+
type="image/webp"
|
|
76
|
+
/>
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function buildRegularSource(
|
|
82
|
+
data: ResponsiveImageType,
|
|
83
|
+
sizes: HTMLImageElement['sizes'] | undefined,
|
|
84
|
+
srcSetCandidates: number[],
|
|
85
|
+
) {
|
|
86
|
+
return (
|
|
87
|
+
<source
|
|
88
|
+
srcSet={
|
|
89
|
+
data.srcSet ??
|
|
90
|
+
buildSrcSetFromSrc(data.src, data.width, srcSetCandidates)
|
|
91
|
+
}
|
|
92
|
+
sizes={sizes ?? data.sizes ?? undefined}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export * from './Image/index.js';
|
|
2
|
+
export * from './SRCImage/index.js';
|
|
2
3
|
export * from './Seo/index.js';
|
|
3
|
-
export * from './VideoPlayer/index.js';
|
|
4
4
|
export * from './StructuredText/index.js';
|
|
5
|
+
export * from './VideoPlayer/index.js';
|
|
5
6
|
|
|
6
7
|
export * from './useQuerySubscription/index.js';
|
|
7
8
|
export * from './useSiteSearch/index.js';
|
|
@@ -243,32 +243,32 @@ export function useSiteSearch<Client extends GenericClient>(
|
|
|
243
243
|
totalPages: 0,
|
|
244
244
|
}
|
|
245
245
|
: response
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
246
|
+
? {
|
|
247
|
+
pageResults: response.data.map((rawSearchResult) => ({
|
|
248
|
+
id: rawSearchResult.id,
|
|
249
|
+
url: rawSearchResult.attributes.url,
|
|
250
|
+
title: rawSearchResult.attributes.highlight.title ? (
|
|
251
|
+
<MatchHighlighter highlighter={highlighter} context="title">
|
|
252
|
+
{rawSearchResult.attributes.highlight.title[0]}
|
|
253
|
+
</MatchHighlighter>
|
|
254
|
+
) : (
|
|
255
|
+
rawSearchResult.attributes.title
|
|
256
|
+
),
|
|
257
|
+
bodyExcerpt: rawSearchResult.attributes.highlight.body ? (
|
|
258
|
+
<MatchHighlighter
|
|
259
|
+
highlighter={highlighter}
|
|
260
|
+
context="bodyExcerpt"
|
|
261
|
+
>
|
|
262
|
+
{rawSearchResult.attributes.highlight.body[0]}
|
|
263
|
+
</MatchHighlighter>
|
|
264
|
+
) : (
|
|
265
|
+
rawSearchResult.attributes.body_excerpt
|
|
266
|
+
),
|
|
267
|
+
raw: rawSearchResult,
|
|
268
|
+
})),
|
|
269
|
+
totalResults: response.meta.total_count,
|
|
270
|
+
totalPages: Math.ceil(response.meta.total_count / resultsPerPage),
|
|
271
|
+
}
|
|
272
|
+
: undefined,
|
|
273
273
|
};
|
|
274
274
|
}
|
|
@@ -18,10 +18,7 @@ const computedPlaybackId = (
|
|
|
18
18
|
return { playbackId: `${muxPlaybackId || playbackId}` };
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const computedStyle = (
|
|
22
|
-
width: Possibly<number>,
|
|
23
|
-
height: Possibly<number>,
|
|
24
|
-
) => {
|
|
21
|
+
const computedStyle = (width: Possibly<number>, height: Possibly<number>) => {
|
|
25
22
|
if (!(width && height)) return undefined;
|
|
26
23
|
|
|
27
24
|
return {
|