Skip to content

Commit

Permalink
Fix weirds click on drag
Browse files Browse the repository at this point in the history
  • Loading branch information
moransantiago committed May 31, 2024
1 parent 216ac6e commit 33819d9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 81 deletions.
5 changes: 5 additions & 0 deletions .changeset/gentle-birds-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"basehub": patch
---

Refresh on draft mode activation, styling corrections, full drag handle.
9 changes: 3 additions & 6 deletions packages/basehub/src/next/toolbar/client-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export const ClientToolbar = ({
const [toolbarRef, setToolbarRef] = React.useState<HTMLDivElement | null>(
null
);
const dragHandleRef = React.useRef<DragHandle>(null);
const tooltipRef = React.useRef<Tooltip>(null);
const [isDragging, setIsDragging] = React.useState(false);
const [message, setMessage] = React.useState("");
const [loading, setLoading] = React.useState(false);

Expand Down Expand Up @@ -195,14 +195,11 @@ export const ClientToolbar = ({
return (
<div className={s.wrapper} ref={(ref) => setToolbarRef(ref)}>
<DragHandle
ref={dragHandleRef}
onDrag={(pos) => {
dragToolbar(pos);
tooltipRef.current?.checkOverflow();
}}
onDragStart={() => setTimeout(() => setIsDragging(true), 500)}
onDragEnd={() => {
setTimeout(() => setIsDragging(false), 500);
}}
>
<div className={s.root} data-draft-active={isForcedDraft || draft}>
{/* branch switcher */}
Expand All @@ -220,7 +217,7 @@ export const ClientToolbar = ({
data-loading={loading}
disabled={isForcedDraft || loading}
onClick={() => {
if (loading || isDragging) return;
if (loading || dragHandleRef.current?.hasDragged) return;

if (draft) {
setLoading(true);
Expand Down
148 changes: 80 additions & 68 deletions packages/basehub/src/next/toolbar/components/drag-handle.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,95 @@
import * as React from "react";
import s from "../toolbar.module.scss";

export const DragHandle = ({
onDrag,
onDragStart,
onDragEnd,
children,
}: {
onDrag: ({ x, y }: { x: number; y: number }) => void;
onDragStart: () => void;
onDragEnd: () => void;
children: React.ReactNode;
}) => {
const [isDragging, setIsDragging] = React.useState(false);
const initialPointer = React.useRef({ x: 0, y: 0 });
const initialToolbar = React.useRef({ x: 0, y: 0 });
export type DragHandle = { hasDragged: boolean };

const handleDrag = React.useCallback(
(e: PointerEvent) => {
if (!isDragging) return;
export const DragHandle = React.forwardRef(
(
{
onDrag,
children,
}: {
onDrag: ({ x, y }: { x: number; y: number }) => void;
children: React.ReactNode;
},
ref
) => {
const [isDragging, setIsDragging] = React.useState(false);
const initialPointer = React.useRef({ x: 0, y: 0 });
const initialToolbar = React.useRef({ x: 0, y: 0 });
const hasDragged = React.useRef(false);

const deltaX = e.clientX - initialPointer.current.x;
const deltaY = e.clientY - initialPointer.current.y;
const newToolbarX = initialToolbar.current.x + deltaX;
const newToolbarY = initialToolbar.current.y + deltaY;
React.useImperativeHandle(ref, () => ({
hasDragged: hasDragged.current,
}));

onDrag({ x: newToolbarX, y: newToolbarY });
},
[isDragging, onDrag]
);
const handleDrag = React.useCallback(
(e: PointerEvent) => {
if (!isDragging) return;

React.useLayoutEffect(() => {
if (!isDragging) return;
const deltaX = e.clientX - initialPointer.current.x;
const deltaY = e.clientY - initialPointer.current.y;
const newToolbarX = initialToolbar.current.x + deltaX;
const newToolbarY = initialToolbar.current.y + deltaY;

window.addEventListener("pointermove", handleDrag);
// set hasDragged to true if the pointer has moved more than 5 px from the initial position
if (Math.abs(deltaX) > 2 || Math.abs(deltaY) > 2) {
hasDragged.current = true;
}

return () => {
window.removeEventListener("pointermove", handleDrag);
};
}, [isDragging, onDrag, handleDrag]);
onDrag({ x: newToolbarX, y: newToolbarY });
},
[isDragging, onDrag]
);

React.useLayoutEffect(() => {
// disable drag on pointer up
if (!isDragging) return;
React.useLayoutEffect(() => {
if (!isDragging) return;

const handlePointerUp = () => {
setIsDragging(false);
onDragEnd();
};
window.addEventListener("pointermove", handleDrag);

window.addEventListener("pointerup", handlePointerUp);
return () => {
window.removeEventListener("pointermove", handleDrag);
};
}, [isDragging, onDrag, handleDrag]);

return () => {
window.removeEventListener("pointerup", handlePointerUp);
};
}, [isDragging, onDragEnd]);
React.useLayoutEffect(() => {
// disable drag on pointer up
if (!isDragging) {
hasDragged.current = false;
return
}

return (
<span
className={`${s.dragHandle} ${isDragging ? s.dragging : ""}`}
onPointerDown={(e) => {
e.stopPropagation();
const handle = e.currentTarget as HTMLSpanElement | null;
if (!handle) return;
initialPointer.current = { x: e.clientX, y: e.clientY };
const rect = handle.getBoundingClientRect();
initialToolbar.current.x = rect.left;
initialToolbar.current.y = rect.top;
setIsDragging(true);
onDragStart();
}}
onPointerUp={() => {
const handlePointerUp = () => {
setIsDragging(false);
if (isDragging) {
onDragEnd();
}
}}
>
{children}
</span>
);
};
};

window.addEventListener("pointerup", handlePointerUp);

return () => {
window.removeEventListener("pointerup", handlePointerUp);
};
}, [isDragging]);

return (
<span
draggable
className={`${s.dragHandle} ${isDragging ? s.dragging : ""}`}
onPointerDown={(e) => {
e.stopPropagation();
const handle = e.currentTarget as HTMLSpanElement | null;
if (!handle) return;
initialPointer.current = { x: e.clientX, y: e.clientY };
const rect = handle.getBoundingClientRect();
initialToolbar.current.x = rect.left;
initialToolbar.current.y = rect.top;
setIsDragging(true);
}}
onPointerUp={() => {
setIsDragging(false);
}}
>
{children}
</span>
);
}
);
5 changes: 1 addition & 4 deletions packages/basehub/src/next/toolbar/components/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@ export const Tooltip = React.forwardRef(
? 0
: rect.width / 2;
const paddingBlock = rect.height;
const tooltipOffset = 50 * 2;
const tooltipOffset = 40 * 2;
const isAlreadyToTop = tooltipContentRef.current.classList.contains(
s.bottom
);

console.log(rect.top, paddingBlock, tooltipOffset);

// reached the top
if (
(isAlreadyToTop
Expand All @@ -50,7 +48,6 @@ export const Tooltip = React.forwardRef(
}

// reached the right
console.log(rect.right, paddingInline, window.innerWidth);
if (rect.right + paddingInline > window.innerWidth) {
tooltipContentRef.current.classList.remove(s.left);
tooltipContentRef.current.classList.add(s.right);
Expand Down
7 changes: 4 additions & 3 deletions packages/basehub/src/next/toolbar/toolbar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
display: flex;
align-items: center;
font-weight: 500;
user-select: none;
}

.wrapper {
Expand Down Expand Up @@ -128,7 +129,7 @@

.tooltip {
position: absolute;
bottom: 45px;
bottom: 40px;
left: 50%;
transform: translateX(-50%) translateY(0);
background-color: #0C0C0C;
Expand All @@ -148,7 +149,7 @@
}

&.top {
top: 45px;
top: 40px;
bottom: unset;
transform: translateY(0) translateX(var(--translate-x));

Expand All @@ -161,7 +162,7 @@
}

&.bottom {
bottom: 45px;
bottom: 40px;
top: unset;
transform: translateY(0) translateX(var(--translate-x));

Expand Down

0 comments on commit 33819d9

Please sign in to comment.