Skip to content

Commit

Permalink
Merge pull request #148 from the-deep/feature/movable-modal
Browse files Browse the repository at this point in the history
Make modal movable
  • Loading branch information
AdityaKhatri authored Apr 19, 2022
2 parents 5640b73 + dea3f1d commit 12ddb48
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ interface BaseProps {
spacing?: SpacingTypes;
size?: SizeTypes;
freeHeight?: boolean;
movable?: boolean;
}

export type Props = BaseProps & ({
Expand Down Expand Up @@ -108,24 +109,83 @@ function Modal(props: Props) {
spacing = 'loose',
size = 'medium',
freeHeight,
movable = false,
} = props;

// eslint-disable-next-line react/destructuring-assignment
const shouldHideHeader = props.hideCloseButton && !heading && !headerActions && !headerIcons;
const headerRef = React.useRef<HTMLDivElement>(null);
const modalRef = React.useRef<HTMLDivElement>(null);
const mouseDownRef = React.useRef<boolean>(false);
const mouseDownPositionDiffRef = React.useRef({
x: 0,
y: 0,
});
const initialBCRRef = React.useRef<DOMRect>();

React.useEffect(() => {
initialBCRRef.current = modalRef.current?.getBoundingClientRect();
}, []);

React.useEffect(() => {
const headerElement = headerRef.current;
const modalElement = modalRef.current;

if (!movable || !headerElement || !modalElement) {
return undefined;
}

const handleMouseMove = (e: MouseEvent) => {
const bcr = initialBCRRef.current;
if (bcr) {
const translateX = (e.clientX - mouseDownPositionDiffRef.current.x) - bcr.x;
const translateY = (e.clientY - mouseDownPositionDiffRef.current.y) - bcr.y;
modalElement.style.transform = `translate(${translateX}px, ${translateY}px)`;
}
};

const handleMouseDown = (e: MouseEvent) => {
mouseDownRef.current = true;
const currentBCR = modalRef.current?.getBoundingClientRect();
if (currentBCR) {
mouseDownPositionDiffRef.current.x = e.clientX - currentBCR.x;
mouseDownPositionDiffRef.current.y = e.clientY - currentBCR.y;
}
window.addEventListener('mousemove', handleMouseMove);
};

const handleMouseUp = () => {
mouseDownRef.current = false;
window.removeEventListener('mousemove', handleMouseMove);
};

if (movable) {
headerElement.addEventListener('mousedown', handleMouseDown);
window.addEventListener('mouseup', handleMouseUp);
}

return () => {
headerElement.removeEventListener('mousedown', handleMouseDown);
window.removeEventListener('mouseup', handleMouseUp);
};
}, [movable]);

return (
<BodyBackdrop className={backdropClassName}>
<div
ref={modalRef}
className={_cs(
styles.modal,
spacingToStyleMap[spacing],
sizeToStyleMap[size],
freeHeight && styles.freeHeight,
className,
movable && styles.movable,
)}
>
{!shouldHideHeader && (
<Header
elementProps={movable ? { ref: headerRef } : undefined}
spacing={spacing}
className={_cs(styles.modalHeader, headerClassName)}
heading={heading}
Expand Down
7 changes: 7 additions & 0 deletions src/components/Modal/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,11 @@
&.free-height {
height: auto;
}

&.movable {
.modal-header {
cursor: move;
user-select: none;
}
}
}

0 comments on commit 12ddb48

Please sign in to comment.