feat(core): 列表数据在途显示骨架屏(加载态),不再先显示空状态
渐进渲染后,列表在接口返回前会短暂显示「0 SKU / 显示 0」的空状态,易被误读为「没数据」。
新增 SkeletonGrid/SkeletonRows(components/loading),区分「加载中(请求在途且无数据)」与
「加载完确实为空」:
- 全局态页(商品库/视频项目/工作台最近项目):App 传 loading={!dataLoaded},未加载完显示骨架。
- 自取页(资产库/商品详情AI素材/图片生成任务/账单流水):各自 loading 标志,首次拉取时显示骨架/加载行。
- 团队成员有 owner 兜底行(非空)不改。
闸:9 页全绿、功能正常;实测 /products 加载期显示骨架→数据到后渲染真实卡片。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/* 列表加载骨架屏:数据在途时显示「加载中」的形,而非空状态。冷灰底上做轻微 shimmer。 */
|
||||
@keyframes sk-shimmer {
|
||||
0% { background-position: -480px 0; }
|
||||
100% { background-position: 480px 0; }
|
||||
}
|
||||
.skeleton-block {
|
||||
background: var(--background-base, #f1f1f1);
|
||||
background-image: linear-gradient(90deg, rgba(0,0,0,0.03) 0%, rgba(0,0,0,0.07) 40%, rgba(0,0,0,0.03) 80%);
|
||||
background-size: 480px 100%;
|
||||
background-repeat: no-repeat;
|
||||
animation: sk-shimmer 1.2s ease-in-out infinite;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.skeleton-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.skeleton-grid .skeleton-card { aspect-ratio: 1 / 1; }
|
||||
.skeleton-rows { display: flex; flex-direction: column; gap: 10px; }
|
||||
.skeleton-rows .skeleton-line { height: 56px; }
|
||||
.skeleton-loading-tag {
|
||||
font-family: var(--font-mono, monospace);
|
||||
font-size: 12px;
|
||||
color: var(--black-alpha-56, #8a8a8a);
|
||||
padding: 4px 0 12px;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import "./loading.css";
|
||||
|
||||
// 列表数据在途时的骨架屏(grid 卡片 / 行),替代「为空」状态,让用户看到「加载中」而非「没数据」。
|
||||
export function SkeletonGrid({ count = 8 }: { count?: number }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="skeleton-loading-tag">// 加载中…</div>
|
||||
<div className="skeleton-grid">
|
||||
{Array.from({ length: count }).map((_, i) => (
|
||||
<div className="skeleton-block skeleton-card" key={i} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SkeletonRows({ count = 6 }: { count?: number }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="skeleton-loading-tag">// 加载中…</div>
|
||||
<div className="skeleton-rows">
|
||||
{Array.from({ length: count }).map((_, i) => (
|
||||
<div className="skeleton-block skeleton-line" key={i} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user