-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathResponsiveImage.jsx
97 lines (91 loc) · 3.09 KB
/
ResponsiveImage.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import React from 'react';
import PropTypes from 'prop-types';
import { Image } from 'semantic-ui-react';
import { flattenToAppURL } from '@plone/volto/helpers';
const getSrcSet = (imageUrl) => `
${imageUrl}/mini 200w,
${imageUrl}/preview 400w,
${imageUrl}/teaser 600w,
${imageUrl}/large 800w,
${imageUrl}/larger 1000w,
${imageUrl}/great 1200w,
${imageUrl}/huge 1600w
`;
const getSizes = (howManyColumns) => {
switch (howManyColumns) {
case 1:
// One-column layout: Image is full width at all breakpoints
return `
(max-width: 767px) 400px,
(min-width: 768px) and (max-width: 991px) 600px,
(min-width: 992px) and (max-width: 1199px) 800px,
(min-width: 1200px) and (max-width: 1919px) 1000px,
(min-width: 1650px) 1200px
`;
case 2:
// Two-column layout: Half-width images for larger breakpoints
return `
(max-width: 767px) 400px,
(min-width: 768px) and (max-width: 991px) 300px,
(min-width: 992px) and (max-width: 1199px) 400px,
(min-width: 1200px) and (max-width: 1919px) 500px,
(min-width: 1650px) 600px
`;
case 3:
// Three-column layout: One-third width images for larger breakpoints
return `
(max-width: 767px) 400px,
(min-width: 768px) and (max-width: 991px) 200px,
(min-width: 992px) and (max-width: 1199px) 300px,
(min-width: 1200px) and (max-width: 1919px) 400px,
(min-width: 1650px) 500px
`;
case 4:
// Four-column layout: Quarter-width images for larger breakpoints
return `
(max-width: 767px) 400px,
(min-width: 768px) and (max-width: 991px) 150px,
(min-width: 992px) and (max-width: 1199px) 200px,
(min-width: 1200px) and (max-width: 1919px) 300px,
(min-width: 1650px) 400px
`;
default:
// Default case: Use a conservative width for default handling
return `
(max-width: 767px) 400px,
(min-width: 768px) and (max-width: 991px) 600px,
(min-width: 992px) and (max-width: 1199px) 800px,
(min-width: 1200px) and (max-width: 1919px) 1000px,
(min-width: 1650px) 1600px
`;
}
};
const ResponsiveImage = React.memo(({ item, howManyColumns, fetchPriority }) => {
const imageUrl = flattenToAppURL(`${item.url}/@@images/${item.image_field}`);
const srcset = getSrcSet(imageUrl);
const sizes = getSizes(howManyColumns);
return (
<Image
className='listImage'
srcSet={srcset}
sizes={sizes}
alt={item.title || 'Image'}
src={imageUrl + '/preview'}
loading={fetchPriority === 'high' ? 'eager' : 'lazy'}
fetchpriority={fetchPriority}
width='100%'
height='auto'
style={{ width: '100%', height: 'auto', aspectRatio: '16/9' }} // Maintain aspect ratio
/>
);
});
ResponsiveImage.propTypes = {
item: PropTypes.shape({
url: PropTypes.string.isRequired,
image_field: PropTypes.string.isRequired,
title: PropTypes.string,
}).isRequired,
howManyColumns: PropTypes.number,
fetchPriority: PropTypes.string,
};
export default ResponsiveImage;