Files
micronomicon/frontend/src/components/editor/PreviewPane.tsx
2026-04-01 08:28:44 +02:00

102 lines
3.8 KiB
TypeScript

import { ScrollArea } from "@/components/ui/scroll-area";
import { useEditorStore } from "@/stores/editorStore";
import { renderMicron } from "./micronRenderer";
import { cn } from "@/lib/utils";
type PreviewMode = "ascii" | "micron" | "raw" | "script";
export default function PreviewPane() {
const previewMode = useEditorStore((s) => s.previewMode);
const setPreviewMode = useEditorStore((s) => s.setPreviewMode);
const compiledAscii = useEditorStore((s) => s.compiledAscii);
const compiledMicron = useEditorStore((s) => s.compiledMicron);
const compiledScript = useEditorStore((s) => s.compiledScript);
const isDynamic = useEditorStore((s) => s.isDynamic);
const isCompiling = useEditorStore((s) => s.isCompiling);
const compileError = useEditorStore((s) => s.compileError);
const tabs: { value: PreviewMode; label: string; show: boolean }[] = [
{ value: "ascii", label: "ASCII", show: true },
{ value: "micron", label: "Micron", show: true },
{ value: "raw", label: "Raw", show: true },
{ value: "script", label: "Script", show: isDynamic },
];
return (
<div className="flex flex-col h-full">
<div className="flex items-center px-3 py-1.5 border-b shrink-0 gap-2">
<span className="text-xs text-muted-foreground flex-1">
Preview
{isDynamic && (
<span className="ml-1.5 text-amber-400" title="This page has dynamic features (source, if, for)">
dynamic
</span>
)}
{isCompiling && (
<span className="ml-2 text-yellow-500 animate-pulse">
compiling
</span>
)}
{compileError && (
<span className="ml-2 text-red-400" title={compileError}>
error
</span>
)}
</span>
<div className="flex gap-0.5 bg-muted rounded-md p-0.5">
{tabs
.filter((t) => t.show)
.map((tab) => (
<button
key={tab.value}
onClick={() => setPreviewMode(tab.value)}
className={cn(
"text-xs px-2 py-0.5 rounded transition-colors",
previewMode === tab.value
? "bg-background text-foreground shadow-sm"
: "text-muted-foreground hover:text-foreground",
)}
>
{tab.label}
</button>
))}
</div>
</div>
<ScrollArea className="flex-1 bg-background">
{previewMode === "ascii" ? (
<pre className="p-4 font-mono text-sm whitespace-pre leading-tight text-green-100/90">
{compiledAscii || (
<span className="text-muted-foreground">
ASCII preview will appear here
</span>
)}
</pre>
) : previewMode === "micron" ? (
compiledMicron ? (
<div
className="p-4 font-mono text-sm whitespace-pre leading-tight"
dangerouslySetInnerHTML={{
__html: renderMicron(compiledMicron),
}}
/>
) : (
<div className="p-4">
<span className="text-muted-foreground text-sm">
Micron preview will appear here
</span>
</div>
)
) : previewMode === "script" ? (
<pre className="p-4 font-mono text-xs whitespace-pre-wrap break-words text-amber-200/80 leading-relaxed">
{compiledScript || "No dynamic script generated."}
</pre>
) : (
<pre className="p-4 font-mono text-sm whitespace-pre-wrap break-words text-muted-foreground">
{compiledMicron || "Raw Micron output will appear here…"}
</pre>
)}
</ScrollArea>
</div>
);
}