Skip to content

Commit 8e201ad

Browse files
mariusc23AndyPengc12
authored andcommitted
Add support for preload media to ReactDOM (facebook#28635)
This PR adds support for `media` option to `ReactDOM.preload()`, which is needed when images differ between screen sizes (for example mobile vs desktop)
1 parent 7cf7913 commit 8e201ad

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

packages/react-dom/src/__tests__/ReactDOMFloat-test.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4261,6 +4261,91 @@ body {
42614261
);
42624262
});
42634263

4264+
it('should handle media on image preload', async () => {
4265+
function App({isClient}) {
4266+
ReactDOM.preload('/server', {
4267+
as: 'image',
4268+
imageSrcSet: '/server',
4269+
imageSizes: '100vw',
4270+
media: 'print and (min-width: 768px)',
4271+
});
4272+
4273+
if (isClient) {
4274+
ReactDOM.preload('/client', {
4275+
as: 'image',
4276+
imageSrcSet: '/client',
4277+
imageSizes: '100vw',
4278+
media: 'screen and (max-width: 480px)',
4279+
});
4280+
}
4281+
4282+
return (
4283+
<html>
4284+
<body>hello</body>
4285+
</html>
4286+
);
4287+
}
4288+
4289+
await act(() => {
4290+
renderToPipeableStream(<App />).pipe(writable);
4291+
});
4292+
expect(getMeaningfulChildren(document)).toEqual(
4293+
<html>
4294+
<head>
4295+
<link
4296+
rel="preload"
4297+
as="image"
4298+
imagesrcset="/server"
4299+
imagesizes="100vw"
4300+
media="print and (min-width: 768px)"
4301+
/>
4302+
</head>
4303+
<body>hello</body>
4304+
</html>,
4305+
);
4306+
4307+
const root = ReactDOMClient.hydrateRoot(document, <App />);
4308+
await waitForAll([]);
4309+
expect(getMeaningfulChildren(document)).toEqual(
4310+
<html>
4311+
<head>
4312+
<link
4313+
rel="preload"
4314+
as="image"
4315+
imagesrcset="/server"
4316+
imagesizes="100vw"
4317+
media="print and (min-width: 768px)"
4318+
/>
4319+
</head>
4320+
<body>hello</body>
4321+
</html>,
4322+
);
4323+
4324+
root.render(<App isClient={true} />);
4325+
await waitForAll([]);
4326+
expect(getMeaningfulChildren(document)).toEqual(
4327+
<html>
4328+
<head>
4329+
<link
4330+
rel="preload"
4331+
as="image"
4332+
imagesrcset="/server"
4333+
imagesizes="100vw"
4334+
media="print and (min-width: 768px)"
4335+
/>
4336+
<link
4337+
rel="preload"
4338+
as="image"
4339+
imagesrcset="/client"
4340+
imagesizes="100vw"
4341+
media="screen and (max-width: 480px)"
4342+
/>
4343+
</head>
4344+
<body>hello</body>
4345+
</html>,
4346+
);
4347+
});
4348+
42644349
it('should warn if you preload a stylesheet and then render a style tag with the same href', async () => {
42654350
const style = 'body { color: red; }';
42664351
function App() {

packages/react-dom/src/shared/ReactDOMFloat.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export function preload(href: string, options: PreloadOptions) {
139139
: undefined,
140140
imageSizes:
141141
typeof options.imageSizes === 'string' ? options.imageSizes : undefined,
142+
media: typeof options.media === 'string' ? options.media : undefined,
142143
});
143144
}
144145
// We don't error because preload needs to be resilient to being called in a variety of scopes

packages/react-dom/src/shared/ReactDOMTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type PreloadOptions = {
1616
crossOrigin?: string,
1717
integrity?: string,
1818
type?: string,
19+
media?: string,
1920
nonce?: string,
2021
fetchPriority?: FetchPriorityEnum,
2122
imageSrcSet?: string,

0 commit comments

Comments
 (0)