v1.8.0 #429

Merged
LukeGus merged 198 commits from dev-1.8.0 into main 2025-11-05 16:36:16 +00:00
2 changed files with 86 additions and 5 deletions
Showing only changes of commit 9a697a7c10 - Show all commits

View File

@@ -241,6 +241,63 @@ export function LeftSidebar({
localStorage.setItem("leftSidebarOpen", JSON.stringify(isSidebarOpen)); localStorage.setItem("leftSidebarOpen", JSON.stringify(isSidebarOpen));
}, [isSidebarOpen]); }, [isSidebarOpen]);
// Sidebar width state for resizing
const [sidebarWidth, setSidebarWidth] = useState<number>(() => {
const saved = localStorage.getItem("leftSidebarWidth");
return saved !== null ? parseInt(saved, 10) : 320;
});
const [isResizing, setIsResizing] = useState(false);
const startXRef = React.useRef<number | null>(null);
const startWidthRef = React.useRef<number>(sidebarWidth);
React.useEffect(() => {
localStorage.setItem("leftSidebarWidth", String(sidebarWidth));
}, [sidebarWidth]);
const handleMouseDown = (e: React.MouseEvent) => {
e.preventDefault();
setIsResizing(true);
startXRef.current = e.clientX;
startWidthRef.current = sidebarWidth;
};
React.useEffect(() => {
if (!isResizing) return;
const handleMouseMove = (e: MouseEvent) => {
if (startXRef.current == null) return;
const dx = e.clientX - startXRef.current;
const newWidth = Math.round(startWidthRef.current + dx);
const minWidth = 200;
const maxWidth = Math.round(window.innerWidth * 0.5);
if (newWidth >= minWidth && newWidth <= maxWidth) {
setSidebarWidth(newWidth);
} else if (newWidth < minWidth) {
setSidebarWidth(minWidth);
} else if (newWidth > maxWidth) {
setSidebarWidth(maxWidth);
}
};
const handleMouseUp = () => {
setIsResizing(false);
startXRef.current = null;
};
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
document.body.style.cursor = "";
document.body.style.userSelect = "";
};
}, [isResizing]);
const filteredHosts = React.useMemo(() => { const filteredHosts = React.useMemo(() => {
if (!debouncedSearch.trim()) return hosts; if (!debouncedSearch.trim()) return hosts;
const q = debouncedSearch.trim().toLowerCase(); const q = debouncedSearch.trim().toLowerCase();
@@ -293,8 +350,12 @@ export function LeftSidebar({
return ( return (
<div className="min-h-svh"> <div className="min-h-svh">
<SidebarProvider open={isSidebarOpen}> <SidebarProvider
<Sidebar variant="floating" className=""> open={isSidebarOpen}
style={{ "--sidebar-width": `${sidebarWidth}px` } as React.CSSProperties}
>
<div className="flex h-screen w-full">
<Sidebar variant="floating" className="">
<SidebarHeader> <SidebarHeader>
<SidebarGroupLabel className="text-lg font-bold text-white"> <SidebarGroupLabel className="text-lg font-bold text-white">
Termix Termix
@@ -416,8 +477,27 @@ export function LeftSidebar({
</SidebarMenuItem> </SidebarMenuItem>
</SidebarMenu> </SidebarMenu>
</SidebarFooter> </SidebarFooter>
</Sidebar> </Sidebar>
<SidebarInset>{children}</SidebarInset>
{/* Resizable divider */}
{isSidebarOpen && (
<div
className="w-4 cursor-col-resize h-screen z-50 bg-transparent hover:bg-dark-border/30 flex items-center justify-center"
onMouseDown={handleMouseDown}
title="Drag to resize sidebar"
>
<div
className={`w-1 h-full transition-colors duration-200 ${
isResizing
? "bg-dark-active"
: "bg-dark-border hover:bg-dark-border-hover"
}`}
/>
</div>
)}
<SidebarInset>{children}</SidebarInset>
</div>
</SidebarProvider> </SidebarProvider>
{!isSidebarOpen && ( {!isSidebarOpen && (

View File

@@ -50,7 +50,8 @@ export function TopNavbar({
allSplitScreenTab: number[]; allSplitScreenTab: number[];
reorderTabs: (fromIndex: number, toIndex: number) => void; reorderTabs: (fromIndex: number, toIndex: number) => void;
}; };
const leftPosition = state === "collapsed" ? "26px" : "264px"; // Use CSS variable for dynamic sidebar width + divider width (4px) + some padding
const leftPosition = state === "collapsed" ? "26px" : "calc(var(--sidebar-width) + 20px)";
const { t } = useTranslation(); const { t } = useTranslation();
const [toolsSheetOpen, setToolsSheetOpen] = useState(false); const [toolsSheetOpen, setToolsSheetOpen] = useState(false);