feat(ui): add showcase toggle and runtime renderer to design explorer
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Loader2, Check, Search, Eye, Sparkles, LayoutTemplate } from "lucide-react";
|
||||
import { Loader2, Check, Search, Eye, Sparkles, LayoutTemplate, Palette } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { STARTER_KITS } from "@/lib/design-kits/registry";
|
||||
import { DEFAULT_DESIGN_KIT_ID } from "@/lib/design-kits/types";
|
||||
@@ -13,6 +13,7 @@ export function DesignSystemExplorer() {
|
||||
|
||||
const [activeKitId, setActiveKitId] = useState<string>(DEFAULT_DESIGN_KIT_ID);
|
||||
const [previewKitId, setPreviewKitId] = useState<string>(DEFAULT_DESIGN_KIT_ID);
|
||||
const [previewMode, setPreviewMode] = useState<"showcase" | "tokens">("showcase");
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [search, setSearch] = useState("");
|
||||
@@ -113,7 +114,12 @@ export function DesignSystemExplorer() {
|
||||
return (
|
||||
<button
|
||||
key={kit.id}
|
||||
onClick={() => setPreviewKitId(kit.id)}
|
||||
onClick={() => {
|
||||
setPreviewKitId(kit.id);
|
||||
if (!kit.hasPreview && previewMode === "tokens") {
|
||||
setPreviewMode("showcase"); // force showcase if no raw tokens gallery
|
||||
}
|
||||
}}
|
||||
className={`w-full text-left p-3 rounded-lg flex items-start gap-3 transition-colors group relative ${
|
||||
isSelected ? 'bg-indigo-50/80 ring-1 ring-indigo-500/30' : 'hover:bg-zinc-50'
|
||||
}`}
|
||||
@@ -137,8 +143,8 @@ export function DesignSystemExplorer() {
|
||||
</div>
|
||||
{/* Visual Indicator if it has an HTML preview */}
|
||||
{kit.hasPreview && (
|
||||
<div className="absolute right-3 top-3.5 text-zinc-300 group-hover:text-indigo-400 transition-colors" title="Visual Preview Available">
|
||||
<LayoutTemplate className="w-3.5 h-3.5" />
|
||||
<div className="absolute right-3 top-3.5 text-zinc-300 group-hover:text-indigo-400 transition-colors" title="Detailed Token Gallery Available">
|
||||
<Palette className="w-3.5 h-3.5" />
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
@@ -156,14 +162,34 @@ export function DesignSystemExplorer() {
|
||||
<div className="flex-1 flex flex-col h-full bg-zinc-100 overflow-hidden relative">
|
||||
{/* Top Action Bar */}
|
||||
<div className="h-14 flex-shrink-0 bg-white border-b border-zinc-200 px-6 flex items-center justify-between shadow-sm z-10">
|
||||
<div className="flex items-center gap-3 min-w-0">
|
||||
<Eye className="w-4 h-4 text-zinc-400" />
|
||||
<span className="text-sm font-medium text-zinc-900 truncate flex items-center gap-2">
|
||||
Previewing: {previewKit.name}
|
||||
{!previewKit.hasPreview && (
|
||||
<span className="px-2 py-0.5 rounded-full bg-zinc-100 text-zinc-500 text-[10px] font-mono tracking-wide uppercase border border-zinc-200">Rules Only</span>
|
||||
<div className="flex items-center gap-6 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye className="w-4 h-4 text-zinc-400" />
|
||||
<span className="text-sm font-medium text-zinc-900 truncate">
|
||||
{previewKit.name}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="flex bg-zinc-100 p-0.5 rounded-lg border border-zinc-200">
|
||||
<button
|
||||
onClick={() => setPreviewMode("showcase")}
|
||||
className={`px-3 py-1 text-xs font-medium rounded-md transition-colors ${
|
||||
previewMode === "showcase" ? 'bg-white text-zinc-900 shadow-sm' : 'text-zinc-500 hover:text-zinc-700'
|
||||
}`}
|
||||
>
|
||||
Showcase
|
||||
</button>
|
||||
{previewKit.hasPreview && (
|
||||
<button
|
||||
onClick={() => setPreviewMode("tokens")}
|
||||
className={`px-3 py-1 text-xs font-medium rounded-md transition-colors ${
|
||||
previewMode === "tokens" ? 'bg-white text-zinc-900 shadow-sm' : 'text-zinc-500 hover:text-zinc-700'
|
||||
}`}
|
||||
>
|
||||
Raw Tokens
|
||||
</button>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
@@ -189,13 +215,13 @@ export function DesignSystemExplorer() {
|
||||
<div className="w-2.5 h-2.5 rounded-full bg-green-400/80"></div>
|
||||
</div>
|
||||
<div className="mx-auto bg-white px-3 py-0.5 rounded-md border border-zinc-200 text-[10px] text-zinc-400 font-mono shadow-sm">
|
||||
{previewKit.id}.design.preview
|
||||
{previewKit.id}.{previewMode}.preview
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<iframe
|
||||
key={previewKit.id} // Forces iframe to remount
|
||||
src={`/api/design-systems/${previewKit.id}/preview`}
|
||||
key={`${previewKit.id}-${previewMode}`} // Forces iframe to remount on change
|
||||
src={previewMode === "showcase" ? `/api/design-systems/${previewKit.id}/showcase` : `/api/design-systems/${previewKit.id}/preview`}
|
||||
className="flex-1 w-full h-full bg-zinc-50"
|
||||
sandbox="allow-scripts allow-same-origin"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user