11import React , { createRef , Fragment } from 'react' ;
22import CloudinaryComponent from '../CloudinaryComponent' ;
3- import { extractCloudinaryProps , getImageTag , makeElementResponsive , getConfiguredCloudinary } from "../../Util" ;
3+ import { extractCloudinaryProps , getImageTag , makeElementResponsive } from "../../Util" ;
44import { Util } from "cloudinary-core" ;
55import PropTypes from "prop-types" ;
66
7+ const RESPONSIVE_OVERRIDE_WARNING = [
8+ `Warning: passing a number value for width cancels the 'responsive' prop's effect on the image transformation.` ,
9+ `The 'responsive' prop affects the image transformation only when width === 'auto'.` ,
10+ `Passing 'width="auto" responsive' will affect the actual image width that is fetched from Cloudinary.` ,
11+ `The 'responsive' prop causes the Image component to request an image which width is equal to the width of it's container.` ,
12+ `When passing 'width="auto" responsive', you can set the <img> element width by passing a 'style' prop`
13+ ] . join ( '\n' ) ;
14+
715/**
816 * A component representing a Cloudinary served image
917 */
@@ -19,7 +27,12 @@ class Image extends CloudinaryComponent {
1927 * @return true when this image element should be made responsive, false otherwise.
2028 */
2129 isResponsive = ( ) => {
22- return this . props . responsive && this . imgElement && this . imgElement . current ;
30+ const { responsive, width} = this . getExtendedProps ( ) ;
31+ if ( responsive && width !== 'auto' ) {
32+ console . warn ( RESPONSIVE_OVERRIDE_WARNING ) ;
33+ }
34+
35+ return responsive && this . imgElement && this . imgElement . current ;
2336 }
2437
2538 /**
@@ -44,33 +57,46 @@ class Image extends CloudinaryComponent {
4457
4558 let attributes = { ...getImageTag ( options ) . attributes ( ) , ...nonCloudinaryProps } ;
4659
60+ //React requires camelCase instead of snake_case attributes
61+ attributes = Util . withCamelCaseKeys ( attributes ) ;
62+
4763 // Set placeholder Id
4864 if ( placeholder && attributes . id ) {
4965 attributes . id = attributes . id + '-cld-placeholder' ;
5066 }
5167
68+ // Set dataSrc if lazy loading and not in view
69+ if ( ! isInView && this . shouldLazyLoad ( options ) ) {
70+ attributes . dataSrc = attributes . dataSrc || attributes . src ;
71+ delete attributes . src ;
72+ }
73+
74+ // The data-src attribute was turned into dataSrc by the camelCase function,
75+ // But it's needed by cloudinary-core's responsive() function. Notice that it's not snake_case.
76+ if ( attributes . dataSrc ) {
77+ attributes [ 'data-src' ] = attributes . dataSrc ;
78+ }
79+
5280 // Remove unneeded attributes,
53- [ "src" , " accessibility" , " placeholder" ] . forEach ( attr => {
81+ [ 'dataSrc' , ' accessibility' , ' placeholder' , 'breakpoints' ] . forEach ( attr => {
5482 delete attributes [ attr ] ;
5583 } ) ;
5684
57- // Set src or data-src attribute
58- const srcAttrName = isInView || ! this . shouldLazyLoad ( options ) ? "src" : "data-src" ;
59- attributes [ srcAttrName ] = getConfiguredCloudinary ( options ) . url ( options . publicId , options ) ;
60-
6185 return attributes ;
6286 }
6387
6488 /**
6589 * Update this image using cloudinary-core
6690 */
6791 update = ( ) => {
92+ const { isInView} = this . state ;
93+
6894 if ( this . isResponsive ( ) ) {
6995 const removeListener = makeElementResponsive ( this . imgElement . current , this . getOptions ( ) ) ;
7096 this . listenerRemovers . push ( removeListener ) ;
7197 }
7298
73- if ( this . shouldLazyLoad ( this . getExtendedProps ( ) ) ) {
99+ if ( ! isInView && this . shouldLazyLoad ( this . getExtendedProps ( ) ) ) {
74100 Util . detectIntersection ( this . imgElement . current , this . onIntersect ) ;
75101 }
76102 }
@@ -153,7 +179,6 @@ class Image extends CloudinaryComponent {
153179 </ Fragment >
154180 ) ;
155181 }
156-
157182 return < img ref = { attachRef } { ...attributes } />
158183 }
159184}
0 commit comments