Files
Edu/packages/ui-components/src/loading.tsx
SpecialX faaaf29f67 docs: ai 协作文档体系重构与多 ai 仲裁结果落地
1.AI 协作文档体系重构(objections/worklines/contracts+matrix.md)

2.coord 仲裁文档(final-decisions/cross-review/final-rulings/orchestration)

3.各服务 01/02 文档补全

4.共享包初始化(shared-ts/shared-go/hooks/ui-components/ui-tokens)

5.Proto 契约补全

6.004 架构影响地图更新

7.端口分配表

8.设计规格文档
2026-07-10 12:58:22 +08:00

66 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ReactNode } from "react";
import { cn } from "./utils/cn.js";
/**
* Loading - 骨架屏 / 加载占位
*
* 用途:数据加载期间展示骨架屏,避免内容跳动。
*
* @example
* <Loading /> // 默认 3 行骨架
* <Loading lines={5} /> // 5 行骨架
* <Loading variant="spinner" /> // 旋转图标
*/
export interface LoadingProps {
/** 骨架行数variant="skeleton" 时生效) */
lines?: number;
/** 展示形态 */
variant?: "skeleton" | "spinner";
/** 自定义类名 */
className?: string;
/** aria-label无障碍 */
ariaLabel?: string;
}
export function Loading({
lines = 3,
variant = "skeleton",
className,
ariaLabel = "加载中",
}: LoadingProps): ReactNode {
if (variant === "spinner") {
return (
<div
role="status"
aria-label={ariaLabel}
className={cn("flex items-center justify-center p-8", className)}
>
<span
className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-muted border-t-primary"
aria-hidden="true"
/>
<span className="sr-only">{ariaLabel}</span>
</div>
);
}
return (
<div
role="status"
aria-label={ariaLabel}
className={cn("flex flex-col gap-2 p-4", className)}
>
{Array.from({ length: lines }, (_, i) => (
<div
key={i}
className="h-4 animate-pulse rounded bg-muted"
style={{ width: `${100 - i * 10}%` }}
aria-hidden="true"
/>
))}
<span className="sr-only">{ariaLabel}</span>
</div>
);
}