feat: 补齐今日视图待办组、卡片键盘操作、深色模式
今日视图 - 补上「待办」组。此前只收 逾期 / 今天到期 / 进行中,导致待办列里没设 截止日期的任务在今日视图里完全消失 —— 用户明明有一堆事没做,却看到 「今天没有待办事项」。现在只要任务未完成且未归档,就必定出现在某个 分组里(归属优先级:逾期 > 今天到期 > 进行中 > 待办)。 - 统计卡片改为与分组一一对应(逾期 / 今天到期 / 进行中 / 本周完成), 不再用「今日待办」这种把四组混在一起、与列表长度对不上的指标。 键盘操作(可访问性) - 卡片可聚焦(Tab / 点击),← → 换列、↑ ↓ 列内调序、Enter 打开详情。 - 换列时追加到目标列末尾:用全量长度而不是可见下标,筛选态下也安全; 列内调序要求该列渲染的是全量,否则禁用(与拖拽的规则一致)。 - 移动后手动恢复焦点 —— 卡片跨列会被重建,不恢复的话连续按键会失效。 深色模式 - 三态:跟随系统 / 浅色 / 深色,选择持久化到 localStorage。 - index.html 内联脚本在首帧之前应用主题,避免深色下闪白。 - 用 @custom-variant dark 做 class 控制(而不是纯 media query), 才能支持「强制浅色」;html 的 color-scheme 让原生控件与滚动条跟随。 验证:单元测试 480 个、端到端测试 25 个全部通过,lint 与构建无错误。 截图脚本新增深色与移动端深色两组,便于后续对照。
This commit is contained in:
+37
-4
@@ -9,6 +9,7 @@ import SideDrawer from '@/components/SideDrawer.vue'
|
||||
import ToastHost from '@/components/ToastHost.vue'
|
||||
import { useKeyboardShortcuts } from '@/composables/useKeyboardShortcuts'
|
||||
import { useTaskStore } from '@/stores/tasks'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useUiStore } from '@/stores/ui'
|
||||
|
||||
const SHORTCUTS = [
|
||||
@@ -18,11 +19,21 @@ const SHORTCUTS = [
|
||||
{ keys: 'Esc', description: '关闭当前面板' },
|
||||
] as const
|
||||
|
||||
/** 这些只在卡片获得焦点后生效 */
|
||||
const CARD_SHORTCUTS = [
|
||||
{ keys: 'Tab', description: '依次聚焦到任务卡片' },
|
||||
{ keys: '← →', description: '把卡片移到上一列 / 下一列' },
|
||||
{ keys: '↑ ↓', description: '在列内上移 / 下移' },
|
||||
{ keys: 'Enter', description: '打开任务详情' },
|
||||
] as const
|
||||
|
||||
const store = useTaskStore()
|
||||
const ui = useUiStore()
|
||||
const theme = useThemeStore()
|
||||
|
||||
onMounted(() => {
|
||||
store.init()
|
||||
theme.init()
|
||||
})
|
||||
|
||||
// 帮助面板是应用级的,因此在任何视图下都能用 ?
|
||||
@@ -34,7 +45,7 @@ useKeyboardShortcuts({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-full min-h-0 flex-col bg-slate-100">
|
||||
<div class="flex h-full min-h-0 flex-col bg-slate-100 dark:bg-slate-950">
|
||||
<AppNav />
|
||||
|
||||
<main class="flex min-h-0 flex-1 flex-col">
|
||||
@@ -45,17 +56,39 @@ useKeyboardShortcuts({
|
||||
<BackupPanel :open="ui.backupOpen" @close="ui.closeBackup()" />
|
||||
|
||||
<SideDrawer :open="ui.helpOpen" title="快捷键" @close="ui.closeHelp()">
|
||||
<h3 class="mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-slate-500">
|
||||
全局
|
||||
</h3>
|
||||
<dl class="flex flex-col gap-3 text-sm">
|
||||
<div v-for="item in SHORTCUTS" :key="item.keys" class="flex items-center gap-3">
|
||||
<dt
|
||||
class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600"
|
||||
class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300"
|
||||
>
|
||||
{{ item.keys }}
|
||||
</dt>
|
||||
<dd class="text-slate-600">{{ item.description }}</dd>
|
||||
<dd class="text-slate-600 dark:text-slate-300">{{ item.description }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<p class="mt-4 text-xs text-slate-400">在输入框内输入时不会触发快捷键。</p>
|
||||
|
||||
<h3
|
||||
class="mt-6 mb-2 text-xs font-medium tracking-wide text-slate-400 uppercase dark:text-slate-500"
|
||||
>
|
||||
卡片聚焦后
|
||||
</h3>
|
||||
<dl class="flex flex-col gap-3 text-sm">
|
||||
<div v-for="item in CARD_SHORTCUTS" :key="item.keys" class="flex items-center gap-3">
|
||||
<dt
|
||||
class="w-14 shrink-0 rounded-md border border-slate-200 bg-slate-50 px-2 py-0.5 text-center font-mono text-xs text-slate-600 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300"
|
||||
>
|
||||
{{ item.keys }}
|
||||
</dt>
|
||||
<dd class="text-slate-600 dark:text-slate-300">{{ item.description }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<p class="mt-4 text-xs text-slate-400 dark:text-slate-500">
|
||||
在输入框内输入时不会触发快捷键。
|
||||
</p>
|
||||
</SideDrawer>
|
||||
|
||||
<ToastHost />
|
||||
|
||||
Reference in New Issue
Block a user