@sampleapp.ai/sdk 1.0.29 → 1.0.30
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/guardian/app-layout-no-sidebar.js +8 -0
- package/dist/components/guardian/ask-ai-view.js +249 -0
- package/dist/components/guardian/code-focus-section.d.ts +41 -0
- package/dist/components/guardian/code-focus-section.js +174 -0
- package/dist/components/guardian/context/guardian-context.js +94 -0
- package/dist/components/guardian/context/vm-context.js +28 -0
- package/dist/components/guardian/default-guide-view.js +34 -0
- package/dist/components/guardian/demo/guardian-demo.js +35 -0
- package/dist/components/guardian/demo/left-view/toggle.js +28 -0
- package/dist/components/guardian/demo/left-view.js +49 -0
- package/dist/components/guardian/guardian-component.js +79 -0
- package/dist/components/guardian/guardian-demo.js +35 -0
- package/dist/components/guardian/guardian-home.d.ts +4 -0
- package/dist/components/guardian/guardian-home.js +61 -0
- package/dist/components/guardian/guardian-playground.js +45 -0
- package/dist/components/guardian/guardian-style-wrapper.js +29 -0
- package/dist/components/guardian/guardian-upload-spec.d.ts +14 -0
- package/dist/components/guardian/guardian-upload-spec.js +160 -0
- package/dist/components/guardian/header/glassmorphic-combobox.d.ts +15 -0
- package/dist/components/guardian/header/glassmorphic-combobox.js +30 -0
- package/dist/components/guardian/header.js +61 -0
- package/dist/components/guardian/hooks/use-frame-messages.js +65 -0
- package/dist/components/guardian/hooks/use-frame-params.js +44 -0
- package/dist/components/guardian/hooks/use-sandbox-url-loader.js +101 -0
- package/dist/components/guardian/ide/browser.js +538 -0
- package/dist/components/guardian/index.js +8 -0
- package/dist/components/guardian/layout/app-layout-no-sidebar.js +8 -0
- package/dist/components/guardian/layout/header/glassmorphic-combobox.js +48 -0
- package/dist/components/guardian/layout/header.js +63 -0
- package/dist/components/guardian/right-view/code-view.js +56 -0
- package/dist/components/guardian/right-view/pill-file-selector.js +233 -0
- package/dist/components/guardian/right-view/preview-control-bar.js +25 -0
- package/dist/components/guardian/right-view/right-panel-view.js +38 -0
- package/dist/components/guardian/right-view/right-top-down-view.js +289 -0
- package/dist/components/guardian/right-view/right-view.js +28 -0
- package/dist/components/guardian/right-view/simplified-editor.js +234 -0
- package/dist/components/guardian/types/ide-types.js +162 -0
- package/dist/components/guardian/types.js +3 -0
- package/dist/components/guardian/ui/ai-loader.js +48 -0
- package/dist/components/guardian/ui/badge.js +24 -0
- package/dist/components/guardian/ui/button.js +45 -0
- package/dist/components/guardian/ui/command.js +63 -0
- package/dist/components/guardian/ui/console-with-app.js +17 -0
- package/dist/components/guardian/ui/dialog.js +57 -0
- package/dist/components/guardian/ui/dropdown-menu.js +82 -0
- package/dist/components/guardian/ui/markdown.js +57 -0
- package/dist/components/guardian/ui/popover.js +25 -0
- package/dist/components/guardian/ui/tooltip.js +25 -0
- package/dist/components/guardian/utils.js +88 -0
- package/dist/components/guardian/zip-to-codebase.js +246 -0
- package/dist/components/guardian/zip-to-filetree.js +284 -0
- package/dist/components/icons.js +22 -0
- package/dist/components/sandbox/Sandbox.js +87 -0
- package/dist/components/sandbox/SandboxHome.js +141 -0
- package/dist/components/sandbox/api.js +108 -0
- package/dist/components/sandbox/guardian/app-layout-no-sidebar.js +8 -0
- package/dist/components/sandbox/guardian/ask-ai-view.js +249 -0
- package/dist/components/sandbox/guardian/code-focus-section.js +174 -0
- package/dist/components/sandbox/guardian/context/guardian-context.js +94 -0
- package/dist/components/sandbox/guardian/context/vm-context.js +28 -0
- package/dist/components/sandbox/guardian/default-guide-view.js +34 -0
- package/dist/components/sandbox/guardian/demo/guardian-demo.js +35 -0
- package/dist/components/sandbox/guardian/demo/left-view/toggle.js +28 -0
- package/dist/components/sandbox/guardian/demo/left-view.js +58 -0
- package/dist/components/sandbox/guardian/guardian-component.js +97 -0
- package/dist/components/sandbox/guardian/guardian-demo.js +35 -0
- package/dist/components/sandbox/guardian/guardian-home.d.ts +4 -0
- package/dist/components/sandbox/guardian/guardian-home.js +61 -0
- package/dist/components/sandbox/guardian/guardian-playground.js +45 -0
- package/dist/components/sandbox/guardian/guardian-style-wrapper.js +33 -0
- package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +14 -0
- package/dist/components/sandbox/guardian/guardian-upload-spec.js +160 -0
- package/dist/components/sandbox/guardian/header/glassmorphic-combobox.js +30 -0
- package/dist/components/sandbox/guardian/header.js +61 -0
- package/dist/components/sandbox/guardian/hooks/use-frame-messages.js +65 -0
- package/dist/components/sandbox/guardian/hooks/use-frame-params.js +44 -0
- package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +145 -0
- package/dist/components/sandbox/guardian/ide/browser.js +538 -0
- package/dist/components/sandbox/guardian/index.js +8 -0
- package/dist/components/sandbox/guardian/right-view/code-view.js +60 -0
- package/dist/components/sandbox/guardian/right-view/pill-file-selector.js +233 -0
- package/dist/components/sandbox/guardian/right-view/preview-control-bar.js +25 -0
- package/dist/components/sandbox/guardian/right-view/right-panel-view.js +38 -0
- package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +289 -0
- package/dist/components/sandbox/guardian/right-view/right-view.js +28 -0
- package/dist/components/sandbox/guardian/right-view/simplified-editor.js +234 -0
- package/dist/components/sandbox/guardian/types/ide-types.js +162 -0
- package/dist/components/sandbox/guardian/types.js +3 -0
- package/dist/components/sandbox/guardian/ui/ai-loader.js +48 -0
- package/dist/components/sandbox/guardian/ui/badge.js +24 -0
- package/dist/components/sandbox/guardian/ui/button.js +45 -0
- package/dist/components/sandbox/guardian/ui/command.js +63 -0
- package/dist/components/sandbox/guardian/ui/console-with-app.js +17 -0
- package/dist/components/sandbox/guardian/ui/dialog.js +57 -0
- package/dist/components/sandbox/guardian/ui/dropdown-menu.js +82 -0
- package/dist/components/sandbox/guardian/ui/markdown/accordion-group/accordion.js +62 -0
- package/dist/components/sandbox/guardian/ui/markdown/accordion-group.js +23 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-check.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-error.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-info.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-note.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-tip.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/callout-warning.js +4 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/shared/callout.js +9 -0
- package/dist/components/sandbox/guardian/ui/markdown/callout/shared/types.js +1 -0
- package/dist/components/sandbox/guardian/ui/markdown/card-group/card.js +18 -0
- package/dist/components/sandbox/guardian/ui/markdown/card-group.js +25 -0
- package/dist/components/sandbox/guardian/ui/markdown/code-group/code-block.js +87 -0
- package/dist/components/sandbox/guardian/ui/markdown/code-group.js +101 -0
- package/dist/components/sandbox/guardian/ui/markdown/icon.js +31 -0
- package/dist/components/sandbox/guardian/ui/markdown.js +786 -0
- package/dist/components/sandbox/guardian/ui/popover.js +25 -0
- package/dist/components/sandbox/guardian/ui/tooltip.js +25 -0
- package/dist/components/sandbox/guardian/utils.js +88 -0
- package/dist/components/sandbox/guardian/zip-to-codebase.js +259 -0
- package/dist/components/sandbox/guardian/zip-to-filetree.js +284 -0
- package/dist/components/sandbox/index.js +4 -0
- package/dist/components/sandbox/sandbox-control-bar.js +91 -0
- package/dist/components/sandbox/sandbox-header.js +52 -0
- package/dist/components/sandbox/sandbox-home/SandboxCard.js +59 -0
- package/dist/components/sandbox/sandbox-home/SandboxHome.js +174 -0
- package/dist/components/sandbox/sandbox-home/SearchBar.js +12 -0
- package/dist/components/sandbox/sandbox-home/index.js +3 -0
- package/dist/components/sandbox/sandbox-left-panel.js +248 -0
- package/dist/components/sandbox/sandbox-loading.js +48 -0
- package/dist/components/sandbox/sandbox-right-panel.js +247 -0
- package/dist/components/sandbox/types.js +1 -0
- package/dist/components/sandbox.js +32 -0
- package/dist/components/tailwind-example.js +46 -0
- package/dist/index.d.ts +336 -1
- package/dist/index.es.js +90131 -421
- package/dist/index.js +13 -2
- package/dist/index.standalone.js +61 -53
- package/dist/index.standalone.umd.js +17 -24
- package/dist/lib/api-client.example.js +60 -0
- package/dist/lib/api-client.js +98 -0
- package/dist/lib/generated-css.js +4 -0
- package/dist/lib/inject-styles.js +42 -0
- package/dist/lib/shadow-dom-wrapper.js +42 -0
- package/dist/lib/utils.js +5 -0
- package/dist/sdk.css +1 -1
- package/dist/tailwind.css +1 -0
- package/package.json +32 -5
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import { useGuardianContext } from "./context/guardian-context";
|
|
4
|
+
// Helper function to find a node in the file tree by path
|
|
5
|
+
function getTargetNode(fileTree, targetPath) {
|
|
6
|
+
const parts = targetPath.split("/").filter(Boolean);
|
|
7
|
+
let current = fileTree;
|
|
8
|
+
for (const part of parts) {
|
|
9
|
+
if (!current.children || !current.children[part]) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
current = current.children[part];
|
|
13
|
+
}
|
|
14
|
+
return current;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Component that focuses on a specific file and line range in the code editor
|
|
18
|
+
* when it comes into view while scrolling, or when the user clicks "View Code".
|
|
19
|
+
*/
|
|
20
|
+
export default function CodeFocusSection({ filePath, lineRange, title, description, children, threshold = 0, themeColor, }) {
|
|
21
|
+
const sectionRef = useRef(null);
|
|
22
|
+
const { generatedCode, fileTree, setActiveFilePath, setActiveFileName, setActiveLineNumber, setActiveLineRange, updateCode, setLanguage, filesEdited, activeFilePath, activeLineRange, } = useGuardianContext();
|
|
23
|
+
// Moves the editor's focus to this file/lines
|
|
24
|
+
const focusCode = () => {
|
|
25
|
+
// Get the file code from generatedCode or fileTree
|
|
26
|
+
// Always search by file_path property first, as that's the source of truth
|
|
27
|
+
let code = "";
|
|
28
|
+
let language;
|
|
29
|
+
let resolvedFilePath;
|
|
30
|
+
let codeOutput;
|
|
31
|
+
// First, search through all code outputs to find one matching file_path
|
|
32
|
+
const matchingCodeOutput = Object.values(generatedCode).find((output) => output.file_path === filePath);
|
|
33
|
+
if (matchingCodeOutput) {
|
|
34
|
+
codeOutput = matchingCodeOutput;
|
|
35
|
+
code = codeOutput.full_code;
|
|
36
|
+
language = codeOutput.code_language;
|
|
37
|
+
resolvedFilePath = codeOutput.file_path;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Fallback: try to get from generatedCode by key, but still use file_path from the object
|
|
41
|
+
if (generatedCode[filePath]) {
|
|
42
|
+
codeOutput = generatedCode[filePath];
|
|
43
|
+
code = codeOutput.full_code;
|
|
44
|
+
language = codeOutput.code_language;
|
|
45
|
+
// Always use the file_path from the code output object as source of truth
|
|
46
|
+
resolvedFilePath = codeOutput.file_path || filePath;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Fallback to fileTree
|
|
50
|
+
try {
|
|
51
|
+
const targetNode = getTargetNode(fileTree, filePath);
|
|
52
|
+
if (targetNode === null || targetNode === void 0 ? void 0 : targetNode.metadata) {
|
|
53
|
+
code = targetNode.metadata.full_code || "";
|
|
54
|
+
language = targetNode.metadata.code_language;
|
|
55
|
+
// Use file_path from metadata if available, otherwise use the provided filePath
|
|
56
|
+
resolvedFilePath = targetNode.metadata.file_path || filePath;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.warn(`Failed to get code for file ${filePath}:`, error);
|
|
61
|
+
resolvedFilePath = filePath;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// If we still don't have a resolved file path, use the provided filePath
|
|
66
|
+
if (!resolvedFilePath) {
|
|
67
|
+
resolvedFilePath = filePath;
|
|
68
|
+
}
|
|
69
|
+
// Check if file has been edited - use resolvedFilePath for lookup
|
|
70
|
+
const editedCode = filesEdited[resolvedFilePath] || filesEdited[filePath];
|
|
71
|
+
const finalCode = editedCode ? editedCode.full_code : code;
|
|
72
|
+
if (finalCode) {
|
|
73
|
+
// Extract filename from path - prefer code_file_name from code output
|
|
74
|
+
const fileName = (codeOutput === null || codeOutput === void 0 ? void 0 : codeOutput.code_file_name) ||
|
|
75
|
+
resolvedFilePath.split("/").pop() ||
|
|
76
|
+
resolvedFilePath;
|
|
77
|
+
// Set the active file using the resolved file path
|
|
78
|
+
setActiveFilePath(resolvedFilePath);
|
|
79
|
+
setActiveFileName(fileName);
|
|
80
|
+
updateCode(finalCode);
|
|
81
|
+
// Set language if available
|
|
82
|
+
if (language) {
|
|
83
|
+
setLanguage(language);
|
|
84
|
+
}
|
|
85
|
+
// Set line number/range if provided
|
|
86
|
+
if (lineRange) {
|
|
87
|
+
setActiveLineRange({
|
|
88
|
+
start: lineRange.start,
|
|
89
|
+
end: lineRange.end,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
setActiveLineRange(undefined);
|
|
94
|
+
setActiveLineNumber(undefined);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
const element = sectionRef.current;
|
|
100
|
+
if (!element)
|
|
101
|
+
return;
|
|
102
|
+
const observer = new IntersectionObserver((entries) => {
|
|
103
|
+
entries.forEach((entry) => {
|
|
104
|
+
// Trigger when the element enters the middle of the viewport
|
|
105
|
+
if (entry.isIntersecting) {
|
|
106
|
+
focusCode();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}, {
|
|
110
|
+
threshold,
|
|
111
|
+
rootMargin: "-40% 0px -40% 0px", // Trigger when element enters the middle 20% of viewport
|
|
112
|
+
});
|
|
113
|
+
observer.observe(element);
|
|
114
|
+
return () => {
|
|
115
|
+
observer.disconnect();
|
|
116
|
+
};
|
|
117
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
118
|
+
}, [
|
|
119
|
+
filePath,
|
|
120
|
+
lineRange,
|
|
121
|
+
generatedCode,
|
|
122
|
+
fileTree,
|
|
123
|
+
setActiveFilePath,
|
|
124
|
+
setActiveFileName,
|
|
125
|
+
setActiveLineNumber,
|
|
126
|
+
setActiveLineRange,
|
|
127
|
+
updateCode,
|
|
128
|
+
setLanguage,
|
|
129
|
+
filesEdited,
|
|
130
|
+
threshold,
|
|
131
|
+
]);
|
|
132
|
+
// Get the resolved file path for comparison
|
|
133
|
+
// This ensures we compare against the actual file_path from the code structure
|
|
134
|
+
const resolvedFilePathForComparison = useMemo(() => {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
// Search by file_path property first (this is the source of truth)
|
|
137
|
+
const matchingCodeOutput = Object.values(generatedCode).find((output) => output.file_path === filePath);
|
|
138
|
+
if (matchingCodeOutput) {
|
|
139
|
+
return matchingCodeOutput.file_path;
|
|
140
|
+
}
|
|
141
|
+
// Fallback to key lookup
|
|
142
|
+
if ((_a = generatedCode[filePath]) === null || _a === void 0 ? void 0 : _a.file_path) {
|
|
143
|
+
return generatedCode[filePath].file_path;
|
|
144
|
+
}
|
|
145
|
+
// Fallback to fileTree
|
|
146
|
+
try {
|
|
147
|
+
const targetNode = getTargetNode(fileTree, filePath);
|
|
148
|
+
if ((_b = targetNode === null || targetNode === void 0 ? void 0 : targetNode.metadata) === null || _b === void 0 ? void 0 : _b.file_path) {
|
|
149
|
+
return targetNode.metadata.file_path;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (_c) {
|
|
153
|
+
// Ignore errors
|
|
154
|
+
}
|
|
155
|
+
return filePath;
|
|
156
|
+
}, [filePath, generatedCode, fileTree]);
|
|
157
|
+
return (React.createElement("div", { ref: sectionRef, className: `relative transition-colors py-6 cursor-pointer`, onClick: focusCode },
|
|
158
|
+
React.createElement("div", { className: "pointer-events-none absolute inset-x-[-2rem] top-0 border-t border-border" }),
|
|
159
|
+
React.createElement("div", { className: "pointer-events-none absolute inset-x-[-2rem] bottom-0 border-b border-border" }),
|
|
160
|
+
(activeFilePath === resolvedFilePathForComparison ||
|
|
161
|
+
activeFilePath === filePath) &&
|
|
162
|
+
(activeLineRange
|
|
163
|
+
? lineRange &&
|
|
164
|
+
activeLineRange.start === lineRange.start &&
|
|
165
|
+
activeLineRange.end === lineRange.end
|
|
166
|
+
: !lineRange) && (React.createElement("div", { className: "absolute left-0 top-0 h-full w-1", style: {
|
|
167
|
+
backgroundColor: themeColor,
|
|
168
|
+
marginLeft: "-2rem",
|
|
169
|
+
} })),
|
|
170
|
+
React.createElement("div", { className: "flex items-center gap-2" },
|
|
171
|
+
React.createElement("h3", { className: "text-md font-semibold text-gray-900 dark:text-gray-100" }, title)),
|
|
172
|
+
description && (React.createElement("p", { className: "text-sm text-gray-400 mt-3" }, description)),
|
|
173
|
+
children && React.createElement("div", { className: "mt-3" }, children)));
|
|
174
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { createContext, useContext, useState, useCallback, } from "react";
|
|
3
|
+
import { CodeLanguage, } from "../types/ide-types";
|
|
4
|
+
const GuardianContext = createContext(undefined);
|
|
5
|
+
export function GuardianProvider({ children }) {
|
|
6
|
+
const [previewUrl, setPreviewUrlState] = useState("");
|
|
7
|
+
const [isBrowserMaximized, setIsBrowserMaximized] = useState(false);
|
|
8
|
+
const [currentView, setCurrentViewState] = useState("preview");
|
|
9
|
+
// Code state
|
|
10
|
+
const [code, setCode] = useState("");
|
|
11
|
+
const [language, setLanguage] = useState(CodeLanguage.TEXT);
|
|
12
|
+
const [activeFileName, setActiveFileName] = useState("");
|
|
13
|
+
const [activeFilePath, setActiveFilePath] = useState("");
|
|
14
|
+
const [activeLineNumber, setActiveLineNumber] = useState(undefined);
|
|
15
|
+
const [activeLineRange, setActiveLineRange] = useState(undefined);
|
|
16
|
+
const [isGeneratingCode, setIsGeneratingCode] = useState(false);
|
|
17
|
+
// Generated code and file tree
|
|
18
|
+
const [generatedCode, setGeneratedCodeState] = useState({});
|
|
19
|
+
const [fileTree, setFileTree] = useState({
|
|
20
|
+
name: "root",
|
|
21
|
+
children: {},
|
|
22
|
+
type: "folder",
|
|
23
|
+
metadata: {
|
|
24
|
+
response_type: "CodeOutput",
|
|
25
|
+
file_path: "",
|
|
26
|
+
code_file_name: "",
|
|
27
|
+
code_language: CodeLanguage.TEXT,
|
|
28
|
+
dependencies_to_install: [],
|
|
29
|
+
framework: null,
|
|
30
|
+
full_code: "",
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
// Dependencies and edited files
|
|
34
|
+
const [activeDependenciesToInstall, setActiveDependenciesToInstall] = useState([]);
|
|
35
|
+
const [filesEdited, setFilesEdited] = useState({});
|
|
36
|
+
const setPreviewUrl = useCallback((url) => {
|
|
37
|
+
setPreviewUrlState(url);
|
|
38
|
+
}, []);
|
|
39
|
+
const setIsBrowserMaximizedState = useCallback((maximized) => {
|
|
40
|
+
setIsBrowserMaximized(maximized);
|
|
41
|
+
}, []);
|
|
42
|
+
const setCurrentView = useCallback((view) => {
|
|
43
|
+
setCurrentViewState(view);
|
|
44
|
+
}, []);
|
|
45
|
+
const updateCode = useCallback((newCode) => {
|
|
46
|
+
setCode(newCode);
|
|
47
|
+
}, []);
|
|
48
|
+
const setGeneratedCode = useCallback((generatedCode) => {
|
|
49
|
+
if (typeof generatedCode === "function") {
|
|
50
|
+
setGeneratedCodeState((prev) => generatedCode(prev));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
setGeneratedCodeState(generatedCode);
|
|
54
|
+
}
|
|
55
|
+
}, []);
|
|
56
|
+
const value = {
|
|
57
|
+
previewUrl,
|
|
58
|
+
setPreviewUrl,
|
|
59
|
+
isBrowserMaximized,
|
|
60
|
+
setIsBrowserMaximized: setIsBrowserMaximizedState,
|
|
61
|
+
currentView,
|
|
62
|
+
setCurrentView,
|
|
63
|
+
code,
|
|
64
|
+
updateCode,
|
|
65
|
+
language,
|
|
66
|
+
setLanguage,
|
|
67
|
+
activeFileName,
|
|
68
|
+
setActiveFileName,
|
|
69
|
+
activeFilePath,
|
|
70
|
+
setActiveFilePath,
|
|
71
|
+
activeLineNumber,
|
|
72
|
+
setActiveLineNumber,
|
|
73
|
+
activeLineRange,
|
|
74
|
+
setActiveLineRange,
|
|
75
|
+
isGeneratingCode,
|
|
76
|
+
setIsGeneratingCode,
|
|
77
|
+
generatedCode,
|
|
78
|
+
setGeneratedCode,
|
|
79
|
+
fileTree,
|
|
80
|
+
setFileTree,
|
|
81
|
+
activeDependenciesToInstall,
|
|
82
|
+
setActiveDependenciesToInstall,
|
|
83
|
+
filesEdited,
|
|
84
|
+
setFilesEdited,
|
|
85
|
+
};
|
|
86
|
+
return (React.createElement(GuardianContext.Provider, { value: value }, children));
|
|
87
|
+
}
|
|
88
|
+
export function useGuardianContext() {
|
|
89
|
+
const context = useContext(GuardianContext);
|
|
90
|
+
if (!context) {
|
|
91
|
+
throw new Error("useGuardianContext must be used within a GuardianProvider");
|
|
92
|
+
}
|
|
93
|
+
return context;
|
|
94
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { createContext, useContext, useState } from "react";
|
|
3
|
+
const VmContext = createContext(undefined);
|
|
4
|
+
export const VmProvider = ({ children }) => {
|
|
5
|
+
const [vmUrlMap, setVmUrlMap] = useState({});
|
|
6
|
+
const setVmUrl = (uid, url) => {
|
|
7
|
+
setVmUrlMap((prev) => (Object.assign(Object.assign({}, prev), { [uid]: url })));
|
|
8
|
+
};
|
|
9
|
+
const getVmUrl = (uid) => {
|
|
10
|
+
const value = vmUrlMap[uid];
|
|
11
|
+
// Return undefined if it's an error marker
|
|
12
|
+
return value === "error" ? undefined : value;
|
|
13
|
+
};
|
|
14
|
+
const setVmError = (uid) => {
|
|
15
|
+
setVmUrlMap((prev) => (Object.assign(Object.assign({}, prev), { [uid]: "error" })));
|
|
16
|
+
};
|
|
17
|
+
const hasError = (uid) => {
|
|
18
|
+
return vmUrlMap[uid] === "error";
|
|
19
|
+
};
|
|
20
|
+
return (React.createElement(VmContext.Provider, { value: { vmUrlMap, setVmUrl, getVmUrl, setVmError, hasError } }, children));
|
|
21
|
+
};
|
|
22
|
+
export const useVmContext = () => {
|
|
23
|
+
const context = useContext(VmContext);
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error("useVmContext must be used within a VmProvider");
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Markdown } from "./ui/markdown";
|
|
4
|
+
export default function DefaultGuideView({ themeColor, }) {
|
|
5
|
+
return (React.createElement("div", { className: "h-full flex flex-col" },
|
|
6
|
+
React.createElement("div", { className: "flex-1 px-8 py-6" },
|
|
7
|
+
React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, `# Guardian Guide
|
|
8
|
+
|
|
9
|
+
Learn how to use Guardian to build and deploy your application with confidence.
|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
Guardian provides a comprehensive development environment with real-time preview, code editing, and AI assistance.
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
- **Live Preview**: See your changes instantly as you code
|
|
18
|
+
- **Code Editor**: Edit files directly in the browser
|
|
19
|
+
- **AI Assistant**: Get help with your code using the Ask AI feature
|
|
20
|
+
|
|
21
|
+
### Navigation
|
|
22
|
+
|
|
23
|
+
Use the tabs at the top to switch between:
|
|
24
|
+
- **Guide**: View this documentation
|
|
25
|
+
- **Ask AI**: Get AI-powered assistance with your code
|
|
26
|
+
|
|
27
|
+
### Code Editing
|
|
28
|
+
|
|
29
|
+
Select files from the file selector to view and edit them. The editor supports syntax highlighting and automatic formatting.
|
|
30
|
+
|
|
31
|
+
### Preview
|
|
32
|
+
|
|
33
|
+
The preview panel shows your running application. Use the reload button to refresh the preview when needed.`))));
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useEffect, useState, useCallback } from "react";
|
|
3
|
+
import ConsoleWithApp from "../ui/console-with-app";
|
|
4
|
+
import { useGuardianContext } from "../context/guardian-context";
|
|
5
|
+
import ConsoleWithGuide from "./left-view";
|
|
6
|
+
import RightView from "../right-view/right-view";
|
|
7
|
+
export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
|
|
8
|
+
const { isBrowserMaximized } = useGuardianContext();
|
|
9
|
+
const { setCurrentView } = useGuardianContext();
|
|
10
|
+
const [reloadCounter, setReloadCounter] = useState(0);
|
|
11
|
+
const [overlayStage, setOverlayStage] = useState("hidden");
|
|
12
|
+
const handleReloadPreview = useCallback(() => {
|
|
13
|
+
setReloadCounter((c) => c + 1);
|
|
14
|
+
}, []);
|
|
15
|
+
const handleStageChange = useCallback((stage) => {
|
|
16
|
+
setOverlayStage(stage);
|
|
17
|
+
if (stage === "rebuilding") {
|
|
18
|
+
// Simulate a 3-second rebuild then hide
|
|
19
|
+
setTimeout(() => setOverlayStage("hidden"), 3000);
|
|
20
|
+
}
|
|
21
|
+
}, []);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setCurrentView("preview");
|
|
24
|
+
}, [setCurrentView]);
|
|
25
|
+
// If isFrame, just return RightView directly
|
|
26
|
+
if (isFrame) {
|
|
27
|
+
return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
|
|
28
|
+
}
|
|
29
|
+
// If browser is maximized, render RightView at full size without the console
|
|
30
|
+
if (isBrowserMaximized && isGuardian) {
|
|
31
|
+
return (React.createElement("div", { className: "w-full h-full rounded-2xl border border-border overflow-hidden" },
|
|
32
|
+
React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
|
|
33
|
+
}
|
|
34
|
+
return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border border-border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { motion } from "framer-motion";
|
|
4
|
+
import { cn } from "../../../../../lib/utils";
|
|
5
|
+
export default function SlidingEditPreviewToggle({ playgroundUid, variant = "default", buttonClassName = "", tabs = [
|
|
6
|
+
{ id: "editor", label: "Edit" },
|
|
7
|
+
{ id: "preview", label: "Preview" },
|
|
8
|
+
], currentView, setCurrentView, }) {
|
|
9
|
+
// Outer div and button shape depending on variant
|
|
10
|
+
const rootClasses = variant === "pill"
|
|
11
|
+
? "relative inline-flex items-center bg-muted/30 rounded-full p-1 border border-border/50"
|
|
12
|
+
: "relative inline-flex items-center bg-muted/30 rounded-lg p-1";
|
|
13
|
+
const btnShape = variant === "pill" ? "rounded-full" : "rounded-md";
|
|
14
|
+
const highlightShape = variant === "pill" ? "rounded-full" : "rounded-md";
|
|
15
|
+
// Default button padding if none provided
|
|
16
|
+
const defaultButtonPadding = variant === "pill" ? "px-5 py-2" : "px-4 py-1.5";
|
|
17
|
+
return (React.createElement("div", { className: rootClasses }, tabs.map((tab) => (React.createElement("button", { key: tab.id, onClick: () => setCurrentView(tab.id), className: cn(`relative ${defaultButtonPadding} text-sm font-medium transition-colors duration-150 ${btnShape} ${currentView === tab.id
|
|
18
|
+
? "text-foreground"
|
|
19
|
+
: "text-muted-foreground hover:text-foreground/80"}`, buttonClassName), style: {
|
|
20
|
+
WebkitTapHighlightColor: "transparent",
|
|
21
|
+
} },
|
|
22
|
+
currentView === tab.id && (React.createElement(motion.div, { layoutId: "activeTabGuide", className: cn(`absolute inset-0 bg-neutral-200 dark:bg-neutral-700 ${highlightShape} shadow-sm border border-border/50`), initial: false, transition: {
|
|
23
|
+
type: "spring",
|
|
24
|
+
stiffness: 500,
|
|
25
|
+
damping: 30,
|
|
26
|
+
} })),
|
|
27
|
+
React.createElement("span", { className: "relative z-10" }, tab.label))))));
|
|
28
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useMemo, useState } from "react";
|
|
3
|
+
import SlidingConsoleGuideToggle from "./left-view/toggle";
|
|
4
|
+
// import AskAiView from "../ask-ai-view";
|
|
5
|
+
// import DefaultGuideView from "../default-guide-view";
|
|
6
|
+
import { Markdown } from "../ui/markdown";
|
|
7
|
+
export default function ConsoleWithGuide({ CustomConsole, GuideView, playgroundUid, onReloadPreview, onStageChange, codeZipFile, themeColor, }) {
|
|
8
|
+
const [currentView, setCurrentView] = useState("console");
|
|
9
|
+
const isConsoleView = useMemo(() => currentView === "console", [currentView]);
|
|
10
|
+
// const isGuideView = useMemo(() => currentView === "guide", [currentView]);
|
|
11
|
+
// const isChatView = useMemo(() => currentView === "chat", [currentView]);
|
|
12
|
+
const renderCustomConsole = () => {
|
|
13
|
+
if (typeof CustomConsole === "string") {
|
|
14
|
+
return (React.createElement("div", { className: "h-full flex flex-col" },
|
|
15
|
+
React.createElement("div", { className: "flex-1 px-8 py-6" },
|
|
16
|
+
React.createElement(Markdown, { className: "text-gray-100", themeColor: themeColor }, CustomConsole))));
|
|
17
|
+
}
|
|
18
|
+
const CustomConsoleComponent = CustomConsole;
|
|
19
|
+
return (React.createElement(CustomConsoleComponent, { onReloadPreview: onReloadPreview !== null && onReloadPreview !== void 0 ? onReloadPreview : (() => { }), onStageChange: onStageChange !== null && onStageChange !== void 0 ? onStageChange : (() => { }), themeColor: themeColor }));
|
|
20
|
+
};
|
|
21
|
+
// Determine which guide view to render
|
|
22
|
+
// const renderGuideView = () => {
|
|
23
|
+
// if (!GuideView) {
|
|
24
|
+
// // If no GuideView provided, render default
|
|
25
|
+
// return (
|
|
26
|
+
// <DefaultGuideView
|
|
27
|
+
// onReloadPreview={onReloadPreview ?? (() => {})}
|
|
28
|
+
// onStageChange={onStageChange ?? (() => {})}
|
|
29
|
+
// themeColor={themeColor}
|
|
30
|
+
// />
|
|
31
|
+
// );
|
|
32
|
+
// }
|
|
33
|
+
// // If GuideView is a string, render as markdown
|
|
34
|
+
// if (typeof GuideView === "string") {
|
|
35
|
+
// return (
|
|
36
|
+
// <div className="h-full flex flex-col">
|
|
37
|
+
// <div className="flex-1 px-8 py-6">
|
|
38
|
+
// <Markdown className="text-gray-100" themeColor={themeColor}>
|
|
39
|
+
// {GuideView}
|
|
40
|
+
// </Markdown>
|
|
41
|
+
// </div>
|
|
42
|
+
// </div>
|
|
43
|
+
// );
|
|
44
|
+
// }
|
|
45
|
+
// // Otherwise, render as React component
|
|
46
|
+
// const GuideComponent = GuideView as ComponentType;
|
|
47
|
+
// return <GuideComponent />;
|
|
48
|
+
// };
|
|
49
|
+
return (React.createElement("div", { className: "flex-1 min-h-0 relative" },
|
|
50
|
+
React.createElement("div", { className: "flex justify-center border-b border-border" },
|
|
51
|
+
React.createElement(SlidingConsoleGuideToggle, { playgroundUid: playgroundUid, variant: "pill", buttonClassName: "text-sm px-4 py-1", currentView: currentView, setCurrentView: setCurrentView, tabs: [
|
|
52
|
+
{ id: "console", label: "Guide" },
|
|
53
|
+
// ...(GuideView ? [{id: "guide-og", label: "Guide OG"}] : []),
|
|
54
|
+
// {id: "chat", label: "Ask AI"},
|
|
55
|
+
] })),
|
|
56
|
+
React.createElement("div", { className: "h-[calc(100vh-9.5rem)] min-h-0 overflow-hidden" },
|
|
57
|
+
React.createElement("div", { className: "h-full min-h-0 overflow-y-auto" }, isConsoleView && renderCustomConsole()))));
|
|
58
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Header from "./header";
|
|
3
|
+
import AppLayoutNoSidebar from "./app-layout-no-sidebar";
|
|
4
|
+
import GuardianDemo from "./demo/guardian-demo";
|
|
5
|
+
import React, { useEffect, useRef } from "react";
|
|
6
|
+
import { useGuardianContext } from "./context/guardian-context";
|
|
7
|
+
import { useSandboxUrlLoader, } from "./hooks/use-sandbox-url-loader";
|
|
8
|
+
import { useFrameMessages } from "./hooks/use-frame-messages";
|
|
9
|
+
export default function GuardianComponent({ demoOptions, frameworkOptions, firstFrameworkByUseCase, currentFramework, currentUseCase, CustomConsole, GuideView, playgroundLogo, playgroundUid, browserUrl, useVm, sandboxUid, codeZipFile, consoleUrlConfigs, completeCodeZipFile, variant, themeColor, hasPreview = true, isFrame = false, apiKey, env, chatUid, }) {
|
|
10
|
+
const { previewUrl, setPreviewUrl } = useGuardianContext();
|
|
11
|
+
// Debug: Log the props received for sandbox configuration
|
|
12
|
+
console.log("[GuardianComponent] API config props:", {
|
|
13
|
+
apiKey: apiKey ? `${apiKey.substring(0, 8)}...` : undefined,
|
|
14
|
+
env,
|
|
15
|
+
chatUid,
|
|
16
|
+
hasApiKey: !!apiKey,
|
|
17
|
+
hasEnv: !!env,
|
|
18
|
+
hasChatUid: !!chatUid,
|
|
19
|
+
});
|
|
20
|
+
// Build startSandboxConfig only if all required fields are present and non-empty
|
|
21
|
+
const startSandboxConfig = apiKey && env && chatUid
|
|
22
|
+
? {
|
|
23
|
+
apiKey,
|
|
24
|
+
env,
|
|
25
|
+
chatUid,
|
|
26
|
+
}
|
|
27
|
+
: undefined;
|
|
28
|
+
console.log("[GuardianComponent] startSandboxConfig:", startSandboxConfig ? "configured" : "undefined (missing required fields)");
|
|
29
|
+
const { getSandboxUrl, loadSandboxUrl, preloadSandboxUrls } = useSandboxUrlLoader(startSandboxConfig);
|
|
30
|
+
// Initialize postMessage listener for iframe communication
|
|
31
|
+
// This sends IFRAME_READY and listens for UPDATE_VIEW messages
|
|
32
|
+
useFrameMessages();
|
|
33
|
+
// Track which console configs we've preloaded to prevent duplicates
|
|
34
|
+
const preloadedConfigsRef = useRef("");
|
|
35
|
+
// Track which main sandbox we've loaded to prevent duplicates
|
|
36
|
+
const loadedSandboxRef = useRef("");
|
|
37
|
+
// Preload console URLs when component mounts
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (consoleUrlConfigs && consoleUrlConfigs.length > 0) {
|
|
40
|
+
// Create a key from the configs to detect changes
|
|
41
|
+
const configKey = JSON.stringify(consoleUrlConfigs.map((c) => c.sandboxUid));
|
|
42
|
+
// Only preload if we haven't already preloaded these configs
|
|
43
|
+
if (preloadedConfigsRef.current !== configKey) {
|
|
44
|
+
preloadedConfigsRef.current = configKey;
|
|
45
|
+
preloadSandboxUrls(consoleUrlConfigs).catch((error) => {
|
|
46
|
+
console.error("Failed to preload console URLs:", error);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Only re-run if consoleUrlConfigs changes (not when preloadSandboxUrls changes)
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, [consoleUrlConfigs]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
// Create a key for this sandbox load
|
|
55
|
+
const sandboxKey = `${sandboxUid}-${browserUrl}-${useVm}`;
|
|
56
|
+
// Check if we've already initiated a load for this exact sandbox config
|
|
57
|
+
if (loadedSandboxRef.current === sandboxKey) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Check if URL is already cached for this sandboxUid + browserUrl combination
|
|
61
|
+
const existingUrl = getSandboxUrl(sandboxUid, browserUrl);
|
|
62
|
+
if (existingUrl !== undefined) {
|
|
63
|
+
// Found cached URL for this exact combination, use it immediately
|
|
64
|
+
setPreviewUrl(existingUrl);
|
|
65
|
+
loadedSandboxRef.current = sandboxKey;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Mark as loading to prevent duplicate requests
|
|
69
|
+
loadedSandboxRef.current = sandboxKey;
|
|
70
|
+
// Load the sandbox URL (will be cached by sandboxUid + browserUrl)
|
|
71
|
+
// This allows switching between different browserUrls and reverting back
|
|
72
|
+
// without losing the cached URLs
|
|
73
|
+
setPreviewUrl("");
|
|
74
|
+
loadSandboxUrl({
|
|
75
|
+
sandboxUid,
|
|
76
|
+
browserUrl,
|
|
77
|
+
useVm,
|
|
78
|
+
})
|
|
79
|
+
.then((url) => {
|
|
80
|
+
setPreviewUrl(url);
|
|
81
|
+
})
|
|
82
|
+
.catch((error) => {
|
|
83
|
+
console.error("Failed to load sandbox URL:", error);
|
|
84
|
+
// Keep preview URL empty on error
|
|
85
|
+
});
|
|
86
|
+
// Only re-run if the sandbox parameters change (not when functions change)
|
|
87
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
88
|
+
}, [sandboxUid, browserUrl, useVm]);
|
|
89
|
+
// If isFrame, just render GuardianDemo without the header/layout wrapper
|
|
90
|
+
if (isFrame) {
|
|
91
|
+
return (React.createElement("div", { className: "h-[100vh]" },
|
|
92
|
+
React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true })));
|
|
93
|
+
}
|
|
94
|
+
return (React.createElement(AppLayoutNoSidebar, { header: React.createElement(Header, { demoOptions: demoOptions, frameworkOptions: frameworkOptions, currentFramework: currentFramework, currentUseCase: currentUseCase, playgroundLogo: playgroundLogo, firstFrameworkByUseCase: firstFrameworkByUseCase }) },
|
|
95
|
+
React.createElement("div", { className: "absolute inset-0 mt-24 px-4 pb-4" },
|
|
96
|
+
React.createElement(GuardianDemo, { CustomConsole: CustomConsole, GuideView: GuideView, browserUrl: previewUrl, playgroundUid: playgroundUid, useVm: useVm, codeZipFile: codeZipFile, completeCodeZipFile: completeCodeZipFile, variant: variant, themeColor: themeColor, hasPreview: hasPreview, isFrame: isFrame, isGuardian: true }))));
|
|
97
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useEffect, useState, useCallback } from "react";
|
|
3
|
+
import ConsoleWithApp from "./ui/console-with-app";
|
|
4
|
+
import { useGuardianContext } from "./context/guardian-context";
|
|
5
|
+
import ConsoleWithGuide from "./demo/left-view";
|
|
6
|
+
import RightView from "./right-view/right-view";
|
|
7
|
+
export default function GuardianDemo({ CustomConsole, GuideView, browserUrl, playgroundUid, useVm, codeZipFile, completeCodeZipFile, variant, themeColor, hasPreview, isFrame = false, isGuardian = false, }) {
|
|
8
|
+
const { isBrowserMaximized } = useGuardianContext();
|
|
9
|
+
const { setCurrentView } = useGuardianContext();
|
|
10
|
+
const [reloadCounter, setReloadCounter] = useState(0);
|
|
11
|
+
const [overlayStage, setOverlayStage] = useState("hidden");
|
|
12
|
+
const handleReloadPreview = useCallback(() => {
|
|
13
|
+
setReloadCounter((c) => c + 1);
|
|
14
|
+
}, []);
|
|
15
|
+
const handleStageChange = useCallback((stage) => {
|
|
16
|
+
setOverlayStage(stage);
|
|
17
|
+
if (stage === "rebuilding") {
|
|
18
|
+
// Simulate a 3-second rebuild then hide
|
|
19
|
+
setTimeout(() => setOverlayStage("hidden"), 3000);
|
|
20
|
+
}
|
|
21
|
+
}, []);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
setCurrentView("preview");
|
|
24
|
+
}, [setCurrentView]);
|
|
25
|
+
// If isFrame, just return RightView directly
|
|
26
|
+
if (isFrame) {
|
|
27
|
+
return (React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }));
|
|
28
|
+
}
|
|
29
|
+
// If browser is maximized, render RightView at full size without the console
|
|
30
|
+
if (isBrowserMaximized && isGuardian) {
|
|
31
|
+
return (React.createElement("div", { className: "w-full h-full rounded-2xl border overflow-hidden" },
|
|
32
|
+
React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian, isBrowserMaximized: true })));
|
|
33
|
+
}
|
|
34
|
+
return (React.createElement(ConsoleWithApp, { containerClassName: "rounded-2xl border", console: React.createElement(ConsoleWithGuide, { CustomConsole: CustomConsole, GuideView: GuideView, playgroundUid: playgroundUid, onReloadPreview: handleReloadPreview, onStageChange: handleStageChange, codeZipFile: codeZipFile, themeColor: themeColor }), app: React.createElement(RightView, { reloadCounter: reloadCounter, overlayStage: overlayStage, browserUrl: browserUrl, useVm: useVm, codeZipFile: codeZipFile, hasPreview: hasPreview, variant: variant, themeColor: themeColor, completeCodeZipFile: completeCodeZipFile, isGuardian: isGuardian }) }));
|
|
35
|
+
}
|