mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-04 22:52:13 +08:00
feat: add skeleton
This commit is contained in:
@@ -1,4 +1,79 @@
|
||||
export function MessageListSkeleton() {
|
||||
// TODO: Add a loading state
|
||||
return null;
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
const STAGGER_MS = 60;
|
||||
|
||||
function SkeletonBar({
|
||||
className,
|
||||
style,
|
||||
originRight,
|
||||
}: {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
originRight?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`animate-skeleton-entrance fill-mode-[forwards] overflow-hidden rounded-md ${originRight ? "origin-[right]" : "origin-[left]"} ${className ?? ""}`}
|
||||
style={{ opacity: 0, ...style }}
|
||||
>
|
||||
<Skeleton className="h-full w-full rounded-md" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function MessageListSkeleton() {
|
||||
let index = 0;
|
||||
return (
|
||||
<div className="flex w-full max-w-(--container-width-md) flex-col gap-12 p-8 pt-16">
|
||||
<div
|
||||
role="human-message"
|
||||
className="flex w-[50%] flex-col items-end gap-2 self-end"
|
||||
>
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
originRight
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-[80%]"
|
||||
originRight
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
</div>
|
||||
<div role="assistant-message" className="flex flex-col gap-2">
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-[70%]"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-full"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-[60%]"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
<SkeletonBar
|
||||
className="h-6 w-[40%]"
|
||||
style={{ animationDelay: `${index++ * STAGGER_MS}ms` }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,18 @@
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
}
|
||||
|
||||
--animate-skeleton-entrance: skeleton-entrance 0.35s ease-out forwards;
|
||||
@keyframes skeleton-entrance {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scaleX(0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scaleX(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
|
||||
Reference in New Issue
Block a user