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(/