diff --git a/frontend/src/MvpPanel.vue b/frontend/src/MvpPanel.vue index 6135f89..e6d6571 100644 --- a/frontend/src/MvpPanel.vue +++ b/frontend/src/MvpPanel.vue @@ -178,6 +178,12 @@ function habitProgressText(h: Habit) { if (h.kind !== 'numeric') return '' return `${Number(logFor(h, todayKey.value)?.value ?? 0)} / ${h.target ?? 1}` } +function habitProgressMax(h: Habit) { + return Math.max(Number(h.target ?? 1), 1) +} +function habitProgressValue(h: Habit) { + return Math.min(Math.max(Number(logFor(h, todayKey.value)?.value ?? 0), 0), habitProgressMax(h)) +} function setLocalHabitValue(h: Habit, next: number | boolean) { habits.value = habits.value.map((item) => item.id !== h.id @@ -403,6 +409,7 @@ onBeforeUnmount(() => {
{{ h.name }} {{ habitProgressText(h) }} +
{{ hideCompletedHabits && todayHabits.length ? '已完成的习惯已隐藏。' : '今天没有安排习惯,轻松一下吧。' }}
@@ -429,6 +436,7 @@ onBeforeUnmount(() => {
{{ h.name }} {{ habitProgressText(h) }} +
diff --git a/frontend/src/style.css b/frontend/src/style.css index 9e3bfce..85ea22b 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -16,9 +16,10 @@ main{min-width:0;padding:27px 34px 50px;overflow:auto;background:linear-gradient .habit-row.done{background:#fffaf5} .habit-row.swipeable{touch-action:pan-y;transform:translate(var(--swipe-x),var(--reorder-y,0px))} .habit-row.swipeable:not([style*="0px"]){transition:none} -.habit-main{flex:1;min-width:0;display:flex;align-items:center;justify-content:space-between;gap:10px;border:0;background:transparent;padding:13px 4px;text-align:left;border-radius:10px} +.habit-main{flex:1;min-width:0;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:7px 10px;border:0;background:transparent;padding:11px 4px;text-align:left;border-radius:10px} .habit-name{font-size:15px;font-weight:700;color:#3c372f;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .habit-progress{margin-left:auto;flex:0 0 auto;font-size:11px;color:var(--muted);white-space:nowrap} +.habit-progress-bar{grid-column:1/-1;width:100%;height:5px;border:0;border-radius:999px;overflow:hidden;background:#eee6db;appearance:none;-webkit-appearance:none}.habit-progress-bar::-webkit-progress-bar{background:#eee6db;border-radius:999px}.habit-progress-bar::-webkit-progress-value{background:linear-gradient(90deg,#f7a066,var(--accent));border-radius:999px;transition:width .2s ease}.habit-progress-bar::-moz-progress-bar{background:linear-gradient(90deg,#f7a066,var(--accent));border-radius:999px} .habit-row.done .habit-name{color:var(--accent);text-decoration:line-through;text-decoration-thickness:1.5px;text-decoration-color:#b99a89} .habit-row .icon.ghost{color:#b3a795;margin-left:4px} .habit-row .icon.ghost:hover{color:var(--danger)} diff --git a/frontend/src/style.test.ts b/frontend/src/style.test.ts index dd95faa..f3f0450 100644 --- a/frontend/src/style.test.ts +++ b/frontend/src/style.test.ts @@ -120,6 +120,14 @@ describe('task and habit row decoration', () => { expect(css).toContain('.habit-progress{margin-left:auto;') }) + it('shows an accessible progress bar for numeric habits in both habit views', () => { + expect(mvpPanel.match(/ { expect(app).toContain("readStoredNavigation(window.localStorage, NAVIGATION_STORAGE_KEY)") expect(app).toContain("writeStoredNavigation(window.localStorage, NAVIGATION_STORAGE_KEY, view, activeList.value)")