Merge branch 'fix/widget-boundaries' into 'release'

Widget boundaries

See merge request theappsmith/internal-tools-client!225
This commit is contained in:
Abhinav Jha 2020-01-08 13:46:16 +00:00
commit 22b3a50e6c
6 changed files with 47 additions and 26 deletions

View File

@ -1,7 +1,6 @@
import React, { useContext } from "react"; import React, { useContext } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import { FocusContext, DragResizeContext } from "pages/Editor/CanvasContexts";
import { DraggableComponentContext } from "components/editorComponents/DraggableComponent";
const PositionStyle = styled.div<{ selected?: boolean }>` const PositionStyle = styled.div<{ selected?: boolean }>`
position: absolute; position: absolute;
@ -30,8 +29,8 @@ type WidgetNameComponentProps = {
export const WidgetNameComponent = (props: WidgetNameComponentProps) => { export const WidgetNameComponent = (props: WidgetNameComponentProps) => {
const { focusedWidget, selectedWidget } = useContext(FocusContext); const { focusedWidget, selectedWidget } = useContext(FocusContext);
const { isDragging } = useContext(DraggableComponentContext); const { isResizing, isDragging } = useContext(DragResizeContext);
const { isResizing } = useContext(ResizingContext);
const showWidgetName = const showWidgetName =
(focusedWidget === props.widgetId || selectedWidget === props.widgetId) && (focusedWidget === props.widgetId || selectedWidget === props.widgetId) &&
!isDragging && !isDragging &&

View File

@ -1,10 +1,10 @@
import React, { useContext, createContext, Context } from "react"; import React, { useContext } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { WidgetProps, WidgetOperations } from "widgets/BaseWidget"; import { WidgetProps, WidgetOperations } from "widgets/BaseWidget";
import { ContainerWidgetProps } from "widgets/ContainerWidget"; import { ContainerWidgetProps } from "widgets/ContainerWidget";
import { useDrag, DragPreviewImage, DragSourceMonitor } from "react-dnd"; import { useDrag, DragPreviewImage, DragSourceMonitor } from "react-dnd";
import blankImage from "assets/images/blank.png"; import blankImage from "assets/images/blank.png";
import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import { FocusContext, DragResizeContext } from "pages/Editor/CanvasContexts";
import { EditorContext } from "components/editorComponents/EditorContextProvider"; import { EditorContext } from "components/editorComponents/EditorContextProvider";
import { ControlIcons } from "icons/ControlIcons"; import { ControlIcons } from "icons/ControlIcons";
import { Tooltip } from "@blueprintjs/core"; import { Tooltip } from "@blueprintjs/core";
@ -12,7 +12,7 @@ import { WIDGET_CLASSNAME_PREFIX } from "constants/WidgetConstants";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { PropertyPaneReduxState } from "reducers/uiReducers/propertyPaneReducer"; import { PropertyPaneReduxState } from "reducers/uiReducers/propertyPaneReducer";
import { AppState } from "reducers"; import { AppState } from "reducers";
import { theme } from "constants/DefaultTheme"; import { theme, getColorWithOpacity } from "constants/DefaultTheme";
import { Colors } from "constants/Colors"; import { Colors } from "constants/Colors";
// FontSizes array in DefaultTheme.tsx // FontSizes array in DefaultTheme.tsx
@ -30,6 +30,17 @@ const DraggableWrapper = styled.div<{ show: boolean }>`
cursor: grab; cursor: grab;
`; `;
const WidgetBoundaries = styled.div`
left: 0;
right: 0;
z-index: 1;
width: 100%;
height: 100%;
border: 1px dashed
${props => getColorWithOpacity(props.theme.colors.textAnchor, 0.5)};
position: absolute;
`;
const DragHandle = styled.div` const DragHandle = styled.div`
position: absolute; position: absolute;
left: 0px; left: 0px;
@ -69,9 +80,6 @@ const deleteControlIcon = ControlIcons.DELETE_CONTROL({
type DraggableComponentProps = ContainerWidgetProps<WidgetProps>; type DraggableComponentProps = ContainerWidgetProps<WidgetProps>;
export const DraggableComponentContext: Context<{
isDragging?: boolean;
}> = createContext({});
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
const DraggableComponent = (props: DraggableComponentProps) => { const DraggableComponent = (props: DraggableComponentProps) => {
@ -104,7 +112,9 @@ const DraggableComponent = (props: DraggableComponentProps) => {
const { updateWidget } = useContext(EditorContext); const { updateWidget } = useContext(EditorContext);
const { isResizing } = useContext(ResizingContext); const { isResizing, setIsDragging, isDragging } = useContext(
DragResizeContext,
);
const deleteWidget = () => { const deleteWidget = () => {
showPropertyPane && showPropertyPane(); showPropertyPane && showPropertyPane();
@ -124,28 +134,34 @@ const DraggableComponent = (props: DraggableComponentProps) => {
e.stopPropagation(); e.stopPropagation();
}; };
const [{ isDragging }, drag, preview] = useDrag({ const [{ isCurrentWidgetDragging }, drag, preview] = useDrag({
item: props as WidgetProps, item: props as WidgetProps,
collect: (monitor: DragSourceMonitor) => ({ collect: (monitor: DragSourceMonitor) => ({
isDragging: monitor.isDragging(), isCurrentWidgetDragging: monitor.isDragging(),
}), }),
begin: () => { begin: () => {
showPropertyPane && showPropertyPane(undefined, true); showPropertyPane && showPropertyPane(undefined, true);
selectWidget && selectWidget(props.widgetId); selectWidget && selectWidget(props.widgetId);
setIsDragging && setIsDragging(props.widgetId);
}, },
end: (widget, monitor) => { end: (widget, monitor) => {
if (monitor.didDrop()) { if (monitor.didDrop()) {
showPropertyPane && showPropertyPane(props.widgetId, true); showPropertyPane && showPropertyPane(props.widgetId, true);
} }
setIsDragging && setIsDragging(undefined);
}, },
canDrag: () => { canDrag: () => {
return !isResizing; return !isResizing;
}, },
}); });
const isResizingOrDragging =
selectedWidget !== props.widgetId && (!!isResizing || !!isDragging);
return ( return (
<DraggableComponentContext.Provider value={{ isDragging }}> <React.Fragment>
<DragPreviewImage connect={preview} src={blankImage} /> <DragPreviewImage connect={preview} src={blankImage} />
<DraggableWrapper <DraggableWrapper
className={WIDGET_CLASSNAME_PREFIX + props.widgetId} className={WIDGET_CLASSNAME_PREFIX + props.widgetId}
ref={drag} ref={drag}
@ -177,7 +193,7 @@ const DraggableComponent = (props: DraggableComponentProps) => {
!isResizing !isResizing
} }
style={{ style={{
display: isDragging ? "none" : "flex", display: isCurrentWidgetDragging ? "none" : "flex",
flexDirection: "column", flexDirection: "column",
position: "absolute", position: "absolute",
left: 0, left: 0,
@ -189,6 +205,9 @@ const DraggableComponent = (props: DraggableComponentProps) => {
zIndex: props.widgetId === selectedWidget ? 3 : 1, zIndex: props.widgetId === selectedWidget ? 3 : 1,
}} }}
> >
<WidgetBoundaries
style={{ display: isResizingOrDragging ? "block" : "none" }}
/>
{props.children} {props.children}
<DragHandle className="control" ref={drag}> <DragHandle className="control" ref={drag}>
<Tooltip content="Move" hoverOpenDelay={500}> <Tooltip content="Move" hoverOpenDelay={500}>
@ -206,7 +225,7 @@ const DraggableComponent = (props: DraggableComponentProps) => {
</Tooltip> </Tooltip>
</EditControl> </EditControl>
</DraggableWrapper> </DraggableWrapper>
</DraggableComponentContext.Provider> </React.Fragment>
); );
}; };

View File

@ -5,7 +5,7 @@ import { WidgetConfigProps } from "reducers/entityReducers/widgetConfigReducer";
import WidgetFactory from "utils/WidgetFactory"; import WidgetFactory from "utils/WidgetFactory";
import { widgetOperationParams, noCollision } from "utils/WidgetPropsUtils"; import { widgetOperationParams, noCollision } from "utils/WidgetPropsUtils";
import { EditorContext } from "components/editorComponents/EditorContextProvider"; import { EditorContext } from "components/editorComponents/EditorContextProvider";
import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import { FocusContext, DragResizeContext } from "pages/Editor/CanvasContexts";
import DragLayerComponent from "./DragLayerComponent"; import DragLayerComponent from "./DragLayerComponent";
@ -27,7 +27,7 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 }); const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 });
const { updateWidget, occupiedSpaces } = useContext(EditorContext); const { updateWidget, occupiedSpaces } = useContext(EditorContext);
const { selectWidget, showPropertyPane } = useContext(FocusContext); const { selectWidget, showPropertyPane } = useContext(FocusContext);
const { isResizing } = useContext(ResizingContext); const { isResizing } = useContext(DragResizeContext);
const spacesOccupiedBySiblingWidgets = const spacesOccupiedBySiblingWidgets =
occupiedSpaces && occupiedSpaces[props.widgetId] occupiedSpaces && occupiedSpaces[props.widgetId]
? occupiedSpaces[props.widgetId] ? occupiedSpaces[props.widgetId]

View File

@ -4,8 +4,7 @@ import { XYCoord } from "react-dnd";
import { getAbsolutePixels } from "utils/helpers"; import { getAbsolutePixels } from "utils/helpers";
import { WidgetOperations, WidgetRowCols } from "widgets/BaseWidget"; import { WidgetOperations, WidgetRowCols } from "widgets/BaseWidget";
import { EditorContext } from "components/editorComponents/EditorContextProvider"; import { EditorContext } from "components/editorComponents/EditorContextProvider";
import { FocusContext, ResizingContext } from "pages/Editor/CanvasContexts"; import { FocusContext, DragResizeContext } from "pages/Editor/CanvasContexts";
import { DraggableComponentContext } from "./DraggableComponent";
import { generateClassName } from "utils/generators"; import { generateClassName } from "utils/generators";
import ResizableContainer, { import ResizableContainer, {
@ -23,8 +22,7 @@ import {
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
export const ResizableComponent = memo((props: ResizableComponentProps) => { export const ResizableComponent = memo((props: ResizableComponentProps) => {
// Fetch information from the context // Fetch information from the context
const { isDragging } = useContext(DraggableComponentContext); const { isDragging, setIsResizing } = useContext(DragResizeContext);
const { setIsResizing } = useContext(ResizingContext);
const { updateWidget, occupiedSpaces } = useContext(EditorContext); const { updateWidget, occupiedSpaces } = useContext(EditorContext);
const { const {
showPropertyPane, showPropertyPane,

View File

@ -5,7 +5,7 @@ import { ContainerWidgetProps } from "widgets/ContainerWidget";
import { WidgetProps } from "widgets/BaseWidget"; import { WidgetProps } from "widgets/BaseWidget";
import PropertyPane from "./PropertyPane"; import PropertyPane from "./PropertyPane";
import ArtBoard from "pages/common/ArtBoard"; import ArtBoard from "pages/common/ArtBoard";
import { ResizingContext, FocusContext } from "./CanvasContexts"; import { DragResizeContext, FocusContext } from "./CanvasContexts";
interface CanvasProps { interface CanvasProps {
dsl: ContainerWidgetProps<WidgetProps>; dsl: ContainerWidgetProps<WidgetProps>;
@ -20,9 +20,12 @@ const Canvas = (props: CanvasProps) => {
const [selectedWidget, selectWidget] = useState(); const [selectedWidget, selectWidget] = useState();
const [focusedWidget, focusWidget] = useState(); const [focusedWidget, focusWidget] = useState();
const [isResizing, setIsResizing] = useState(false); const [isResizing, setIsResizing] = useState(false);
const [isDragging, setIsDragging] = useState(false);
try { try {
return ( return (
<ResizingContext.Provider value={{ isResizing, setIsResizing }}> <DragResizeContext.Provider
value={{ isResizing, setIsResizing, isDragging, setIsDragging }}
>
<FocusContext.Provider <FocusContext.Provider
value={{ value={{
selectedWidget, selectedWidget,
@ -38,7 +41,7 @@ const Canvas = (props: CanvasProps) => {
WidgetFactory.createWidget(props.dsl, RenderModes.CANVAS)} WidgetFactory.createWidget(props.dsl, RenderModes.CANVAS)}
</ArtBoard> </ArtBoard>
</FocusContext.Provider> </FocusContext.Provider>
</ResizingContext.Provider> </DragResizeContext.Provider>
); );
} catch (error) { } catch (error) {
console.log("Error rendering DSL", error); console.log("Error rendering DSL", error);

View File

@ -8,7 +8,9 @@ export const FocusContext: Context<{
showPropertyPane?: (widgetId?: string, toggle?: boolean) => void; showPropertyPane?: (widgetId?: string, toggle?: boolean) => void;
}> = createContext({}); }> = createContext({});
export const ResizingContext: Context<{ export const DragResizeContext: Context<{
isResizing?: boolean; isResizing?: boolean;
setIsResizing?: Function; setIsResizing?: Function;
isDragging?: boolean;
setIsDragging?: Function;
}> = createContext({}); }> = createContext({});