"use client" import * as React from "react" import Image from "next/image" import Link from "next/link" import { Check, ChevronRight, Clipboard, File, Folder, Fullscreen, Monitor, RotateCw, Smartphone, Tablet, Terminal, } from "lucide-react" import { ImperativePanelHandle } from "react-resizable-panels" import { registryItemFileSchema, registryItemSchema } from "shadcn/schema" import { z } from "zod" import { trackEvent } from "@/lib/events" import { createFileTreeForRegistryItemFiles, FileTree } from "@/lib/registry" import { cn } from "@/lib/utils" import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard" import { getIconForLanguageExtension } from "@/components/icons" import { OpenInV0Button } from "@/components/open-in-v0-button" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible" import { ResizableHandle, ResizablePanel, ResizablePanelGroup, } from "@/components/ui/resizable" import { Separator } from "@/components/ui/separator" import { Sidebar, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarProvider, } from "@/components/ui/sidebar" import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" import { ToggleGroup, ToggleGroupItem, } from "@/components/ui/toggle-group" type BlockViewerContext = { item: z.infer view: "code" | "preview" setView: (view: "code" | "preview") => void activeFile: string | null setActiveFile: (file: string) => void resizablePanelRef: React.RefObject | null tree: ReturnType | null highlightedFiles: | (z.infer & { highlightedContent: string })[] | null iframeKey?: number setIframeKey?: React.Dispatch> } const BlockViewerContext = React.createContext(null) function useBlockViewer() { const context = React.useContext(BlockViewerContext) if (!context) { throw new Error("useBlockViewer must be used within a BlockViewerProvider.") } return context } function BlockViewerProvider({ item, tree, highlightedFiles, children, }: Pick & { children: React.ReactNode }) { const [view, setView] = React.useState("preview") const [activeFile, setActiveFile] = React.useState< BlockViewerContext["activeFile"] >(highlightedFiles?.[0].target ?? null) const resizablePanelRef = React.useRef(null) const [iframeKey, setIframeKey] = React.useState(0) return (
{children}
) } function BlockViewerToolbar() { const { setView, view, item, resizablePanelRef, setIframeKey } = useBlockViewer() const { copyToClipboard, isCopied } = useCopyToClipboard() // const viewPath = process.env.NEXT_PUBLIC_VIEW_PATH || "/view" return (
{/* Title and Description Section */}
{item.meta?.details && (

{item.meta.details}

)}
{/* Controllers Section */}
{/* {isPro && !hasAccess ? ( ) : ( */} {/* )} */}
{ setView("preview") if (resizablePanelRef?.current) { resizablePanelRef.current.resize(parseInt(value)) } }} className="gap-1 *:data-[slot=toggle-group-item]:!size-6 *:data-[slot=toggle-group-item]:!rounded-sm" >
setView(value as "preview" | "code")} > Preview {/* */} Code
) } function BlockViewerIframe({ className }: { className?: string }) { const { item, iframeKey } = useBlockViewer() const viewPath = process.env.NEXT_PUBLIC_VIEW_PATH || "/view" return (