ai-chatbot/components/home/home-animation-embed.tsx
Your Name e5a07fa022
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix: refine home animation embed layout
2026-03-24 23:39:18 +08:00

114 lines
3.4 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.

"use client";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
type HomeAnimationEmbedProps = {
htmlContent: string;
title?: string;
description?: string;
className?: string;
frameClassName?: string;
};
export function HomeAnimationEmbed({
htmlContent,
title,
description,
className,
frameClassName,
}: HomeAnimationEmbedProps) {
const [interactive, setInteractive] = useState(false);
useEffect(() => {
if (!interactive) {
return;
}
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setInteractive(false);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [interactive]);
if (!htmlContent.trim()) {
return null;
}
return (
<div
className={cn(
"overflow-hidden rounded-[24px] border border-black/10 bg-white shadow-[0_10px_24px_rgba(0,0,0,0.05)]",
className,
)}
onMouseLeave={() => setInteractive(false)}
>
{title || description ? (
<div className="flex items-start justify-between gap-4 border-b border-black/8 px-4 py-3">
<div className="min-w-0">
{title ? (
<div className="text-[14px] font-semibold text-black">{title}</div>
) : null}
{description ? (
<div className="mt-1 text-[12px] text-black/45">{description}</div>
) : null}
</div>
<button
type="button"
className={cn(
"inline-flex h-8 items-center rounded-full px-3 text-[12px] font-medium transition-colors",
interactive
? "bg-black text-white hover:bg-black/85"
: "border border-black/10 bg-white text-black/65 hover:bg-black/5",
)}
onClick={() => setInteractive((value) => !value)}
>
{interactive ? "退出互动" : "进入互动"}
</button>
</div>
) : null}
<div
className={cn(
"relative h-[360px] w-full bg-[#f6f6f6] md:h-[420px]",
frameClassName,
)}
>
<iframe
title={title || "首页互动动画"}
srcDoc={htmlContent}
sandbox="allow-scripts allow-forms allow-pointer-lock"
loading="lazy"
className={cn(
"h-full w-full border-0 transition-opacity",
interactive ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-95",
)}
/>
{!interactive ? (
<button
type="button"
className="absolute inset-0 flex flex-col items-center justify-center gap-3 bg-white/12 backdrop-blur-[1px]"
onClick={() => setInteractive(true)}
>
<span className="rounded-full bg-white/92 px-4 py-2 text-[13px] font-medium text-black shadow-sm">
点击进入互动
</span>
<span className="text-[12px] text-black/55">
默认保留页面滚动,进入互动后可拖拽和滚轮操作,按 `Esc` 或移出模块退出
</span>
</button>
) : (
<div className="pointer-events-none absolute bottom-3 right-3 rounded-full bg-black/70 px-3 py-1 text-[11px] text-white">
互动中
</div>
)}
</div>
</div>
);
}