@sampleapp.ai/sdk 1.0.36 → 1.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/sandbox/Sandbox.js +5 -0
- package/dist/components/sandbox/api.js +2 -2
- package/dist/components/sandbox/guardian/guardian-component.js +7 -38
- package/dist/components/sandbox/guardian/guardian-playground.js +2 -2
- package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +12 -10
- package/dist/components/sandbox/guardian/index.js +1 -1
- package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +2 -1
- package/dist/components/sandbox/guardian/ui/markdown.js +2 -2
- package/dist/components/sandbox/guardian/utils.js +4 -22
- package/dist/components/sandbox/index.js +1 -1
- package/dist/components/sandbox/sandbox-home/SandboxHome.js +5 -0
- package/dist/index.d.ts +8 -40
- package/dist/index.es.js +834 -870
- package/dist/index.js +1 -1
- package/dist/lib/api-client.js +9 -26
- package/package.json +1 -1
- package/dist/components/guardian/app-layout-no-sidebar.js +0 -8
- package/dist/components/guardian/ask-ai-view.js +0 -249
- package/dist/components/guardian/code-focus-section.d.ts +0 -41
- package/dist/components/guardian/code-focus-section.js +0 -174
- package/dist/components/guardian/context/guardian-context.js +0 -94
- package/dist/components/guardian/context/vm-context.js +0 -28
- package/dist/components/guardian/default-guide-view.js +0 -34
- package/dist/components/guardian/demo/guardian-demo.js +0 -35
- package/dist/components/guardian/demo/left-view/toggle.js +0 -28
- package/dist/components/guardian/demo/left-view.js +0 -49
- package/dist/components/guardian/guardian-component.js +0 -79
- package/dist/components/guardian/guardian-demo.js +0 -35
- package/dist/components/guardian/guardian-home.d.ts +0 -4
- package/dist/components/guardian/guardian-home.js +0 -61
- package/dist/components/guardian/guardian-playground.js +0 -45
- package/dist/components/guardian/guardian-style-wrapper.js +0 -29
- package/dist/components/guardian/guardian-upload-spec.d.ts +0 -14
- package/dist/components/guardian/guardian-upload-spec.js +0 -160
- package/dist/components/guardian/header/glassmorphic-combobox.d.ts +0 -15
- package/dist/components/guardian/header/glassmorphic-combobox.js +0 -30
- package/dist/components/guardian/header.js +0 -61
- package/dist/components/guardian/hooks/use-frame-messages.js +0 -65
- package/dist/components/guardian/hooks/use-frame-params.js +0 -44
- package/dist/components/guardian/hooks/use-sandbox-url-loader.js +0 -101
- package/dist/components/guardian/ide/browser.js +0 -538
- package/dist/components/guardian/index.js +0 -8
- package/dist/components/guardian/layout/app-layout-no-sidebar.js +0 -8
- package/dist/components/guardian/layout/header/glassmorphic-combobox.js +0 -48
- package/dist/components/guardian/layout/header.js +0 -63
- package/dist/components/guardian/right-view/code-view.js +0 -56
- package/dist/components/guardian/right-view/pill-file-selector.js +0 -233
- package/dist/components/guardian/right-view/preview-control-bar.js +0 -25
- package/dist/components/guardian/right-view/right-panel-view.js +0 -38
- package/dist/components/guardian/right-view/right-top-down-view.js +0 -289
- package/dist/components/guardian/right-view/right-view.js +0 -28
- package/dist/components/guardian/right-view/simplified-editor.js +0 -234
- package/dist/components/guardian/types/ide-types.js +0 -162
- package/dist/components/guardian/types.js +0 -3
- package/dist/components/guardian/ui/ai-loader.js +0 -48
- package/dist/components/guardian/ui/badge.js +0 -24
- package/dist/components/guardian/ui/button.js +0 -45
- package/dist/components/guardian/ui/command.js +0 -63
- package/dist/components/guardian/ui/console-with-app.js +0 -17
- package/dist/components/guardian/ui/dialog.js +0 -57
- package/dist/components/guardian/ui/dropdown-menu.js +0 -82
- package/dist/components/guardian/ui/markdown.js +0 -57
- package/dist/components/guardian/ui/popover.js +0 -25
- package/dist/components/guardian/ui/tooltip.js +0 -25
- package/dist/components/guardian/utils.js +0 -88
- package/dist/components/guardian/zip-to-codebase.js +0 -246
- package/dist/components/guardian/zip-to-filetree.js +0 -284
- package/dist/components/sandbox/SandboxHome.js +0 -141
- package/dist/components/sandbox/guardian/guardian-demo.js +0 -35
- package/dist/components/sandbox/guardian/guardian-home.d.ts +0 -4
- package/dist/components/sandbox/guardian/guardian-home.js +0 -61
- package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +0 -14
- package/dist/components/sandbox/guardian/guardian-upload-spec.js +0 -160
- package/dist/components/sandbox/guardian/ui/theme-color-context.d.ts +0 -6
- package/dist/components/sandbox/sandbox-control-bar.js +0 -91
- package/dist/components/sandbox/sandbox-header.js +0 -52
- package/dist/components/sandbox/sandbox-left-panel.js +0 -248
- package/dist/components/sandbox/sandbox-loading.js +0 -48
- package/dist/components/sandbox/sandbox-right-panel.js +0 -247
- package/dist/components/sandbox.js +0 -32
- package/dist/lib/api-client.example.js +0 -60
- package/dist/lib/ssr-safe-decode-entity.js +0 -16
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
|
3
|
-
// FileExplorer and Editor components are not yet implemented in SDK
|
|
4
|
-
// These imports are commented out until those components are added
|
|
5
|
-
// import FileExplorer, {
|
|
6
|
-
// FileTreeNode,
|
|
7
|
-
// } from "../ide/file-explorer";
|
|
8
|
-
// import Editor from "../ide/Editor";
|
|
9
|
-
import React, { useEffect } from "react";
|
|
10
|
-
import { useGuardianContext } from "../context/guardian-context";
|
|
11
|
-
import { zipPathToFileTree } from "../zip-to-filetree";
|
|
12
|
-
import { zipPathToCodebase } from "../zip-to-codebase";
|
|
13
|
-
// Stub components until FileExplorer and Editor are implemented
|
|
14
|
-
const FileExplorer = ({ isGenerating }) => (React.createElement("div", { className: "h-full flex items-center justify-center text-muted-foreground text-sm" }, "File Explorer - Coming Soon"));
|
|
15
|
-
const Editor = () => (React.createElement("div", { className: "h-full flex items-center justify-center text-muted-foreground text-sm" }, "Code Editor - Coming Soon"));
|
|
16
|
-
// ORIGINAL URL: https://launchdarkly.sampleapp.ai/chat/mgl0vkr1IPwCIR
|
|
17
|
-
export default function CodeView({ codeZipFile }) {
|
|
18
|
-
const { setFileTree, setGeneratedCode } = useGuardianContext();
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
let isMounted = true;
|
|
21
|
-
zipPathToFileTree(codeZipFile)
|
|
22
|
-
.then((fileTree) => {
|
|
23
|
-
if (isMounted) {
|
|
24
|
-
setFileTree(fileTree);
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
.catch((error) => {
|
|
28
|
-
console.error("Failed to load zip file:", error);
|
|
29
|
-
});
|
|
30
|
-
zipPathToCodebase(codeZipFile)
|
|
31
|
-
.then((codebase) => {
|
|
32
|
-
if (isMounted) {
|
|
33
|
-
setGeneratedCode(codebase);
|
|
34
|
-
}
|
|
35
|
-
})
|
|
36
|
-
.catch((error) => {
|
|
37
|
-
console.error("Failed to load codebase:", error);
|
|
38
|
-
});
|
|
39
|
-
return () => {
|
|
40
|
-
isMounted = false;
|
|
41
|
-
};
|
|
42
|
-
}, [codeZipFile, setFileTree, setGeneratedCode]);
|
|
43
|
-
return (React.createElement("div", { className: "h-[calc(100vh-12.9rem)] w-full" },
|
|
44
|
-
React.createElement(PanelGroup, { direction: "horizontal", className: "relative h-full" },
|
|
45
|
-
React.createElement(Panel, { defaultSize: 25, minSize: 15, maxSize: 50, order: 1 },
|
|
46
|
-
React.createElement("div", { className: "h-full" },
|
|
47
|
-
React.createElement(FileExplorer, { isGenerating: false }))),
|
|
48
|
-
React.createElement(PanelResizeHandle, { className: "w-0 relative group flex-shrink-0" },
|
|
49
|
-
React.createElement("div", { className: "absolute inset-y-0 left-1/2 -translate-x-1/2 w-2 -ml-1 transition-colors flex justify-center items-center bg-transparent" },
|
|
50
|
-
React.createElement("div", { className: "absolute inset-y-0 left-0 w-1/2 group-hover:bg-blue-400/20 transition-colors" }),
|
|
51
|
-
React.createElement("div", { className: "absolute inset-y-0 right-0 w-1/2 group-hover:bg-blue-400/20 transition-colors" }),
|
|
52
|
-
React.createElement("div", { className: "h-full w-px bg-border group-hover:bg-blue-400 transition-colors relative z-10" }))),
|
|
53
|
-
React.createElement(Panel, { defaultSize: 75, order: 2 },
|
|
54
|
-
React.createElement("div", { className: "h-full" },
|
|
55
|
-
React.createElement(Editor, null))))));
|
|
56
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { useGuardianContext } from "../context/guardian-context";
|
|
4
|
-
import { cn } from "../../../lib/utils";
|
|
5
|
-
import { useFrameParams } from "../hooks/use-frame-params";
|
|
6
|
-
import { FileCode, FileJson, FileText, Settings, Layout, Database, Image, Terminal, } from "lucide-react";
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../ui/tooltip";
|
|
8
|
-
const FILE_ICONS = {
|
|
9
|
-
// JavaScript/React
|
|
10
|
-
js: { icon: FileCode, color: "text-yellow-600" },
|
|
11
|
-
jsx: { icon: FileCode, color: "text-blue-500" },
|
|
12
|
-
ts: { icon: FileCode, color: "text-blue-600" },
|
|
13
|
-
tsx: { icon: FileCode, color: "text-blue-500" },
|
|
14
|
-
json: { icon: FileJson, color: "text-yellow-500" },
|
|
15
|
-
html: { icon: Layout, color: "text-orange-500" },
|
|
16
|
-
css: { icon: FileText, color: "text-blue-400" },
|
|
17
|
-
scss: { icon: FileText, color: "text-pink-500" },
|
|
18
|
-
less: { icon: FileText, color: "text-indigo-500" },
|
|
19
|
-
// Python
|
|
20
|
-
py: { icon: FileCode, color: "text-green-500" },
|
|
21
|
-
pyc: { icon: FileCode, color: "text-green-400" },
|
|
22
|
-
pyw: { icon: FileCode, color: "text-green-500" },
|
|
23
|
-
ipynb: { icon: Terminal, color: "text-red-500" },
|
|
24
|
-
// Config files
|
|
25
|
-
env: { icon: Settings, color: "text-zinc-500" },
|
|
26
|
-
gitignore: { icon: Settings, color: "text-zinc-500" },
|
|
27
|
-
yml: { icon: Settings, color: "text-purple-500" },
|
|
28
|
-
yaml: { icon: Settings, color: "text-purple-500" },
|
|
29
|
-
toml: { icon: Settings, color: "text-purple-500" },
|
|
30
|
-
ini: { icon: Settings, color: "text-zinc-500" },
|
|
31
|
-
cfg: { icon: Settings, color: "text-zinc-500" },
|
|
32
|
-
config: { icon: Settings, color: "text-zinc-500" },
|
|
33
|
-
// Database
|
|
34
|
-
sql: { icon: Database, color: "text-blue-500" },
|
|
35
|
-
sqlite: { icon: Database, color: "text-blue-500" },
|
|
36
|
-
sqlite3: { icon: Database, color: "text-blue-500" },
|
|
37
|
-
// Images
|
|
38
|
-
png: { icon: Image, color: "text-green-500" },
|
|
39
|
-
jpg: { icon: Image, color: "text-green-500" },
|
|
40
|
-
jpeg: { icon: Image, color: "text-green-500" },
|
|
41
|
-
gif: { icon: Image, color: "text-green-500" },
|
|
42
|
-
svg: { icon: Image, color: "text-green-500" },
|
|
43
|
-
ico: { icon: Image, color: "text-green-500" },
|
|
44
|
-
// Default
|
|
45
|
-
default: { icon: FileText, color: "text-zinc-500" },
|
|
46
|
-
};
|
|
47
|
-
export default function PillFileSelector({ themeColor }) {
|
|
48
|
-
const containerRef = React.useRef(null);
|
|
49
|
-
const fileRefs = React.useRef({});
|
|
50
|
-
const lastInitializedFilePath = React.useRef(null);
|
|
51
|
-
const { generatedCode, updateCode, setLanguage, activeFilePath: contextActiveFilePath, setActiveFileName, setActiveFilePath, setActiveDependenciesToInstall, setActiveLineRange, filesEdited, } = useGuardianContext();
|
|
52
|
-
// Read frame params - these override context when isFrame=true
|
|
53
|
-
const frameParams = useFrameParams();
|
|
54
|
-
// Use frame param overrides when in frame mode
|
|
55
|
-
const activeFilePath = frameParams.isFrame && frameParams.activeFilePath
|
|
56
|
-
? frameParams.activeFilePath
|
|
57
|
-
: contextActiveFilePath;
|
|
58
|
-
const effectiveThemeColor = frameParams.isFrame && frameParams.theme ? frameParams.theme : themeColor;
|
|
59
|
-
// Get file entries and sort them
|
|
60
|
-
const fileEntries = Object.entries(generatedCode).sort(([a], [b]) => {
|
|
61
|
-
const aName = a.split("/").pop() || a;
|
|
62
|
-
const bName = b.split("/").pop() || b;
|
|
63
|
-
return aName.localeCompare(bName);
|
|
64
|
-
});
|
|
65
|
-
const handleFileClick = (filePath, fileData) => {
|
|
66
|
-
// In frame mode, replace all frame params with activeFilePath and isFrame only
|
|
67
|
-
if (frameParams.isFrame) {
|
|
68
|
-
const url = new URL(window.location.href);
|
|
69
|
-
url.search = "";
|
|
70
|
-
url.searchParams.set("activeFilePath", filePath);
|
|
71
|
-
url.searchParams.set("isFrame", "true");
|
|
72
|
-
url.searchParams.set("theme", effectiveThemeColor);
|
|
73
|
-
window.history.replaceState({}, "", url.toString());
|
|
74
|
-
}
|
|
75
|
-
const fileName = filePath.split("/").pop() || filePath;
|
|
76
|
-
setActiveFileName(fileName);
|
|
77
|
-
setActiveFilePath(filePath);
|
|
78
|
-
setLanguage(fileData.code_language);
|
|
79
|
-
updateCode(filePath in filesEdited
|
|
80
|
-
? filesEdited[filePath].full_code
|
|
81
|
-
: fileData.full_code);
|
|
82
|
-
setActiveDependenciesToInstall(fileData.dependencies_to_install);
|
|
83
|
-
};
|
|
84
|
-
const getFileIcon = (fileName) => {
|
|
85
|
-
var _a;
|
|
86
|
-
const ext = ((_a = fileName.split(".").pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "";
|
|
87
|
-
return FILE_ICONS[ext] || FILE_ICONS.default;
|
|
88
|
-
};
|
|
89
|
-
// Exclude certain files from display
|
|
90
|
-
const excludedFiles = [
|
|
91
|
-
".env",
|
|
92
|
-
"vite-plugin-react-instrumentation.ts",
|
|
93
|
-
"instrumentation-client.ts",
|
|
94
|
-
];
|
|
95
|
-
const filteredFiles = fileEntries.filter(([filePath]) => {
|
|
96
|
-
const fileName = filePath.split("/").pop() || filePath;
|
|
97
|
-
return !excludedFiles.includes(fileName);
|
|
98
|
-
});
|
|
99
|
-
// Scroll a pill into view whenever the active file changes
|
|
100
|
-
const scrollActivePillIntoView = React.useCallback((filePath) => {
|
|
101
|
-
const targetPath = filePath !== null && filePath !== void 0 ? filePath : activeFilePath;
|
|
102
|
-
if (!targetPath)
|
|
103
|
-
return;
|
|
104
|
-
const container = containerRef.current;
|
|
105
|
-
const activeButton = fileRefs.current[targetPath];
|
|
106
|
-
if (!container || !activeButton)
|
|
107
|
-
return;
|
|
108
|
-
// Small delay to ensure DOM has updated
|
|
109
|
-
setTimeout(() => {
|
|
110
|
-
const containerRect = container.getBoundingClientRect();
|
|
111
|
-
const activeRect = activeButton.getBoundingClientRect();
|
|
112
|
-
const isOutOfView = activeRect.left < containerRect.left ||
|
|
113
|
-
activeRect.right > containerRect.right;
|
|
114
|
-
if (isOutOfView) {
|
|
115
|
-
activeButton.scrollIntoView({
|
|
116
|
-
behavior: "instant",
|
|
117
|
-
block: "nearest",
|
|
118
|
-
inline: "center",
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}, 50);
|
|
122
|
-
}, [activeFilePath]);
|
|
123
|
-
// Ensure the active file pill is always visible in the scroll area
|
|
124
|
-
React.useEffect(() => {
|
|
125
|
-
scrollActivePillIntoView();
|
|
126
|
-
}, [scrollActivePillIntoView, filteredFiles.length]);
|
|
127
|
-
// Listen for frame param updates from postMessage
|
|
128
|
-
React.useEffect(() => {
|
|
129
|
-
if (!frameParams.isFrame)
|
|
130
|
-
return;
|
|
131
|
-
const handleFrameParamsUpdate = (event) => {
|
|
132
|
-
var _a;
|
|
133
|
-
try {
|
|
134
|
-
const customEvent = event;
|
|
135
|
-
const nextPath = (_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.activeFilePath;
|
|
136
|
-
scrollActivePillIntoView(nextPath);
|
|
137
|
-
}
|
|
138
|
-
catch (_b) {
|
|
139
|
-
// Fallback to current activeFilePath if parsing fails
|
|
140
|
-
scrollActivePillIntoView();
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
window.addEventListener("frameParamsUpdated", handleFrameParamsUpdate);
|
|
144
|
-
return () => window.removeEventListener("frameParamsUpdated", handleFrameParamsUpdate);
|
|
145
|
-
}, [frameParams.isFrame, scrollActivePillIntoView]);
|
|
146
|
-
// Load file from frame params when they change
|
|
147
|
-
React.useEffect(() => {
|
|
148
|
-
// Skip if not in frame mode or no file path specified
|
|
149
|
-
if (!frameParams.isFrame || !frameParams.activeFilePath) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
// Skip if we've already initialized this exact file path
|
|
153
|
-
if (lastInitializedFilePath.current === frameParams.activeFilePath) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
// Skip if generatedCode isn't loaded yet
|
|
157
|
-
if (!generatedCode || Object.keys(generatedCode).length === 0) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
// Search by file_path property first (source of truth), then fallback to key lookup
|
|
161
|
-
let fileData;
|
|
162
|
-
let resolvedFilePath;
|
|
163
|
-
// First, search through all code outputs to find one matching file_path
|
|
164
|
-
const matchingCodeOutput = Object.values(generatedCode).find((output) => output.file_path === frameParams.activeFilePath);
|
|
165
|
-
if (matchingCodeOutput) {
|
|
166
|
-
fileData = matchingCodeOutput;
|
|
167
|
-
resolvedFilePath = matchingCodeOutput.file_path;
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
// Fallback: try to get from generatedCode by key
|
|
171
|
-
if (generatedCode[frameParams.activeFilePath]) {
|
|
172
|
-
fileData = generatedCode[frameParams.activeFilePath];
|
|
173
|
-
resolvedFilePath = fileData.file_path || frameParams.activeFilePath;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
if (fileData && resolvedFilePath) {
|
|
177
|
-
lastInitializedFilePath.current = frameParams.activeFilePath; // Track initialized path
|
|
178
|
-
const fileName = fileData.code_file_name ||
|
|
179
|
-
resolvedFilePath.split("/").pop() ||
|
|
180
|
-
resolvedFilePath;
|
|
181
|
-
setActiveFileName(fileName);
|
|
182
|
-
setActiveFilePath(resolvedFilePath);
|
|
183
|
-
setLanguage(fileData.code_language);
|
|
184
|
-
updateCode(resolvedFilePath in filesEdited
|
|
185
|
-
? filesEdited[resolvedFilePath].full_code
|
|
186
|
-
: fileData.full_code);
|
|
187
|
-
setActiveDependenciesToInstall(fileData.dependencies_to_install);
|
|
188
|
-
// Set line range if provided in frame params
|
|
189
|
-
if (frameParams.linesStart !== undefined) {
|
|
190
|
-
setActiveLineRange({
|
|
191
|
-
start: frameParams.linesStart,
|
|
192
|
-
end: frameParams.linesEnd,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
setActiveLineRange(undefined);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
200
|
-
}, [frameParams.isFrame, frameParams.activeFilePath, generatedCode]);
|
|
201
|
-
if (filteredFiles.length === 0) {
|
|
202
|
-
return null;
|
|
203
|
-
}
|
|
204
|
-
return (React.createElement(TooltipProvider, null,
|
|
205
|
-
React.createElement("div", { ref: containerRef, className: "flex items-center gap-1 px-2 py-1.5 overflow-x-auto no-scrollbar [-ms-overflow-style:none] [scrollbar-width:none] flex-1" }, filteredFiles.map(([filePath, fileData]) => {
|
|
206
|
-
const fileName = filePath.split("/").pop() || filePath;
|
|
207
|
-
const isActive = filePath === activeFilePath;
|
|
208
|
-
const isEdited = filePath in filesEdited;
|
|
209
|
-
const fileIcon = getFileIcon(fileName);
|
|
210
|
-
const IconComponent = fileIcon.icon;
|
|
211
|
-
return (React.createElement(Tooltip, { key: filePath },
|
|
212
|
-
React.createElement(TooltipTrigger, { asChild: true },
|
|
213
|
-
React.createElement("button", { ref: (el) => {
|
|
214
|
-
if (el) {
|
|
215
|
-
fileRefs.current[filePath] = el;
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
delete fileRefs.current[filePath];
|
|
219
|
-
}
|
|
220
|
-
}, onClick: () => handleFileClick(filePath, fileData), className: cn("flex items-center gap-1.5 px-2.5 py-1 rounded text-xs font-normal transition-colors whitespace-nowrap", isActive
|
|
221
|
-
? "rounded-2xl text-zinc-100"
|
|
222
|
-
: "text-zinc-400 hover:text-zinc-200", isEdited && "ring-1 ring-yellow-500/50"), style: isActive
|
|
223
|
-
? {
|
|
224
|
-
backgroundColor: `${effectiveThemeColor}33`, // ~20% opacity
|
|
225
|
-
color: effectiveThemeColor,
|
|
226
|
-
}
|
|
227
|
-
: undefined },
|
|
228
|
-
React.createElement(IconComponent, { size: 12, className: cn("flex-shrink-0", !isActive && "text-zinc-500"), style: isActive ? { color: effectiveThemeColor } : undefined }),
|
|
229
|
-
React.createElement("span", { className: "truncate max-w-[180px]" }, fileName),
|
|
230
|
-
isEdited && (React.createElement("span", { className: "h-1 w-1 rounded-full bg-yellow-400 flex-shrink-0" })))),
|
|
231
|
-
React.createElement(TooltipContent, { side: "top", className: "bg-zinc-900 text-zinc-200 text-[11px] px-2 py-1 rounded shadow border border-zinc-700 whitespace-pre font-mono" }, filePath)));
|
|
232
|
-
}))));
|
|
233
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { useFrameParams } from "../hooks/use-frame-params";
|
|
3
|
-
import { useGuardianContext } from "../context/guardian-context";
|
|
4
|
-
import { ChevronDown, RefreshCw, Maximize2, Minimize2, ExternalLink, } from "lucide-react";
|
|
5
|
-
export default function PreviewControlBar({ isMinimized, onToggle, onRefresh, themeColor, externalUrl, // <-- NEW PROP
|
|
6
|
-
}) {
|
|
7
|
-
const { isBrowserMaximized, setIsBrowserMaximized } = useGuardianContext();
|
|
8
|
-
const frameParams = useFrameParams();
|
|
9
|
-
const effectiveThemeColor = frameParams.isFrame && frameParams.theme ? frameParams.theme : themeColor;
|
|
10
|
-
return (React.createElement("div", { className: "w-full flex items-center justify-between px-4 py-[0.32rem] border-b" },
|
|
11
|
-
React.createElement("button", { onClick: onToggle, className: "flex items-center gap-2 transition-colors", title: isMinimized ? "Show preview" : "Hide preview" },
|
|
12
|
-
React.createElement("div", { className: "transition-transform duration-300 ease-in-out", style: {
|
|
13
|
-
transform: isMinimized ? "rotate(0deg)" : "rotate(180deg)",
|
|
14
|
-
color: effectiveThemeColor,
|
|
15
|
-
} },
|
|
16
|
-
React.createElement(ChevronDown, { className: "w-4 h-4" })),
|
|
17
|
-
React.createElement("span", { className: "text-sm font-medium", style: { color: effectiveThemeColor } }, "Preview")),
|
|
18
|
-
React.createElement("div", { className: "flex items-center gap-2" },
|
|
19
|
-
externalUrl && (React.createElement("a", { href: externalUrl, target: "_blank", rel: "noopener noreferrer", title: "Open in new tab", style: { color: effectiveThemeColor }, className: "p-1.5 rounded transition-colors hover:bg-zinc-800 dark:hover:bg-zinc-800" },
|
|
20
|
-
React.createElement(ExternalLink, { className: "w-4 h-4" }),
|
|
21
|
-
React.createElement("span", { className: "sr-only" }, "Open external link"))),
|
|
22
|
-
React.createElement("button", { onClick: onRefresh, className: "p-1.5 rounded transition-colors hover:bg-zinc-800 dark:hover:bg-zinc-800", title: "Refresh preview", style: { color: effectiveThemeColor } },
|
|
23
|
-
React.createElement(RefreshCw, { className: "w-4 h-4" })),
|
|
24
|
-
React.createElement("button", { onClick: () => setIsBrowserMaximized(!isBrowserMaximized), className: "p-1.5 rounded transition-colors hover:bg-zinc-800 dark:hover:bg-zinc-800", title: isBrowserMaximized ? "Exit fullscreen" : "Fullscreen preview", style: { color: effectiveThemeColor } }, isBrowserMaximized ? (React.createElement(Minimize2, { className: "w-4 h-4" })) : (React.createElement(Maximize2, { className: "w-4 h-4" }))))));
|
|
25
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import SlidingEditPreviewToggle from "../demo/left-view/toggle";
|
|
4
|
-
import Browser from "../ide/browser";
|
|
5
|
-
import CodeView from "./code-view";
|
|
6
|
-
import { useGuardianContext } from "../context/guardian-context";
|
|
7
|
-
import { Component as AiLoader } from "../ui/ai-loader";
|
|
8
|
-
export default function RightPanelView({ reloadCounter, overlayStage, browserUrl, useVm, codeZipFile, }) {
|
|
9
|
-
const { setCurrentView, currentView } = useGuardianContext();
|
|
10
|
-
return (React.createElement("div", null,
|
|
11
|
-
React.createElement("div", { className: "flex justify-center border-b" },
|
|
12
|
-
React.createElement(SlidingEditPreviewToggle, { playgroundUid: "guardian", currentView: currentView, setCurrentView: (view) => setCurrentView(view), variant: "pill", buttonClassName: "text-sm px-4 py-1 h-auto", tabs: [
|
|
13
|
-
{ id: "editor", label: "Code" },
|
|
14
|
-
{ id: "preview", label: "Preview" },
|
|
15
|
-
] })),
|
|
16
|
-
React.createElement("div", { style: {
|
|
17
|
-
display: currentView === "preview" ? "block" : "none",
|
|
18
|
-
} }, !browserUrl ? (React.createElement("div", { className: "h-[calc(100vh-12.2rem)] w-full relative overflow-hidden rounded-b-none" },
|
|
19
|
-
React.createElement(AiLoader, { text: "Booting up...", fullScreen: false }))) : (React.createElement(Browser, { previewUrl: browserUrl, setPreviewUrl: () => { }, containerEndpoint: browserUrl, outerContainerClassName: useVm
|
|
20
|
-
? "h-[calc(100vh-9.6rem)] w-full border-none rounded-b-none"
|
|
21
|
-
: "h-[calc(100vh-12.2rem)] w-full border-none rounded-b-none", reloadSignal: reloadCounter, useVm: useVm }, overlayStage !== "hidden" && (React.createElement("div", { className: "absolute inset-0 z-20 flex items-center justify-center" },
|
|
22
|
-
overlayStage === "error" && (React.createElement("div", { className: "w-full h-full bg-red-950 text-red-200 flex items-center justify-center" },
|
|
23
|
-
React.createElement("div", { className: "text-center" },
|
|
24
|
-
React.createElement("div", { className: "text-2xl font-semibold" }, "Service Unavailable"),
|
|
25
|
-
React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Elevated error rates detected. Initiating rollback...")))),
|
|
26
|
-
overlayStage === "rebuilding" && (React.createElement("div", { className: "w-full h-full bg-amber-900 text-amber-100 flex items-center justify-center" },
|
|
27
|
-
React.createElement("div", { className: "text-center" },
|
|
28
|
-
React.createElement("div", { className: "text-2xl font-semibold" }, "Rebuilding preview\u2026"),
|
|
29
|
-
React.createElement("div", { className: "text-sm mt-2 opacity-80" }, "Applying safe configuration"),
|
|
30
|
-
React.createElement("div", { className: "mt-4 inline-flex items-center gap-2" },
|
|
31
|
-
React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse" }),
|
|
32
|
-
React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:150ms]" }),
|
|
33
|
-
React.createElement("span", { className: "h-2 w-2 rounded-full bg-amber-300 animate-pulse [animation-delay:300ms]" })))))))))),
|
|
34
|
-
React.createElement("div", { style: {
|
|
35
|
-
display: currentView === "editor" ? "block" : "none",
|
|
36
|
-
} },
|
|
37
|
-
React.createElement(CodeView, { codeZipFile: codeZipFile }))));
|
|
38
|
-
}
|