feat: make side bar size adjustble

This commit is contained in:
Richard Tang
2026-04-16 11:15:47 -07:00
parent ae1599c66a
commit 36ebf27e3e
2 changed files with 85 additions and 4 deletions
@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useCallback, useRef } from "react";
import { NavLink, useLocation, useNavigate } from "react-router-dom";
import {
X,
@@ -46,8 +46,49 @@ export default function QueenProfilePanel({
const name = profile?.name ?? summary?.name ?? "Queen";
const title = profile?.title ?? summary?.title ?? "";
// ── Resizable width ──────────────────────────────────────────────────
const MIN_WIDTH = 280;
const MAX_WIDTH = 600;
const [width, setWidth] = useState(340);
const dragging = useRef(false);
const startX = useRef(0);
const startWidth = useRef(0);
const onDragStart = useCallback((e: React.MouseEvent) => {
e.preventDefault();
dragging.current = true;
startX.current = e.clientX;
startWidth.current = width;
const onMove = (ev: MouseEvent) => {
if (!dragging.current) return;
// Panel is on the right, so dragging left (negative delta) grows it
const delta = startX.current - ev.clientX;
setWidth(Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, startWidth.current + delta)));
};
const onUp = () => {
dragging.current = false;
document.removeEventListener("mousemove", onMove);
document.removeEventListener("mouseup", onUp);
document.body.style.cursor = "";
document.body.style.userSelect = "";
};
document.addEventListener("mousemove", onMove);
document.addEventListener("mouseup", onUp);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
}, [width]);
return (
<aside className="w-[340px] flex-shrink-0 border-l border-border/60 bg-card overflow-y-auto">
<aside
className="flex-shrink-0 border-l border-border/60 bg-card overflow-y-auto relative"
style={{ width }}
>
{/* Drag handle */}
<div
onMouseDown={onDragStart}
className="absolute top-0 left-0 w-1 h-full cursor-col-resize hover:bg-primary/30 active:bg-primary/50 transition-colors z-10"
/>
{/* Header */}
<div className="flex items-center justify-between px-5 py-3.5 border-b border-border/60">
<div className="flex items-center gap-2 text-sm font-semibold text-foreground">
+42 -2
View File
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useCallback, useRef } from "react";
import { useNavigate } from "react-router-dom";
import {
ChevronLeft,
@@ -19,6 +19,38 @@ export default function Sidebar() {
const [coloniesExpanded, setColoniesExpanded] = useState(true);
const [queensExpanded, setQueensExpanded] = useState(true);
// ── Resizable width ──────────────────────────────────────────────────
const MIN_WIDTH = 180;
const MAX_WIDTH = 400;
const [width, setWidth] = useState(240);
const dragging = useRef(false);
const startX = useRef(0);
const startWidth = useRef(0);
const onDragStart = useCallback((e: React.MouseEvent) => {
e.preventDefault();
dragging.current = true;
startX.current = e.clientX;
startWidth.current = width;
const onMove = (ev: MouseEvent) => {
if (!dragging.current) return;
const delta = ev.clientX - startX.current;
setWidth(Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, startWidth.current + delta)));
};
const onUp = () => {
dragging.current = false;
document.removeEventListener("mousemove", onMove);
document.removeEventListener("mouseup", onUp);
document.body.style.cursor = "";
document.body.style.userSelect = "";
};
document.addEventListener("mousemove", onMove);
document.addEventListener("mouseup", onUp);
document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
}, [width]);
if (sidebarCollapsed) {
return (
<aside className="w-[52px] flex-shrink-0 flex flex-col bg-sidebar-bg border-r border-sidebar-border h-full">
@@ -47,7 +79,15 @@ export default function Sidebar() {
}
return (
<aside className="w-[240px] flex-shrink-0 flex flex-col bg-sidebar-bg border-r border-sidebar-border h-full">
<aside
className="flex-shrink-0 flex flex-col bg-sidebar-bg border-r border-sidebar-border h-full relative"
style={{ width }}
>
{/* Drag handle on right edge */}
<div
onMouseDown={onDragStart}
className="absolute top-0 right-0 w-1 h-full cursor-col-resize hover:bg-primary/30 active:bg-primary/50 transition-colors z-10"
/>
{/* Header */}
<div className="h-12 flex items-center justify-between px-4 border-b border-border/60">
<button