Skip to content

Commit d5c39f5

Browse files
committed
feat(webapp): remove the middle collapse handle in favor of the footer button
The side menu footer collapse button now handles toggling, so the middle-right handle (and its animated chevron) is redundant. The cmd+b shortcut is preserved.
1 parent f593730 commit d5c39f5

1 file changed

Lines changed: 0 additions & 127 deletions

File tree

apps/webapp/app/components/navigation/SideMenu.tsx

Lines changed: 0 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ export function SideMenu({
296296
isCollapsed ? "w-[2.75rem]" : "w-56"
297297
)}
298298
>
299-
<CollapseToggle isCollapsed={isCollapsed} onToggle={handleToggleCollapsed} />
300299
<div className="absolute inset-0 grid grid-cols-[100%] grid-rows-[2.5rem_auto_1fr_auto] overflow-hidden">
301300
<div className="flex min-w-0 items-center overflow-hidden border-b border-transparent px-1 py-1">
302301
<div className={cn("min-w-0", !isCollapsed && "flex-1")}>
@@ -1432,129 +1431,3 @@ function CollapseMenuButton({
14321431
</div>
14331432
);
14341433
}
1435-
1436-
function AnimatedChevron({
1437-
isHovering,
1438-
isCollapsed,
1439-
}: {
1440-
isHovering: boolean;
1441-
isCollapsed: boolean;
1442-
}) {
1443-
// When hovering and expanded: left chevron (pointing left to collapse)
1444-
// When hovering and collapsed: right chevron (pointing right to expand)
1445-
// When not hovering: straight vertical line
1446-
1447-
const getRotation = () => {
1448-
if (!isHovering) return { top: 0, bottom: 0 };
1449-
if (isCollapsed) {
1450-
// Right chevron
1451-
return { top: -17, bottom: 17 };
1452-
} else {
1453-
// Left chevron
1454-
return { top: 17, bottom: -17 };
1455-
}
1456-
};
1457-
1458-
const { top, bottom } = getRotation();
1459-
1460-
// Calculate horizontal offset to keep chevron centered when rotated
1461-
// Left chevron: translate left (-1.5px)
1462-
// Right chevron: translate right (+1.5px)
1463-
const getTranslateX = () => {
1464-
if (!isHovering) return 0;
1465-
return isCollapsed ? 1.5 : -1.5;
1466-
};
1467-
1468-
return (
1469-
<motion.svg
1470-
width="4"
1471-
height="30"
1472-
viewBox="0 0 4 30"
1473-
fill="none"
1474-
xmlns="http://www.w3.org/2000/svg"
1475-
className="pointer-events-none relative z-10 overflow-visible text-charcoal-600 transition-colors group-hover:text-text-bright"
1476-
initial={false}
1477-
animate={{
1478-
x: getTranslateX(),
1479-
}}
1480-
transition={{ duration: 0.4, ease: "easeOut" }}
1481-
>
1482-
{/* Top segment */}
1483-
<motion.line
1484-
x1="2"
1485-
y1="1.5"
1486-
x2="2"
1487-
y2="15"
1488-
stroke="currentColor"
1489-
strokeWidth="3"
1490-
strokeLinecap="round"
1491-
initial={false}
1492-
animate={{
1493-
rotate: top,
1494-
}}
1495-
transition={{ duration: 0.2, ease: "easeOut" }}
1496-
style={{ transformOrigin: "2px 15px" }}
1497-
/>
1498-
{/* Bottom segment */}
1499-
<motion.line
1500-
x1="2"
1501-
y1="15"
1502-
x2="2"
1503-
y2="28.5"
1504-
stroke="currentColor"
1505-
strokeWidth="3"
1506-
strokeLinecap="round"
1507-
initial={false}
1508-
animate={{
1509-
rotate: bottom,
1510-
}}
1511-
transition={{ duration: 0.2, ease: "easeOut" }}
1512-
style={{ transformOrigin: "2px 15px" }}
1513-
/>
1514-
</motion.svg>
1515-
);
1516-
}
1517-
1518-
function CollapseToggle({ isCollapsed, onToggle }: { isCollapsed: boolean; onToggle: () => void }) {
1519-
const [isHovering, setIsHovering] = useState(false);
1520-
1521-
return (
1522-
<div className="absolute -right-3 top-1/2 z-10 -translate-y-1/2">
1523-
{/* Vertical line to mask the side menu border */}
1524-
<div
1525-
className={cn(
1526-
"pointer-events-none absolute left-1/2 top-1/2 h-10 w-px -translate-y-1/2 transition-colors duration-200",
1527-
isHovering ? "bg-charcoal-750" : "bg-background-bright"
1528-
)}
1529-
/>
1530-
<TooltipProvider disableHoverableContent>
1531-
<Tooltip>
1532-
<TooltipTrigger asChild>
1533-
<button
1534-
type="button"
1535-
aria-label={isCollapsed ? "Expand side menu" : "Collapse side menu"}
1536-
onClick={onToggle}
1537-
onMouseEnter={() => setIsHovering(true)}
1538-
onMouseLeave={() => setIsHovering(false)}
1539-
className={cn(
1540-
"group flex h-12 w-6 items-center justify-center rounded-md text-text-dimmed transition-all duration-200 focus-custom",
1541-
isHovering
1542-
? "border border-grid-bright bg-background-bright shadow-md hover:bg-charcoal-750 hover:text-text-bright"
1543-
: "border border-transparent bg-transparent"
1544-
)}
1545-
>
1546-
<AnimatedChevron isHovering={isHovering} isCollapsed={isCollapsed} />
1547-
</button>
1548-
</TooltipTrigger>
1549-
<TooltipContent side="right" className="flex items-center gap-2 text-xs">
1550-
{isCollapsed ? "Expand" : "Collapse"}
1551-
<span className="flex items-center">
1552-
<ShortcutKey shortcut={{ modifiers: ["mod"] }} variant="medium/bright" />
1553-
<ShortcutKey shortcut={{ key: "b" }} variant="medium/bright" />
1554-
</span>
1555-
</TooltipContent>
1556-
</Tooltip>
1557-
</TooltipProvider>
1558-
</div>
1559-
);
1560-
}

0 commit comments

Comments
 (0)