"use client"; import { Button } from "@/components/ui/button"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { Input } from "@/components/ui/input"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import { cn } from "@/lib/utils"; import { ChevronDownIcon } from "lucide-react"; import type { ComponentProps, ReactNode } from "react"; import { createContext, useContext, useEffect, useState } from "react"; export type WebPreviewContextValue = { url: string; setUrl: (url: string) => void; consoleOpen: boolean; setConsoleOpen: (open: boolean) => void; }; const WebPreviewContext = createContext(null); const useWebPreview = () => { const context = useContext(WebPreviewContext); if (!context) { throw new Error("WebPreview components must be used within a WebPreview"); } return context; }; export type WebPreviewProps = ComponentProps<"div"> & { defaultUrl?: string; onUrlChange?: (url: string) => void; }; export const WebPreview = ({ className, children, defaultUrl = "", onUrlChange, ...props }: WebPreviewProps) => { const [url, setUrl] = useState(defaultUrl); const [consoleOpen, setConsoleOpen] = useState(false); const handleUrlChange = (newUrl: string) => { setUrl(newUrl); onUrlChange?.(newUrl); }; const contextValue: WebPreviewContextValue = { url, setUrl: handleUrlChange, consoleOpen, setConsoleOpen, }; return (
{children}
); }; export type WebPreviewNavigationProps = ComponentProps<"div">; export const WebPreviewNavigation = ({ className, children, ...props }: WebPreviewNavigationProps) => (
{children}
); export type WebPreviewNavigationButtonProps = ComponentProps & { tooltip?: string; }; export const WebPreviewNavigationButton = ({ onClick, disabled, tooltip, children, ...props }: WebPreviewNavigationButtonProps) => (

{tooltip}

); export type WebPreviewUrlProps = ComponentProps; export const WebPreviewUrl = ({ value, onChange, onKeyDown, ...props }: WebPreviewUrlProps) => { const { url, setUrl } = useWebPreview(); const [inputValue, setInputValue] = useState(url); // Sync input value with context URL when it changes externally useEffect(() => { setInputValue(url); }, [url]); const handleChange = (event: React.ChangeEvent) => { setInputValue(event.target.value); onChange?.(event); }; const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === "Enter") { const target = event.target as HTMLInputElement; setUrl(target.value); } onKeyDown?.(event); }; return ( ); }; export type WebPreviewBodyProps = ComponentProps<"iframe"> & { loading?: ReactNode; }; export const WebPreviewBody = ({ className, loading, src, ...props }: WebPreviewBodyProps) => { const { url } = useWebPreview(); return (