From a970a03f5d6af83246e9ca53fd897f104adecb74 Mon Sep 17 00:00:00 2001 From: bboysoul Date: Mon, 21 Sep 2026 11:32:49 +0800 Subject: [PATCH] style: refine archived habits section --- frontend/e2e/habit-detail-paper-flow.spec.ts | 12 ++++++++++++ frontend/src/style.css | 6 +++--- frontend/src/visual-polish.test.ts | 5 ++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/frontend/e2e/habit-detail-paper-flow.spec.ts b/frontend/e2e/habit-detail-paper-flow.spec.ts index 298b66e..38351fa 100644 --- a/frontend/e2e/habit-detail-paper-flow.spec.ts +++ b/frontend/e2e/habit-detail-paper-flow.spec.ts @@ -108,7 +108,19 @@ test('habit detail paper flow is responsive, ordered, scrollable, and preserves await dialog.getByRole('button', { name: '关闭习惯详情' }).click() const archiveToggle = page.locator('.habit-archive-toggle') + const activeList = page.locator('.habit-list.plain-list').last() + const [activeListBox, archiveToggleBox] = await Promise.all([activeList.boundingBox(), archiveToggle.boundingBox()]) + expect(activeListBox).not.toBeNull() + expect(archiveToggleBox).not.toBeNull() + expect(archiveToggleBox!.y - (activeListBox!.y + activeListBox!.height)).toBeGreaterThanOrEqual(24) + await expect(archiveToggle).toHaveCSS('background-color', 'rgba(0, 0, 0, 0)') + await expect(archiveToggle).toHaveCSS('border-top-width', '0px') await archiveToggle.click() + const archivedPanel = page.locator('#archived-habits-panel') + const [toggleOpenBox, archivePanelBox] = await Promise.all([archiveToggle.boundingBox(), archivedPanel.boundingBox()]) + expect(toggleOpenBox).not.toBeNull() + expect(archivePanelBox).not.toBeNull() + expect(archivePanelBox!.y - (toggleOpenBox!.y + toggleOpenBox!.height)).toBeGreaterThanOrEqual(10) const archivedOpener = page.getByRole('button', { name: new RegExp(archivedName) }) await archivedOpener.click() dialog = page.getByRole('dialog', { name: archivedName }) diff --git a/frontend/src/style.css b/frontend/src/style.css index c8000b1..4bf881b 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -70,8 +70,8 @@ main{background:var(--surface-base)} .soft-button,.danger-button,.file-button,.secondary,.restore,.archived-toggle,.archived-countdowns button{background:var(--surface-raised);border-color:var(--border-cream);box-shadow:var(--highlight-inner)} .primary,.primary-small{background:var(--accent);color:#fff} .danger-button{color:var(--danger);border-color:#dba99d;background:#fff8f5}.inline-error,.purge-list-error{color:var(--danger);background:#fff0ec}.task-check[aria-pressed="true"] .task-check-mark,.habit-row.done .habit-check .task-check-mark{background:var(--success);border-color:var(--success)} -.habit-archive-section{display:grid;gap:0}.habit-archive-toggle{width:100%;min-height:44px;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;text-align:left}.habit-archive-toggle>span{min-width:0}.habit-archive-toggle>svg:last-child{transition:transform .16s ease}.habit-archive-toggle>svg.expanded{transform:rotate(90deg)}.archived-habits{width:100%;display:grid;gap:0;background:var(--surface-raised);border:1px solid var(--border-cream);border-radius:var(--radius-card);overflow:hidden}.archived-habit-row{width:100%;min-height:44px;appearance:none;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 12px;color:inherit;text-align:left;background:var(--surface-raised);border:0;border-bottom:1px solid var(--border-cream);font:inherit}.archived-habit-row:last-child{border-bottom:0}.archived-habit-row>span{min-width:0;display:grid;gap:3px}.archived-habit-row b,.archived-habit-row small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archived-habit-row small{color:var(--muted);font-size:11px}.archived-habit-row>svg{flex:none}.habit-archive-status{min-height:44px;margin:0;padding:12px;display:flex;align-items:center;justify-content:space-between;gap:12px}.app-sheet__danger{display:flex;gap:8px}.app-sheet__danger>button{min-height:44px}.habit-restore-button{flex:1}.habit-delete-button{flex:1} -@media(max-width:930px){.habit-archive-section{width:100%;gap:0}.habit-archive-toggle{width:100%;min-height:44px;appearance:none;background:var(--surface-raised);border:1px solid var(--border-cream);box-shadow:none}.archived-habits{width:100%;display:grid;gap:0}.archived-habit-row{width:100%;min-height:44px;appearance:none;grid-template-columns:minmax(0,1fr) auto;background:var(--surface-raised);border-bottom:1px solid var(--border-cream)}.habit-detail-sheet.app-sheet--detail{width:100%;border-radius:var(--sheet-radius) var(--sheet-radius) 0 0!important}} +.habit-archive-section{display:grid;gap:10px}.habit-archive-toggle{width:100%;min-height:44px;display:grid;grid-template-columns:28px minmax(0,1fr) 28px;align-items:center;gap:8px;padding:0 4px;border:0;background:transparent;box-shadow:none;color:var(--text-secondary);font-weight:650;text-align:left}.habit-archive-toggle:hover{background:#fff8ee}.habit-archive-toggle:active{background:#fff1df}.habit-archive-toggle:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px}.habit-archive-toggle>svg{justify-self:center}.habit-archive-toggle>span{min-width:0}.habit-archive-toggle>svg:last-child{transition:transform .16s ease}.habit-archive-toggle>svg.expanded{transform:rotate(90deg)}.archived-habits{margin-top:2px;width:100%;display:grid;gap:0;background:var(--surface-raised);border:1px solid var(--border-cream);border-radius:var(--radius-card);overflow:hidden;box-shadow:var(--highlight-inner)}.archived-habit-row{width:100%;min-height:44px;appearance:none;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px 12px;color:inherit;text-align:left;background:var(--surface-raised);border:0;border-bottom:1px solid var(--border-cream);font:inherit}.archived-habit-row:last-child{border-bottom:0}.archived-habit-row>span{min-width:0;display:grid;gap:3px}.archived-habit-row b,.archived-habit-row small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archived-habit-row small{color:var(--muted);font-size:11px}.archived-habit-row>svg{flex:none}.habit-archive-status{min-height:44px;margin:0;padding:12px;display:flex;align-items:center;justify-content:space-between;gap:12px}.app-sheet__danger{display:flex;gap:8px}.app-sheet__danger>button{min-height:44px}.habit-restore-button{flex:1}.habit-delete-button{flex:1} +@media(max-width:930px){.habit-archive-section{width:100%;gap:10px}.habit-archive-toggle{width:100%;min-height:44px;appearance:none;background:transparent;border:0;box-shadow:none}.archived-habits{width:100%;display:grid;gap:0}.archived-habit-row{width:100%;min-height:44px;appearance:none;grid-template-columns:minmax(0,1fr) auto;background:var(--surface-raised);border-bottom:1px solid var(--border-cream)}.habit-detail-sheet.app-sheet--detail{width:100%;border-radius:var(--sheet-radius) var(--sheet-radius) 0 0!important}} input,select,textarea{background:var(--surface-raised);border-color:var(--border-cream);border-radius:var(--radius-control);box-shadow:var(--highlight-inner)} .detail-title textarea{background:transparent;box-shadow:none} .sidebar-popover button,.sidebar-action-sheet .app-sheet__body button,.app-sheet--actions .app-sheet__body>button{background:var(--surface-raised)} @@ -135,7 +135,7 @@ main.list-main{background:#fdfaf3} main.list-main>.list-page-context,main.list-main>.list-section-heading,main.list-main>.task-list,main.list-main>.list-page-meta,main.list-main>.pager,main.list-main>.mvp-view{width:min(100%,630px);margin-left:auto;margin-right:auto} main.list-main>.mvp-view{gap:0} main.list-main>.mvp-view>.habit-section-heading{width:100%} -main.list-main>.mvp-view>.habit-archive-section{border-top:1px solid #e8e0d5} +main.list-main>.mvp-view>.habit-archive-section{margin-top:24px;padding-top:12px;border-top:1px solid #e8e0d5} .list-page-context{width:min(100%,630px);margin:0 auto 0;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:0 16px} .habit-page-context{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:0 16px} .habit-section-heading{margin-top:0} diff --git a/frontend/src/visual-polish.test.ts b/frontend/src/visual-polish.test.ts index 4d3533b..3da147f 100644 --- a/frontend/src/visual-polish.test.ts +++ b/frontend/src/visual-polish.test.ts @@ -139,7 +139,10 @@ describe('approved five-detail polish', () => { expect(css).toContain('.habit-section-heading{margin-top:0}') expect(css).toContain('main.list-main>.mvp-view{gap:0}') expect(css).toContain('main.list-main>.mvp-view>.habit-section-heading{width:100%}') - expect(css).toContain('main.list-main>.mvp-view>.habit-archive-section{border-top:1px solid #e8e0d5}') + expect(css).toContain('main.list-main>.mvp-view>.habit-archive-section{margin-top:24px;padding-top:12px;border-top:1px solid #e8e0d5}') + expect(css).toContain('.habit-archive-section{display:grid;gap:10px}') + expect(css).toContain('.habit-archive-toggle{width:100%;min-height:44px;display:grid;grid-template-columns:28px minmax(0,1fr) 28px;align-items:center;gap:8px;padding:0 4px;border:0;background:transparent;box-shadow:none') + expect(css).toContain('.archived-habits{margin-top:2px;') }) it('uses one 58px plain-list contract for active task and habit rows', () => {