diff --git a/app/client/src/components/designSystems/appsmith/WidgetNameComponent.tsx b/app/client/src/components/designSystems/appsmith/WidgetNameComponent.tsx index 569db74f4b..6b5beb15c9 100644 --- a/app/client/src/components/designSystems/appsmith/WidgetNameComponent.tsx +++ b/app/client/src/components/designSystems/appsmith/WidgetNameComponent.tsx @@ -1,7 +1,8 @@ import React, { useContext } from "react"; import styled from "styled-components"; -import { FocusContext } from "pages/Editor/CanvasContexts"; +import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import { DraggableComponentContext } from "components/editorComponents/DraggableComponent"; + const PositionStyle = styled.div<{ selected?: boolean }>` position: absolute; top: -${props => props.theme.spaces[10]}px; @@ -30,10 +31,12 @@ type WidgetNameComponentProps = { export const WidgetNameComponent = (props: WidgetNameComponentProps) => { const { focusedWidget, selectedWidget } = useContext(FocusContext); const { isDragging } = useContext(DraggableComponentContext); - - return (focusedWidget === props.widgetId || - selectedWidget === props.widgetId) && - !isDragging ? ( + const { isResizing } = useContext(ResizingContext); + const showWidgetName = + (focusedWidget === props.widgetId || selectedWidget === props.widgetId) && + !isDragging && + !isResizing; + return showWidgetName ? (
{props.widgetName}
diff --git a/app/client/src/components/editorComponents/DraggableComponent.tsx b/app/client/src/components/editorComponents/DraggableComponent.tsx index 77065642b2..fbb36961a9 100644 --- a/app/client/src/components/editorComponents/DraggableComponent.tsx +++ b/app/client/src/components/editorComponents/DraggableComponent.tsx @@ -127,12 +127,12 @@ const DraggableComponent = (props: DraggableComponentProps) => { isDragging: monitor.isDragging(), }), begin: () => { - showPropertyPane && showPropertyPane(); + showPropertyPane && showPropertyPane(undefined, true); selectWidget && selectWidget(props.widgetId); }, end: (widget, monitor) => { if (monitor.didDrop()) { - showPropertyPane && showPropertyPane(props.widgetId); + showPropertyPane && showPropertyPane(props.widgetId, true); } }, canDrag: () => { diff --git a/app/client/src/components/editorComponents/DropTargetComponent.tsx b/app/client/src/components/editorComponents/DropTargetComponent.tsx index 4bb93ab3c5..de9341de60 100644 --- a/app/client/src/components/editorComponents/DropTargetComponent.tsx +++ b/app/client/src/components/editorComponents/DropTargetComponent.tsx @@ -9,12 +9,6 @@ import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import DragLayerComponent from "./DragLayerComponent"; -/* -TODO(abhinav): - 1) Drag collision is not working - 2) Dragging into a new container does not work -*/ - type DropTargetComponentProps = WidgetProps & { children?: ReactNode; snapColumnSpace: number; @@ -52,8 +46,10 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => { props.snapRowSpace, props.widgetId, ); - + // Only show propertypane if this is a new widget. + // If it is not a new widget, then let the DraggableComponent handle it. showPropertyPane && + updateWidgetParams.payload.newWidgetId && showPropertyPane(updateWidgetParams.payload.newWidgetId); updateWidget && @@ -106,7 +102,7 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => { }; const handleFocus = () => { - if (!props.parentId) { + if (!props.parentId && !isResizing) { selectWidget && selectWidget(props.widgetId); showPropertyPane && showPropertyPane(); } diff --git a/app/client/src/components/editorComponents/ResizableComponent.tsx b/app/client/src/components/editorComponents/ResizableComponent.tsx index a1886a267e..0bfaa274cd 100644 --- a/app/client/src/components/editorComponents/ResizableComponent.tsx +++ b/app/client/src/components/editorComponents/ResizableComponent.tsx @@ -120,14 +120,16 @@ export const ResizableComponent = memo((props: ResizableComponentProps) => { // Clear border styles setIsColliding && setIsColliding(false); // Tell the Canvas that we've stopped resizing - setIsResizing && setIsResizing(false); + setTimeout(() => { + setIsResizing && setIsResizing(false); + }, 300); // Tell the Canvas to put the focus back to this widget // By setting the focus, we enable the control buttons on the widget selectWidget && selectWidget(props.widgetId); // Let the propertypane show. // The propertypane decides whether to show itself, based on // whether it was showing when the widget resize started. - showPropertyPane && showPropertyPane(props.widgetId); + showPropertyPane && showPropertyPane(props.widgetId, true); }; const style = getBorderStyles( isWidgetFocused, @@ -148,10 +150,12 @@ export const ResizableComponent = memo((props: ResizableComponentProps) => { style={style} onResizeStop={updateSize} onResize={checkForCollision} - onResizeStart={() => { + onResizeStart={(e: any) => { setIsResizing && setIsResizing(true); selectWidget && selectWidget(props.widgetId); - showPropertyPane && showPropertyPane(); + showPropertyPane && showPropertyPane(undefined, true); + e.preventDefault(); + e.stopPropagation(); }} resizeGrid={[props.parentColumnSpace, props.parentRowSpace]} bounds={bounds} diff --git a/app/client/src/constants/ReduxActionConstants.tsx b/app/client/src/constants/ReduxActionConstants.tsx index 8c6ef760b0..10341f155a 100644 --- a/app/client/src/constants/ReduxActionConstants.tsx +++ b/app/client/src/constants/ReduxActionConstants.tsx @@ -1,5 +1,4 @@ import { WidgetProps, WidgetCardProps } from "widgets/BaseWidget"; -import { RefObject } from "react"; import { PageAction } from "constants/ActionConstants"; export const ReduxActionTypes: { [key: string]: string } = { @@ -220,7 +219,6 @@ export interface UpdateCanvasPayload { export interface ShowPropertyPanePayload { widgetId: string; - node: RefObject; toggle: boolean; } diff --git a/app/client/src/pages/Editor/Popper.tsx b/app/client/src/pages/Editor/Popper.tsx index f11941dd3a..7d77ef08cc 100644 --- a/app/client/src/pages/Editor/Popper.tsx +++ b/app/client/src/pages/Editor/Popper.tsx @@ -23,7 +23,6 @@ const PopperWrapper = styled(PaneWrapper)` export default (props: PopperProps) => { const contentRef = useRef(null); useEffect(() => { - //TODO(abhinav): optimize this, remove previous Popper instance. const parentElement = props.targetNode && props.targetNode.parentElement; if ( parentElement && @@ -31,7 +30,7 @@ export default (props: PopperProps) => { props.targetNode && props.isOpen ) { - new PopperJS( + const _popper = new PopperJS( props.targetNode, (contentRef.current as unknown) as Element, { @@ -49,6 +48,10 @@ export default (props: PopperProps) => { }, }, ); + _popper.disableEventListeners(); + return () => { + _popper.destroy(); + }; } }, [props.targetNode, props.isOpen]); return createPortal( diff --git a/app/client/src/pages/Editor/WidgetsEditor.tsx b/app/client/src/pages/Editor/WidgetsEditor.tsx index dcac336983..1e1d46a677 100644 --- a/app/client/src/pages/Editor/WidgetsEditor.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor.tsx @@ -100,8 +100,16 @@ const mapDispatchToProps = (dispatch: any) => { dsl: ContainerWidgetProps, ) => dispatch(savePage(pageId, layoutId, dsl)), showPropertyPane: (widgetId?: string, toggle = false) => { + // If widgetId is not provided, we don't show the property pane. + // However, if toggle is provided, it will be a start or end of an action + // toggle payload is handled in SHOW_PROPERTY_PANE action. + // Ergo, when eithter widgetId or toggle are provided, SHOW_PROPERTY_PANE + // Else, HIDE_PROPERTY_PANE dispatch({ - type: ReduxActionTypes.SHOW_PROPERTY_PANE, + type: + widgetId || toggle + ? ReduxActionTypes.SHOW_PROPERTY_PANE + : ReduxActionTypes.HIDE_PROPERTY_PANE, payload: { widgetId, toggle }, }); }, diff --git a/app/client/src/reducers/uiReducers/propertyPaneReducer.tsx b/app/client/src/reducers/uiReducers/propertyPaneReducer.tsx index af90afa52a..80a041d802 100644 --- a/app/client/src/reducers/uiReducers/propertyPaneReducer.tsx +++ b/app/client/src/reducers/uiReducers/propertyPaneReducer.tsx @@ -15,17 +15,39 @@ const propertyPaneReducer = createReducer(initialState, { state: PropertyPaneReduxState, action: ReduxAction, ) => { - const { widgetId } = action.payload; - return { ...state, widgetId, isVisible: true }; + const { widgetId, toggle } = action.payload; + // If toggle is true, an action has started or ended. + // If the action has started, isVisibleBeforeAction should be undefined + // If the action has ended, isVisibleBeforeAction should be the visible state + // of the property pane to use. + let isVisibleBeforeAction = undefined; + if (toggle && state.isVisibleBeforeAction === undefined) { + isVisibleBeforeAction = state.isVisible; + } + + // If toggle is true, an action has started or ended + // If isVisibleBeforeAction is undefined, show property pane + // If isVisibleBeforeAction is defined, set visibility to its value + let isVisible = true; + if (toggle && state.isVisibleBeforeAction === undefined) { + isVisible = false; + } else if (toggle && state.isVisibleBeforeAction !== undefined) { + isVisible = state.isVisibleBeforeAction; + } else { + isVisible = true; + } + + return { ...state, widgetId, isVisible, isVisibleBeforeAction }; }, [ReduxActionTypes.HIDE_PROPERTY_PANE]: (state: PropertyPaneReduxState) => { - return { ...state, isVisible: false }; + return { ...state, isVisible: false, isVisibleBeforeAction: undefined }; }, }); export interface PropertyPaneReduxState { widgetId?: string; isVisible: boolean; + isVisibleBeforeAction?: boolean; } export default propertyPaneReducer;