mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-04 18:59:08 +01:00
Scrollable tab bar fixes (#69)
This commit is contained in:
parent
e83b5c8763
commit
b8b03ea817
@ -15,7 +15,7 @@ interface TabProps {
|
|||||||
isDragging: boolean;
|
isDragging: boolean;
|
||||||
onSelect: () => void;
|
onSelect: () => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onDragStart: () => void;
|
onDragStart: (event: MouseEvent) => void;
|
||||||
onLoaded: () => void;
|
onLoaded: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,8 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
ref: { current: null },
|
ref: { current: null },
|
||||||
tabStartX: 0,
|
tabStartX: 0,
|
||||||
tabIndex: 0,
|
tabIndex: 0,
|
||||||
|
initialOffsetX: null,
|
||||||
|
totalScrollOffset: null,
|
||||||
dragged: false,
|
dragged: false,
|
||||||
});
|
});
|
||||||
const osInstanceRef = useRef<OverlayScrollbars>(null);
|
const osInstanceRef = useRef<OverlayScrollbars>(null);
|
||||||
@ -240,30 +242,45 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
const handleMouseMove = (event: MouseEvent) => {
|
const handleMouseMove = (event: MouseEvent) => {
|
||||||
const { tabId, ref, tabStartX } = draggingTabDataRef.current;
|
const { tabId, ref, tabStartX } = draggingTabDataRef.current;
|
||||||
|
|
||||||
let currentX = event.clientX - ref.current.getBoundingClientRect().width / 2;
|
let initialOffsetX = draggingTabDataRef.current.initialOffsetX;
|
||||||
|
let totalScrollOffset = draggingTabDataRef.current.totalScrollOffset;
|
||||||
|
if (initialOffsetX === null) {
|
||||||
|
initialOffsetX = event.clientX - tabStartX;
|
||||||
|
draggingTabDataRef.current.initialOffsetX = initialOffsetX;
|
||||||
|
}
|
||||||
|
let currentX = event.clientX - initialOffsetX - totalScrollOffset;
|
||||||
let tabBarRectWidth = tabBarRef.current.getBoundingClientRect().width;
|
let tabBarRectWidth = tabBarRef.current.getBoundingClientRect().width;
|
||||||
const dragDirection = getDragDirection(currentX);
|
const dragDirection = getDragDirection(currentX);
|
||||||
|
|
||||||
// Scroll the tab bar if the dragged tab overflows the container bounds
|
// Scroll the tab bar if the dragged tab overflows the container bounds
|
||||||
if (scrollable) {
|
if (scrollable) {
|
||||||
const { viewport } = osInstanceRef.current.elements();
|
const { viewport } = osInstanceRef.current.elements();
|
||||||
const { overflowAmount } = osInstanceRef.current.state();
|
const currentScrollLeft = viewport.scrollLeft;
|
||||||
const { scrollOffsetElement } = osInstanceRef.current.elements();
|
|
||||||
|
|
||||||
if (event.clientX <= 0) {
|
if (event.clientX <= 0) {
|
||||||
viewport.scrollLeft = 0;
|
viewport.scrollLeft = Math.max(0, currentScrollLeft - 5); // Scroll left
|
||||||
|
if (viewport.scrollLeft !== currentScrollLeft) {
|
||||||
|
// Only adjust if the scroll actually changed
|
||||||
|
draggingTabDataRef.current.totalScrollOffset += currentScrollLeft - viewport.scrollLeft;
|
||||||
|
}
|
||||||
} else if (event.clientX >= tabBarRectWidth) {
|
} else if (event.clientX >= tabBarRectWidth) {
|
||||||
viewport.scrollLeft = tabBarRectWidth;
|
viewport.scrollLeft = Math.min(viewport.scrollWidth, currentScrollLeft + 5); // Scroll right
|
||||||
}
|
if (viewport.scrollLeft !== currentScrollLeft) {
|
||||||
|
// Only adjust if the scroll actually changed
|
||||||
if (scrollOffsetElement.scrollLeft > 0) {
|
draggingTabDataRef.current.totalScrollOffset -= viewport.scrollLeft - currentScrollLeft;
|
||||||
currentX += overflowAmount.x;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-calculate currentX after potential scroll adjustment
|
||||||
|
initialOffsetX = draggingTabDataRef.current.initialOffsetX;
|
||||||
|
totalScrollOffset = draggingTabDataRef.current.totalScrollOffset;
|
||||||
|
currentX = event.clientX - initialOffsetX - totalScrollOffset;
|
||||||
|
|
||||||
|
setDraggingTab((prev) => (prev !== tabId ? tabId : prev));
|
||||||
|
|
||||||
// Check if the tab has moved 5 pixels
|
// Check if the tab has moved 5 pixels
|
||||||
if (Math.abs(currentX - tabStartX) >= 5) {
|
if (Math.abs(currentX - tabStartX) >= 50) {
|
||||||
setDraggingTab((prev) => (prev !== tabId ? tabId : prev));
|
|
||||||
draggingTabDataRef.current.dragged = true;
|
draggingTabDataRef.current.dragged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +362,14 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
// Update workspace tab ids
|
// Update workspace tab ids
|
||||||
services.ObjectService.UpdateWorkspaceTabIds(workspace.oid, tabIds);
|
services.ObjectService.UpdateWorkspaceTabIds(workspace.oid, tabIds);
|
||||||
}, 300);
|
}, 300);
|
||||||
|
} else {
|
||||||
|
// Reset styles
|
||||||
|
tabRefs.current.forEach((ref) => {
|
||||||
|
ref.current.style.zIndex = "0";
|
||||||
|
ref.current.classList.remove("animate");
|
||||||
|
});
|
||||||
|
// Reset dragging state
|
||||||
|
setDraggingTab(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.removeEventListener("mouseup", handleMouseUp);
|
document.removeEventListener("mouseup", handleMouseUp);
|
||||||
@ -353,7 +378,9 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDragStart = useCallback(
|
const handleDragStart = useCallback(
|
||||||
(name: string, ref: React.RefObject<HTMLDivElement>) => {
|
(event: React.MouseEvent<HTMLDivElement, MouseEvent>, name: string, ref: React.RefObject<HTMLDivElement>) => {
|
||||||
|
if (event.button !== 0) return;
|
||||||
|
|
||||||
const tabIndex = tabIds.indexOf(name);
|
const tabIndex = tabIds.indexOf(name);
|
||||||
const tabStartX = dragStartPositions[tabIndex]; // Starting X position of the tab
|
const tabStartX = dragStartPositions[tabIndex]; // Starting X position of the tab
|
||||||
|
|
||||||
@ -363,6 +390,8 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
ref,
|
ref,
|
||||||
tabStartX,
|
tabStartX,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
|
initialOffsetX: null,
|
||||||
|
totalScrollOffset: 0,
|
||||||
dragged: false,
|
dragged: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -428,7 +457,7 @@ const TabBar = ({ workspace }: TabBarProps) => {
|
|||||||
id={tabId}
|
id={tabId}
|
||||||
onSelect={() => handleSelectTab(tabId)}
|
onSelect={() => handleSelectTab(tabId)}
|
||||||
active={activetabid === tabId}
|
active={activetabid === tabId}
|
||||||
onDragStart={() => handleDragStart(tabId, tabRefs.current[index])}
|
onDragStart={(event) => handleDragStart(event, tabId, tabRefs.current[index])}
|
||||||
onClose={() => handleCloseTab(tabId)}
|
onClose={() => handleCloseTab(tabId)}
|
||||||
onLoaded={() => handleTabLoaded(tabId)}
|
onLoaded={() => handleTabLoaded(tabId)}
|
||||||
isBeforeActive={isBeforeActive(tabId)}
|
isBeforeActive={isBeforeActive(tabId)}
|
||||||
|
Loading…
Reference in New Issue
Block a user