feat(create): show a loading placeholder for the customizer and preview (#11093)

* feat(create): show a loading placeholder for the customizer and preview

* fix(create): render the placeholder as the suspense fallback so it prerenders
This commit is contained in:
shadcn
2026-07-06 13:13:00 +04:00
committed by GitHub
parent 4163c1dbea
commit d8ace420ba
3 changed files with 25 additions and 1 deletions

View File

@@ -0,0 +1,15 @@
import { Skeleton } from "@/styles/base-nova/ui/skeleton"
export function CreateSkeleton() {
return (
<div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden section-soft [--customizer-width:--spacing(48)] [--gap:--spacing(4)] md:[--gap:--spacing(6)] 2xl:[--customizer-width:--spacing(56)]">
<div
data-slot="designer"
className="flex min-h-0 flex-1 flex-col gap-(--gap) p-(--gap) pt-[calc(var(--gap)*0.25)] md:flex-row-reverse"
>
<Skeleton className="flex-1 rounded-2xl" />
<Skeleton className="min-h-[151px] w-full self-start rounded-2xl md:h-full md:max-h-full md:min-h-0 md:w-(--customizer-width)" />
</div>
</div>
)
}

View File

@@ -1,5 +1,6 @@
import { Suspense } from "react"
import { CreateSkeleton } from "@/app/(app)/create/components/create-skeleton"
import { HistoryProvider } from "@/app/(app)/create/hooks/use-history"
import { LocksProvider } from "@/app/(app)/create/hooks/use-locks"
@@ -10,7 +11,10 @@ export default function CreateLayout({
}) {
return (
<LocksProvider>
<Suspense>
{/* HistoryProvider reads useSearchParams(), which opts this subtree out
of prerendering up to this boundary. The fallback is what paints on
first load, so it must be the page placeholder, not empty. */}
<Suspense fallback={<CreateSkeleton />}>
<HistoryProvider>{children}</HistoryProvider>
</Suspense>
</LocksProvider>

View File

@@ -0,0 +1,5 @@
import { CreateSkeleton } from "@/app/(app)/create/components/create-skeleton"
export default function CreateLoading() {
return <CreateSkeleton />
}