Skip to content

Commit

Permalink
abstract logic into a custom hook
Browse files Browse the repository at this point in the history
  • Loading branch information
agneym committed Dec 16, 2019
1 parent d7cf1e0 commit 303b0e8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 49 deletions.
59 changes: 10 additions & 49 deletions playground/src/Draggable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import React, {
FC,
ReactNode,
useRef,
useState,
useEffect,
useCallback,
} from "react";
import React, { FC, ReactNode, useRef } from "react";
import styled from "styled-components";
import useDrag from "./useDrag";

const Container = styled.div`
display: flex;
Expand All @@ -29,51 +23,18 @@ interface IProps {
const Draggable: FC<IProps> = ({ className = "", leftChild, rightChild }) => {
const containerRef = useRef<HTMLDivElement>(null);
const dividerRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(0);
const [containerRect, setContainerRect] = useState<DOMRect | null>(null);

useEffect(() => {
const containerEl = containerRef.current;
if (containerEl) {
const fullWidth = containerEl.clientWidth;
const containerRect = containerEl.getBoundingClientRect();
setContainerRect(containerRect);
setWidth(fullWidth / 2);
}
}, []);
const keepDragging = useCallback(
(event: MouseEvent) => {
const { clientX } = event;
if (containerRect) {
setWidth(clientX - containerRect.left);
}
},
[containerRect]
);
const stopDrag = useCallback(() => {
document.removeEventListener("mousemove", keepDragging);
document.removeEventListener("mouseup", stopDrag);
}, [keepDragging]);
const startDrag = useCallback(() => {
document.addEventListener("mousemove", keepDragging);
document.addEventListener("mouseup", stopDrag);
}, [keepDragging, stopDrag]);
useEffect(() => {
const dividerEl = dividerRef.current;
if (dividerEl) {
dividerEl.addEventListener("mousedown", startDrag);
}
return () => {
if (dividerEl) {
dividerEl.removeEventListener("mousedown", startDrag);
}
};
}, [startDrag]);
const { leftWidth, rightWidth } = useDrag({
containerRef,
dividerRef,
dividerWidth: DIVIDER_WIDTH,
});

return (
<Container className={className} ref={containerRef}>
{leftChild(width)}
{leftChild(leftWidth)}
<Divider ref={dividerRef} />
{containerRect && rightChild(containerRect.width - width - DIVIDER_WIDTH)}
{rightChild(rightWidth)}
</Container>
);
};
Expand Down
57 changes: 57 additions & 0 deletions playground/src/Draggable/useDrag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useState, useEffect, useCallback, RefObject } from "react";

interface IProps {
containerRef: RefObject<HTMLDivElement | null>;
dividerRef: RefObject<HTMLDivElement | null>;
dividerWidth: number;
}

function useDrag({ containerRef, dividerRef, dividerWidth }: IProps) {
const [width, setWidth] = useState(0);
const [containerRect, setContainerRect] = useState<DOMRect | null>(null);

useEffect(() => {
const containerEl = containerRef.current;
if (containerEl) {
const fullWidth = containerEl.clientWidth;
const containerRect = containerEl.getBoundingClientRect();
setContainerRect(containerRect);
setWidth(fullWidth / 2);
}
}, []);
const keepDragging = useCallback(
(event: MouseEvent) => {
const { clientX } = event;
if (containerRect) {
setWidth(clientX - containerRect.left);
}
},
[containerRect]
);
const stopDrag = useCallback(() => {
document.removeEventListener("mousemove", keepDragging);
document.removeEventListener("mouseup", stopDrag);
}, [keepDragging]);
const startDrag = useCallback(() => {
document.addEventListener("mousemove", keepDragging);
document.addEventListener("mouseup", stopDrag);
}, [keepDragging, stopDrag]);
useEffect(() => {
const dividerEl = dividerRef.current;
if (dividerEl) {
dividerEl.addEventListener("mousedown", startDrag);
}
return () => {
if (dividerEl) {
dividerEl.removeEventListener("mousedown", startDrag);
}
};
}, [startDrag]);

return {
leftWidth: width,
rightWidth: containerRect ? containerRect.width - width : 0,
};
}

export default useDrag;

0 comments on commit 303b0e8

Please sign in to comment.