Optimize popper creation and destructions. Preserve property pane visibility before and after actions.
This commit is contained in:
parent
40d160fb78
commit
9d7eaaca80
|
|
@ -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 ? (
|
||||
<PositionStyle selected={selectedWidget === props.widgetId}>
|
||||
<pre>{props.widgetName}</pre>
|
||||
</PositionStyle>
|
||||
|
|
|
|||
|
|
@ -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: () => {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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<HTMLDivElement>;
|
||||
toggle: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -100,8 +100,16 @@ const mapDispatchToProps = (dispatch: any) => {
|
|||
dsl: ContainerWidgetProps<WidgetProps>,
|
||||
) => 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 },
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,17 +15,39 @@ const propertyPaneReducer = createReducer(initialState, {
|
|||
state: PropertyPaneReduxState,
|
||||
action: ReduxAction<ShowPropertyPanePayload>,
|
||||
) => {
|
||||
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user