diff --git a/app/client/src/components/designSystems/appsmith/ImageComponent.tsx b/app/client/src/components/designSystems/appsmith/ImageComponent.tsx index ee3ea08429..7d8974ff44 100644 --- a/app/client/src/components/designSystems/appsmith/ImageComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/ImageComponent.tsx @@ -8,6 +8,7 @@ export interface StyledImageProps { imageUrl?: string; backgroundColor?: string; showHoverPointer?: boolean; + objectFit: string; onClick?: (event: React.MouseEvent) => void; } @@ -17,16 +18,16 @@ export const StyledImage = styled.div< } >` position: relative; - display: flex; + display: flex; flex-direction: "row"; + background-size: ${(props) => props.objectFit ?? "cover"}; cursor: ${(props) => props.showHoverPointer && props.onClick ? "pointer" : "inherit"}; background: ${(props) => props.backgroundColor}; - background-image: url("${(props) => - props.imageError ? props.defaultImageUrl : props.imageUrl}"); + background-image: ${(props) => + `url(${props.imageError ? props.defaultImageUrl : props.imageUrl})`}; background-position: center; background-repeat: no-repeat; - background-size: contain; height: 100%; width: 100%; `; @@ -142,6 +143,7 @@ class ImageComponent extends React.Component< cursor, }} > + {/* Used for running onImageError and onImageLoad Functions since Background Image doesn't have the functionality */} {this.props.widgetName} void; onClick?: (event: React.MouseEvent) => void; } diff --git a/app/client/src/mockResponses/WidgetConfigResponse.tsx b/app/client/src/mockResponses/WidgetConfigResponse.tsx index 1609b5ea80..7dca03b71b 100644 --- a/app/client/src/mockResponses/WidgetConfigResponse.tsx +++ b/app/client/src/mockResponses/WidgetConfigResponse.tsx @@ -57,6 +57,7 @@ const WidgetConfigResponse: WidgetConfigReducerState = { "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", imageShape: "RECTANGLE", maxZoomLevel: 1, + objectFit: "cover", image: "", rows: 3 * GRID_DENSITY_MIGRATION_V1, columns: 4 * GRID_DENSITY_MIGRATION_V1, diff --git a/app/client/src/utils/WidgetPropsUtils.tsx b/app/client/src/utils/WidgetPropsUtils.tsx index 08ed18fb54..7f92d81fb8 100644 --- a/app/client/src/utils/WidgetPropsUtils.tsx +++ b/app/client/src/utils/WidgetPropsUtils.tsx @@ -791,6 +791,23 @@ const transformDSL = (currentDSL: ContainerWidgetProps) => { return currentDSL; }; +export const migrateObjectFitToImageWidget = ( + dsl: ContainerWidgetProps, +) => { + const addObjectFitProperty = (widgetProps: WidgetProps) => { + widgetProps.objectFit = "cover"; + if (widgetProps.children && widgetProps.children.length) { + widgetProps.children.forEach((eachWidgetProp: WidgetProps) => { + if (widgetProps.type === "IMAGE_WIDGET") { + addObjectFitProperty(eachWidgetProp); + } + }); + } + }; + addObjectFitProperty(dsl); + return dsl; +}; + const migrateOverFlowingTabsWidgets = ( currentDSL: ContainerWidgetProps, canvasWidgets: any, diff --git a/app/client/src/widgets/ImageWidget.tsx b/app/client/src/widgets/ImageWidget.tsx index 02d97e6065..d6571cbe12 100644 --- a/app/client/src/widgets/ImageWidget.tsx +++ b/app/client/src/widgets/ImageWidget.tsx @@ -78,6 +78,32 @@ class ImageWidget extends BaseWidget { isTriggerProperty: false, validation: VALIDATION_TYPES.NUMBER, }, + { + helpText: + "Sets how the Image should be resized to fit its container.", + propertyName: "objectFit", + label: "Object Fit", + controlType: "DROP_DOWN", + defaultValue: "cover", + options: [ + { + label: "Contain", + value: "contain", + }, + { + label: "Cover", + value: "cover", + }, + { + label: "Auto", + value: "auto", + }, + ], + isJSConvertible: true, + isBindProperty: true, + isTriggerProperty: false, + validation: VALIDATION_TYPES.TEXT, + }, ], }, { @@ -99,7 +125,7 @@ class ImageWidget extends BaseWidget { } getPageView() { - const { maxZoomLevel } = this.props; + const { maxZoomLevel, objectFit } = this.props; return ( { imageUrl={this.props.image} isLoading={this.props.isLoading} maxZoomLevel={maxZoomLevel} + objectFit={objectFit} onClick={this.props.onClick ? this.onImageClick : undefined} showHoverPointer={this.props.renderMode === RenderModes.PAGE} widgetId={this.props.widgetId} @@ -140,6 +167,7 @@ export interface ImageWidgetProps extends WidgetProps { imageShape: ImageShape; defaultImage: string; maxZoomLevel: number; + objectFit: string; onClick?: string; }