react-datocms 5.0.3 → 6.0.1
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 +39 -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 +44 -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/Seo/nextUtils.js +15 -15
- package/dist/cjs/Seo/nextUtils.js.map +1 -1
- package/dist/cjs/Seo/renderMetaTags.js +1 -1
- package/dist/cjs/Seo/renderMetaTags.js.map +1 -1
- package/dist/cjs/StructuredText/index.js.map +1 -1
- 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 +9 -31
- package/dist/cjs/useSiteSearch/index.js.map +1 -1
- package/dist/cjs/useVideoPlayer/index.js.map +1 -1
- package/dist/esm/Image/index.js +31 -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 +37 -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/Seo/nextUtils.js +15 -15
- package/dist/esm/Seo/nextUtils.js.map +1 -1
- package/dist/esm/Seo/renderMetaTags.js +1 -1
- package/dist/esm/Seo/renderMetaTags.js.map +1 -1
- package/dist/esm/StructuredText/index.js.map +1 -1
- 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 +2 -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/Seo/remixUtils.d.ts +1 -1
- package/dist/types/Seo/renderMetaTags.d.ts +1 -1
- package/dist/types/Seo/renderMetaTagsToString.d.ts +1 -1
- package/dist/types/StructuredText/index.d.ts +3 -3
- package/dist/types/VideoPlayer/index.d.ts +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/useQuerySubscription/index.d.ts +1 -1
- package/dist/types/useVideoPlayer/index.d.ts +2 -2
- 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 +65 -177
- package/src/Image/utils.ts +58 -0
- package/src/SRCImage/__tests__/__snapshots__/index.test.tsx.snap +274 -0
- package/src/SRCImage/__tests__/index.test.tsx +91 -0
- package/src/SRCImage/index.tsx +99 -0
- package/src/SRCImage/utils.tsx +95 -0
- package/src/Seo/__tests__/index.test.tsx +1 -1
- package/src/Seo/nextUtils.ts +20 -20
- package/src/Seo/remixUtils.ts +1 -1
- package/src/Seo/renderMetaTags.tsx +2 -2
- package/src/Seo/renderMetaTagsToString.tsx +1 -1
- package/src/StructuredText/__tests__/index.test.tsx +2 -2
- package/src/StructuredText/index.tsx +10 -10
- package/src/VideoPlayer/index.tsx +2 -2
- package/src/index.ts +2 -1
- package/src/useQuerySubscription/index.ts +4 -4
- package/src/useSiteSearch/index.tsx +29 -28
- package/src/useVideoPlayer/index.ts +3 -6
|
@@ -0,0 +1,274 @@
|
|
|
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
|
+
alt=""
|
|
22
|
+
loading="lazy"
|
|
23
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
24
|
+
style={
|
|
25
|
+
{
|
|
26
|
+
"aspectRatio": "750 / 421",
|
|
27
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
28
|
+
"backgroundPosition": "50% 50%",
|
|
29
|
+
"backgroundRepeat": "no-repeat",
|
|
30
|
+
"backgroundSize": "cover",
|
|
31
|
+
"color": "transparent",
|
|
32
|
+
"height": "auto",
|
|
33
|
+
"maxWidth": "750px",
|
|
34
|
+
"width": "100%",
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/>
|
|
38
|
+
</picture>
|
|
39
|
+
</SRCImage>
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
exports[`Image full data renders correctly 1`] = `
|
|
43
|
+
<SRCImage
|
|
44
|
+
data={
|
|
45
|
+
{
|
|
46
|
+
"alt": "DatoCMS swag",
|
|
47
|
+
"aspectRatio": 1.7777777777777777,
|
|
48
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
49
|
+
"height": 421,
|
|
50
|
+
"sizes": "(max-width: 750px) 100vw, 750px",
|
|
51
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
52
|
+
"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",
|
|
53
|
+
"title": "These are awesome, we know that.",
|
|
54
|
+
"width": 750,
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
>
|
|
58
|
+
<picture>
|
|
59
|
+
<source
|
|
60
|
+
sizes="(max-width: 750px) 100vw, 750px"
|
|
61
|
+
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"
|
|
62
|
+
/>
|
|
63
|
+
<img
|
|
64
|
+
alt="DatoCMS swag"
|
|
65
|
+
loading="lazy"
|
|
66
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
67
|
+
style={
|
|
68
|
+
{
|
|
69
|
+
"aspectRatio": "750 / 421",
|
|
70
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
71
|
+
"backgroundPosition": "50% 50%",
|
|
72
|
+
"backgroundRepeat": "no-repeat",
|
|
73
|
+
"backgroundSize": "cover",
|
|
74
|
+
"color": "transparent",
|
|
75
|
+
"height": "auto",
|
|
76
|
+
"maxWidth": "750px",
|
|
77
|
+
"width": "100%",
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
title="These are awesome, we know that."
|
|
81
|
+
/>
|
|
82
|
+
</picture>
|
|
83
|
+
</SRCImage>
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
exports[`Image minimal data renders correctly 1`] = `
|
|
87
|
+
<SRCImage
|
|
88
|
+
data={
|
|
89
|
+
{
|
|
90
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
91
|
+
"height": 421,
|
|
92
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
93
|
+
"width": 750,
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
>
|
|
97
|
+
<picture>
|
|
98
|
+
<source
|
|
99
|
+
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"
|
|
100
|
+
/>
|
|
101
|
+
<img
|
|
102
|
+
alt=""
|
|
103
|
+
loading="lazy"
|
|
104
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
105
|
+
style={
|
|
106
|
+
{
|
|
107
|
+
"aspectRatio": "750 / 421",
|
|
108
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
109
|
+
"backgroundPosition": "50% 50%",
|
|
110
|
+
"backgroundRepeat": "no-repeat",
|
|
111
|
+
"backgroundSize": "cover",
|
|
112
|
+
"color": "transparent",
|
|
113
|
+
"height": "auto",
|
|
114
|
+
"maxWidth": "750px",
|
|
115
|
+
"width": "100%",
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/>
|
|
119
|
+
</picture>
|
|
120
|
+
</SRCImage>
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
exports[`Image minimalDataWithRelativeUrl renders correctly 1`] = `
|
|
124
|
+
<SRCImage
|
|
125
|
+
data={
|
|
126
|
+
{
|
|
127
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
128
|
+
"height": 421,
|
|
129
|
+
"src": "/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
130
|
+
"width": 750,
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
>
|
|
134
|
+
<picture>
|
|
135
|
+
<source
|
|
136
|
+
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"
|
|
137
|
+
/>
|
|
138
|
+
<img
|
|
139
|
+
alt=""
|
|
140
|
+
loading="lazy"
|
|
141
|
+
src="/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
142
|
+
style={
|
|
143
|
+
{
|
|
144
|
+
"aspectRatio": "750 / 421",
|
|
145
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
146
|
+
"backgroundPosition": "50% 50%",
|
|
147
|
+
"backgroundRepeat": "no-repeat",
|
|
148
|
+
"backgroundSize": "cover",
|
|
149
|
+
"color": "transparent",
|
|
150
|
+
"height": "auto",
|
|
151
|
+
"maxWidth": "750px",
|
|
152
|
+
"width": "100%",
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/>
|
|
156
|
+
</picture>
|
|
157
|
+
</SRCImage>
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
exports[`Image passing className and/or style renders correctly 1`] = `
|
|
161
|
+
<SRCImage
|
|
162
|
+
className="class-name"
|
|
163
|
+
data={
|
|
164
|
+
{
|
|
165
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
166
|
+
"height": 421,
|
|
167
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
168
|
+
"width": 750,
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
style={
|
|
172
|
+
{
|
|
173
|
+
"border": "1px solid red",
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
>
|
|
177
|
+
<picture>
|
|
178
|
+
<source
|
|
179
|
+
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"
|
|
180
|
+
/>
|
|
181
|
+
<img
|
|
182
|
+
alt=""
|
|
183
|
+
className="class-name"
|
|
184
|
+
loading="lazy"
|
|
185
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
186
|
+
style={
|
|
187
|
+
{
|
|
188
|
+
"aspectRatio": "750 / 421",
|
|
189
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
190
|
+
"backgroundPosition": "50% 50%",
|
|
191
|
+
"backgroundRepeat": "no-repeat",
|
|
192
|
+
"backgroundSize": "cover",
|
|
193
|
+
"border": "1px solid red",
|
|
194
|
+
"color": "transparent",
|
|
195
|
+
"height": "auto",
|
|
196
|
+
"maxWidth": "750px",
|
|
197
|
+
"width": "100%",
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/>
|
|
201
|
+
</picture>
|
|
202
|
+
</SRCImage>
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
exports[`Image priority=true renders correctly 1`] = `
|
|
206
|
+
<SRCImage
|
|
207
|
+
data={
|
|
208
|
+
{
|
|
209
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
210
|
+
"height": 421,
|
|
211
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
212
|
+
"width": 750,
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
priority={true}
|
|
216
|
+
>
|
|
217
|
+
<picture>
|
|
218
|
+
<source
|
|
219
|
+
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"
|
|
220
|
+
/>
|
|
221
|
+
<img
|
|
222
|
+
alt=""
|
|
223
|
+
fetchpriority="high"
|
|
224
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
225
|
+
style={
|
|
226
|
+
{
|
|
227
|
+
"aspectRatio": "750 / 421",
|
|
228
|
+
"backgroundImage": "url("data:image/jpeg;base64,<IMAGE-DATA>")",
|
|
229
|
+
"backgroundPosition": "50% 50%",
|
|
230
|
+
"backgroundRepeat": "no-repeat",
|
|
231
|
+
"backgroundSize": "cover",
|
|
232
|
+
"color": "transparent",
|
|
233
|
+
"height": "auto",
|
|
234
|
+
"maxWidth": "750px",
|
|
235
|
+
"width": "100%",
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/>
|
|
239
|
+
</picture>
|
|
240
|
+
</SRCImage>
|
|
241
|
+
`;
|
|
242
|
+
|
|
243
|
+
exports[`Image usePlaceholder=false renders correctly 1`] = `
|
|
244
|
+
<SRCImage
|
|
245
|
+
data={
|
|
246
|
+
{
|
|
247
|
+
"base64": "data:image/jpeg;base64,<IMAGE-DATA>",
|
|
248
|
+
"height": 421,
|
|
249
|
+
"src": "https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750",
|
|
250
|
+
"width": 750,
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
usePlaceholder={false}
|
|
254
|
+
>
|
|
255
|
+
<picture>
|
|
256
|
+
<source
|
|
257
|
+
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"
|
|
258
|
+
/>
|
|
259
|
+
<img
|
|
260
|
+
alt=""
|
|
261
|
+
loading="lazy"
|
|
262
|
+
src="https://www.datocms-assets.com/205/image.png?ar=16%3A9&fit=crop&w=750"
|
|
263
|
+
style={
|
|
264
|
+
{
|
|
265
|
+
"aspectRatio": "750 / 421",
|
|
266
|
+
"height": "auto",
|
|
267
|
+
"maxWidth": "750px",
|
|
268
|
+
"width": "100%",
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/>
|
|
272
|
+
</picture>
|
|
273
|
+
</SRCImage>
|
|
274
|
+
`;
|
|
@@ -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,99 @@
|
|
|
1
|
+
// biome-ignore lint/style/useImportType: wrong warning
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { ResponsiveImageType } from '../Image';
|
|
4
|
+
import { buildRegularSource, buildWebpSource, priorityProp } from './utils.js';
|
|
5
|
+
|
|
6
|
+
export type SRCImagePropTypes = {
|
|
7
|
+
/** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */
|
|
8
|
+
data: ResponsiveImageType;
|
|
9
|
+
/** Additional CSS className for root node */
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Additional CSS rules to add to the root node */
|
|
12
|
+
style?: React.CSSProperties;
|
|
13
|
+
/**
|
|
14
|
+
* When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
|
|
15
|
+
* 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.
|
|
16
|
+
* Should only be used when the image is visible above the fold.
|
|
17
|
+
**/
|
|
18
|
+
priority?: boolean;
|
|
19
|
+
/** Whether the component should use a blurred image placeholder */
|
|
20
|
+
usePlaceholder?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The HTML5 `sizes` attribute for the image
|
|
23
|
+
*
|
|
24
|
+
* Learn more about srcset and sizes:
|
|
25
|
+
* -> https://web.dev/learn/design/responsive-images/#sizes
|
|
26
|
+
* -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
|
|
27
|
+
**/
|
|
28
|
+
sizes?: HTMLImageElement['sizes'];
|
|
29
|
+
/**
|
|
30
|
+
* If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
|
|
31
|
+
*
|
|
32
|
+
* Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
|
|
33
|
+
**/
|
|
34
|
+
srcSetCandidates?: number[];
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function SRCImage({
|
|
38
|
+
className,
|
|
39
|
+
style,
|
|
40
|
+
data,
|
|
41
|
+
usePlaceholder = true,
|
|
42
|
+
priority = false,
|
|
43
|
+
sizes,
|
|
44
|
+
srcSetCandidates = [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4],
|
|
45
|
+
}: SRCImagePropTypes) {
|
|
46
|
+
const webpSource = buildWebpSource(data, sizes);
|
|
47
|
+
const regularSource = buildRegularSource(data, sizes, srcSetCandidates);
|
|
48
|
+
|
|
49
|
+
const placeholderStyle: React.CSSProperties | undefined =
|
|
50
|
+
usePlaceholder && data.base64
|
|
51
|
+
? {
|
|
52
|
+
backgroundImage: `url("${data.base64}")`,
|
|
53
|
+
backgroundSize: 'cover',
|
|
54
|
+
backgroundRepeat: 'no-repeat',
|
|
55
|
+
backgroundPosition: '50% 50%',
|
|
56
|
+
color: 'transparent',
|
|
57
|
+
}
|
|
58
|
+
: usePlaceholder && data.bgColor
|
|
59
|
+
? { backgroundColor: data.bgColor ?? undefined, color: 'transparent' }
|
|
60
|
+
: undefined;
|
|
61
|
+
|
|
62
|
+
const { width } = data;
|
|
63
|
+
|
|
64
|
+
const height =
|
|
65
|
+
data.height ?? Math.round(data.aspectRatio ? width / data.aspectRatio : 0);
|
|
66
|
+
|
|
67
|
+
const sizingStyle = {
|
|
68
|
+
aspectRatio: `${width} / ${height}`,
|
|
69
|
+
width: '100%',
|
|
70
|
+
maxWidth: `${width}px`,
|
|
71
|
+
height: 'auto',
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const loadingBehaviourProps = priority
|
|
75
|
+
? priorityProp(priority ? 'high' : undefined)
|
|
76
|
+
: { loading: 'lazy' };
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<picture>
|
|
80
|
+
{webpSource}
|
|
81
|
+
{regularSource}
|
|
82
|
+
{data.src && (
|
|
83
|
+
// biome-ignore lint/a11y/useAltText: We do with alt the best we can
|
|
84
|
+
<img
|
|
85
|
+
src={data.src}
|
|
86
|
+
alt={data.alt ?? ''}
|
|
87
|
+
title={data.title ?? undefined}
|
|
88
|
+
{...loadingBehaviourProps}
|
|
89
|
+
className={className}
|
|
90
|
+
style={{
|
|
91
|
+
...placeholderStyle,
|
|
92
|
+
...sizingStyle,
|
|
93
|
+
...style,
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
)}
|
|
97
|
+
</picture>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, { version } from 'react';
|
|
2
|
+
import type { 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 = Number.parseInt(majorStr, 10);
|
|
9
|
+
const minor = Number.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(Number.parseInt(maxH) * multiplier)}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (maxW) {
|
|
47
|
+
url.searchParams.set(
|
|
48
|
+
'max-w',
|
|
49
|
+
`${Math.floor(Number.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/Seo/nextUtils.ts
CHANGED
|
@@ -76,7 +76,7 @@ export function toNextMetadata(
|
|
|
76
76
|
const { tag, attributes, content } = datum;
|
|
77
77
|
|
|
78
78
|
if (tag === 'title') {
|
|
79
|
-
metadata
|
|
79
|
+
metadata.title = content;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
if (isSeoOrFaviconTag(datum) && isSeoMetaTag(datum)) {
|
|
@@ -88,15 +88,15 @@ export function toNextMetadata(
|
|
|
88
88
|
|
|
89
89
|
if (parts?.length === 1) {
|
|
90
90
|
if (parts[0] === 'image') {
|
|
91
|
-
metadata
|
|
91
|
+
metadata.openGraph ||= {};
|
|
92
92
|
|
|
93
|
-
metadata
|
|
94
|
-
...metadata
|
|
93
|
+
metadata.openGraph.images = {
|
|
94
|
+
...metadata.openGraph.images,
|
|
95
95
|
url: content,
|
|
96
96
|
};
|
|
97
97
|
} else {
|
|
98
|
-
metadata
|
|
99
|
-
...metadata
|
|
98
|
+
metadata.openGraph = {
|
|
99
|
+
...metadata.openGraph,
|
|
100
100
|
[camelize(parts[0])]: content,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
@@ -104,17 +104,17 @@ export function toNextMetadata(
|
|
|
104
104
|
|
|
105
105
|
if (parts?.length === 2) {
|
|
106
106
|
if (parts[0] === 'image' && parts[1] === 'width') {
|
|
107
|
-
metadata
|
|
107
|
+
metadata.openGraph ||= {};
|
|
108
108
|
|
|
109
|
-
metadata
|
|
110
|
-
...metadata
|
|
109
|
+
metadata.openGraph.images = {
|
|
110
|
+
...metadata.openGraph.images,
|
|
111
111
|
width: content,
|
|
112
112
|
};
|
|
113
113
|
} else if (parts[0] === 'image' && parts[1] === 'height') {
|
|
114
|
-
metadata
|
|
114
|
+
metadata.openGraph ||= {};
|
|
115
115
|
|
|
116
|
-
metadata
|
|
117
|
-
...metadata
|
|
116
|
+
metadata.openGraph.images = {
|
|
117
|
+
...metadata.openGraph.images,
|
|
118
118
|
height: content,
|
|
119
119
|
};
|
|
120
120
|
}
|
|
@@ -131,8 +131,8 @@ export function toNextMetadata(
|
|
|
131
131
|
const [_, ...parts] = name.split(':');
|
|
132
132
|
|
|
133
133
|
if (parts?.length === 1) {
|
|
134
|
-
metadata
|
|
135
|
-
...metadata
|
|
134
|
+
metadata.twitter = {
|
|
135
|
+
...metadata.twitter,
|
|
136
136
|
[camelize(parts[0])]: content,
|
|
137
137
|
};
|
|
138
138
|
}
|
|
@@ -146,10 +146,10 @@ export function toNextMetadata(
|
|
|
146
146
|
if (isAppleTouchIconAttributes(datum.attributes)) {
|
|
147
147
|
const { sizes, href } = datum.attributes;
|
|
148
148
|
|
|
149
|
-
metadata
|
|
149
|
+
metadata.icons ||= {};
|
|
150
150
|
|
|
151
|
-
metadata
|
|
152
|
-
...(metadata
|
|
151
|
+
metadata.icons.apple = [
|
|
152
|
+
...(metadata.icons.apple || []),
|
|
153
153
|
{ url: href, sizes },
|
|
154
154
|
];
|
|
155
155
|
}
|
|
@@ -157,10 +157,10 @@ export function toNextMetadata(
|
|
|
157
157
|
if (isFaviconAttributes(datum.attributes)) {
|
|
158
158
|
const { sizes, type, rel, href } = datum.attributes;
|
|
159
159
|
|
|
160
|
-
metadata
|
|
160
|
+
metadata.icons ||= {};
|
|
161
161
|
|
|
162
|
-
metadata
|
|
163
|
-
...(metadata
|
|
162
|
+
metadata.icons.icon = [
|
|
163
|
+
...(metadata.icons.icon || []),
|
|
164
164
|
{ url: href, sizes, type, rel },
|
|
165
165
|
];
|
|
166
166
|
}
|
package/src/Seo/remixUtils.ts
CHANGED