Skip to content

Commit 5328e34

Browse files
committed
Prioritize tasks in dense sidebar
1 parent 325a314 commit 5328e34

1 file changed

Lines changed: 20 additions & 20 deletions

File tree

src/components/Sidebar.tsx

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,12 @@ const SIDEBAR_MIN_WIDTH = 160;
4747
const SIDEBAR_MAX_WIDTH = 480;
4848
const 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

6357
function 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

Comments
 (0)