fix: restore Today floating add button
This commit is contained in:
@@ -36,7 +36,7 @@ test('Today plain-list composition has no overlap or horizontal overflow', async
|
|||||||
}
|
}
|
||||||
|
|
||||||
const geometry = await page.locator('main').evaluate((main) => {
|
const geometry = await page.locator('main').evaluate((main) => {
|
||||||
const selectors = ['.today-environment', '.today-page-title', '.today-remaining', '.today-inline-filter', '.today-section-toggle']
|
const selectors = ['.today-environment', '.today-heading', '.today-section-toggle']
|
||||||
const rects = selectors.map(selector => main.querySelector(selector)!.getBoundingClientRect())
|
const rects = selectors.map(selector => main.querySelector(selector)!.getBoundingClientRect())
|
||||||
const context = main.querySelector('.today-context')!
|
const context = main.querySelector('.today-context')!
|
||||||
const contextRect = context.getBoundingClientRect()
|
const contextRect = context.getBoundingClientRect()
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ test('Today plain-list layout matches the approved responsive geometry', async (
|
|||||||
environmentHeight: width >= 721 ? 55 : width === 375 ? 79 : 81,
|
environmentHeight: width >= 721 ? 55 : width === 375 ? 79 : 81,
|
||||||
})
|
})
|
||||||
await expect(page.locator('.today-heading')).toHaveCount(1)
|
await expect(page.locator('.today-heading')).toHaveCount(1)
|
||||||
await expect(page.locator('.today-inline-add')).toHaveCount(1)
|
await expect(page.locator('.today-inline-add')).toHaveCount(0)
|
||||||
|
await expect(page.locator('.unified-fab')).toHaveCount(1)
|
||||||
await expect(taskRowLocator).toHaveCount(1)
|
await expect(taskRowLocator).toHaveCount(1)
|
||||||
await expect(habitRowLocator).toHaveCount(1)
|
await expect(habitRowLocator).toHaveCount(1)
|
||||||
await expect(page.locator('.today-environment')).toBeVisible()
|
await expect(page.locator('.today-environment')).toBeVisible()
|
||||||
@@ -72,7 +73,6 @@ test('Today plain-list layout matches the approved responsive geometry', async (
|
|||||||
const filter = document.querySelector<HTMLElement>('.today-inline-filter')!
|
const filter = document.querySelector<HTMLElement>('.today-inline-filter')!
|
||||||
const firstSection = document.querySelector<HTMLElement>('.today-section-toggle')!
|
const firstSection = document.querySelector<HTMLElement>('.today-section-toggle')!
|
||||||
const heading = document.querySelector<HTMLElement>('.today-heading')!
|
const heading = document.querySelector<HTMLElement>('.today-heading')!
|
||||||
const inlineAdd = document.querySelector<HTMLElement>('.today-inline-add')!
|
|
||||||
const main = document.querySelector<HTMLElement>('main.today-main')!
|
const main = document.querySelector<HTMLElement>('main.today-main')!
|
||||||
const content = rect('.today-context')
|
const content = rect('.today-context')
|
||||||
const sectionTitle = firstSection.querySelector<HTMLElement>('.today-section-title')!
|
const sectionTitle = firstSection.querySelector<HTMLElement>('.today-section-title')!
|
||||||
@@ -145,9 +145,6 @@ test('Today plain-list layout matches the approved responsive geometry', async (
|
|||||||
headingAlignItems: getComputedStyle(heading).alignItems,
|
headingAlignItems: getComputedStyle(heading).alignItems,
|
||||||
filterTop: filter.getBoundingClientRect().top,
|
filterTop: filter.getBoundingClientRect().top,
|
||||||
filterRight: filter.getBoundingClientRect().right,
|
filterRight: filter.getBoundingClientRect().right,
|
||||||
inlineAddPosition: getComputedStyle(inlineAdd).position,
|
|
||||||
inlineAddWidth: inlineAdd.getBoundingClientRect().width,
|
|
||||||
inlineAddBottom: inlineAdd.getBoundingClientRect().bottom,
|
|
||||||
viewportHeight: innerHeight,
|
viewportHeight: innerHeight,
|
||||||
titleFontSize: getComputedStyle(title).fontSize,
|
titleFontSize: getComputedStyle(title).fontSize,
|
||||||
titleFontWeight: getComputedStyle(title).fontWeight,
|
titleFontWeight: getComputedStyle(title).fontWeight,
|
||||||
@@ -206,13 +203,9 @@ test('Today plain-list layout matches the approved responsive geometry', async (
|
|||||||
expect(metrics.styles.filterTop).toBeGreaterThanOrEqual(metrics.ordered[1].top)
|
expect(metrics.styles.filterTop).toBeGreaterThanOrEqual(metrics.ordered[1].top)
|
||||||
expect(metrics.styles.filterTop).toBeLessThanOrEqual(metrics.ordered[1].bottom - metrics.styles.filterHeight)
|
expect(metrics.styles.filterTop).toBeLessThanOrEqual(metrics.ordered[1].bottom - metrics.styles.filterHeight)
|
||||||
expect(metrics.styles.filterRight).toBeCloseTo(metrics.content.right, 0)
|
expect(metrics.styles.filterRight).toBeCloseTo(metrics.content.right, 0)
|
||||||
expect(metrics.styles.inlineAddPosition).toBe('relative')
|
|
||||||
expect(metrics.styles.inlineAddWidth).toBeCloseTo(metrics.content.width, 0)
|
|
||||||
expect(metrics.styles.inlineAddBottom).toBeGreaterThanOrEqual(metrics.ordered[metrics.ordered.length - 1].bottom)
|
|
||||||
expect(metrics.styles.inlineAddBottom).toBeLessThanOrEqual(metrics.styles.viewportHeight + 1)
|
|
||||||
if (width <= 720) expect(metrics.styles.contextHeight).toBeLessThanOrEqual(210)
|
if (width <= 720) expect(metrics.styles.contextHeight).toBeLessThanOrEqual(210)
|
||||||
expect(metrics.styles.fabShadow).toBe('')
|
expect(metrics.styles.fabShadow).toContain('8px 18px')
|
||||||
expect(metrics.styles.fabIconWidth).toBe(0)
|
expect(metrics.styles.fabIconWidth).toBeCloseTo(30, 0)
|
||||||
if (width >= 721) {
|
if (width >= 721) {
|
||||||
expect(metrics.uniqueRows).toHaveLength(1)
|
expect(metrics.uniqueRows).toHaveLength(1)
|
||||||
expect(metrics.content.width).toBeCloseTo(width >= 1440 ? 1080 : 630, 0)
|
expect(metrics.content.width).toBeCloseTo(width >= 1440 ? 1080 : 630, 0)
|
||||||
|
|||||||
@@ -1747,7 +1747,7 @@ onUnmounted(() => {
|
|||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="activeView==='today' && !query && hiddenCompletedTaskCount > 0 && !visibleTasks.length && !loading" class="today-filtered-empty-note"><span>已隐藏已完成任务</span><button type="button" class="link" @click="showCompleted=true">显示</button></div>
|
<div v-if="activeView==='today' && !query && hiddenCompletedTaskCount > 0 && !visibleTasks.length && !loading" class="today-filtered-empty-note"><span>已隐藏已完成任务</span><button type="button" class="link" @click="showCompleted=true">显示</button></div>
|
||||||
<div v-else-if="!visibleTasks.length&&!loading" class="empty"><ListTodo/><b>{{ query ? '没有匹配的任务' : hiddenCompletedTaskCount > 0 ? '已完成任务已隐藏' : '这里还很安静' }}</b><span>{{query?'换个关键词试试':hiddenCompletedTaskCount > 0 ? '开启“显示已完成”即可查看。':'写下第一件想完成的小事吧'}}</span><button v-if="activeView==='today' && !query && hiddenCompletedTaskCount === 0" class="soft-button empty-action" @click="openTaskCompose"><Plus/>添加今天任务</button></div>
|
<div v-else-if="!visibleTasks.length&&!loading" class="empty"><ListTodo/><b>{{ query ? '没有匹配的任务' : hiddenCompletedTaskCount > 0 ? '已完成任务已隐藏' : '这里还很安静' }}</b><span>{{query?'换个关键词试试':hiddenCompletedTaskCount > 0 ? '开启“显示已完成”即可查看。':'写下第一件想完成的小事吧'}}</span></div>
|
||||||
</section>
|
</section>
|
||||||
<div v-if="activeView==='today'" class="today-habits-section today-section-anchor">
|
<div v-if="activeView==='today'" class="today-habits-section today-section-anchor">
|
||||||
<button id="today-habits-heading" class="today-section-toggle" type="button" :aria-expanded="!todaySectionCollapse.habits" aria-controls="today-habits" @click="toggleTodaySection('habits')"><span class="today-section-title">习惯</span><span class="today-section-summary">{{todayHabitTotal}}</span><span class="today-section-chevron" aria-hidden="true">{{ todaySectionCollapse.habits ? '›' : '⌄' }}</span></button>
|
<button id="today-habits-heading" class="today-section-toggle" type="button" :aria-expanded="!todaySectionCollapse.habits" aria-controls="today-habits" @click="toggleTodaySection('habits')"><span class="today-section-title">习惯</span><span class="today-section-summary">{{todayHabitTotal}}</span><span class="today-section-chevron" aria-hidden="true">{{ todaySectionCollapse.habits ? '›' : '⌄' }}</span></button>
|
||||||
@@ -1756,7 +1756,6 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<button v-if="activeView==='today' && showFloatingAdd" class="today-inline-add" type="button" aria-label="添加任务" @click="openTaskCompose"><Plus/><span>添加任务</span></button>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<AppSheet v-if="selectedTask" :open="true" :modal="compactLayout" variant="detail" panel-class="detail" title-id="task-detail-title" :close-on-scrim="compactLayout" :busy="taskDetailBusy" @close="closeTaskDetail" @submit.prevent="saveSelectedTaskChanges">
|
<AppSheet v-if="selectedTask" :open="true" :modal="compactLayout" variant="detail" panel-class="detail" title-id="task-detail-title" :close-on-scrim="compactLayout" :busy="taskDetailBusy" @close="closeTaskDetail" @submit.prevent="saveSelectedTaskChanges">
|
||||||
@@ -1791,7 +1790,7 @@ onUnmounted(() => {
|
|||||||
</AppSheet>
|
</AppSheet>
|
||||||
|
|
||||||
<nav class="bottom" :inert="memoBackgroundInert ? true : undefined" aria-label="主要导航"><button :class="{active:activeView==='today'}" :aria-current="activeView==='today' ? 'page' : undefined" @click="switchView('today')"><ListTodo/><span>今天</span></button><button :class="{active:activeView==='habits'}" :aria-current="activeView==='habits' ? 'page' : undefined" @click="switchView('habits')"><Repeat2/><span>习惯</span></button><button :class="{active:activeView==='countdowns'}" :aria-current="activeView==='countdowns' ? 'page' : undefined" @click="switchView('countdowns')"><CalendarHeart/><span>倒数日</span></button><button :class="{active:activeView==='settings'}" :aria-current="activeView==='settings' ? 'page' : undefined" @click="switchView('settings')"><Settings/><span>设置</span></button></nav>
|
<nav class="bottom" :inert="memoBackgroundInert ? true : undefined" aria-label="主要导航"><button :class="{active:activeView==='today'}" :aria-current="activeView==='today' ? 'page' : undefined" @click="switchView('today')"><ListTodo/><span>今天</span></button><button :class="{active:activeView==='habits'}" :aria-current="activeView==='habits' ? 'page' : undefined" @click="switchView('habits')"><Repeat2/><span>习惯</span></button><button :class="{active:activeView==='countdowns'}" :aria-current="activeView==='countdowns' ? 'page' : undefined" @click="switchView('countdowns')"><CalendarHeart/><span>倒数日</span></button><button :class="{active:activeView==='settings'}" :aria-current="activeView==='settings' ? 'page' : undefined" @click="switchView('settings')"><Settings/><span>设置</span></button></nav>
|
||||||
<FloatingAddButton v-if="activeView!=='today' && ['tasks','upcoming','habits','countdowns','memos'].includes(activeView)" :show="showFloatingAdd" :label="activeView==='habits' ? '添加习惯' : activeView==='countdowns' ? '添加倒数日' : activeView==='memos' ? '添加备忘录' : '添加任务'" @activate="activateFloatingAdd" />
|
<FloatingAddButton v-if="['tasks','today','upcoming','habits','countdowns','memos'].includes(activeView)" :show="showFloatingAdd" :label="activeView==='habits' ? '添加习惯' : activeView==='countdowns' ? '添加倒数日' : activeView==='memos' ? '添加备忘录' : '添加任务'" @activate="activateFloatingAdd" />
|
||||||
<AppSheet :open="taskComposeOpen" variant="create" panel-class="task-compose-sheet" title-id="task-compose-title" initial-focus=".task-compose-input" :style="taskComposeStyle" @close="closeTaskCompose" @submit.prevent="submitTaskCompose">
|
<AppSheet :open="taskComposeOpen" variant="create" panel-class="task-compose-sheet" title-id="task-compose-title" initial-focus=".task-compose-input" :style="taskComposeStyle" @close="closeTaskCompose" @submit.prevent="submitTaskCompose">
|
||||||
<header class="app-sheet__header"><div><h2 id="task-compose-title">{{ taskComposeTitle }}</h2></div><button class="icon" type="button" aria-label="关闭添加任务" @click="closeTaskCompose"><X/></button></header>
|
<header class="app-sheet__header"><div><h2 id="task-compose-title">{{ taskComposeTitle }}</h2></div><button class="icon" type="button" aria-label="关闭添加任务" @click="closeTaskCompose"><X/></button></header>
|
||||||
<div class="app-sheet__body">
|
<div class="app-sheet__body">
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ describe('Today environment integration', () => {
|
|||||||
expect(app).not.toContain('today-habit-track')
|
expect(app).not.toContain('today-habit-track')
|
||||||
expect(app).not.toContain('role="progressbar"')
|
expect(app).not.toContain('role="progressbar"')
|
||||||
expect(app).toContain("'today-active': activeView==='today'")
|
expect(app).toContain("'today-active': activeView==='today'")
|
||||||
expect(app).toContain('class="today-inline-add"')
|
expect(app).not.toContain('class="today-inline-add"')
|
||||||
expect(app).toContain("activeView!=='today' && ['tasks','upcoming','habits','countdowns','memos'].includes(activeView)")
|
expect(app).not.toContain('<Plus/>添加今天任务')
|
||||||
expect(css).toContain('.today-inline-add{')
|
expect(app).toContain("['tasks','today','upcoming','habits','countdowns','memos'].includes(activeView)")
|
||||||
expect(css).toContain('position:relative')
|
expect(css).not.toContain('.today-inline-add{')
|
||||||
expect(css).toContain('main.today-main{padding-left:max(44px,calc((100% - 1080px)/2));padding-right:max(44px,calc((100% - 1080px)/2))}')
|
expect(css).toContain('main.today-main{padding-left:max(44px,calc((100% - 1080px)/2));padding-right:max(44px,calc((100% - 1080px)/2))}')
|
||||||
expect(css).toContain('.today-environment{grid-template-columns:repeat(3,minmax(0,1fr));')
|
expect(css).toContain('.today-environment{grid-template-columns:repeat(3,minmax(0,1fr));')
|
||||||
expect(css).toContain('@media(max-width:930px){main.today-main{padding-left:max(44px,calc((100% - 630px)/2));padding-right:max(44px,calc((100% - 630px)/2))}}')
|
expect(css).toContain('@media(max-width:930px){main.today-main{padding-left:max(44px,calc((100% - 630px)/2));padding-right:max(44px,calc((100% - 630px)/2))}}')
|
||||||
|
|||||||
@@ -158,10 +158,6 @@ main.today-main .topbar{margin-bottom:12px}
|
|||||||
.today-heading .today-page-title{margin:0}
|
.today-heading .today-page-title{margin:0}
|
||||||
.today-heading .today-remaining{margin:6px 0 0}
|
.today-heading .today-remaining{margin:6px 0 0}
|
||||||
.today-heading .today-inline-filter{align-self:center;justify-self:end}
|
.today-heading .today-inline-filter{align-self:center;justify-self:end}
|
||||||
.today-inline-add{position:relative;width:100%;height:44px;margin:18px auto 0;display:flex;align-items:center;justify-content:center;gap:7px;border:1px solid #dfc9b2;border-radius:11px;background:var(--surface-raised);color:var(--accent);box-shadow:var(--highlight-inner),0 5px 16px rgba(88,67,42,.1);font-size:13px;font-weight:700}
|
|
||||||
.today-inline-add svg{width:17px;height:17px}
|
|
||||||
.today-inline-add:active{transform:scale(.985)}
|
|
||||||
.today-inline-add:focus-visible{outline:3px solid var(--focus-ring);outline-offset:2px}
|
|
||||||
.today-environment{grid-template-columns:repeat(3,minmax(0,1fr));align-items:center;gap:0;padding:0 0 18px;border-bottom:1px solid #e8e0d5;color:#8a8178}
|
.today-environment{grid-template-columns:repeat(3,minmax(0,1fr));align-items:center;gap:0;padding:0 0 18px;border-bottom:1px solid #e8e0d5;color:#8a8178}
|
||||||
.today-environment__item{height:36px;padding:0 0 0 18px;justify-content:flex-start}
|
.today-environment__item{height:36px;padding:0 0 0 18px;justify-content:flex-start}
|
||||||
.today-environment__item:first-child{padding-left:0}
|
.today-environment__item:first-child{padding-left:0}
|
||||||
@@ -175,7 +171,7 @@ main.today-main .topbar{margin-bottom:12px}
|
|||||||
.today-main .task-tail{padding-left:12px;font-size:12px}.today-main .habit-row{gap:0}.today-main .habit-main{display:flex;align-items:center;min-width:0;padding:0}
|
.today-main .task-tail{padding-left:12px;font-size:12px}.today-main .habit-row{gap:0}.today-main .habit-main{display:flex;align-items:center;min-width:0;padding:0}
|
||||||
.shell.today-active .unified-fab{box-shadow:0 8px 18px rgba(174,65,29,.22)}.shell.today-active .unified-fab>svg{width:30px;height:30px;stroke-width:1.5}
|
.shell.today-active .unified-fab{box-shadow:0 8px 18px rgba(174,65,29,.22)}.shell.today-active .unified-fab>svg{width:30px;height:30px;stroke-width:1.5}
|
||||||
@media(max-width:930px){main.today-main{padding-left:max(44px,calc((100% - 630px)/2));padding-right:max(44px,calc((100% - 630px)/2))}}
|
@media(max-width:930px){main.today-main{padding-left:max(44px,calc((100% - 630px)/2));padding-right:max(44px,calc((100% - 630px)/2))}}
|
||||||
@media(max-width:720.98px){main.today-main{padding-left:29px!important;padding-right:29px!important;padding-bottom:calc(78px + var(--safe-area-bottom))}.today-environment{grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:21px auto;align-items:stretch;column-gap:0;row-gap:7px;padding-bottom:10px}.today-environment__calendar{grid-column:1/-1;grid-row:1;height:21px!important;padding:0;justify-content:space-between;align-items:start;border-left:0}.today-environment__weather,.today-environment__gold{grid-row:2;height:clamp(38px,calc(25vw - 55.75px),42px);padding-top:7px;border-top:1px solid #e8e0d5}.today-environment__weather{grid-column:1;padding-left:0;padding-right:10px;border-left:0}.today-environment__gold{grid-column:2;padding-left:12px}.today-environment__weather strong,.today-environment__gold strong,.today-environment__gold-primary{line-height:16px}.today-environment__item small{line-height:13px}.today-heading{margin-top:16px}.today-page-title{font-size:24px}.today-heading .today-remaining{margin-top:4px}.today-main .task-row,.today-main .habit-row{height:58px;min-height:58px;max-height:58px}.today-context .completed-filter-pill{width:87px;height:44px;min-height:44px}.today-context .completed-filter-pill__track{width:30px;height:18px}.today-context .completed-filter-pill__thumb{width:14px;height:14px}.today-context .completed-filter-pill[aria-checked="true"] .completed-filter-pill__thumb{transform:translateX(12px)}.today-inline-add{margin-top:14px}}
|
@media(max-width:720.98px){main.today-main{padding-left:29px!important;padding-right:29px!important;padding-bottom:calc(78px + var(--safe-area-bottom))}.today-environment{grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:21px auto;align-items:stretch;column-gap:0;row-gap:7px;padding-bottom:10px}.today-environment__calendar{grid-column:1/-1;grid-row:1;height:21px!important;padding:0;justify-content:space-between;align-items:start;border-left:0}.today-environment__weather,.today-environment__gold{grid-row:2;height:clamp(38px,calc(25vw - 55.75px),42px);padding-top:7px;border-top:1px solid #e8e0d5}.today-environment__weather{grid-column:1;padding-left:0;padding-right:10px;border-left:0}.today-environment__gold{grid-column:2;padding-left:12px}.today-environment__weather strong,.today-environment__gold strong,.today-environment__gold-primary{line-height:16px}.today-environment__item small{line-height:13px}.today-heading{margin-top:16px}.today-page-title{font-size:24px}.today-heading .today-remaining{margin-top:4px}.today-main .task-row,.today-main .habit-row{height:58px;min-height:58px;max-height:58px}.today-context .completed-filter-pill{width:87px;height:44px;min-height:44px}.today-context .completed-filter-pill__track{width:30px;height:18px}.today-context .completed-filter-pill__thumb{width:14px;height:14px}.today-context .completed-filter-pill[aria-checked="true"] .completed-filter-pill__thumb{transform:translateX(12px)}}
|
||||||
@media(max-width:380px){.today-environment__weather,.today-environment__gold{height:40px;padding-top:5px;padding-bottom:5px}}
|
@media(max-width:380px){.today-environment__weather,.today-environment__gold{height:40px;padding-top:5px;padding-bottom:5px}}
|
||||||
|
|
||||||
/* Approved Settings 01: continuous paper ledger. */
|
/* Approved Settings 01: continuous paper ledger. */
|
||||||
|
|||||||
Reference in New Issue
Block a user