Add inline title/description editing and list delete to the list view

ListView: the title and description are now inline-editable fields saved on
blur via PATCH /api/lists/:id; an empty description shows an "Add a
description" placeholder. A "Manage" menu in the top right (click-outside and
Esc to close) holds a "Delete list" action that opens a confirmation modal;
confirming calls DELETE and routes back to the all-lists view. No backend
change — the existing PATCH/DELETE endpoints cover it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 19:10:31 +01:00
co-authored by Claude Sonnet 5
parent 8d0e0165bb
commit 3bf70504cc
3 changed files with 367 additions and 9 deletions
+182
View File
@@ -233,6 +233,188 @@ h1 {
background: var(--bg);
}
/* --- list detail: header, inline title/description, manage menu -------- */
.list-head {
display: flex;
align-items: flex-start;
gap: 0.5rem;
}
.list-head__title {
flex: 1;
min-width: 0;
margin: 0 0 0.5rem;
}
.list-head__title input,
.list-head__desc {
width: 100%;
font: inherit;
color: var(--text);
background: transparent;
border: 1px solid transparent;
border-radius: 6px;
padding: 0.25rem 0.4rem;
}
.list-head__title input {
font-size: 1.4rem;
font-weight: 600;
}
.list-head__desc {
display: block;
resize: vertical;
min-height: 2.75rem;
font-size: 0.95rem;
color: var(--muted);
margin-bottom: 0.75rem;
}
.list-head__title input:hover,
.list-head__desc:hover {
border-color: var(--border);
}
.list-head__title input:focus,
.list-head__desc:focus {
outline: none;
color: var(--text);
background: var(--bg);
border-color: var(--accent);
}
.menu {
position: relative;
flex: none;
}
.menu__toggle {
border: 1px solid var(--border);
background: var(--bg);
color: var(--text);
border-radius: 8px;
padding: 0.35rem 0.7rem;
font: inherit;
font-size: 0.9rem;
cursor: pointer;
}
.menu__toggle:hover {
border-color: var(--muted);
}
.menu__backdrop {
position: fixed;
inset: 0;
z-index: 10;
}
.menu__list {
position: absolute;
right: 0;
top: calc(100% + 4px);
z-index: 20;
min-width: 10rem;
margin: 0;
padding: 0.25rem;
list-style: none;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
}
.menu__item {
display: block;
width: 100%;
text-align: left;
border: none;
background: none;
color: var(--text);
font: inherit;
padding: 0.45rem 0.6rem;
border-radius: 6px;
cursor: pointer;
}
.menu__item:hover {
background: var(--bg);
}
.menu__item--danger {
color: var(--error);
}
/* --- confirmation modal --------------------------------------------------- */
.modal {
position: fixed;
inset: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.modal__backdrop {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.45);
}
.modal__dialog {
position: relative;
z-index: 1;
width: 100%;
max-width: 24rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 1.5rem;
}
.modal__dialog h2 {
margin: 0 0 0.5rem;
font-size: 1.15rem;
}
.modal__actions {
display: flex;
justify-content: flex-end;
gap: 0.6rem;
margin-top: 1.25rem;
}
.btn-secondary,
.btn-danger {
border: 1px solid var(--border);
border-radius: 8px;
padding: 0.5rem 0.9rem;
font: inherit;
font-size: 0.95rem;
cursor: pointer;
}
.btn-secondary {
background: var(--bg);
color: var(--text);
}
.btn-danger {
background: #b3261e;
border-color: #b3261e;
color: #fff;
}
.btn-secondary:disabled,
.btn-danger:disabled {
opacity: 0.6;
cursor: default;
}
.form {
display: grid;
gap: 1rem;