@@ -47,18 +47,12 @@ const SIDEBAR_MIN_WIDTH = 160;
4747const SIDEBAR_MAX_WIDTH = 480 ;
4848const SIDEBAR_SIZE_KEY = 'sidebar:width' ;
4949
50- /** Floor heights for the two scrollable sidebar regions — kept in lockstep so
51- * neither region can be squeezed to nothing under flex pressure. The projects
52- * section value adds the header strip on top of the tasks-list floor. */
53- const TASKS_LIST_MIN_HEIGHT = '140px' ;
54- const PROJECTS_SECTION_MIN_HEIGHT = '170px' ;
55- /** Caps the project list before it starts pushing the tasks list around;
56- * beyond this the list scrolls internally. */
57- const PROJECTS_LIST_MAX_HEIGHT = '40vh' ;
58- /** Below this many projects the natural content size is already smaller than
59- * PROJECTS_SECTION_MIN_HEIGHT, so reserving the floor would just create dead
60- * space. The floor only matters once content can plausibly threaten tasks. */
61- const PROJECTS_FLOOR_THRESHOLD = 4 ;
50+ /** The task list is the primary navigation surface. When both lists are dense,
51+ * cap projects after a few visible rows so tasks keep most of the sidebar. */
52+ const TASKS_LIST_MIN_HEIGHT = '180px' ;
53+ const PROJECTS_LIST_DEFAULT_MAX_HEIGHT = '40vh' ;
54+ const PROJECTS_LIST_DENSE_MAX_HEIGHT = 'min(24vh, 180px)' ;
55+ const DENSE_SIDEBAR_LIST_THRESHOLD = 4 ;
6256
6357function getAttentionColor ( attention : TaskAttentionState ) : string | null {
6458 if ( attention === 'active' ) return theme . accent ;
@@ -117,6 +111,14 @@ export function Sidebar() {
117111 return map ;
118112 } ) ;
119113 const groupedTasks = createMemo ( ( ) => computeGroupedTasks ( ) ) ;
114+ const sidebarTaskCount = createMemo (
115+ ( ) => store . taskOrder . length + store . collapsedTaskOrder . length ,
116+ ) ;
117+ const projectListMaxHeight = ( ) =>
118+ store . projects . length >= DENSE_SIDEBAR_LIST_THRESHOLD &&
119+ sidebarTaskCount ( ) >= DENSE_SIDEBAR_LIST_THRESHOLD
120+ ? PROJECTS_LIST_DENSE_MAX_HEIGHT
121+ : PROJECTS_LIST_DEFAULT_MAX_HEIGHT ;
120122 function handleResizeMouseDown ( e : MouseEvent ) {
121123 e . preventDefault ( ) ;
122124 setResizing ( true ) ;
@@ -388,15 +390,14 @@ export function Sidebar() {
388390 </ div >
389391 </ div >
390392
391- { /* Projects section — outer enforces the same floor as the tasks list,
392- but only above the threshold (so few-project users see no waste) */ }
393+ { /* Projects section */ }
393394 < div
394395 style = { {
395396 display : 'flex' ,
396397 'flex-direction' : 'column' ,
397398 gap : '6px' ,
398- 'min-height' :
399- store . projects . length >= PROJECTS_FLOOR_THRESHOLD ? PROJECTS_SECTION_MIN_HEIGHT : '0' ,
399+ flex : '0 1 auto' ,
400+ 'min-height' : '0' ,
400401 } }
401402 >
402403 < div
@@ -429,16 +430,15 @@ export function Sidebar() {
429430 />
430431 </ div >
431432
432- { /* Scrollable project list — fills the outer (which carries the
433- floor); caps so tasks below get a fair share */ }
433+ { /* Scrollable project list */ }
434434 < div
435435 style = { {
436436 display : 'flex' ,
437437 'flex-direction' : 'column' ,
438438 gap : '6px' ,
439- flex : '1 ' ,
439+ flex : '0 1 auto ' ,
440440 'min-height' : '0' ,
441- 'max-height' : PROJECTS_LIST_MAX_HEIGHT ,
441+ 'max-height' : projectListMaxHeight ( ) ,
442442 'overflow-y' : 'auto' ,
443443 } }
444444 >
0 commit comments