diff --git a/src/components/AppNav.spec.ts b/src/components/AppNav.spec.ts index 7952167..86aebd6 100644 --- a/src/components/AppNav.spec.ts +++ b/src/components/AppNav.spec.ts @@ -46,6 +46,16 @@ describe('AppNav 导航', () => { expect(links[1]?.attributes('aria-current')).toBe('page') }) + it('当前入口用主色(sky-700)铺底,与实心主按钮同一套色', async () => { + const { wrapper } = await setup('/today') + const [board, today] = wrapper.findAll('a') + + expect(today?.classes()).toContain('bg-sky-700') + // 早先是接近黑的 slate-900,与页面主色脱节 + expect(today?.classes()).not.toContain('bg-slate-900') + expect(board?.classes()).not.toContain('bg-sky-700') + }) + it('点击可切换路由', async () => { const { wrapper, router } = await setup('/') diff --git a/src/components/AppNav.vue b/src/components/AppNav.vue index 9dcc04b..f1b1f0f 100644 --- a/src/components/AppNav.vue +++ b/src/components/AppNav.vue @@ -51,8 +51,8 @@ const LINKS = [ class="shrink-0 rounded-md px-3 py-1.5 text-sm whitespace-nowrap transition" :class=" isExactActive - ? 'bg-slate-900 font-medium text-white shadow-sm dark:bg-zinc-100 dark:text-zinc-900' - : 'text-slate-600 hover:bg-slate-100 hover:text-slate-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100' + ? 'bg-sky-700 font-medium text-white shadow-sm dark:bg-sky-500 dark:text-slate-950' + : 'text-slate-600 hover:bg-sky-50 hover:text-sky-800 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-100' " :aria-current="isExactActive ? 'page' : undefined" @click="navigate" diff --git a/src/components/BoardToolbar.spec.ts b/src/components/BoardToolbar.spec.ts index 44403ad..ce7b16b 100644 --- a/src/components/BoardToolbar.spec.ts +++ b/src/components/BoardToolbar.spec.ts @@ -189,6 +189,41 @@ describe('BoardToolbar 归档', () => { }) }) +describe('BoardToolbar 主次按钮', () => { + beforeEach(() => { + setActivePinia(createPinia()) + }) + + it('点击「新建任务」emit new-task', async () => { + const { wrapper } = setup() + + await buttonByText(wrapper, '新建任务')?.trigger('click') + + expect(wrapper.emitted('new-task')).toHaveLength(1) + }) + + it('实心主按钮只有「新建任务」,「批量添加」降为描边次要按钮', () => { + const { wrapper } = setup() + + const primary = buttonByText(wrapper, '新建任务') + const batch = buttonByText(wrapper, '批量添加') + + expect(primary?.classes()).toContain('bg-sky-700') + expect(primary?.classes()).toContain('text-white') + expect(batch?.classes()).toContain('bg-white') + expect(batch?.classes()).not.toContain('bg-sky-700') + }) + + it('「新建任务」在平板上仍带文字,不退化成纯图标', () => { + const { wrapper } = setup() + + const button = buttonByText(wrapper, '新建任务') + // 主操作只在手机(<640)收成图标 + expect(button?.find('span').classes()).toContain('max-sm:hidden') + expect(button?.classes()).not.toContain('max-lg:w-9') + }) +}) + describe('BoardToolbar 批量添加', () => { beforeEach(() => { setActivePinia(createPinia()) diff --git a/src/components/BoardToolbar.vue b/src/components/BoardToolbar.vue index e2e7ec5..3b7a97f 100644 --- a/src/components/BoardToolbar.vue +++ b/src/components/BoardToolbar.vue @@ -14,6 +14,7 @@ defineProps<{ hiddenNote?: string; selecting?: boolean }>() const emit = defineEmits<{ archive: [] + 'new-task': [] 'batch-add': [] 'toggle-select': [] 'manage-tags': [] @@ -177,11 +178,38 @@ defineExpose({ focusSearch }) - +
+ +
-
+ +

时间

-
+
创建
-
+
{{ createdAtText ?? '—' }}
完成
-
+
{{ completedLabel }}
更新
-
+
{{ updatedAtText ?? '—' }}
diff --git a/src/views/BoardView.spec.ts b/src/views/BoardView.spec.ts index 001db5b..1969755 100644 --- a/src/views/BoardView.spec.ts +++ b/src/views/BoardView.spec.ts @@ -437,6 +437,23 @@ describe('BoardView 快捷键', () => { }) }) +describe('BoardView 新建任务', () => { + function buttonByText(wrapper: ReturnType, text: string) { + return wrapper.findAll('button').find((node) => node.text().includes(text)) + } + + it('点击工具栏「新建任务」聚焦待办列的快速新增输入框', async () => { + const { pinia } = setup() + const wrapper = mountBoard(pinia) + await nextTick() + + await buttonByText(wrapper, '新建任务')?.trigger('click') + await nextTick() + + expect(document.activeElement).toBe(wrapper.find('input[aria-label="添加任务"]').element) + }) +}) + describe('BoardView 键盘移动', () => { type Direction = 'left' | 'right' | 'up' | 'down' diff --git a/src/views/BoardView.vue b/src/views/BoardView.vue index 43a7736..c044c8d 100644 --- a/src/views/BoardView.vue +++ b/src/views/BoardView.vue @@ -141,6 +141,15 @@ useKeyboardShortcuts({ '/': whenNoPanel(() => toolbarRef.value?.focusSearch()), }) +/** + * 「新建任务」主按钮:焦点落到第一列(待办)的快速添加输入框 —— + * 与按 N 同一条路径,不再另造一套弹窗,保持「在列内就地录入」的心智。 + */ +function focusNewTask(): void { + if (ui.anyPanelOpen) return + columnRefs.get(0)?.focusQuickAdd() +} + function toggleTask(id: string): void { const task = store.activeTasks.find((item) => item.id === id) if (!task) return @@ -318,6 +327,7 @@ watch(filter, () => { :hidden-note="hiddenNote" :selecting="selecting" @archive="archiveCompleted" + @new-task="focusNewTask" @batch-add="batchOpen = true" @toggle-select="toggleSelectMode" @manage-tags="ui.openTags()"