Files
wehub-resource-sync d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

56 lines
2.0 KiB
TypeScript

'use client'
import dynamic from 'next/dynamic'
import type { SidebarView } from '@/app/(landing)/components/landing-preview/components/landing-preview-sidebar/landing-preview-sidebar'
import { useLazyMount } from '@/app/(landing)/hooks/use-lazy-mount'
/** Dimension-stable placeholder sized to the preview's exact footprint (zero CLS). */
const PLACEHOLDER_CLASS = 'aspect-[1116/615] w-full rounded bg-[var(--surface-1)]'
/**
* Client mount for the {@link LandingPreview} - the heavy, animated workspace
* island (framer-motion + reactflow). Isolated here so the sections that show it
* stay Server Components: only this leaf is `'use client'`.
*
* Loaded with `ssr: false` so the framer-motion/reactflow bundle never ships in
* the server-rendered HTML, and gated on viewport proximity via
* {@link useLazyMount} so the below-the-fold previews don't pull the heavy
* bundle into the initial homepage load. A dimension-stable placeholder (the
* preview's exact `aspect-[1116/615]` footprint, filled with the canvas
* surface) holds the space before and during load, so there is zero layout
* shift or flash.
*/
const LandingPreview = dynamic(
() =>
import('@/app/(landing)/components/landing-preview/landing-preview').then(
(mod) => mod.LandingPreview
),
{
ssr: false,
loading: () => <div className={PLACEHOLDER_CLASS} />,
}
)
interface LandingPreviewMountProps {
/** Forwarded to {@link LandingPreview}; `false` renders a static snapshot. */
autoplay?: boolean
/** Forwarded to {@link LandingPreview}; the static snapshot's staged view. */
view?: SidebarView
/** Forwarded to {@link LandingPreview}; the static snapshot's workflow. */
workflowId?: string
}
export function LandingPreviewMount({ autoplay, view, workflowId }: LandingPreviewMountProps) {
const { ref, inView } = useLazyMount('400px')
return (
<div ref={ref}>
{inView ? (
<LandingPreview autoplay={autoplay} initialView={view} initialWorkflowId={workflowId} />
) : (
<div className={PLACEHOLDER_CLASS} />
)}
</div>
)
}