/* eslint-disable react-hooks/static-components */ import * as React from "react" import { type Metadata } from "next" import { notFound } from "next/navigation" import { siteConfig } from "@/lib/config" import { getDemoItem, getRegistryComponent, getRegistryItem, } from "@/lib/registry" import { absoluteUrl } from "@/lib/utils" import { getStyle, legacyStyles, type Style } from "@/registry/_legacy-styles" import "@/app/legacy-themes.css" import { ComponentPreview } from "./component-preview" export const revalidate = false export const dynamic = "force-static" export const dynamicParams = false const getCachedRegistryItem = React.cache( async (name: string, styleName: Style["name"]) => { // Try registry item first, then fallback to demo item (for examples). const item = await getRegistryItem(name, styleName) if (item) { return item } return await getDemoItem(name, styleName) } ) export async function generateMetadata({ params, }: { params: Promise<{ style: string name: string }> }): Promise { const { style: styleName, name } = await params const style = getStyle(styleName) if (!style) { return {} } const item = await getCachedRegistryItem(name, style.name) if (!item) { return {} } const title = item.name const description = item.description return { title: item.name, description, openGraph: { title, description, type: "article", url: absoluteUrl(`/view/${style.name}/${item.name}`), images: [ { url: siteConfig.ogImage, width: 1200, height: 630, alt: siteConfig.name, }, ], }, twitter: { card: "summary_large_image", title, description, images: [siteConfig.ogImage], creator: "@shadcn", }, } } export async function generateStaticParams() { const { Index } = await import("@/registry/__index__") // const { Index: BasesIndex } = await import("@/registry/bases/__index__") const { ExamplesIndex } = await import("@/examples/__index__") const params: Array<{ style: string; name: string }> = [] for (const style of legacyStyles) { // Check if this is a base-prefixed style (e.g., base-nova, radix-nova). const baseMatch = style.name.match(/^(base|radix|aria)-/) if (baseMatch) { const baseName = baseMatch[1] // Add examples from ExamplesIndex. const examples = ExamplesIndex[baseName] if (examples) { for (const exampleName of Object.keys(examples)) { if (exampleName.startsWith("sidebar-")) { params.push({ style: style.name, name: exampleName, }) } } } // // Add UI components from BasesIndex. // const baseIndex = BasesIndex[baseName] // if (baseIndex) { // for (const itemName in baseIndex) { // const item = baseIndex[itemName] // if ( // [ // "registry:block", // "registry:component", // "registry:example", // "registry:internal", // ].includes(item.type) // ) { // params.push({ // style: style.name, // name: item.name, // }) // } // } // } continue } // Handle legacy styles (e.g., new-york-v4). if (!Index[style.name]) { continue } const styleIndex = Index[style.name] for (const itemName in styleIndex) { const item = styleIndex[itemName] if ( [ "registry:block", "registry:component", "registry:example", "registry:internal", ].includes(item.type) ) { params.push({ style: style.name, name: item.name, }) } } } return params } export default async function BlockPage({ params, }: { params: Promise<{ style: string name: string }> }) { const { style: styleName, name } = await params const style = getStyle(styleName) if (!style) { return notFound() } const item = await getCachedRegistryItem(name, style.name) const Component = getRegistryComponent(name, style.name) if (!item || !Component) { return notFound() } return ( ) }