diff --git a/app/client/src/editorComponents/DraggableComponent.tsx b/app/client/src/editorComponents/DraggableComponent.tsx index e4b9c3bd6f..f45d20d5b6 100644 --- a/app/client/src/editorComponents/DraggableComponent.tsx +++ b/app/client/src/editorComponents/DraggableComponent.tsx @@ -1,10 +1,11 @@ -import React, { useContext } from "react"; +import React, { useContext, createContext, useState, Context } from "react"; import styled from "styled-components"; import { WidgetProps, WidgetOperations } from "../widgets/BaseWidget"; import { useDrag, DragPreviewImage, DragSourceMonitor } from "react-dnd"; import blankImage from "../assets/images/blank.png"; import { ContainerProps } from "./ContainerComponent"; import { FocusContext } from "../pages/Editor/Canvas"; +import { WidgetFunctionsContext } from "../pages/Editor"; import { ControlIcons } from "../icons/ControlIcons"; import { theme } from "../constants/DefaultTheme"; @@ -50,11 +51,16 @@ const deleteControlIcon = ControlIcons.DELETE_CONTROL({ type DraggableComponentProps = WidgetProps & ContainerProps; +export const ResizingContext: Context<{ + setIsResizing?: Function; +}> = createContext({}); + const DraggableComponent = (props: DraggableComponentProps) => { const { isFocused, setFocus } = useContext(FocusContext); + const { updateWidget } = useContext(WidgetFunctionsContext); + const [isResizing, setIsResizing] = useState(false); const deleteWidget = () => { - props.updateWidget && - props.updateWidget(WidgetOperations.DELETE, props.widgetId); + updateWidget && updateWidget(WidgetOperations.DELETE, props.widgetId); }; const [{ isDragging }, drag, preview] = useDrag({ item: props, @@ -64,7 +70,7 @@ const DraggableComponent = (props: DraggableComponentProps) => { }); return ( - + { e.stopPropagation(); } }} - show={props.widgetId === isFocused} + show={props.widgetId === isFocused && !isResizing} style={{ display: isDragging ? "none" : "flex", flexDirection: "column", @@ -99,7 +105,7 @@ const DraggableComponent = (props: DraggableComponentProps) => { {props.children} - + ); }; diff --git a/app/client/src/editorComponents/DropTargetComponent.tsx b/app/client/src/editorComponents/DropTargetComponent.tsx index 85a2581d27..c3d96b7881 100644 --- a/app/client/src/editorComponents/DropTargetComponent.tsx +++ b/app/client/src/editorComponents/DropTargetComponent.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useContext } from "react"; import { WidgetProps } from "../widgets/BaseWidget"; import { OccupiedSpace } from "../widgets/ContainerWidget"; import { WidgetConfigProps } from "../reducers/entityReducers/widgetConfigReducer"; @@ -7,6 +7,7 @@ import { ContainerProps } from "./ContainerComponent"; import WidgetFactory from "../utils/WidgetFactory"; import { widgetOperationParams, noCollision } from "../utils/WidgetPropsUtils"; import DragLayerComponent from "./DragLayerComponent"; +import { WidgetFunctionsContext } from "../pages/Editor"; type DropTargetComponentProps = ContainerProps & { updateWidget?: Function; @@ -27,14 +28,15 @@ type DropTargetBounds = { export const DropTargetComponent = (props: DropTargetComponentProps) => { // Hook to keep the offset of the drop target container in state const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 }); + const { updateWidget } = useContext(WidgetFunctionsContext); // Make this component a drop target const [{ isOver, isExactlyOver }, drop] = useDrop({ accept: Object.values(WidgetFactory.getWidgetTypes()), drop(widget: WidgetProps & Partial, monitor) { // Make sure we're dropping in this container. if (isOver) { - props.updateWidget && - props.updateWidget( + updateWidget && + updateWidget( ...widgetOperationParams( widget, monitor.getClientOffset() as XYCoord, diff --git a/app/client/src/editorComponents/ResizableComponent.tsx b/app/client/src/editorComponents/ResizableComponent.tsx index 81f9e8d4f4..1ceaab6679 100644 --- a/app/client/src/editorComponents/ResizableComponent.tsx +++ b/app/client/src/editorComponents/ResizableComponent.tsx @@ -4,6 +4,8 @@ import { Rnd } from "react-rnd"; import { XYCoord } from "react-dnd"; import { WidgetProps, WidgetOperations } from "../widgets/BaseWidget"; import { ContainerProps, ParentBoundsContext } from "./ContainerComponent"; +import { ResizingContext } from "./DraggableComponent"; +import { WidgetFunctionsContext } from "../pages/Editor"; export type ResizableComponentProps = WidgetProps & ContainerProps; @@ -35,7 +37,9 @@ const ResizableContainer = styled(Rnd)` `; export const ResizableComponent = (props: ResizableComponentProps) => { + const { setIsResizing } = useContext(ResizingContext); const { boundingParent } = useContext(ParentBoundsContext); + const { updateWidget } = useContext(WidgetFunctionsContext); let bounds = "body"; if (boundingParent && boundingParent.current) { bounds = "." + boundingParent.current.className.split(" ")[1]; @@ -47,6 +51,7 @@ export const ResizableComponent = (props: ResizableComponentProps) => { delta: { width: number; height: number }, position: XYCoord, ) => { + setIsResizing && setIsResizing(false); const leftColumn = props.leftColumn + position.x / props.parentColumnSpace; const topRow = props.topRow + position.y / props.parentRowSpace; @@ -55,8 +60,8 @@ export const ResizableComponent = (props: ResizableComponentProps) => { const bottomRow = props.bottomRow + (delta.height + position.y) / props.parentRowSpace; - props.updateWidget && - props.updateWidget(WidgetOperations.RESIZE, props.widgetId, { + updateWidget && + updateWidget(WidgetOperations.RESIZE, props.widgetId, { leftColumn, rightColumn, topRow, @@ -78,6 +83,9 @@ export const ResizableComponent = (props: ResizableComponentProps) => { minHeight={props.parentRowSpace} style={{ ...props.style }} onResizeStop={updateSize} + onResizeStart={() => { + setIsResizing && setIsResizing(true); + }} resizeGrid={[props.parentColumnSpace, props.parentRowSpace]} bounds={bounds} enableResizing={{ diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx index a3e88c5a2e..a5e9350d9a 100644 --- a/app/client/src/pages/Editor/Canvas.tsx +++ b/app/client/src/pages/Editor/Canvas.tsx @@ -8,7 +8,6 @@ import React, { import styled from "styled-components"; import WidgetFactory from "../../utils/WidgetFactory"; import { RenderModes } from "../../constants/WidgetConstants"; -import { WidgetFunctions } from "../../widgets/BaseWidget"; import { ContainerWidgetProps } from "../../widgets/ContainerWidget"; import { WidgetProps } from "../../widgets/BaseWidget"; @@ -21,7 +20,6 @@ const ArtBoard = styled.div` interface CanvasProps { dsl: ContainerWidgetProps; - widgetFunctions: WidgetFunctions; } export const FocusContext: Context<{ @@ -35,11 +33,7 @@ const Canvas = (props: CanvasProps) => { {props.dsl.widgetId && - WidgetFactory.createWidget( - props.dsl, - props.widgetFunctions, - RenderModes.CANVAS, - )} + WidgetFactory.createWidget(props.dsl, RenderModes.CANVAS)} ); diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index a4c781d9ee..086ad989b5 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -1,4 +1,4 @@ -import React, { Component } from "react"; +import React, { Component, Context, createContext } from "react"; import { connect } from "react-redux"; import styled from "styled-components"; import Canvas from "./Canvas"; @@ -6,6 +6,7 @@ import { WidgetCardProps, WidgetProps, WidgetOperation, + WidgetFunctions, } from "../../widgets/BaseWidget"; import { AppState } from "../../reducers"; import { EditorReduxState } from "../../reducers/uiReducers/editorReducer"; @@ -61,6 +62,10 @@ type EditorProps = { isSaving: boolean; }; +export const WidgetFunctionsContext: Context = createContext( + {}, +); + class Editor extends Component { componentDidMount() { this.props.fetchCanvasWidgets(this.props.currentPageId); @@ -68,7 +73,12 @@ class Editor extends Component { public render() { return ( - + { - {this.props.dsl && ( - - )} + {this.props.dsl && } - + ); } } diff --git a/app/client/src/utils/WidgetFactory.tsx b/app/client/src/utils/WidgetFactory.tsx index 9ca0c0adcd..bbac31556b 100644 --- a/app/client/src/utils/WidgetFactory.tsx +++ b/app/client/src/utils/WidgetFactory.tsx @@ -2,7 +2,6 @@ import { WidgetType, RenderMode } from "../constants/WidgetConstants"; import { WidgetBuilder, WidgetProps, - WidgetFunctions, WidgetDataProps, } from "../widgets/BaseWidget"; @@ -18,13 +17,11 @@ class WidgetFactory { static createWidget( widgetData: WidgetDataProps, - widgetFunctions: WidgetFunctions, renderMode: RenderMode, ): JSX.Element { const widgetProps: WidgetProps = { key: widgetData.widgetId, renderMode: renderMode, - ...widgetFunctions, ...widgetData, }; const widgetBuilder = this.widgetMap.get(widgetData.type); diff --git a/app/client/src/utils/WidgetPropsUtils.tsx b/app/client/src/utils/WidgetPropsUtils.tsx index 7ac4e40891..5395d90b88 100644 --- a/app/client/src/utils/WidgetPropsUtils.tsx +++ b/app/client/src/utils/WidgetPropsUtils.tsx @@ -237,7 +237,6 @@ export const generateWidgetProps = ( return { ...widgetConfig, type, - executeAction: () => {}, widgetId: generateReactKey(), widgetName: widgetName || generateReactKey(), //TODO: figure out what this is to populate appropriately isVisible: true, diff --git a/app/client/src/widgets/BaseWidget.tsx b/app/client/src/widgets/BaseWidget.tsx index 7ca2745541..f67fbf8bcf 100644 --- a/app/client/src/widgets/BaseWidget.tsx +++ b/app/client/src/widgets/BaseWidget.tsx @@ -9,16 +9,16 @@ import { RenderModes, CSSUnits, } from "../constants/WidgetConstants"; -import { Component } from "react"; +import React, { Component } from "react"; import { BaseStyle } from "../editorComponents/BaseComponent"; import _ from "lodash"; -import React from "react"; import DraggableComponent from "../editorComponents/DraggableComponent"; import ResizableComponent from "../editorComponents/ResizableComponent"; import { ActionPayload } from "../constants/ActionConstants"; +import { WidgetFunctionsContext } from "../pages/Editor"; abstract class BaseWidget< - T extends WidgetProps & WidgetFunctions, + T extends WidgetProps, K extends WidgetState > extends Component { constructor(props: T) { @@ -32,6 +32,13 @@ abstract class BaseWidget< this.state = initialState as K; } + static contextType = WidgetFunctionsContext; + + executeAction(actionPayloads?: ActionPayload[]): void { + const { executeAction } = this.context; + executeAction && executeAction(actionPayloads); + } + componentDidMount(): void { this.calculateWidgetBounds( this.props.rightColumn, @@ -142,7 +149,7 @@ export interface WidgetBuilder { buildWidget(widgetProps: T): JSX.Element; } -export interface WidgetProps extends WidgetFunctions, WidgetDataProps { +export interface WidgetProps extends WidgetDataProps { key?: string; renderMode: RenderMode; } @@ -162,7 +169,7 @@ export interface WidgetDataProps { } export interface WidgetFunctions { - executeAction: (actionPayloads?: ActionPayload[]) => void; + executeAction?: (actionPayloads?: ActionPayload[]) => void; updateWidget?: Function; } diff --git a/app/client/src/widgets/ButtonWidget.tsx b/app/client/src/widgets/ButtonWidget.tsx index 75f56b8b39..8967c0df80 100644 --- a/app/client/src/widgets/ButtonWidget.tsx +++ b/app/client/src/widgets/ButtonWidget.tsx @@ -6,7 +6,7 @@ import { ActionPayload } from "../constants/ActionConstants"; class ButtonWidget extends BaseWidget { onButtonClick() { - this.props.executeAction(this.props.onClick); + super.executeAction(this.props.onClick); } getPageView() { diff --git a/app/client/src/widgets/ContainerWidget.tsx b/app/client/src/widgets/ContainerWidget.tsx index ed4deae0e2..ec1ded6bb3 100644 --- a/app/client/src/widgets/ContainerWidget.tsx +++ b/app/client/src/widgets/ContainerWidget.tsx @@ -1,9 +1,5 @@ import React from "react"; -import BaseWidget, { - WidgetProps, - WidgetState, - WidgetFunctions, -} from "./BaseWidget"; +import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; import ContainerComponent from "../editorComponents/ContainerComponent"; import { ContainerOrientation, WidgetType } from "../constants/WidgetConstants"; import WidgetFactory from "../utils/WidgetFactory"; @@ -51,12 +47,7 @@ class ContainerWidget extends BaseWidget< childWidgetData.parentColumnSpace = this.state.snapColumnSpace; childWidgetData.parentRowSpace = this.state.snapRowSpace; childWidgetData.parentId = this.props.widgetId; - const widgetFunctions: WidgetFunctions = this.props as WidgetFunctions; - return WidgetFactory.createWidget( - childWidgetData, - widgetFunctions, - this.props.renderMode, - ); + return WidgetFactory.createWidget(childWidgetData, this.props.renderMode); } getPageView() {