Files
ttstd-infinite-canvas/web/src/components/ui/aceternity/full-screen-loader.tsx

58 lines
2.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 { useEffect, useState } from "react";
import { BrandLogoFrame } from "@/components/brand/brand-logo";
import { cn } from "@/lib/utils";
type FullScreenLoaderProps = {
label?: string;
detail?: string;
className?: string;
};
export function FullScreenLoader({ label = "正在恢复工作区", detail = "同步账号、模型和项目数据", className }: FullScreenLoaderProps) {
return (
<div
data-full-screen-loader
role="status"
aria-live="polite"
aria-label={`${label},${detail}`}
className={cn("full-screen-loader", className)}
>
<div className="full-screen-loader-scene" aria-hidden="true">
<span className="full-screen-loader-guide is-horizontal" />
<span className="full-screen-loader-guide is-vertical" />
<span className="full-screen-loader-frame is-left"><i /><i /><i /></span>
<span className="full-screen-loader-frame is-right"><i /><i /><i /></span>
<span className="full-screen-loader-script"><i /><i /><i /><b /></span>
<span className="full-screen-loader-timeline"><i /><i /><i /><i /><b /></span>
<span className="full-screen-loader-orbit" />
<BrandLogoFrame className="full-screen-loader-logo" logoClassName="full-screen-loader-logo-image" alt="" fallback={<span className="full-screen-loader-logo-fallback" />} />
</div>
<div className="full-screen-loader-copy"><strong>{label}</strong><span>{detail}</span><LoadingSignal /></div>
</div>
);
}
export function WorkspaceRouteLoader({ label = "正在打开页面" }: { label?: string }) {
const [visible, setVisible] = useState(false);
useEffect(() => {
const timer = window.setTimeout(() => setVisible(true), 140);
return () => window.clearTimeout(timer);
}, []);
return (
<section data-workspace-route-loader className={cn("workspace-route-loader", visible && "is-visible")} role="status" aria-live="polite" aria-label={label}>
<div className="workspace-route-loader-content">
<span className="workspace-route-loader-mark"><BrandLogoFrame className="workspace-route-loader-logo" logoClassName="size-4" alt="" fallback={<span className="full-screen-loader-logo-fallback" />} /></span>
<LoadingSignal />
<span>{label}</span>
</div>
</section>
);
}
function LoadingSignal() {
return <span className="loading-signal" aria-hidden="true"><i /><i /><i /></span>;
}