1
0

feat: Header 倒计时数字滚动动画 — @number-flow/react 替换静态文本

This commit is contained in:
2026-05-16 00:14:35 +08:00
parent 88f4119a4e
commit f8d563c668
9 changed files with 212 additions and 41 deletions

View File

@@ -1,9 +1,8 @@
import NumberFlow from "@number-flow/react";
import { useEffect, useState } from "react";
import { RefreshIcon } from "tdesign-icons-react";
import { Button, Typography } from "tdesign-react";
import { formatCountdown } from "../utils/time";
interface RefreshCountdownProps {
dashboardUpdatedAt: number;
isFetching: boolean;
@@ -45,8 +44,55 @@ export function RefreshCountdown({
);
}
const refreshText =
dashboardUpdatedAt > 0 ? (isFetching ? "刷新中..." : formatCountdown(nextRefreshSeconds ?? 0)) : "等待首次刷新";
if (dashboardUpdatedAt <= 0) {
return <Typography.Text theme="secondary"></Typography.Text>;
}
return <Typography.Text theme="secondary">{refreshText}</Typography.Text>;
if (isFetching) {
return <Typography.Text theme="secondary">...</Typography.Text>;
}
const seconds = nextRefreshSeconds ?? 0;
const isMinuteMode = refreshInterval >= 60000;
if (isMinuteMode) {
const mm = Math.floor(seconds / 60);
const ss = seconds % 60;
return (
<span aria-label={formatAccessibleLabel(seconds, true)} className="refresh-countdown-flow">
<NumberFlow
className="refresh-countdown-flow__number"
format={{ minimumIntegerDigits: 1 }}
trend={-1}
value={mm}
/>
<span className="refresh-countdown-flow__unit"></span>
<NumberFlow
className="refresh-countdown-flow__number"
digits={{ 1: { max: 5 } }}
format={{ minimumIntegerDigits: 2 }}
trend={-1}
value={ss}
/>
<span className="refresh-countdown-flow__unit"></span>
</span>
);
}
return (
<span aria-label={formatAccessibleLabel(seconds, false)} className="refresh-countdown-flow">
<NumberFlow className="refresh-countdown-flow__number" trend={-1} value={seconds} />
<span className="refresh-countdown-flow__unit"></span>
</span>
);
}
function formatAccessibleLabel(seconds: number, isMinuteMode: boolean): string {
if (isMinuteMode) {
const mm = Math.floor(seconds / 60);
const ss = seconds % 60;
return `${mm}${String(ss).padStart(2, "0")}`;
}
return `${seconds}`;
}

View File

@@ -63,6 +63,24 @@
white-space: nowrap;
}
.refresh-countdown-flow {
display: inline-flex;
align-items: baseline;
font-variant-numeric: tabular-nums;
white-space: nowrap;
color: var(--td-text-color-secondary);
}
.refresh-countdown-flow__number {
line-height: 0.85;
--number-flow-mask-height: 0.15em;
--number-flow-mask-width: 0.25em;
}
.refresh-countdown-flow__unit {
margin: 0 1px;
}
.status-dot {
display: inline-block;
width: 12px;