Show grid only on hover. Remove min grid space between adjacent components. Fix all dropzones showing issue. Disable show control on hover.
This commit is contained in:
parent
5bf84ee361
commit
622e5dc0a9
|
|
@ -4,6 +4,7 @@ import { useDragLayer, XYCoord } from "react-dnd";
|
||||||
import DropZone from "./Dropzone";
|
import DropZone from "./Dropzone";
|
||||||
import { noCollision } from "../utils/WidgetPropsUtils";
|
import { noCollision } from "../utils/WidgetPropsUtils";
|
||||||
import { OccupiedSpace } from "../widgets/ContainerWidget";
|
import { OccupiedSpace } from "../widgets/ContainerWidget";
|
||||||
|
import DropTargetMask from "./DropTargetMask";
|
||||||
|
|
||||||
const WrappedDragLayer = styled.div`
|
const WrappedDragLayer = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -23,6 +24,8 @@ type DragLayerProps = {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
dropTargetOffset: XYCoord;
|
dropTargetOffset: XYCoord;
|
||||||
occupiedSpaces: OccupiedSpace[] | null;
|
occupiedSpaces: OccupiedSpace[] | null;
|
||||||
|
onBoundsUpdate: Function;
|
||||||
|
isOver: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const DragLayerComponent = (props: DragLayerProps) => {
|
const DragLayerComponent = (props: DragLayerProps) => {
|
||||||
|
|
@ -54,8 +57,15 @@ const DragLayerComponent = (props: DragLayerProps) => {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<WrappedDragLayer>
|
<WrappedDragLayer>
|
||||||
|
<DropTargetMask
|
||||||
|
rowHeight={props.parentRowHeight}
|
||||||
|
columnWidth={props.parentColumnWidth}
|
||||||
|
setBounds={props.onBoundsUpdate}
|
||||||
|
showGrid={isDragging && props.isOver}
|
||||||
|
/>
|
||||||
<DropZone
|
<DropZone
|
||||||
{...props}
|
{...props}
|
||||||
|
visible={props.visible && props.isOver}
|
||||||
width={widgetWidth}
|
width={widgetWidth}
|
||||||
height={widgetHeight}
|
height={widgetHeight}
|
||||||
currentOffset={currentOffset as XYCoord}
|
currentOffset={currentOffset as XYCoord}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ const DraggableWrapper = styled.div<{ show: boolean }>`
|
||||||
& > div.control {
|
& > div.control {
|
||||||
display: ${props => (props.show ? "block" : "none")};
|
display: ${props => (props.show ? "block" : "none")};
|
||||||
}
|
}
|
||||||
&:hover > div {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
display: block;
|
display: block;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import { ContainerProps } from "./ContainerComponent";
|
||||||
import WidgetFactory from "../utils/WidgetFactory";
|
import WidgetFactory from "../utils/WidgetFactory";
|
||||||
import { widgetOperationParams, noCollision } from "../utils/WidgetPropsUtils";
|
import { widgetOperationParams, noCollision } from "../utils/WidgetPropsUtils";
|
||||||
import DragLayerComponent from "./DragLayerComponent";
|
import DragLayerComponent from "./DragLayerComponent";
|
||||||
import DropTargetMask from "./DropTargetMask";
|
|
||||||
|
|
||||||
type DropTargetComponentProps = ContainerProps & {
|
type DropTargetComponentProps = ContainerProps & {
|
||||||
updateWidget?: Function;
|
updateWidget?: Function;
|
||||||
|
|
@ -29,7 +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 });
|
||||||
// Make this component a drop target
|
// Make this component a drop target
|
||||||
const [{ isOver }, drop] = useDrop({
|
const [{ isOver, isExactlyOver }, drop] = useDrop({
|
||||||
accept: Object.values(WidgetFactory.getWidgetTypes()),
|
accept: Object.values(WidgetFactory.getWidgetTypes()),
|
||||||
drop(widget: WidgetProps & Partial<WidgetConfigProps>, monitor) {
|
drop(widget: WidgetProps & Partial<WidgetConfigProps>, monitor) {
|
||||||
// Make sure we're dropping in this container.
|
// Make sure we're dropping in this container.
|
||||||
|
|
@ -54,6 +53,7 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
(monitor.isOver({ shallow: true }) &&
|
(monitor.isOver({ shallow: true }) &&
|
||||||
props.widgetId !== monitor.getItem().widgetId) ||
|
props.widgetId !== monitor.getItem().widgetId) ||
|
||||||
(monitor.isOver() && props.widgetId !== monitor.getItem().widgetId),
|
(monitor.isOver() && props.widgetId !== monitor.getItem().widgetId),
|
||||||
|
isExactlyOver: monitor.isOver({ shallow: true }),
|
||||||
}),
|
}),
|
||||||
// Only allow drop if the drag object is directly over this component
|
// Only allow drop if the drag object is directly over this component
|
||||||
// As opposed to the drag object being over a child component, or outside the component bounds
|
// As opposed to the drag object being over a child component, or outside the component bounds
|
||||||
|
|
@ -86,27 +86,31 @@ export const DropTargetComponent = (props: DropTargetComponentProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={drop}
|
ref={drop}
|
||||||
|
className="dropTarget"
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "relative",
|
||||||
left: props.style.xPosition + props.style.xPositionUnit,
|
left: 0,
|
||||||
height: props.style.componentHeight,
|
height: props.isRoot
|
||||||
width: props.style.componentWidth,
|
? props.style.componentHeight + (props.style.heightUnit || "px")
|
||||||
top: props.style.yPosition + props.style.yPositionUnit,
|
: "100%",
|
||||||
|
width: props.isRoot
|
||||||
|
? props.style.componentWidth + (props.style.widthUnit || "px")
|
||||||
|
: "100%",
|
||||||
|
top: 0,
|
||||||
|
background: "white",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropTargetMask
|
|
||||||
rowHeight={props.snapRowSpace}
|
|
||||||
columnWidth={props.snapColumnSpace}
|
|
||||||
setBounds={handleBoundsUpdate}
|
|
||||||
/>
|
|
||||||
<DragLayerComponent
|
<DragLayerComponent
|
||||||
parentOffset={dropTargetOffset}
|
parentOffset={dropTargetOffset}
|
||||||
parentRowHeight={props.snapRowSpace}
|
parentRowHeight={props.snapRowSpace}
|
||||||
parentColumnWidth={props.snapColumnSpace}
|
parentColumnWidth={props.snapColumnSpace}
|
||||||
visible={isOver}
|
visible={isOver}
|
||||||
|
isOver={isExactlyOver}
|
||||||
dropTargetOffset={dropTargetOffset}
|
dropTargetOffset={dropTargetOffset}
|
||||||
occupiedSpaces={props.occupiedSpaces}
|
occupiedSpaces={props.occupiedSpaces}
|
||||||
|
onBoundsUpdate={handleBoundsUpdate}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import React, { useLayoutEffect, MutableRefObject } from "react";
|
import React, { useLayoutEffect, MutableRefObject } from "react";
|
||||||
import styled from "styled-components";
|
import styled, { css } from "styled-components";
|
||||||
|
|
||||||
type DropTargetMaskProps = {
|
type DropTargetMaskProps = {
|
||||||
rowHeight: number;
|
rowHeight: number;
|
||||||
columnWidth: number;
|
columnWidth: number;
|
||||||
setBounds: Function;
|
setBounds: Function;
|
||||||
|
showGrid: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DropTargetMaskWrapper = styled.div<DropTargetMaskProps>`
|
export const DropTargetMaskWrapper = styled.div<DropTargetMaskProps>`
|
||||||
|
|
@ -16,14 +17,19 @@ export const DropTargetMaskWrapper = styled.div<DropTargetMaskProps>`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: white;
|
background: white;
|
||||||
|
${props =>
|
||||||
|
props.showGrid &&
|
||||||
|
css`
|
||||||
background-image: radial-gradient(
|
background-image: radial-gradient(
|
||||||
circle,
|
circle,
|
||||||
${props => props.theme.colors.grid} 2px,
|
${props => props.theme.colors.grid} 2px,
|
||||||
transparent 0
|
transparent 0
|
||||||
);
|
);
|
||||||
background-size: ${props => props.columnWidth}px ${props => props.rowHeight}px;
|
background-size: ${props => props.columnWidth}px
|
||||||
|
${props => props.rowHeight}px;
|
||||||
background-position: -${props => props.columnWidth / 2}px -${props =>
|
background-position: -${props => props.columnWidth / 2}px -${props =>
|
||||||
props.rowHeight / 2}px;
|
props.rowHeight / 2}px;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
/* eslint-disable react/display-name */
|
/* eslint-disable react/display-name */
|
||||||
export const DropTargetMask = (props: DropTargetMaskProps) => {
|
export const DropTargetMask = (props: DropTargetMaskProps) => {
|
||||||
|
|
@ -39,7 +45,6 @@ export const DropTargetMask = (props: DropTargetMaskProps) => {
|
||||||
props.setBounds(rect);
|
props.setBounds(rect);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return <DropTargetMaskWrapper {...props} ref={dropTargetMask} />;
|
return <DropTargetMaskWrapper {...props} ref={dropTargetMask} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,10 @@ export const getDropZoneOffsets = (
|
||||||
|
|
||||||
const areIntersecting = (r1: Rect, r2: Rect) => {
|
const areIntersecting = (r1: Rect, r2: Rect) => {
|
||||||
return !(
|
return !(
|
||||||
r2.left > r1.right ||
|
r2.left >= r1.right ||
|
||||||
r2.right < r1.left ||
|
r2.right <= r1.left ||
|
||||||
r2.top > r1.bottom ||
|
r2.top >= r1.bottom ||
|
||||||
r2.bottom < r1.top
|
r2.bottom <= r1.top
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,19 +90,7 @@ class ContainerWidget extends BaseWidget<
|
||||||
getCanvasView() {
|
getCanvasView() {
|
||||||
const style = this.getPositionStyle();
|
const style = this.getPositionStyle();
|
||||||
const occupiedSpaces = this.getOccupiedSpaces();
|
const occupiedSpaces = this.getOccupiedSpaces();
|
||||||
const renderDraggableComponent = (
|
const renderComponent = (
|
||||||
<DraggableComponent
|
|
||||||
style={{ ...style, xPosition: 0, yPosition: 0 }}
|
|
||||||
{...this.props}
|
|
||||||
orientation={"VERTICAL"}
|
|
||||||
>
|
|
||||||
<ResizableComponent style={{ ...style }} {...this.props}>
|
|
||||||
{this.getPageView()}
|
|
||||||
</ResizableComponent>
|
|
||||||
</DraggableComponent>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropTargetComponent
|
<DropTargetComponent
|
||||||
{...this.props}
|
{...this.props}
|
||||||
{...this.state}
|
{...this.state}
|
||||||
|
|
@ -110,10 +98,24 @@ class ContainerWidget extends BaseWidget<
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
|
isRoot={!this.props.parentId}
|
||||||
>
|
>
|
||||||
{this.props.parentId ? renderDraggableComponent : this.getPageView()}
|
{this.getPageView()}
|
||||||
</DropTargetComponent>
|
</DropTargetComponent>
|
||||||
);
|
);
|
||||||
|
const renderDraggableComponent = (
|
||||||
|
<DraggableComponent
|
||||||
|
style={{ ...style }}
|
||||||
|
{...this.props}
|
||||||
|
orientation={"VERTICAL"}
|
||||||
|
>
|
||||||
|
<ResizableComponent style={{ ...style }} {...this.props}>
|
||||||
|
{renderComponent}
|
||||||
|
</ResizableComponent>
|
||||||
|
</DraggableComponent>
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.props.parentId ? renderDraggableComponent : renderComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
getWidgetType(): WidgetType {
|
getWidgetType(): WidgetType {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user