Skip to content

Commit 0edd296

Browse files
built-by-asclaude
andcommitted
Add three-dot menu for session management
Replaces delete button and click-to-edit with a three-dot menu button that appears on hover. The menu provides options to rename or delete sessions. Menu closes when clicking outside or after selecting an option. Changes: - Added three-dot menu button that appears on hover - Menu contains "Rename" and "Delete" options - Removed direct click-to-edit on session name - Removed standalone delete button - Added click-outside handler to close menus - Delete option highlights red on hover for clarity Co-Authored-By: Claude <[email protected]>
1 parent c5baeb1 commit 0edd296

File tree

2 files changed

+68
-23
lines changed

2 files changed

+68
-23
lines changed

renderer.ts

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -363,19 +363,17 @@ function addToSidebar(sessionId: string, name: string, hasActivePty: boolean) {
363363
<span class="truncate session-name-text" data-id="${sessionId}">${name}</span>
364364
<input type="text" class="session-name-input hidden" data-id="${sessionId}" value="${name}" />
365365
</div>
366-
<button class="session-delete-btn" data-id="${sessionId}" title="Delete session">×</button>
366+
<div class="relative">
367+
<button class="session-menu-btn" data-id="${sessionId}" title="Session options">⋯</button>
368+
<div class="session-menu hidden" data-id="${sessionId}">
369+
<button class="session-menu-item rename-session-btn" data-id="${sessionId}">Rename</button>
370+
<button class="session-menu-item delete-session-btn" data-id="${sessionId}">Delete</button>
371+
</div>
372+
</div>
367373
`;
368374

369-
// Click on session name to edit
370-
const nameText = item.querySelector(".session-name-text");
371-
const nameInput = item.querySelector(".session-name-input") as HTMLInputElement;
372-
373-
nameText?.addEventListener("click", (e) => {
374-
e.stopPropagation();
375-
startEditingSessionName(sessionId);
376-
});
377-
378375
// Handle input blur and enter key
376+
const nameInput = item.querySelector(".session-name-input") as HTMLInputElement;
379377
nameInput?.addEventListener("blur", () => {
380378
finishEditingSessionName(sessionId);
381379
});
@@ -388,18 +386,46 @@ function addToSidebar(sessionId: string, name: string, hasActivePty: boolean) {
388386
}
389387
});
390388

389+
// Click on item to activate session
391390
item.addEventListener("click", (e) => {
392391
const target = e.target as HTMLElement;
393-
if (!target.classList.contains("session-delete-btn") &&
394-
!target.classList.contains("session-name-text") &&
395-
!target.classList.contains("session-name-input")) {
392+
if (!target.classList.contains("session-menu-btn") &&
393+
!target.classList.contains("session-menu-item") &&
394+
!target.classList.contains("session-name-input") &&
395+
!target.closest(".session-menu")) {
396396
handleSessionClick(sessionId);
397397
}
398398
});
399399

400-
const deleteBtn = item.querySelector(".session-delete-btn");
400+
// Menu button toggle
401+
const menuBtn = item.querySelector(".session-menu-btn");
402+
const menu = item.querySelector(".session-menu") as HTMLElement;
403+
404+
menuBtn?.addEventListener("click", (e) => {
405+
e.stopPropagation();
406+
407+
// Close all other menus
408+
document.querySelectorAll(".session-menu").forEach(m => {
409+
if (m !== menu) m.classList.add("hidden");
410+
});
411+
412+
// Toggle this menu
413+
menu?.classList.toggle("hidden");
414+
});
415+
416+
// Rename button
417+
const renameBtn = item.querySelector(".rename-session-btn");
418+
renameBtn?.addEventListener("click", (e) => {
419+
e.stopPropagation();
420+
menu?.classList.add("hidden");
421+
startEditingSessionName(sessionId);
422+
});
423+
424+
// Delete button
425+
const deleteBtn = item.querySelector(".delete-session-btn");
401426
deleteBtn?.addEventListener("click", (e) => {
402427
e.stopPropagation();
428+
menu?.classList.add("hidden");
403429
deleteSession(sessionId);
404430
});
405431

@@ -1464,3 +1490,13 @@ saveSettingsBtn?.addEventListener("click", async () => {
14641490

14651491
// Load settings on startup
14661492
loadSettings();
1493+
1494+
// Close session menus when clicking outside
1495+
document.addEventListener("click", (e) => {
1496+
const target = e.target as HTMLElement;
1497+
if (!target.closest(".session-menu") && !target.classList.contains("session-menu-btn")) {
1498+
document.querySelectorAll(".session-menu").forEach(menu => {
1499+
menu.classList.add("hidden");
1500+
});
1501+
}
1502+
});

styles.css

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,35 @@
7373
@apply bg-red-500;
7474
}
7575

76-
.session-delete-btn {
77-
@apply text-gray-500 hover:text-red-500 ml-2;
76+
.session-menu-btn {
77+
@apply text-gray-500 hover:text-gray-300 hover:bg-gray-600 ml-2 px-2 rounded transition-all;
7878
opacity: 0;
79-
transition: opacity 0.2s;
79+
font-size: 18px;
80+
line-height: 1;
8081
}
8182

82-
.session-list-item:hover .session-delete-btn {
83+
.session-list-item:hover .session-menu-btn {
8384
opacity: 1;
8485
}
8586

87+
.session-menu {
88+
@apply absolute right-0 mt-1 bg-gray-700 border border-gray-600 rounded shadow-lg z-10 py-1 min-w-[120px];
89+
}
90+
91+
.session-menu-item {
92+
@apply w-full text-left px-3 py-2 text-sm text-gray-300 hover:bg-gray-600 hover:text-white transition-colors;
93+
}
94+
95+
.session-menu-item.delete-session-btn {
96+
@apply hover:bg-red-600 hover:text-white;
97+
}
98+
8699
.session-name-container {
87100
min-width: 0;
88101
}
89102

90103
.session-name-text {
91-
cursor: pointer;
92-
}
93-
94-
.session-name-text:hover {
95-
@apply text-gray-100;
104+
@apply text-gray-300;
96105
}
97106

98107
.session-name-input {

0 commit comments

Comments
 (0)