@@ -2,7 +2,7 @@ import * as React from 'react';
22
33import { BREAKPOINTS } from '../../constants' ;
44import { ProjectSettingsContext } from '../../context/projectSettingsContext' ;
5- import { ImageDeviceProps , ImageObjectProps , QAProps } from '../../models' ;
5+ import { Device , ImageDeviceProps , ImageObjectProps , QAProps } from '../../models' ;
66import { getQaAttrubutes } from '../../utils' ;
77import { isCompressible } from '../../utils/imageCompress' ;
88import ImageBase from '../ImageBase/ImageBase' ;
@@ -18,31 +18,50 @@ export interface ImageProps extends Partial<ImageObjectProps>, Partial<ImageDevi
1818export interface DeviceSpecificFragmentProps extends QAProps {
1919 disableWebp : boolean ;
2020 src : string ;
21- breakpoint : number ;
21+ maxBreakpoint ?: number ;
22+ minBreakpoint ?: number ;
2223}
2324
2425const checkWebP = ( src : string ) => {
2526 return src . endsWith ( '.webp' ) ? src : src + '.webp' ;
2627} ;
2728
29+ export const EMPTY_IMG =
30+ 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxIiBoZWlnaHQ9IjEiPjwvc3ZnPg==' ;
31+
2832const DeviceSpecificFragment = ( {
2933 disableWebp,
3034 src,
31- breakpoint,
35+ maxBreakpoint,
36+ minBreakpoint,
3237 qa,
33- } : DeviceSpecificFragmentProps ) => (
34- < React . Fragment >
35- { ! disableWebp && (
36- < source
37- srcSet = { checkWebP ( src ) }
38- type = "image/webp"
39- media = { `(max-width: ${ breakpoint } px)` }
40- data-qa = { `${ qa } -compressed` }
41- />
42- ) }
43- < source srcSet = { src } media = { `(max-width: ${ breakpoint } px)` } data-qa = { qa } />
44- </ React . Fragment >
45- ) ;
38+ } : DeviceSpecificFragmentProps ) => {
39+ const media : string [ ] = [ ] ;
40+
41+ if ( maxBreakpoint ) {
42+ media . push ( `(max-width: ${ maxBreakpoint } px)` ) ;
43+ }
44+
45+ if ( minBreakpoint ) {
46+ media . push ( `(min-width: ${ minBreakpoint } px)` ) ;
47+ }
48+
49+ const mediaString = media . join ( ' and ' ) ;
50+
51+ return (
52+ < React . Fragment >
53+ { ! disableWebp && (
54+ < source
55+ srcSet = { checkWebP ( src ) }
56+ type = "image/webp"
57+ media = { mediaString }
58+ data-qa = { `${ qa } -compressed` }
59+ />
60+ ) }
61+ < source srcSet = { src } media = { mediaString } data-qa = { qa } />
62+ </ React . Fragment >
63+ ) ;
64+ } ;
4665
4766const Image = ( props : ImageProps ) => {
4867 const projectSettings = React . useContext ( ProjectSettingsContext ) ;
@@ -61,48 +80,64 @@ const Image = (props: ImageProps) => {
6180 qa,
6281 fetchPriority,
6382 loading,
83+ hide,
6484 } = props ;
6585 const [ imgLoadingError , setImgLoadingError ] = React . useState ( false ) ;
6686
6787 const src = imageSrc || desktop ;
6888
69- if ( ! src ) {
70- return null ;
71- }
89+ const hideDevices =
90+ typeof hide === 'boolean' || ! hide
91+ ? Object . values ( Device ) . reduce (
92+ ( acc , device ) => ( { ...acc , [ device ] : Boolean ( hide ) } ) ,
93+ { } as Record < Device , boolean > ,
94+ )
95+ : hide ;
7296
7397 const qaAttributes = getQaAttrubutes (
7498 qa ,
7599 'mobile-webp-source' ,
76100 'mobile-source' ,
77101 'tablet-webp-source' ,
78102 'tablet-source' ,
103+ 'desktop-source' ,
79104 'desktop-source-compressed' ,
80105 ) ;
81106
82107 const disableWebp =
108+ ! src ||
83109 projectSettings . disableCompress ||
84110 disableCompress ||
85111 ! isCompressible ( src ) ||
86112 imgLoadingError ;
87113
88114 return (
89115 < picture className = { containerClassName } data-qa = { qa } >
90- { mobile && (
116+ { ( mobile || hideDevices . mobile ) && (
91117 < DeviceSpecificFragment
92- src = { mobile }
93- disableWebp = { disableWebp }
94- breakpoint = { BREAKPOINTS . sm }
118+ src = { mobile || EMPTY_IMG }
119+ disableWebp = { disableWebp || Boolean ( hideDevices . mobile ) }
120+ maxBreakpoint = { BREAKPOINTS . sm }
95121 qa = { qaAttributes . mobileSource }
96122 />
97123 ) }
98- { tablet && (
124+ { ( tablet || hideDevices . tablet ) && (
99125 < DeviceSpecificFragment
100- src = { tablet }
101- disableWebp = { disableWebp }
102- breakpoint = { BREAKPOINTS . md }
126+ src = { tablet || EMPTY_IMG }
127+ disableWebp = { disableWebp || Boolean ( hideDevices . tablet ) }
128+ maxBreakpoint = { BREAKPOINTS . md }
129+ minBreakpoint = { BREAKPOINTS . sm }
103130 qa = { qaAttributes . tabletSource }
104131 />
105132 ) }
133+ { hideDevices . desktop && (
134+ < DeviceSpecificFragment
135+ src = { EMPTY_IMG }
136+ disableWebp
137+ minBreakpoint = { BREAKPOINTS . md }
138+ qa = { qaAttributes . desktopSource }
139+ />
140+ ) }
106141 { src && ! disableWebp && (
107142 < source
108143 srcSet = { checkWebP ( src ) }
0 commit comments