godcrm/components/AIChatPanel/hooks/usePanelResize.ts
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

126 lines
No EOL
3.9 KiB
TypeScript

/**
* usePanelResize Hook
* Handles panel resizing logic extracted from AIChatPanel
*/
import { useState, useCallback, useEffect } from 'react';
interface UsePanelResizeOptions {
initialPanelWidth?: number;
initialSidebarWidth?: number;
initialPanelHeight?: number | 'auto';
minPanelWidth?: number;
maxPanelWidth?: number;
minSidebarWidth?: number;
maxSidebarWidth?: number;
}
export function usePanelResize({
initialPanelWidth = 420,
initialSidebarWidth = 256,
initialPanelHeight = 'auto',
minPanelWidth = 320,
maxPanelWidth = 1170,
minSidebarWidth = 180,
maxSidebarWidth = 400
}: UsePanelResizeOptions = {}) {
const [panelWidth, setPanelWidthState] = useState(initialPanelWidth);
const [sidebarWidth, setSidebarWidthState] = useState(initialSidebarWidth);
const [panelHeight, setPanelHeight] = useState<number | 'auto'>(initialPanelHeight);
const [isResizing, setIsResizing] = useState(false);
const [isResizingWidth, setIsResizingWidth] = useState(false);
const [isResizingSidebar, setIsResizingSidebar] = useState(false);
// Constrain panel width within limits
const setPanelWidth = useCallback((width: number) => {
const constrainedWidth = Math.max(minPanelWidth, Math.min(maxPanelWidth, width));
setPanelWidthState(constrainedWidth);
}, [minPanelWidth, maxPanelWidth]);
// Constrain sidebar width within limits
const setSidebarWidth = useCallback((width: number) => {
const constrainedWidth = Math.max(minSidebarWidth, Math.min(maxSidebarWidth, width));
setSidebarWidthState(constrainedWidth);
}, [minSidebarWidth, maxSidebarWidth]);
// Start resizing panel width
const startResizingWidth = useCallback(() => {
setIsResizingWidth(true);
const handleMouseMove = (e: MouseEvent) => {
const newWidth = e.clientX;
setPanelWidth(newWidth);
};
const handleMouseUp = () => {
setIsResizingWidth(false);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
}, [setPanelWidth]);
// Start resizing sidebar width
const startResizingSidebar = useCallback(() => {
setIsResizingSidebar(true);
const handleMouseMove = (e: MouseEvent) => {
const rect = e.currentTarget as Element;
const newWidth = (rect as HTMLElement)?.offsetWidth - (e.clientX - (rect as HTMLElement)?.offsetLeft) || sidebarWidth;
setSidebarWidth(newWidth);
};
const handleMouseUp = () => {
setIsResizingSidebar(false);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
}, [setSidebarWidth, sidebarWidth]);
// Start resizing panel height
const startResizing = useCallback(() => {
setIsResizing(true);
const handleMouseMove = (e: MouseEvent) => {
const newHeight = window.innerHeight - e.clientY;
setPanelHeight(Math.max(200, Math.min(window.innerHeight - 100, newHeight)));
};
const handleMouseUp = () => {
setIsResizing(false);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
};
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
}, []);
// Cleanup event listeners on unmount
useEffect(() => {
return () => {
window.removeEventListener('mousemove', () => {});
window.removeEventListener('mouseup', () => {});
};
}, []);
return {
panelWidth,
sidebarWidth,
panelHeight,
isResizing,
isResizingWidth,
isResizingSidebar,
setPanelWidth,
setSidebarWidth,
setPanelHeight,
startResizing,
startResizingWidth,
startResizingSidebar
};
}