+
+ );
+}
+
+function DemoViewport({
+ dark,
+ lang,
+ mounted,
+}: {
+ dark: boolean;
+ lang: Language;
+ mounted: boolean;
+}) {
+ const [frameLoaded, setFrameLoaded] = useState(false);
+ const [revealed, setRevealed] = useState(false);
+ const theme = dark ? 'default-dark' : 'default-light';
+ const demoUrl = `/product-demo/demo/index.html?theme=${theme}&locale=${demoLocale[lang]}`;
+ const posterUrl = `/images/product-demo-${dark ? 'dark' : 'light'}-${lang}.png`;
+
+ useEffect(() => {
+ if (!frameLoaded) return;
+ // iframe onLoad 只代表文档加载完成,等内部应用渲染后再揭开 poster
+ const timer = setTimeout(() => setRevealed(true), 900);
+ return () => clearTimeout(timer);
+ }, [frameLoaded]);
+
+ return (
+
+ {mounted ? (
-
真实桌面端组件 · 使用隔离的 Mock 数据,可直接操作菜单、筛选和设置
+ ) : null}
+
);
}
diff --git a/apps/docs/components/hero/DownloadButton.tsx b/apps/docs/components/hero/DownloadButton.tsx
new file mode 100644
index 0000000..20451ba
--- /dev/null
+++ b/apps/docs/components/hero/DownloadButton.tsx
@@ -0,0 +1,37 @@
+'use client';
+
+import { useSyncExternalStore } from 'react';
+import { Download } from 'lucide-react';
+import type { Language } from '@/lib/i18n';
+import { releaseUrl } from '@/lib/shared';
+
+function detectPlatform(): string | null {
+ const ua = navigator.userAgent;
+ if (/Mac/i.test(ua)) return 'macOS';
+ if (/Win/i.test(ua)) return 'Windows';
+ if (/Linux|X11/i.test(ua)) return 'Linux';
+ return null;
+}
+
+const labels: Record