Fix editor stacking context
This commit is contained in:
parent
81272a0839
commit
74ee90d816
|
|
@ -37,7 +37,7 @@
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>React App</title>
|
<title>Appsmith | Editor</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,15 @@ export type Theme = {
|
||||||
borders: { thickness: string; style: "dashed" | "solid"; color: Color }[];
|
borders: { thickness: string; style: "dashed" | "solid"; color: Color }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getColorWithOpacity = (color: Color, opacity: number) => {
|
||||||
|
color = color.slice(1);
|
||||||
|
const val = parseInt(color, 16);
|
||||||
|
const r = (val >> 16) & 255;
|
||||||
|
const g = (val >> 8) & 255;
|
||||||
|
const b = val & 255;
|
||||||
|
return `rgba(${r},${g},${b},${opacity})`;
|
||||||
|
};
|
||||||
|
|
||||||
export const theme: Theme = {
|
export const theme: Theme = {
|
||||||
radii: [0, 4, 8, 10, 20, 50],
|
radii: [0, 4, 8, 10, 20, 50],
|
||||||
fontSizes: [0, 10, 12, 14, 16, 18, 24, 28, 32, 48, 64],
|
fontSizes: [0, 10, 12, 14, 16, 18, 24, 28, 32, 48, 64],
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import DropTargetMask from "./DropTargetMask";
|
||||||
const WrappedDragLayer = styled.div`
|
const WrappedDragLayer = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 10;
|
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -26,6 +25,8 @@ type DragLayerProps = {
|
||||||
occupiedSpaces: OccupiedSpace[] | null;
|
occupiedSpaces: OccupiedSpace[] | null;
|
||||||
onBoundsUpdate: Function;
|
onBoundsUpdate: Function;
|
||||||
isOver: boolean;
|
isOver: boolean;
|
||||||
|
parentRows?: number;
|
||||||
|
parentCols?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DragLayerComponent = (props: DragLayerProps) => {
|
const DragLayerComponent = (props: DragLayerProps) => {
|
||||||
|
|
@ -41,6 +42,8 @@ const DragLayerComponent = (props: DragLayerProps) => {
|
||||||
monitor.getItem(),
|
monitor.getItem(),
|
||||||
props.dropTargetOffset,
|
props.dropTargetOffset,
|
||||||
props.occupiedSpaces,
|
props.occupiedSpaces,
|
||||||
|
props.parentRows,
|
||||||
|
props.parentCols,
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ const DraggableWrapper = styled.div<{ show: boolean }>`
|
||||||
display: ${props => (props.show ? "block" : "none")};
|
display: ${props => (props.show ? "block" : "none")};
|
||||||
}
|
}
|
||||||
display: block;
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DragHandle = styled.div`
|
const DragHandle = styled.div`
|
||||||
|
|
@ -27,7 +29,6 @@ const DragHandle = styled.div`
|
||||||
cursor: move;
|
cursor: move;
|
||||||
display: none;
|
display: none;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
z-index: 11;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const DeleteControl = styled.div`
|
const DeleteControl = styled.div`
|
||||||
|
|
@ -36,7 +37,6 @@ const DeleteControl = styled.div`
|
||||||
top: -${props => props.theme.fontSizes[CONTROL_THEME_FONTSIZE_INDEX] / 2}px;
|
top: -${props => props.theme.fontSizes[CONTROL_THEME_FONTSIZE_INDEX] / 2}px;
|
||||||
display: none;
|
display: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 11;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const moveControlIcon = ControlIcons.MOVE_CONTROL({
|
const moveControlIcon = ControlIcons.MOVE_CONTROL({
|
||||||
|
|
@ -100,13 +100,13 @@ const DraggableComponent = (props: DraggableComponentProps) => {
|
||||||
props.style.componentHeight + (props.style.heightUnit || "px"),
|
props.style.componentHeight + (props.style.heightUnit || "px"),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{props.children}
|
||||||
<DragHandle className="control" ref={drag}>
|
<DragHandle className="control" ref={drag}>
|
||||||
{moveControlIcon}
|
{moveControlIcon}
|
||||||
</DragHandle>
|
</DragHandle>
|
||||||
<DeleteControl className="control" onClick={deleteWidget}>
|
<DeleteControl className="control" onClick={deleteWidget}>
|
||||||
{deleteControlIcon}
|
{deleteControlIcon}
|
||||||
</DeleteControl>
|
</DeleteControl>
|
||||||
{props.children}
|
|
||||||
</DraggableWrapper>
|
</DraggableWrapper>
|
||||||
</ResizingContext.Provider>
|
</ResizingContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext } from "react";
|
||||||
import { WidgetProps } from "../widgets/BaseWidget";
|
import { WidgetProps } from "../widgets/BaseWidget";
|
||||||
import { OccupiedSpace } from "../widgets/ContainerWidget";
|
import { OccupiedSpaceContext } from "../widgets/ContainerWidget";
|
||||||
import { WidgetConfigProps } from "../reducers/entityReducers/widgetConfigReducer";
|
import { WidgetConfigProps } from "../reducers/entityReducers/widgetConfigReducer";
|
||||||
import { useDrop, XYCoord } from "react-dnd";
|
import { useDrop, XYCoord } from "react-dnd";
|
||||||
import { ContainerProps } from "./ContainerComponent";
|
import { ContainerProps } from "./ContainerComponent";
|
||||||
|
|
@ -15,7 +15,6 @@ type DropTargetComponentProps = ContainerProps & {
|
||||||
snapRows?: number;
|
snapRows?: number;
|
||||||
snapColumnSpace: number;
|
snapColumnSpace: number;
|
||||||
snapRowSpace: number;
|
snapRowSpace: number;
|
||||||
occupiedSpaces: OccupiedSpace[] | null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type DropTargetBounds = {
|
type DropTargetBounds = {
|
||||||
|
|
@ -29,6 +28,7 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
// Hook to keep the offset of the drop target container in state
|
// Hook to keep the offset of the drop target container in state
|
||||||
const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 });
|
const [dropTargetOffset, setDropTargetOffset] = useState({ x: 0, y: 0 });
|
||||||
const { updateWidget } = useContext(WidgetFunctionsContext);
|
const { updateWidget } = useContext(WidgetFunctionsContext);
|
||||||
|
const occupiedSpaces = useContext(OccupiedSpaceContext);
|
||||||
// Make this component a drop target
|
// Make this component a drop target
|
||||||
const [{ isOver, isExactlyOver }, drop] = useDrop({
|
const [{ isOver, isExactlyOver }, drop] = useDrop({
|
||||||
accept: Object.values(WidgetFactory.getWidgetTypes()),
|
accept: Object.values(WidgetFactory.getWidgetTypes()),
|
||||||
|
|
@ -69,7 +69,9 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
props.snapRowSpace,
|
props.snapRowSpace,
|
||||||
widget,
|
widget,
|
||||||
dropTargetOffset,
|
dropTargetOffset,
|
||||||
props.occupiedSpaces,
|
occupiedSpaces,
|
||||||
|
props.snapRows,
|
||||||
|
props.snapColumns,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -88,7 +90,6 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={drop}
|
ref={drop}
|
||||||
className="dropTarget"
|
|
||||||
style={{
|
style={{
|
||||||
position: "relative",
|
position: "relative",
|
||||||
left: 0,
|
left: 0,
|
||||||
|
|
@ -99,7 +100,6 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
? props.style.componentWidth + (props.style.widthUnit || "px")
|
? props.style.componentWidth + (props.style.widthUnit || "px")
|
||||||
: "100%",
|
: "100%",
|
||||||
top: 0,
|
top: 0,
|
||||||
background: "white",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DragLayerComponent
|
<DragLayerComponent
|
||||||
|
|
@ -109,8 +109,10 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
visible={isOver}
|
visible={isOver}
|
||||||
isOver={isExactlyOver}
|
isOver={isExactlyOver}
|
||||||
dropTargetOffset={dropTargetOffset}
|
dropTargetOffset={dropTargetOffset}
|
||||||
occupiedSpaces={props.occupiedSpaces}
|
occupiedSpaces={occupiedSpaces}
|
||||||
onBoundsUpdate={handleBoundsUpdate}
|
onBoundsUpdate={handleBoundsUpdate}
|
||||||
|
parentRows={props.snapRows}
|
||||||
|
parentCols={props.snapColumns}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{props.children}
|
{props.children}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ export const DropTargetMaskWrapper = styled.div<DropTargetMaskProps>`
|
||||||
right: 0;
|
right: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: white;
|
|
||||||
${props =>
|
${props =>
|
||||||
props.showGrid &&
|
props.showGrid &&
|
||||||
css`
|
css`
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,9 @@ import { theme } from "../constants/DefaultTheme";
|
||||||
|
|
||||||
const DropZoneWrapper = styled.div`
|
const DropZoneWrapper = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
|
||||||
background: ${props => props.theme.colors.hover};
|
background: ${props => props.theme.colors.hover};
|
||||||
border: 1px dashed ${props => props.theme.colors.textAnchor};
|
border: 1px dashed ${props => props.theme.colors.textAnchor};
|
||||||
opacity: 0.7;
|
opacity: 0.6;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type DropZoneProps = {
|
type DropZoneProps = {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
import React, { useContext, CSSProperties } from "react";
|
import React, { useContext, CSSProperties, useState } from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Rnd } from "react-rnd";
|
import { Rnd } from "react-rnd";
|
||||||
import { XYCoord } from "react-dnd";
|
import { XYCoord } from "react-dnd";
|
||||||
import { WidgetProps, WidgetOperations } from "../widgets/BaseWidget";
|
import { WidgetProps, WidgetOperations } from "../widgets/BaseWidget";
|
||||||
|
import { OccupiedSpaceContext } from "../widgets/ContainerWidget";
|
||||||
import { ContainerProps, ParentBoundsContext } from "./ContainerComponent";
|
import { ContainerProps, ParentBoundsContext } from "./ContainerComponent";
|
||||||
|
import { isDropZoneOccupied } from "../utils/WidgetPropsUtils";
|
||||||
import { ResizingContext } from "./DraggableComponent";
|
import { ResizingContext } from "./DraggableComponent";
|
||||||
|
import { FocusContext } from "../pages/Editor/Canvas";
|
||||||
import { WidgetFunctionsContext } from "../pages/Editor";
|
import { WidgetFunctionsContext } from "../pages/Editor";
|
||||||
|
import { theme, getColorWithOpacity } from "../constants/DefaultTheme";
|
||||||
|
|
||||||
export type ResizableComponentProps = WidgetProps & ContainerProps;
|
export type ResizableComponentProps = WidgetProps & ContainerProps;
|
||||||
|
|
||||||
|
|
@ -18,28 +22,23 @@ const handleStyles: {
|
||||||
top: {
|
top: {
|
||||||
height: "30px",
|
height: "30px",
|
||||||
top: "-15px",
|
top: "-15px",
|
||||||
zIndex: 11,
|
|
||||||
},
|
},
|
||||||
bottom: {
|
bottom: {
|
||||||
height: "30px",
|
height: "30px",
|
||||||
bottom: "-15px",
|
bottom: "-15px",
|
||||||
zIndex: 11,
|
|
||||||
},
|
},
|
||||||
left: {
|
left: {
|
||||||
width: "30px",
|
width: "30px",
|
||||||
left: "-15px",
|
left: "-15px",
|
||||||
zIndex: 11,
|
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
width: "30px",
|
width: "30px",
|
||||||
right: "-15px",
|
right: "-15px",
|
||||||
zIndex: 11,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ResizableContainer = styled(Rnd)`
|
const ResizableContainer = styled(Rnd)`
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
|
||||||
border: ${props => {
|
border: ${props => {
|
||||||
return Object.values(props.theme.borders[0]).join(" ");
|
return Object.values(props.theme.borders[0]).join(" ");
|
||||||
}};
|
}};
|
||||||
|
|
@ -50,7 +49,6 @@ const ResizableContainer = styled(Rnd)`
|
||||||
width: ${props => props.theme.spaces[2]}px;
|
width: ${props => props.theme.spaces[2]}px;
|
||||||
height: ${props => props.theme.spaces[2]}px;
|
height: ${props => props.theme.spaces[2]}px;
|
||||||
border-radius: ${props => props.theme.radii[5]}%;
|
border-radius: ${props => props.theme.radii[5]}%;
|
||||||
z-index: 9;
|
|
||||||
background: ${props => props.theme.colors.containerBorder};
|
background: ${props => props.theme.colors.containerBorder};
|
||||||
}
|
}
|
||||||
&:after {
|
&:after {
|
||||||
|
|
@ -68,10 +66,49 @@ export const ResizableComponent = (props: ResizableComponentProps) => {
|
||||||
const { setIsResizing } = useContext(ResizingContext);
|
const { setIsResizing } = useContext(ResizingContext);
|
||||||
const { boundingParent } = useContext(ParentBoundsContext);
|
const { boundingParent } = useContext(ParentBoundsContext);
|
||||||
const { updateWidget } = useContext(WidgetFunctionsContext);
|
const { updateWidget } = useContext(WidgetFunctionsContext);
|
||||||
|
const { setFocus } = useContext(FocusContext);
|
||||||
|
const occupiedSpaces = useContext(OccupiedSpaceContext);
|
||||||
|
const [isColliding, setIsColliding] = useState(false);
|
||||||
|
|
||||||
let bounds = "body";
|
let bounds = "body";
|
||||||
if (boundingParent && boundingParent.current) {
|
if (boundingParent && boundingParent.current) {
|
||||||
bounds = "." + boundingParent.current.className.split(" ")[1];
|
bounds = "." + boundingParent.current.className.split(" ")[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const checkForCollision = (
|
||||||
|
e: Event,
|
||||||
|
dir: any,
|
||||||
|
ref: any,
|
||||||
|
delta: { width: number; height: number },
|
||||||
|
position: XYCoord,
|
||||||
|
) => {
|
||||||
|
const left = props.leftColumn + position.x / props.parentColumnSpace;
|
||||||
|
const top = props.topRow + position.y / props.parentRowSpace;
|
||||||
|
|
||||||
|
const right =
|
||||||
|
props.rightColumn + (delta.width + position.x) / props.parentColumnSpace;
|
||||||
|
const bottom =
|
||||||
|
props.bottomRow + (delta.height + position.y) / props.parentRowSpace;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isDropZoneOccupied(
|
||||||
|
{
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
bottom,
|
||||||
|
right,
|
||||||
|
},
|
||||||
|
props.widgetId,
|
||||||
|
occupiedSpaces,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setIsColliding(true);
|
||||||
|
} else {
|
||||||
|
if (!!isColliding) {
|
||||||
|
setIsColliding(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
const updateSize = (
|
const updateSize = (
|
||||||
e: Event,
|
e: Event,
|
||||||
dir: any,
|
dir: any,
|
||||||
|
|
@ -80,6 +117,7 @@ export const ResizableComponent = (props: ResizableComponentProps) => {
|
||||||
position: XYCoord,
|
position: XYCoord,
|
||||||
) => {
|
) => {
|
||||||
setIsResizing && setIsResizing(false);
|
setIsResizing && setIsResizing(false);
|
||||||
|
setFocus && setFocus(props.widgetId);
|
||||||
const leftColumn = props.leftColumn + position.x / props.parentColumnSpace;
|
const leftColumn = props.leftColumn + position.x / props.parentColumnSpace;
|
||||||
const topRow = props.topRow + position.y / props.parentRowSpace;
|
const topRow = props.topRow + position.y / props.parentRowSpace;
|
||||||
|
|
||||||
|
|
@ -88,6 +126,7 @@ export const ResizableComponent = (props: ResizableComponentProps) => {
|
||||||
const bottomRow =
|
const bottomRow =
|
||||||
props.bottomRow + (delta.height + position.y) / props.parentRowSpace;
|
props.bottomRow + (delta.height + position.y) / props.parentRowSpace;
|
||||||
|
|
||||||
|
if (!isColliding) {
|
||||||
updateWidget &&
|
updateWidget &&
|
||||||
updateWidget(WidgetOperations.RESIZE, props.widgetId, {
|
updateWidget(WidgetOperations.RESIZE, props.widgetId, {
|
||||||
leftColumn,
|
leftColumn,
|
||||||
|
|
@ -95,6 +134,8 @@ export const ResizableComponent = (props: ResizableComponentProps) => {
|
||||||
topRow,
|
topRow,
|
||||||
bottomRow,
|
bottomRow,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
setIsColliding(false);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<ResizableContainer
|
<ResizableContainer
|
||||||
|
|
@ -109,8 +150,14 @@ export const ResizableComponent = (props: ResizableComponentProps) => {
|
||||||
disableDragging
|
disableDragging
|
||||||
minWidth={props.parentColumnSpace}
|
minWidth={props.parentColumnSpace}
|
||||||
minHeight={props.parentRowSpace}
|
minHeight={props.parentRowSpace}
|
||||||
style={{ ...props.style }}
|
style={{
|
||||||
|
...props.style,
|
||||||
|
background: isColliding
|
||||||
|
? getColorWithOpacity(theme.colors.error, 0.6)
|
||||||
|
: props.style.backgroundColor,
|
||||||
|
}}
|
||||||
onResizeStop={updateSize}
|
onResizeStop={updateSize}
|
||||||
|
onResize={checkForCollision}
|
||||||
onResizeStart={() => {
|
onResizeStart={() => {
|
||||||
setIsResizing && setIsResizing(true);
|
setIsResizing && setIsResizing(true);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const ArtBoard = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
background: white;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface CanvasProps {
|
interface CanvasProps {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ const CanvasContainer = styled.section`
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 11;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,13 @@ const areIntersecting = (r1: Rect, r2: Rect) => {
|
||||||
|
|
||||||
export const isDropZoneOccupied = (
|
export const isDropZoneOccupied = (
|
||||||
offset: Rect,
|
offset: Rect,
|
||||||
widget: WidgetProps,
|
widgetId: string,
|
||||||
occupied: OccupiedSpace[] | null,
|
occupied: OccupiedSpace[] | null,
|
||||||
) => {
|
) => {
|
||||||
if (occupied) {
|
if (occupied) {
|
||||||
occupied = occupied.filter(widgetDetails => {
|
occupied = occupied.filter(widgetDetails => {
|
||||||
return (
|
return (
|
||||||
widgetDetails.id !== widget.widgetId &&
|
widgetDetails.id !== widgetId && widgetDetails.parentId !== widgetId
|
||||||
widgetDetails.parentId !== widget.widgetId
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
for (let i = 0; i < occupied.length; i++) {
|
for (let i = 0; i < occupied.length; i++) {
|
||||||
|
|
@ -86,6 +85,16 @@ export const isDropZoneOccupied = (
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isWidgetOverflowingParentBounds = (
|
||||||
|
parentRowCols: { rows?: number; cols?: number },
|
||||||
|
offset: Rect,
|
||||||
|
) => {
|
||||||
|
return (
|
||||||
|
(parentRowCols.cols || GridDefaults.DEFAULT_GRID_COLUMNS) < offset.right ||
|
||||||
|
(parentRowCols.rows || GridDefaults.DEFAULT_GRID_ROWS) < offset.bottom
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const noCollision = (
|
export const noCollision = (
|
||||||
clientOffset: XYCoord,
|
clientOffset: XYCoord,
|
||||||
colWidth: number,
|
colWidth: number,
|
||||||
|
|
@ -93,6 +102,8 @@ export const noCollision = (
|
||||||
widget: WidgetProps & Partial<WidgetConfigProps>,
|
widget: WidgetProps & Partial<WidgetConfigProps>,
|
||||||
dropTargetOffset: XYCoord,
|
dropTargetOffset: XYCoord,
|
||||||
occupiedSpaces: OccupiedSpace[] | null,
|
occupiedSpaces: OccupiedSpace[] | null,
|
||||||
|
rows?: number,
|
||||||
|
cols?: number,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (clientOffset && dropTargetOffset && widget) {
|
if (clientOffset && dropTargetOffset && widget) {
|
||||||
const [left, top] = getDropZoneOffsets(
|
const [left, top] = getDropZoneOffsets(
|
||||||
|
|
@ -113,7 +124,10 @@ export const noCollision = (
|
||||||
top,
|
top,
|
||||||
bottom: top + widgetHeight,
|
bottom: top + widgetHeight,
|
||||||
};
|
};
|
||||||
return !isDropZoneOccupied(currentOffset, widget, occupiedSpaces);
|
return (
|
||||||
|
!isDropZoneOccupied(currentOffset, widget.widgetId, occupiedSpaces) &&
|
||||||
|
!isWidgetOverflowingParentBounds({ rows, cols }, currentOffset)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react";
|
import React, { createContext, Context } from "react";
|
||||||
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget";
|
||||||
import ContainerComponent from "../editorComponents/ContainerComponent";
|
import ContainerComponent from "../editorComponents/ContainerComponent";
|
||||||
import { ContainerOrientation, WidgetType } from "../constants/WidgetConstants";
|
import { ContainerOrientation, WidgetType } from "../constants/WidgetConstants";
|
||||||
|
|
@ -11,6 +11,9 @@ import DraggableComponent from "../editorComponents/DraggableComponent";
|
||||||
import ResizableComponent from "../editorComponents/ResizableComponent";
|
import ResizableComponent from "../editorComponents/ResizableComponent";
|
||||||
|
|
||||||
const { DEFAULT_GRID_COLUMNS, DEFAULT_GRID_ROW_HEIGHT } = GridDefaults;
|
const { DEFAULT_GRID_COLUMNS, DEFAULT_GRID_ROW_HEIGHT } = GridDefaults;
|
||||||
|
export const OccupiedSpaceContext: Context<
|
||||||
|
OccupiedSpace[] | any
|
||||||
|
> = createContext(null);
|
||||||
|
|
||||||
class ContainerWidget extends BaseWidget<
|
class ContainerWidget extends BaseWidget<
|
||||||
ContainerWidgetProps<WidgetProps>,
|
ContainerWidgetProps<WidgetProps>,
|
||||||
|
|
@ -78,6 +81,7 @@ class ContainerWidget extends BaseWidget<
|
||||||
}))
|
}))
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanvasView() {
|
getCanvasView() {
|
||||||
const style = this.getPositionStyle();
|
const style = this.getPositionStyle();
|
||||||
const occupiedSpaces = this.getOccupiedSpaces();
|
const occupiedSpaces = this.getOccupiedSpaces();
|
||||||
|
|
@ -85,7 +89,6 @@ class ContainerWidget extends BaseWidget<
|
||||||
<DropTargetComponent
|
<DropTargetComponent
|
||||||
{...this.props}
|
{...this.props}
|
||||||
{...this.state}
|
{...this.state}
|
||||||
occupiedSpaces={occupiedSpaces}
|
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
|
|
@ -106,7 +109,11 @@ class ContainerWidget extends BaseWidget<
|
||||||
</DraggableComponent>
|
</DraggableComponent>
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.props.parentId ? renderDraggableComponent : renderComponent;
|
return (
|
||||||
|
<OccupiedSpaceContext.Provider value={occupiedSpaces}>
|
||||||
|
{this.props.parentId ? renderDraggableComponent : renderComponent}
|
||||||
|
</OccupiedSpaceContext.Provider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getWidgetType(): WidgetType {
|
getWidgetType(): WidgetType {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user