"use client"; import type { CSSProperties, ReactNode } from "react"; import { cn } from "@/lib/utils"; import type { XuluxPreviewFrame as XuluxPreviewFrameConfig } from "../templates/types"; type Props = { frame?: XuluxPreviewFrameConfig | undefined; children: ReactNode; className?: string | undefined; }; function aspectRatioWidthFactor(aspectRatio: string): number | null { const match = /^\s*(\d+(?:\.\d+)?)\s*\/\s*(\d+(?:\.\d+)?)\s*$/.exec( aspectRatio, ); if (!match) return null; const width = Number(match[1]); const height = Number(match[2]); if (!Number.isFinite(width) || !Number.isFinite(height) || height <= 0) { return null; } return width / height; } export function XuluxPreviewFrame({ frame, children, className }: Props) { if (!frame) { return
{children}
; } if (frame.kind === "terminal") { const width = frame.width ?? 800; const height = frame.height ?? 480; const terminalStyle = { width: `min(${width}px, calc(100cqw - 2rem))`, height: `min(${height}px, calc(100cqh - 2rem))`, } satisfies CSSProperties; return (
{frame.title ?? "terminal"}
{children}
); } const width = frame.width ?? 320; const aspectRatio = frame.aspectRatio ?? "9 / 19.5"; const widthFactor = aspectRatioWidthFactor(aspectRatio); const phoneStyle = { width: `min(${width}px, calc(100cqw - 2rem)${ widthFactor ? `, calc((100cqh - 2rem) * ${widthFactor})` : "" })`, aspectRatio, } satisfies CSSProperties; return (
{children}
); }