feat: add object fit control (#4986)

* Added attribute to image widget to change cover properties
This commit is contained in:
Tolulope Adetula 2021-06-29 14:30:14 +01:00 committed by GitHub
parent 140d6c8dda
commit 132abdaa54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 5 deletions

View File

@ -8,6 +8,7 @@ export interface StyledImageProps {
imageUrl?: string; imageUrl?: string;
backgroundColor?: string; backgroundColor?: string;
showHoverPointer?: boolean; showHoverPointer?: boolean;
objectFit: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void; onClick?: (event: React.MouseEvent<HTMLElement>) => void;
} }
@ -17,16 +18,16 @@ export const StyledImage = styled.div<
} }
>` >`
position: relative; position: relative;
display: flex; display: flex;
flex-direction: "row"; flex-direction: "row";
background-size: ${(props) => props.objectFit ?? "cover"};
cursor: ${(props) => cursor: ${(props) =>
props.showHoverPointer && props.onClick ? "pointer" : "inherit"}; props.showHoverPointer && props.onClick ? "pointer" : "inherit"};
background: ${(props) => props.backgroundColor}; background: ${(props) => props.backgroundColor};
background-image: url("${(props) => background-image: ${(props) =>
props.imageError ? props.defaultImageUrl : props.imageUrl}"); `url(${props.imageError ? props.defaultImageUrl : props.imageUrl})`};
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: contain;
height: 100%; height: 100%;
width: 100%; width: 100%;
`; `;
@ -142,6 +143,7 @@ class ImageComponent extends React.Component<
cursor, cursor,
}} }}
> >
{/* Used for running onImageError and onImageLoad Functions since Background Image doesn't have the functionality */}
<img <img
alt={this.props.widgetName} alt={this.props.widgetName}
onError={this.onImageError} onError={this.onImageError}
@ -178,6 +180,7 @@ export interface ImageComponentProps extends ComponentProps {
isLoading: boolean; isLoading: boolean;
showHoverPointer?: boolean; showHoverPointer?: boolean;
maxZoomLevel: number; maxZoomLevel: number;
objectFit: string;
disableDrag: (disabled: boolean) => void; disableDrag: (disabled: boolean) => void;
onClick?: (event: React.MouseEvent<HTMLElement>) => void; onClick?: (event: React.MouseEvent<HTMLElement>) => void;
} }

View File

@ -57,6 +57,7 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
"https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png", "https://res.cloudinary.com/drako999/image/upload/v1589196259/default.png",
imageShape: "RECTANGLE", imageShape: "RECTANGLE",
maxZoomLevel: 1, maxZoomLevel: 1,
objectFit: "cover",
image: "", image: "",
rows: 3 * GRID_DENSITY_MIGRATION_V1, rows: 3 * GRID_DENSITY_MIGRATION_V1,
columns: 4 * GRID_DENSITY_MIGRATION_V1, columns: 4 * GRID_DENSITY_MIGRATION_V1,

View File

@ -791,6 +791,23 @@ const transformDSL = (currentDSL: ContainerWidgetProps<WidgetProps>) => {
return currentDSL; return currentDSL;
}; };
export const migrateObjectFitToImageWidget = (
dsl: ContainerWidgetProps<WidgetProps>,
) => {
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 = ( const migrateOverFlowingTabsWidgets = (
currentDSL: ContainerWidgetProps<WidgetProps>, currentDSL: ContainerWidgetProps<WidgetProps>,
canvasWidgets: any, canvasWidgets: any,

View File

@ -78,6 +78,32 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
isTriggerProperty: false, isTriggerProperty: false,
validation: VALIDATION_TYPES.NUMBER, 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<ImageWidgetProps, WidgetState> {
} }
getPageView() { getPageView() {
const { maxZoomLevel } = this.props; const { maxZoomLevel, objectFit } = this.props;
return ( return (
<ImageComponent <ImageComponent
defaultImageUrl={this.props.defaultImage} defaultImageUrl={this.props.defaultImage}
@ -109,6 +135,7 @@ class ImageWidget extends BaseWidget<ImageWidgetProps, WidgetState> {
imageUrl={this.props.image} imageUrl={this.props.image}
isLoading={this.props.isLoading} isLoading={this.props.isLoading}
maxZoomLevel={maxZoomLevel} maxZoomLevel={maxZoomLevel}
objectFit={objectFit}
onClick={this.props.onClick ? this.onImageClick : undefined} onClick={this.props.onClick ? this.onImageClick : undefined}
showHoverPointer={this.props.renderMode === RenderModes.PAGE} showHoverPointer={this.props.renderMode === RenderModes.PAGE}
widgetId={this.props.widgetId} widgetId={this.props.widgetId}
@ -140,6 +167,7 @@ export interface ImageWidgetProps extends WidgetProps {
imageShape: ImageShape; imageShape: ImageShape;
defaultImage: string; defaultImage: string;
maxZoomLevel: number; maxZoomLevel: number;
objectFit: string;
onClick?: string; onClick?: string;
} }