increased handle width in task panel (vibe-kanban) (#1202)

* Done! I've implemented the conditional width expansion solution for both resize handles.

**Changes made to [TasksLayout.tsx](file:///private/var/folders/5q/5vgq75y92dz0k7n62z93299r0000gn/T/vibe-kanban/worktrees/827f-handle/frontend/src/components/layout/TasksLayout.tsx):**

1. Added state tracking for panel sizes in both components
2. Updated `onLayout` handlers to track current panel sizes
3. Applied conditional styling: when panel < 5%, handle expands from 4px (`w-1`) to 24px (`w-6`)
4. Added smooth transitions between states

This fixes the grabability issue in both scenarios:
- Kanban/attempt handle (when kanban is collapsed)
- Attempt/aux handle in preview/diffs view (when attempt is collapsed)

* Perfect! I've updated the code to use the `onCollapse` and `onExpand` callbacks instead of size comparisons. The implementation is now cleaner and more semantic.

**Changes made:**
- Replaced size tracking with boolean collapsed state
- Added `onCollapse` and `onExpand` callbacks to both Panel components
- Updated handle styling to use `isKanbanCollapsed` and `isAttemptCollapsed` states
- Removed the size tracking logic from `onLayout` handlers

This approach is better because it directly uses the library's built-in collapse/expand events rather than inferring state from size values.

* Much better! I refactored the className to use the `cn` utility with multiple arguments for better readability. This is more idiomatic for Tailwind-based projects using shadcn/ui.
This commit is contained in:
Britannio Jarrett
2025-11-06 13:33:28 +00:00
committed by GitHub
parent e2ca4083fb
commit bcb9b4f0b9

View File

@@ -1,6 +1,7 @@
import { ReactNode, useState } from 'react'; import { ReactNode, useState } from 'react';
import { PanelGroup, Panel, PanelResizeHandle } from 'react-resizable-panels'; import { PanelGroup, Panel, PanelResizeHandle } from 'react-resizable-panels';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { cn } from '@/lib/utils';
export type LayoutMode = 'preview' | 'diffs' | null; export type LayoutMode = 'preview' | 'diffs' | null;
@@ -86,6 +87,7 @@ function RightWorkArea({
const [innerSizes] = useState<SplitSizes>(() => const [innerSizes] = useState<SplitSizes>(() =>
loadSizes(STORAGE_KEYS.ATTEMPT_AUX, DEFAULT_ATTEMPT_AUX) loadSizes(STORAGE_KEYS.ATTEMPT_AUX, DEFAULT_ATTEMPT_AUX)
); );
const [isAttemptCollapsed, setIsAttemptCollapsed] = useState(false);
return ( return (
<div className="h-full min-h-0 flex flex-col"> <div className="h-full min-h-0 flex flex-col">
@@ -114,6 +116,8 @@ function RightWorkArea({
minSize={MIN_PANEL_SIZE} minSize={MIN_PANEL_SIZE}
collapsible collapsible
collapsedSize={0} collapsedSize={0}
onCollapse={() => setIsAttemptCollapsed(true)}
onExpand={() => setIsAttemptCollapsed(false)}
className="min-w-0 min-h-0 overflow-hidden" className="min-w-0 min-h-0 overflow-hidden"
role="region" role="region"
aria-label="Details" aria-label="Details"
@@ -123,7 +127,13 @@ function RightWorkArea({
<PanelResizeHandle <PanelResizeHandle
id="handle-aa" id="handle-aa"
className="relative z-30 w-1 bg-border cursor-col-resize group touch-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-1 focus-visible:ring-offset-background" className={cn(
'relative z-30 bg-border cursor-col-resize group touch-none',
'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/60',
'focus-visible:ring-offset-1 focus-visible:ring-offset-background',
'transition-all',
isAttemptCollapsed ? 'w-6' : 'w-1'
)}
aria-label="Resize panels" aria-label="Resize panels"
role="separator" role="separator"
aria-orientation="vertical" aria-orientation="vertical"
@@ -176,6 +186,7 @@ function DesktopSimple({
const [outerSizes] = useState<SplitSizes>(() => const [outerSizes] = useState<SplitSizes>(() =>
loadSizes(STORAGE_KEYS.KANBAN_ATTEMPT, DEFAULT_KANBAN_ATTEMPT) loadSizes(STORAGE_KEYS.KANBAN_ATTEMPT, DEFAULT_KANBAN_ATTEMPT)
); );
const [isKanbanCollapsed, setIsKanbanCollapsed] = useState(false);
// When preview/diffs is open, hide Kanban entirely and render only RightWorkArea // When preview/diffs is open, hide Kanban entirely and render only RightWorkArea
if (mode !== null) { if (mode !== null) {
@@ -207,6 +218,8 @@ function DesktopSimple({
minSize={MIN_PANEL_SIZE} minSize={MIN_PANEL_SIZE}
collapsible collapsible
collapsedSize={0} collapsedSize={0}
onCollapse={() => setIsKanbanCollapsed(true)}
onExpand={() => setIsKanbanCollapsed(false)}
className="min-w-0 min-h-0 overflow-hidden" className="min-w-0 min-h-0 overflow-hidden"
role="region" role="region"
aria-label="Kanban board" aria-label="Kanban board"
@@ -216,7 +229,13 @@ function DesktopSimple({
<PanelResizeHandle <PanelResizeHandle
id="handle-kr" id="handle-kr"
className="relative z-30 w-1 bg-border cursor-col-resize group touch-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-1 focus-visible:ring-offset-background" className={cn(
'relative z-30 bg-border cursor-col-resize group touch-none',
'focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/60',
'focus-visible:ring-offset-1 focus-visible:ring-offset-background',
'transition-all',
isKanbanCollapsed ? 'w-6' : 'w-1'
)}
aria-label="Resize panels" aria-label="Resize panels"
role="separator" role="separator"
aria-orientation="vertical" aria-orientation="vertical"