fix: compact desktop task composer
ci / gitleaks (push) Successful in 9s
ci / docker (push) Successful in 4m7s

This commit is contained in:
2026-09-20 12:05:12 +08:00
parent 1688577077
commit d7014c4f4f
3 changed files with 57 additions and 1 deletions
+51
View File
@@ -25,6 +25,57 @@ async function openTaskComposer(page: Page) {
return page.getByRole('dialog', { name: /添加(?:今天)?任务/ }) return page.getByRole('dialog', { name: /添加(?:今天)?任务/ })
} }
test('desktop task composer stays compact, centered, and scrollable on short screens', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 })
await page.goto('/')
let dialog = await openTaskComposer(page)
await expect(dialog).toBeVisible()
const measure = () => dialog.evaluate(element => {
const panel = element as HTMLElement
const rect = panel.getBoundingClientRect()
const body = panel.querySelector<HTMLElement>('.app-sheet__body')!
const header = panel.querySelector<HTMLElement>('.app-sheet__header')!.getBoundingClientRect()
const footer = panel.querySelector<HTMLElement>('.app-sheet__footer')!.getBoundingClientRect()
return {
viewport: { width: innerWidth, height: innerHeight },
panel: { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom, width: rect.width, height: rect.height },
body: { clientHeight: body.clientHeight, scrollHeight: body.scrollHeight, overflowY: getComputedStyle(body).overflowY },
headerTop: header.top,
footerBottom: footer.bottom,
}
})
let metrics = await measure()
expect(metrics.panel.width).toBeCloseTo(560, 0)
expect(metrics.panel.left).toBeCloseTo((metrics.viewport.width - metrics.panel.width) / 2, 0)
expect(metrics.panel.top).toBeCloseTo((metrics.viewport.height - metrics.panel.height) / 2, 0)
expect(metrics.panel.height).toBeLessThanOrEqual(521)
await page.setViewportSize({ width: 1280, height: 633 })
metrics = await measure()
expect(metrics.panel.width).toBeCloseTo(560, 0)
expect(metrics.panel.left).toBeCloseTo((metrics.viewport.width - metrics.panel.width) / 2, 0)
expect(metrics.panel.top).toBeCloseTo((metrics.viewport.height - metrics.panel.height) / 2, 0)
expect(metrics.panel.height).toBeLessThanOrEqual(metrics.viewport.height * 0.82 + 1)
expect(metrics.body.overflowY).toBe('auto')
expect(metrics.body.scrollHeight).toBeGreaterThan(metrics.body.clientHeight)
expect(metrics.headerTop).toBeGreaterThanOrEqual(0)
expect(metrics.footerBottom).toBeLessThanOrEqual(metrics.viewport.height + 1)
await page.keyboard.press('Escape')
await page.setViewportSize({ width: 930, height: 844 })
dialog = await openTaskComposer(page)
const mobile = await dialog.evaluate(element => {
const rect = element.getBoundingClientRect()
return { left: rect.left, right: rect.right, bottom: rect.bottom, width: rect.width, viewportWidth: innerWidth, viewportHeight: innerHeight }
})
expect(mobile.left).toBeCloseTo(0, 0)
expect(mobile.right).toBeCloseTo(mobile.viewportWidth, 0)
expect(mobile.width).toBeCloseTo(mobile.viewportWidth, 0)
expect(mobile.bottom).toBeCloseTo(mobile.viewportHeight, 0)
})
test('bottom navigation uses the paper baseline geometry', async ({ page }) => { test('bottom navigation uses the paper baseline geometry', async ({ page }) => {
await page.goto('/') await page.goto('/')
const metrics = await page.locator('.bottom').evaluate(element => { const metrics = await page.locator('.bottom').evaluate(element => {
File diff suppressed because one or more lines are too long
+5
View File
@@ -542,6 +542,11 @@ describe('completion feedback motion', () => {
expect(dueRemovalBlock).not.toContain('saveRepeat(') expect(dueRemovalBlock).not.toContain('saveRepeat(')
}) })
it('keeps the desktop task composer compact and centered', () => {
expect(css).toContain('@media(min-width:931px){.task-compose-sheet:not(.habit-compose-sheet){width:min(560px,calc(100vw - 48px));height:min(520px,82dvh);max-height:none;padding:0;display:flex;flex-direction:column;gap:0;overflow:hidden}')
expect(css).toContain('.app-sheet-mask:has(>.task-compose-sheet:not(.habit-compose-sheet)){place-items:center;padding:24px}')
})
it('keeps all task composer touch controls at least 44px on mobile without horizontal overflow', () => { it('keeps all task composer touch controls at least 44px on mobile without horizontal overflow', () => {
expect(css).toContain('@media(max-width:390px){.task-compose-sheet') expect(css).toContain('@media(max-width:390px){.task-compose-sheet')
expect(css).toContain('.task-compose-sheet .app-sheet__header>button{min-width:44px;min-height:44px}') expect(css).toContain('.task-compose-sheet .app-sheet__header>button{min-width:44px;min-height:44px}')