diff --git a/src/index.test.tsx b/src/index.test.tsx index ab3f8074..6c91d604 100755 --- a/src/index.test.tsx +++ b/src/index.test.tsx @@ -111,8 +111,8 @@ test("should call onDragStart when start dragging", async t => { .simulate("mousedown"); t.is(onDragStart.callCount, 1); t.is(onDragStart.firstCall.args[0].type, "mousedown"); - t.is(onDragStart.firstCall.args[1].x, 200); - t.is(onDragStart.firstCall.args[1].y, 200); + t.is(onDragStart.firstCall.args[1].x, 100); + t.is(onDragStart.firstCall.args[1].y, 100); }); test("should call onDrag when dragging", async t => { @@ -124,9 +124,9 @@ test("should call onDrag when dragging", async t => { .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(200, 220); t.is(onDrag.callCount, 1); - t.is(onDrag.firstCall.args[1].x, 600); - t.is(onDrag.firstCall.args[1].y, 620); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(400px, 420px)"), -1); + t.is(onDrag.firstCall.args[1].x, 300); + t.is(onDrag.firstCall.args[1].y, 320); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(300px, 320px)"), -1); }); test("should call onDragStop when drag stop", async t => { @@ -137,10 +137,10 @@ test("should call onDragStop when drag stop", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(200, 220); - mouseUp(100, 120); + mouseUp(200, 220); t.is(onDragStop.callCount, 1); - t.is(onDragStop.firstCall.args[1].x, -100); - t.is(onDragStop.firstCall.args[1].y, -100); + t.is(onDragStop.firstCall.args[1].x, 300); + t.is(onDragStop.firstCall.args[1].y, 320); }); test("should dragging disabled when axis equals none", async t => { @@ -208,7 +208,7 @@ test("should snap when dragging smaller than threshold", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(14, 49); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(108px, 108px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(100px, 100px)"), -1); }); test("should snap when dragging larger than threshold", async t => { @@ -220,7 +220,7 @@ test("should snap when dragging larger than threshold", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(15, 50); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(138px, 208px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(130px, 200px)"), -1); }); test("should limit position by parent bounds", async t => { @@ -244,7 +244,7 @@ test("should limit position by parent bounds", async t => { .childAt(0) .getDOMNode() .getAttribute("style") || "" - ).indexOf("transform: translate(708px, 508px)"), + ).indexOf("transform: translate(700px, 500px)"), -1, ); }); @@ -275,7 +275,7 @@ test("should limit position by selector bounds", async t => { .childAt(0) .getDOMNode() .getAttribute("style") || "" - ).indexOf("translate(908px, 708px)"), + ).indexOf("translate(900px, 700px)"), -1, ); }); @@ -468,7 +468,7 @@ test("should move x when resizing left", async t => { t.deepEqual(onResize.getCall(0).args[2].clientWidth, 150); t.deepEqual(onResize.getCall(0).args[2].clientHeight, 100); t.deepEqual(onResize.getCall(0).args[3], { width: 50, height: 0 }); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(58px, 108px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(50px, 100px)"), -1); }); test("should move y when resizing top", async t => { @@ -512,7 +512,7 @@ test("should move y when resizing top", async t => { t.deepEqual(onResize.getCall(0).args[2].clientWidth, 100); t.deepEqual(onResize.getCall(0).args[2].clientHeight, 150); t.deepEqual(onResize.getCall(0).args[3], { width: 0, height: 50 }); - t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(108px, 58px)"), -1); + t.not((rnd.getDOMNode().getAttribute("style") || "").indexOf("transform: translate(100px, 50px)"), -1); }); test("should snapped by original grid when x axis resizing smaller then threshold", async t => { @@ -742,8 +742,8 @@ test("should clamped by parent size", async t => { .at(0) .simulate("mousedown", { clientX: 0, clientY: 0 }); mouseMove(1200, 1200); - t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.width, "800px"); - t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.height, "600px"); + t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.width, "808px"); + t.is((rnd.childAt(0).getDOMNode() as HTMLElement).style.height, "608px"); }); test("should clamped by selector size", async t => { @@ -788,14 +788,14 @@ test("should clamped by selector size", async t => { .childAt(0) .childAt(0) .getDOMNode() as HTMLElement).style.width, - "1000px", + "1008px", ); t.is( (rnd .childAt(0) .childAt(0) .getDOMNode() as HTMLElement).style.height, - "800px", + "808px", ); }); diff --git a/src/index.tsx b/src/index.tsx index 9c8836fd..e8874048 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -276,9 +276,15 @@ export class Rnd extends React.Component { } onDragStop(e: Event, data: DraggableData) { + const { left, top } = this.getOffsetFromParent(); + + let draggablePosition = { + x: data.x + left, + y: data.y + top, + }; + if (this.props.onDragStop) { - const { left, top } = this.getOffsetFromParent(); - this.props.onDragStop(e, { ...data, x: data.x + left, y: data.y + top }); + this.props.onDragStop(e, { ...data, ...draggablePosition }); } } @@ -439,7 +445,9 @@ export class Rnd extends React.Component { } getOffsetFromParent(): { top: number; left: number } { + const { dragAxis } = this.props; const parent = this.getParent(); + if (!parent) { return { top: 0, @@ -451,10 +459,45 @@ export class Rnd extends React.Component { const parentTop = parentRect.top; const selfRect = this.getSelfElement().getBoundingClientRect(); const position = this.getDraggablePosition(); - return { + const rawPosition = { left: selfRect.left - parentLeft - position.x, top: selfRect.top - parentTop - position.y, }; + let adjustedPosition = rawPosition; + + switch (dragAxis) { + case "x": + adjustedPosition = { + ...rawPosition, + top: 0, + }; + break; + case "y": + adjustedPosition = { + ...rawPosition, + left: 0, + }; + break; + case "both": + adjustedPosition = { + ...rawPosition, + }; + break; + case "none": + adjustedPosition = { + ...rawPosition, + left: 0, + top: 0, + }; + break; + default: + adjustedPosition = { + ...rawPosition, + }; + break; + } + + return adjustedPosition; } render() { @@ -473,9 +516,11 @@ export class Rnd extends React.Component { onResizeStart, onResize, onResizeStop, + snapOnResizeStop, onDragStart, onDrag, onDragStop, + snapOnDragStop, resizeHandleStyles, resizeHandleClasses, enableResizing, @@ -494,14 +539,17 @@ export class Rnd extends React.Component { ...cursorStyle, ...style, }; + const { left, top } = this.getOffsetFromParent(); let draggablePosition; + if (position) { draggablePosition = { x: position.x - left, y: position.y - top, }; } + return ( { diff --git a/stories/index.tsx b/stories/index.tsx index 396e0919..8ee3bc35 100644 --- a/stories/index.tsx +++ b/stories/index.tsx @@ -29,6 +29,8 @@ import SandboxLockAspectRatioWithBounds from "./sandbox/lock-aspect-ratio-with-b import LockAspectRatioBasic from "./lock-aspect-ratio/basic"; +import RestrictDrag from "./restrict-axis/restrict-drag"; + storiesOf("bare", module).add("bare", () => ); storiesOf("basic", module) @@ -58,3 +60,4 @@ storiesOf("sandbox", module) .add("lock aspect ratio with bounds", () => ); storiesOf("ratio", module).add("lock aspect ratio", () => ); +storiesOf("restrict axis", module).add("restrict drag axis", () => ); diff --git a/stories/restrict-axis/restrict-drag.tsx b/stories/restrict-axis/restrict-drag.tsx new file mode 100644 index 00000000..1c83497c --- /dev/null +++ b/stories/restrict-axis/restrict-drag.tsx @@ -0,0 +1,102 @@ +import React from "react"; +import { Rnd } from "../../src"; + +type State = { + x: number; + y: number; + width: number; + height: number; + restrict: "x" | "y" | "both" | "none"; +}; + +const style = { + display: "flex", + alignItems: "center", + justifyContent: "center", + border: "solid 1px #ddd", + background: "#f0f0f0", +}; +export default class RestrictDrag extends React.Component<{}, State> { + constructor(props) { + super(props); + this.state = { + width: 200, + height: 200, + x: 0, + y: 80, + restrict: "x", + }; + } + handleDragStop = (e, d) => { + const restrictedAxis = this.state.restrict; + let pos = {}; + switch (restrictedAxis) { + case "x": + pos = { + x: d.x, + }; + break; + case "y": + pos = { + y: d.y, + }; + break; + case "both": + pos = { + x: d.x, + y: d.y, + }; + break; + case "none": + pos = {}; + break; + default: + pos = {}; + break; + } + this.setState({ ...pos }); + }; + + render() { + console.log("STATE", this.state); + return ( +
+ + { + this.setState({ + width: ref.offsetWidth, + height: ref.offsetHeight, + ...position, + }); + }} + > + 001 + +
+ ); + } +} diff --git a/stories/size/size-percent-uncontrolled.tsx b/stories/size/size-percent-uncontrolled.tsx index 4593d73a..0e94dfc6 100644 --- a/stories/size/size-percent-uncontrolled.tsx +++ b/stories/size/size-percent-uncontrolled.tsx @@ -1,5 +1,5 @@ import React from "react"; -import Rnd from "../../src"; +import { Rnd } from "../../src"; import { style } from "../styles"; export default () => (