Files
nexus-terminal/packages/frontend/src/composables/useSidebarResize.ts
T
Baobhan Sith ca1fcf9fc3 update
2025-04-21 23:45:50 +08:00

101 lines
3.3 KiB
TypeScript

import { ref, onMounted, onUnmounted, type Ref, watch } from 'vue'; // +++ Import watch +++
interface UseSidebarResizeOptions {
sidebarRef: Ref<HTMLElement | null>;
handleRef: Ref<HTMLElement | null>;
side: 'left' | 'right';
minWidth?: number;
maxWidth?: number;
onResizeEnd?: (newWidth: number) => void;
}
export function useSidebarResize({
sidebarRef,
handleRef,
side,
minWidth = 200, // 默认最小宽度
maxWidth = 800, // 默认最大宽度
onResizeEnd,
}: UseSidebarResizeOptions) {
const isDragging = ref(false);
const startX = ref(0);
const startWidth = ref(0);
const handleMouseDown = (event: MouseEvent) => {
console.log(`[useSidebarResize] handleMouseDown triggered for side: ${side}`, { sidebar: sidebarRef.value, handle: handleRef.value }); // +++ Add Log +++
if (!sidebarRef.value || !handleRef.value) {
console.log('[useSidebarResize] MouseDown ignored: sidebarRef or handleRef is null.'); // +++ Add Log +++
return;
}
isDragging.value = true;
startX.value = event.clientX;
startWidth.value = sidebarRef.value.offsetWidth;
document.body.style.cursor = 'col-resize'; // 改变鼠标样式
document.body.style.userSelect = 'none'; // 禁止选择文本
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
};
const handleMouseMove = (event: MouseEvent) => {
if (!isDragging.value || !sidebarRef.value) return;
const currentX = event.clientX;
const deltaX = currentX - startX.value;
let newWidth: number;
if (side === 'left') {
newWidth = startWidth.value + deltaX;
} else { // side === 'right'
newWidth = startWidth.value - deltaX;
}
// 应用宽度限制
newWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
sidebarRef.value.style.width = `${newWidth}px`;
};
const handleMouseUp = () => {
if (!isDragging.value) return;
isDragging.value = false;
document.body.style.cursor = ''; // 恢复鼠标样式
document.body.style.userSelect = ''; // 恢复文本选择
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
if (sidebarRef.value && onResizeEnd) {
onResizeEnd(sidebarRef.value.offsetWidth); // 传递最终宽度
}
};
// 使用 watch 监视 handleRef 的变化
watch(handleRef, (newHandle, oldHandle) => {
// 移除旧句柄上的监听器(如果存在)
if (oldHandle) {
oldHandle.removeEventListener('mousedown', handleMouseDown);
}
// 在新句柄上添加监听器(如果存在)
if (newHandle) {
newHandle.addEventListener('mousedown', handleMouseDown);
}
}, { immediate: true }); // immediate: true 确保初始时也能尝试附加
onUnmounted(() => {
// 组件卸载时确保移除监听器
if (handleRef.value) {
handleRef.value.removeEventListener('mousedown', handleMouseDown);
}
// 清理可能残留的全局监听器
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
document.body.style.cursor = '';
document.body.style.userSelect = '';
});
// 返回 isDragging 状态,可能用于 UI 反馈
return { isDragging };
}