feat(layout): add pointer cancel handling to ActivityBar and improve drag end detection in TabBar
- Implemented a new `handlePointerCancel` function in the ActivityBar to manage pointer cancellation events, enhancing drag-and-drop interactions. - Updated the TabBar component to utilize a callback for detecting drag end proximity to the tab strip, improving the user experience during tab management.
This commit is contained in:
1 parent
9e87feed2a
commit
e62561feb9
2 files changed
+39
-15
No files matched your search
@@ -326,6 +326,22 @@ function DropZone({
|
||||
[requestPointerDrop, resetDragState],
|
||||
);
|
||||
|
||||
const handlePointerCancel = useCallback(
|
||||
(event: PointerEvent) => {
|
||||
const state = pointerDragRef.current;
|
||||
if (!state || state.pointerId !== event.pointerId) return;
|
||||
|
||||
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
||||
event.currentTarget.releasePointerCapture(event.pointerId);
|
||||
}
|
||||
resetDragState();
|
||||
window.setTimeout(() => {
|
||||
suppressClickRef.current = false;
|
||||
}, 0);
|
||||
},
|
||||
[resetDragState],
|
||||
);
|
||||
|
||||
const handleDragStart = useCallback(
|
||||
(e: DragEvent, itemId: string) => {
|
||||
dragItemIdRef.current = itemId;
|
||||
@@ -402,6 +418,7 @@ function DropZone({
|
||||
onPointerDown={(e) => handlePointerDown(e, item.id)}
|
||||
onPointerMove={handlePointerMove}
|
||||
onPointerEnd={handlePointerEnd}
|
||||
onPointerCancel={handlePointerCancel}
|
||||
draggable={!usePointerDrag}
|
||||
suppressClickRef={suppressClickRef}
|
||||
showDropIndicator={dropIndex === idx}
|
||||
@@ -439,6 +456,7 @@ function ActivityBarButton({
|
||||
onPointerDown,
|
||||
onPointerMove,
|
||||
onPointerEnd,
|
||||
onPointerCancel,
|
||||
draggable,
|
||||
suppressClickRef,
|
||||
showDropIndicator,
|
||||
@@ -461,6 +479,7 @@ function ActivityBarButton({
|
||||
onPointerDown: (e: PointerEvent) => void;
|
||||
onPointerMove: (e: PointerEvent) => void;
|
||||
onPointerEnd: (e: PointerEvent) => void;
|
||||
onPointerCancel: (e: PointerEvent) => void;
|
||||
draggable: boolean;
|
||||
suppressClickRef: MutableRefObject<boolean>;
|
||||
showDropIndicator: boolean;
|
||||
@@ -483,7 +502,7 @@ function ActivityBarButton({
|
||||
onPointerDown={onPointerDown}
|
||||
onPointerMove={onPointerMove}
|
||||
onPointerUp={onPointerEnd}
|
||||
onPointerCancel={onPointerEnd}
|
||||
onPointerCancel={onPointerCancel}
|
||||
className={`relative flex flex-col items-center justify-center w-full transition-colors ${showLabel ? "min-h-12 gap-0.5 py-1" : "h-9"}`}
|
||||
style={{
|
||||
color: active ? "var(--df-primary)" : "var(--df-text-muted)",
|
||||
|
||||
@@ -710,6 +710,22 @@ function TabBar({
|
||||
[tabs],
|
||||
);
|
||||
|
||||
const isDragEndFallbackNearTabStrip = useCallback((clientX: number, clientY: number) => {
|
||||
const strip = tabStripRef.current;
|
||||
if (!strip || clientX === 0) return false;
|
||||
|
||||
const rect = strip.getBoundingClientRect();
|
||||
const horizontalTolerance = 48;
|
||||
const verticalTolerance = Math.max(96, rect.height * 3);
|
||||
const isWithinHorizontalRange =
|
||||
clientX >= rect.left - horizontalTolerance && clientX <= rect.right + horizontalTolerance;
|
||||
if (!isWithinHorizontalRange) return false;
|
||||
|
||||
if (clientY === 0) return true;
|
||||
|
||||
return clientY >= rect.top - verticalTolerance && clientY <= rect.bottom + verticalTolerance;
|
||||
}, []);
|
||||
|
||||
const handleDropAtIndex = useCallback(
|
||||
(insertionIndex: number, event?: DragEvent<HTMLDivElement>) => {
|
||||
const externalTabId = event?.dataTransfer.getData("application/nyaterm-tab");
|
||||
@@ -759,20 +775,9 @@ function TabBar({
|
||||
}
|
||||
|
||||
const fallbackTabId = draggedTabIdRef.current;
|
||||
const strip = tabStripRef.current;
|
||||
if (fallbackTabId && strip && event.clientX !== 0) {
|
||||
const rect = strip.getBoundingClientRect();
|
||||
const horizontalTolerance = 48;
|
||||
const verticalTolerance = 16;
|
||||
const isNearTabStrip =
|
||||
event.clientX >= rect.left - horizontalTolerance &&
|
||||
event.clientX <= rect.right + horizontalTolerance &&
|
||||
event.clientY >= rect.top - verticalTolerance &&
|
||||
event.clientY <= rect.bottom + verticalTolerance;
|
||||
if (isNearTabStrip) {
|
||||
handleDropAtIndex(getInsertionIndexFromClientX(event.clientX));
|
||||
return;
|
||||
}
|
||||
if (fallbackTabId && isDragEndFallbackNearTabStrip(event.clientX, event.clientY)) {
|
||||
handleDropAtIndex(getInsertionIndexFromClientX(event.clientX));
|
||||
return;
|
||||
}
|
||||
|
||||
resetDragState();
|
||||
|
||||
Reference in new issue
Block a user