@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.
Files changed (82) hide show
  1. package/dist/components/sandbox/Sandbox.js +5 -0
  2. package/dist/components/sandbox/api.js +2 -2
  3. package/dist/components/sandbox/guardian/guardian-component.js +7 -38
  4. package/dist/components/sandbox/guardian/guardian-playground.js +2 -2
  5. package/dist/components/sandbox/guardian/hooks/use-sandbox-url-loader.js +12 -10
  6. package/dist/components/sandbox/guardian/index.js +1 -1
  7. package/dist/components/sandbox/guardian/right-view/right-top-down-view.js +2 -1
  8. package/dist/components/sandbox/guardian/ui/markdown.js +2 -2
  9. package/dist/components/sandbox/guardian/utils.js +4 -22
  10. package/dist/components/sandbox/index.js +1 -1
  11. package/dist/components/sandbox/sandbox-home/SandboxHome.js +5 -0
  12. package/dist/index.d.ts +8 -40
  13. package/dist/index.es.js +834 -870
  14. package/dist/index.js +1 -1
  15. package/dist/lib/api-client.js +9 -26
  16. package/package.json +1 -1
  17. package/dist/components/guardian/app-layout-no-sidebar.js +0 -8
  18. package/dist/components/guardian/ask-ai-view.js +0 -249
  19. package/dist/components/guardian/code-focus-section.d.ts +0 -41
  20. package/dist/components/guardian/code-focus-section.js +0 -174
  21. package/dist/components/guardian/context/guardian-context.js +0 -94
  22. package/dist/components/guardian/context/vm-context.js +0 -28
  23. package/dist/components/guardian/default-guide-view.js +0 -34
  24. package/dist/components/guardian/demo/guardian-demo.js +0 -35
  25. package/dist/components/guardian/demo/left-view/toggle.js +0 -28
  26. package/dist/components/guardian/demo/left-view.js +0 -49
  27. package/dist/components/guardian/guardian-component.js +0 -79
  28. package/dist/components/guardian/guardian-demo.js +0 -35
  29. package/dist/components/guardian/guardian-home.d.ts +0 -4
  30. package/dist/components/guardian/guardian-home.js +0 -61
  31. package/dist/components/guardian/guardian-playground.js +0 -45
  32. package/dist/components/guardian/guardian-style-wrapper.js +0 -29
  33. package/dist/components/guardian/guardian-upload-spec.d.ts +0 -14
  34. package/dist/components/guardian/guardian-upload-spec.js +0 -160
  35. package/dist/components/guardian/header/glassmorphic-combobox.d.ts +0 -15
  36. package/dist/components/guardian/header/glassmorphic-combobox.js +0 -30
  37. package/dist/components/guardian/header.js +0 -61
  38. package/dist/components/guardian/hooks/use-frame-messages.js +0 -65
  39. package/dist/components/guardian/hooks/use-frame-params.js +0 -44
  40. package/dist/components/guardian/hooks/use-sandbox-url-loader.js +0 -101
  41. package/dist/components/guardian/ide/browser.js +0 -538
  42. package/dist/components/guardian/index.js +0 -8
  43. package/dist/components/guardian/layout/app-layout-no-sidebar.js +0 -8
  44. package/dist/components/guardian/layout/header/glassmorphic-combobox.js +0 -48
  45. package/dist/components/guardian/layout/header.js +0 -63
  46. package/dist/components/guardian/right-view/code-view.js +0 -56
  47. package/dist/components/guardian/right-view/pill-file-selector.js +0 -233
  48. package/dist/components/guardian/right-view/preview-control-bar.js +0 -25
  49. package/dist/components/guardian/right-view/right-panel-view.js +0 -38
  50. package/dist/components/guardian/right-view/right-top-down-view.js +0 -289
  51. package/dist/components/guardian/right-view/right-view.js +0 -28
  52. package/dist/components/guardian/right-view/simplified-editor.js +0 -234
  53. package/dist/components/guardian/types/ide-types.js +0 -162
  54. package/dist/components/guardian/types.js +0 -3
  55. package/dist/components/guardian/ui/ai-loader.js +0 -48
  56. package/dist/components/guardian/ui/badge.js +0 -24
  57. package/dist/components/guardian/ui/button.js +0 -45
  58. package/dist/components/guardian/ui/command.js +0 -63
  59. package/dist/components/guardian/ui/console-with-app.js +0 -17
  60. package/dist/components/guardian/ui/dialog.js +0 -57
  61. package/dist/components/guardian/ui/dropdown-menu.js +0 -82
  62. package/dist/components/guardian/ui/markdown.js +0 -57
  63. package/dist/components/guardian/ui/popover.js +0 -25
  64. package/dist/components/guardian/ui/tooltip.js +0 -25
  65. package/dist/components/guardian/utils.js +0 -88
  66. package/dist/components/guardian/zip-to-codebase.js +0 -246
  67. package/dist/components/guardian/zip-to-filetree.js +0 -284
  68. package/dist/components/sandbox/SandboxHome.js +0 -141
  69. package/dist/components/sandbox/guardian/guardian-demo.js +0 -35
  70. package/dist/components/sandbox/guardian/guardian-home.d.ts +0 -4
  71. package/dist/components/sandbox/guardian/guardian-home.js +0 -61
  72. package/dist/components/sandbox/guardian/guardian-upload-spec.d.ts +0 -14
  73. package/dist/components/sandbox/guardian/guardian-upload-spec.js +0 -160
  74. package/dist/components/sandbox/guardian/ui/theme-color-context.d.ts +0 -6
  75. package/dist/components/sandbox/sandbox-control-bar.js +0 -91
  76. package/dist/components/sandbox/sandbox-header.js +0 -52
  77. package/dist/components/sandbox/sandbox-left-panel.js +0 -248
  78. package/dist/components/sandbox/sandbox-loading.js +0 -48
  79. package/dist/components/sandbox/sandbox-right-panel.js +0 -247
  80. package/dist/components/sandbox.js +0 -32
  81. package/dist/lib/api-client.example.js +0 -60
  82. package/dist/lib/ssr-safe-decode-entity.js +0 -16
@@ -1,248 +0,0 @@
1
- "use client";
2
- import React, { useState, useCallback, useRef, useEffect } from "react";
3
- import { LoaderIcon, ArrowUpIcon } from "../icons";
4
- /**
5
- * Left panel with Guide and Ask AI tabs
6
- */
7
- export function SandboxLeftPanel({ mdx, GuideComponent, playgroundUid, themeColor, apiKey, apiBaseUrl = "https://api.sampleapp.ai", files, }) {
8
- const [activeTab, setActiveTab] = useState("guide");
9
- return (React.createElement("div", { style: {
10
- display: "flex",
11
- flexDirection: "column",
12
- height: "100%",
13
- backgroundColor: "#18181b",
14
- borderRight: "1px solid rgba(255, 255, 255, 0.1)",
15
- } },
16
- React.createElement("div", { style: {
17
- display: "flex",
18
- justifyContent: "center",
19
- padding: "12px 16px",
20
- borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
21
- } },
22
- React.createElement("div", { style: {
23
- display: "flex",
24
- gap: "4px",
25
- padding: "4px",
26
- backgroundColor: "rgba(255, 255, 255, 0.05)",
27
- borderRadius: "8px",
28
- } },
29
- React.createElement(TabButton, { active: activeTab === "guide", onClick: () => setActiveTab("guide"), themeColor: themeColor }, "Guide"),
30
- React.createElement(TabButton, { active: activeTab === "chat", onClick: () => setActiveTab("chat"), themeColor: themeColor }, "Ask AI"))),
31
- React.createElement("div", { style: { flex: 1, overflow: "hidden", minHeight: 0 } },
32
- activeTab === "guide" && (React.createElement(GuideTab, { mdx: mdx, GuideComponent: GuideComponent, themeColor: themeColor })),
33
- activeTab === "chat" && (React.createElement(ChatTab, { playgroundUid: playgroundUid, themeColor: themeColor, apiKey: apiKey, apiBaseUrl: apiBaseUrl, files: files })))));
34
- }
35
- function TabButton({ children, active, onClick, themeColor, }) {
36
- return (React.createElement("button", { onClick: onClick, style: {
37
- padding: "8px 16px",
38
- fontSize: "13px",
39
- fontWeight: 500,
40
- borderRadius: "6px",
41
- border: "none",
42
- cursor: "pointer",
43
- transition: "all 0.15s ease",
44
- backgroundColor: active ? themeColor : "transparent",
45
- color: active ? "white" : "rgba(255, 255, 255, 0.6)",
46
- } }, children));
47
- }
48
- function GuideTab({ mdx, GuideComponent, themeColor, }) {
49
- if (GuideComponent) {
50
- return (React.createElement("div", { style: { height: "100%", overflow: "auto", padding: "24px" } },
51
- React.createElement(GuideComponent, null)));
52
- }
53
- if (mdx) {
54
- return (React.createElement("div", { style: {
55
- height: "100%",
56
- overflow: "auto",
57
- padding: "24px",
58
- } },
59
- React.createElement("div", { style: {
60
- fontSize: "14px",
61
- lineHeight: 1.7,
62
- color: "rgba(255, 255, 255, 0.8)",
63
- }, dangerouslySetInnerHTML: { __html: mdx } })));
64
- }
65
- return (React.createElement("div", { style: {
66
- height: "100%",
67
- display: "flex",
68
- alignItems: "center",
69
- justifyContent: "center",
70
- padding: "24px",
71
- } },
72
- React.createElement("div", { style: { textAlign: "center" } },
73
- React.createElement("p", { style: {
74
- fontSize: "14px",
75
- color: "rgba(255, 255, 255, 0.5)",
76
- } }, "No guide content provided."),
77
- React.createElement("p", { style: {
78
- fontSize: "12px",
79
- color: "rgba(255, 255, 255, 0.3)",
80
- marginTop: "8px",
81
- } },
82
- "Pass ",
83
- React.createElement("code", { style: { color: themeColor } }, "mdx"),
84
- " or",
85
- " ",
86
- React.createElement("code", { style: { color: themeColor } }, "GuideComponent"),
87
- " prop to display content."))));
88
- }
89
- function ChatTab({ playgroundUid, themeColor, apiKey, apiBaseUrl, files, }) {
90
- const [messages, setMessages] = useState([]);
91
- const [input, setInput] = useState("");
92
- const [isLoading, setIsLoading] = useState(false);
93
- const messagesEndRef = useRef(null);
94
- const textareaRef = useRef(null);
95
- // Scroll to bottom when messages change
96
- useEffect(() => {
97
- var _a;
98
- (_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
99
- }, [messages]);
100
- const handleSubmit = useCallback(async (e) => {
101
- e.preventDefault();
102
- if (!input.trim() || isLoading)
103
- return;
104
- const userMessage = input.trim();
105
- setInput("");
106
- setMessages((prev) => [...prev, { role: "user", content: userMessage }]);
107
- setIsLoading(true);
108
- try {
109
- // Build context from files if available
110
- const codeContext = files
111
- ? files.map((f) => `--- ${f.path} ---\n${f.content}`).join("\n\n")
112
- : "";
113
- const response = await fetch(`${apiBaseUrl}/v1/chat`, {
114
- method: "POST",
115
- headers: Object.assign({ "Content-Type": "application/json" }, (apiKey && { Authorization: `Bearer ${apiKey}` })),
116
- body: JSON.stringify({
117
- playgroundUid,
118
- messages: [
119
- ...messages,
120
- { role: "user", content: userMessage },
121
- ],
122
- context: codeContext,
123
- }),
124
- });
125
- if (!response.ok) {
126
- throw new Error(`API error: ${response.status}`);
127
- }
128
- const data = await response.json();
129
- setMessages((prev) => [
130
- ...prev,
131
- { role: "assistant", content: data.message || data.content },
132
- ]);
133
- }
134
- catch (error) {
135
- console.error("Chat error:", error);
136
- setMessages((prev) => [
137
- ...prev,
138
- {
139
- role: "assistant",
140
- content: "Sorry, I encountered an error. Please check your API key and try again.",
141
- },
142
- ]);
143
- }
144
- finally {
145
- setIsLoading(false);
146
- }
147
- }, [input, isLoading, messages, playgroundUid, apiKey, apiBaseUrl, files]);
148
- return (React.createElement("div", { style: {
149
- height: "100%",
150
- display: "flex",
151
- flexDirection: "column",
152
- } },
153
- React.createElement("div", { style: {
154
- flex: 1,
155
- overflow: "auto",
156
- padding: "16px",
157
- } }, messages.length === 0 ? (React.createElement("div", { style: {
158
- height: "100%",
159
- display: "flex",
160
- alignItems: "center",
161
- justifyContent: "center",
162
- } },
163
- React.createElement("div", { style: { textAlign: "center", maxWidth: "280px" } },
164
- React.createElement("div", { style: {
165
- width: "48px",
166
- height: "48px",
167
- borderRadius: "12px",
168
- backgroundColor: `${themeColor}20`,
169
- display: "flex",
170
- alignItems: "center",
171
- justifyContent: "center",
172
- margin: "0 auto 16px",
173
- } },
174
- React.createElement("span", { style: { fontSize: "24px" } }, "\uD83D\uDCAC")),
175
- React.createElement("p", { style: {
176
- fontSize: "14px",
177
- fontWeight: 500,
178
- color: "rgba(255, 255, 255, 0.8)",
179
- marginBottom: "8px",
180
- } }, "Ask AI about this code"),
181
- React.createElement("p", { style: {
182
- fontSize: "12px",
183
- color: "rgba(255, 255, 255, 0.4)",
184
- } }, "Get help understanding the code, debugging issues, or extending functionality.")))) : (React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "16px" } },
185
- messages.map((msg, i) => (React.createElement("div", { key: i, style: {
186
- display: "flex",
187
- flexDirection: "column",
188
- alignItems: msg.role === "user" ? "flex-end" : "flex-start",
189
- } },
190
- React.createElement("div", { style: {
191
- maxWidth: "85%",
192
- padding: "12px 16px",
193
- borderRadius: "12px",
194
- backgroundColor: msg.role === "user" ? themeColor : "rgba(255, 255, 255, 0.1)",
195
- color: "rgba(255, 255, 255, 0.9)",
196
- fontSize: "13px",
197
- lineHeight: 1.5,
198
- } }, msg.content)))),
199
- isLoading && (React.createElement("div", { style: { display: "flex", alignItems: "flex-start" } },
200
- React.createElement("div", { style: {
201
- padding: "12px 16px",
202
- borderRadius: "12px",
203
- backgroundColor: "rgba(255, 255, 255, 0.1)",
204
- } },
205
- React.createElement(LoaderIcon, { size: 16, style: { color: themeColor } })))),
206
- React.createElement("div", { ref: messagesEndRef })))),
207
- React.createElement("div", { style: {
208
- padding: "16px",
209
- borderTop: "1px solid rgba(255, 255, 255, 0.1)",
210
- } },
211
- React.createElement("form", { onSubmit: handleSubmit },
212
- React.createElement("div", { style: {
213
- display: "flex",
214
- gap: "8px",
215
- alignItems: "flex-end",
216
- } },
217
- React.createElement("textarea", { ref: textareaRef, value: input, onChange: (e) => setInput(e.target.value), onKeyDown: (e) => {
218
- if (e.key === "Enter" && !e.shiftKey) {
219
- e.preventDefault();
220
- handleSubmit(e);
221
- }
222
- }, placeholder: "Ask a question...", rows: 1, style: {
223
- flex: 1,
224
- padding: "12px",
225
- borderRadius: "8px",
226
- border: "1px solid rgba(255, 255, 255, 0.1)",
227
- backgroundColor: "rgba(255, 255, 255, 0.05)",
228
- color: "rgba(255, 255, 255, 0.9)",
229
- fontSize: "13px",
230
- resize: "none",
231
- outline: "none",
232
- fontFamily: "inherit",
233
- } }),
234
- React.createElement("button", { type: "submit", disabled: !input.trim() || isLoading, style: {
235
- width: "40px",
236
- height: "40px",
237
- borderRadius: "8px",
238
- border: "none",
239
- backgroundColor: input.trim() ? themeColor : "rgba(255, 255, 255, 0.1)",
240
- color: "white",
241
- cursor: input.trim() && !isLoading ? "pointer" : "not-allowed",
242
- display: "flex",
243
- alignItems: "center",
244
- justifyContent: "center",
245
- transition: "all 0.15s ease",
246
- opacity: isLoading ? 0.5 : 1,
247
- } }, isLoading ? (React.createElement(LoaderIcon, { size: 18 })) : (React.createElement(ArrowUpIcon, { size: 18 }))))))));
248
- }
@@ -1,48 +0,0 @@
1
- import React from "react";
2
- import { LoaderIcon } from "../icons";
3
- /**
4
- * Loading overlay for the sandbox iframe.
5
- */
6
- export function SandboxLoading({ themeColor }) {
7
- return (React.createElement("div", { style: {
8
- position: "absolute",
9
- inset: 0,
10
- display: "flex",
11
- flexDirection: "column",
12
- alignItems: "center",
13
- justifyContent: "center",
14
- backgroundColor: "rgba(0, 0, 0, 0.8)",
15
- backdropFilter: "blur(4px)",
16
- zIndex: 10,
17
- } },
18
- React.createElement("div", { style: {
19
- display: "flex",
20
- flexDirection: "column",
21
- alignItems: "center",
22
- gap: "16px",
23
- } },
24
- React.createElement("div", { style: {
25
- width: "48px",
26
- height: "48px",
27
- borderRadius: "12px",
28
- backgroundColor: `${themeColor}20`,
29
- display: "flex",
30
- alignItems: "center",
31
- justifyContent: "center",
32
- } },
33
- React.createElement(LoaderIcon, { size: 24, style: {
34
- color: themeColor,
35
- animation: "spin 1s linear infinite",
36
- } })),
37
- React.createElement("span", { style: {
38
- fontSize: "14px",
39
- color: "rgba(255, 255, 255, 0.7)",
40
- fontWeight: 500,
41
- } }, "Loading sandbox...")),
42
- React.createElement("style", null, `
43
- @keyframes spin {
44
- from { transform: rotate(0deg); }
45
- to { transform: rotate(360deg); }
46
- }
47
- `)));
48
- }
@@ -1,247 +0,0 @@
1
- "use client";
2
- import React, { useState, useCallback, useEffect } from "react";
3
- import { SandboxLoading } from "./sandbox-loading";
4
- import { RefreshCwIcon, ExternalLinkIcon, LoaderIcon } from "../icons";
5
- /**
6
- * Right panel with Preview and Code Editor
7
- */
8
- export function SandboxRightPanel({ previewUrl, files = [], defaultActiveFile, themeColor, showPreview, showCode, onLoad, onError, }) {
9
- var _a;
10
- const [isLoading, setIsLoading] = useState(true);
11
- const [reloadKey, setReloadKey] = useState(0);
12
- const [activeFile, setActiveFile] = useState(defaultActiveFile || ((_a = files[0]) === null || _a === void 0 ? void 0 : _a.path) || "");
13
- const [previewHeight, setPreviewHeight] = useState(60); // percentage
14
- const [isDragging, setIsDragging] = useState(false);
15
- const handleRefresh = useCallback(() => {
16
- setIsLoading(true);
17
- setReloadKey((k) => k + 1);
18
- }, []);
19
- const handleOpenExternal = useCallback(() => {
20
- if (previewUrl) {
21
- window.open(previewUrl, "_blank", "noopener,noreferrer");
22
- }
23
- }, [previewUrl]);
24
- const handleIframeLoad = useCallback(() => {
25
- setIsLoading(false);
26
- onLoad === null || onLoad === void 0 ? void 0 : onLoad();
27
- }, [onLoad]);
28
- const handleIframeError = useCallback(() => {
29
- setIsLoading(false);
30
- onError === null || onError === void 0 ? void 0 : onError(new Error(`Failed to load: ${previewUrl}`));
31
- }, [onError, previewUrl]);
32
- // Reset loading when URL changes
33
- useEffect(() => {
34
- if (previewUrl) {
35
- setIsLoading(true);
36
- }
37
- }, [previewUrl, reloadKey]);
38
- // Handle resize drag
39
- const handleMouseDown = useCallback(() => {
40
- setIsDragging(true);
41
- }, []);
42
- useEffect(() => {
43
- if (!isDragging)
44
- return;
45
- const handleMouseMove = (e) => {
46
- const container = document.getElementById("sandbox-right-panel");
47
- if (!container)
48
- return;
49
- const rect = container.getBoundingClientRect();
50
- const percentage = ((e.clientY - rect.top) / rect.height) * 100;
51
- setPreviewHeight(Math.min(80, Math.max(20, percentage)));
52
- };
53
- const handleMouseUp = () => {
54
- setIsDragging(false);
55
- };
56
- document.addEventListener("mousemove", handleMouseMove);
57
- document.addEventListener("mouseup", handleMouseUp);
58
- return () => {
59
- document.removeEventListener("mousemove", handleMouseMove);
60
- document.removeEventListener("mouseup", handleMouseUp);
61
- };
62
- }, [isDragging]);
63
- const activeFileContent = files.find((f) => f.path === activeFile);
64
- // If only showing preview
65
- if (showPreview && !showCode) {
66
- return (React.createElement("div", { style: { height: "100%", display: "flex", flexDirection: "column" } },
67
- React.createElement(PreviewControlBar, { previewUrl: previewUrl, themeColor: themeColor, isLoading: isLoading, onRefresh: handleRefresh, onOpenExternal: handleOpenExternal }),
68
- React.createElement("div", { style: { flex: 1, position: "relative" } },
69
- isLoading && React.createElement(SandboxLoading, { themeColor: themeColor }),
70
- previewUrl ? (React.createElement("iframe", { key: reloadKey, src: previewUrl, onLoad: handleIframeLoad, onError: handleIframeError, sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-modals", allow: "clipboard-read; clipboard-write", style: {
71
- width: "100%",
72
- height: "100%",
73
- border: "none",
74
- backgroundColor: "#000",
75
- }, title: "Preview" })) : (React.createElement("div", { style: {
76
- height: "100%",
77
- display: "flex",
78
- alignItems: "center",
79
- justifyContent: "center",
80
- backgroundColor: "#000",
81
- } },
82
- React.createElement("p", { style: { color: "rgba(255, 255, 255, 0.5)", fontSize: "14px" } }, "No preview URL provided"))))));
83
- }
84
- // If only showing code
85
- if (showCode && !showPreview) {
86
- return (React.createElement("div", { style: { height: "100%", display: "flex", flexDirection: "column" } },
87
- React.createElement(CodePanel, { files: files, activeFile: activeFile, setActiveFile: setActiveFile, themeColor: themeColor, content: (activeFileContent === null || activeFileContent === void 0 ? void 0 : activeFileContent.content) || "", language: activeFileContent === null || activeFileContent === void 0 ? void 0 : activeFileContent.language })));
88
- }
89
- // Show both preview and code (default)
90
- return (React.createElement("div", { id: "sandbox-right-panel", style: {
91
- height: "100%",
92
- display: "flex",
93
- flexDirection: "column",
94
- position: "relative",
95
- } },
96
- React.createElement("div", { style: { height: `${previewHeight}%`, display: "flex", flexDirection: "column" } },
97
- React.createElement(PreviewControlBar, { previewUrl: previewUrl, themeColor: themeColor, isLoading: isLoading, onRefresh: handleRefresh, onOpenExternal: handleOpenExternal }),
98
- React.createElement("div", { style: { flex: 1, position: "relative", minHeight: 0 } },
99
- isLoading && React.createElement(SandboxLoading, { themeColor: themeColor }),
100
- previewUrl ? (React.createElement("iframe", { key: reloadKey, src: previewUrl, onLoad: handleIframeLoad, onError: handleIframeError, sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-modals", allow: "clipboard-read; clipboard-write", style: {
101
- width: "100%",
102
- height: "100%",
103
- border: "none",
104
- backgroundColor: "#000",
105
- }, title: "Preview" })) : (React.createElement("div", { style: {
106
- height: "100%",
107
- display: "flex",
108
- alignItems: "center",
109
- justifyContent: "center",
110
- backgroundColor: "#000",
111
- } },
112
- React.createElement(LoaderIcon, { size: 24, style: { color: themeColor } }))))),
113
- React.createElement("div", { onMouseDown: handleMouseDown, style: {
114
- height: "8px",
115
- cursor: "row-resize",
116
- display: "flex",
117
- alignItems: "center",
118
- justifyContent: "center",
119
- backgroundColor: isDragging ? `${themeColor}30` : "transparent",
120
- transition: "background-color 0.15s",
121
- flexShrink: 0,
122
- } },
123
- React.createElement("div", { style: {
124
- width: "40px",
125
- height: "4px",
126
- borderRadius: "2px",
127
- backgroundColor: isDragging
128
- ? themeColor
129
- : "rgba(255, 255, 255, 0.2)",
130
- transition: "background-color 0.15s",
131
- } })),
132
- React.createElement("div", { style: { flex: 1, minHeight: 0 } },
133
- React.createElement(CodePanel, { files: files, activeFile: activeFile, setActiveFile: setActiveFile, themeColor: themeColor, content: (activeFileContent === null || activeFileContent === void 0 ? void 0 : activeFileContent.content) || "", language: activeFileContent === null || activeFileContent === void 0 ? void 0 : activeFileContent.language }))));
134
- }
135
- function PreviewControlBar({ previewUrl, themeColor, isLoading, onRefresh, onOpenExternal, }) {
136
- return (React.createElement("div", { style: {
137
- display: "flex",
138
- alignItems: "center",
139
- justifyContent: "space-between",
140
- padding: "8px 12px",
141
- borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
142
- backgroundColor: "rgba(0, 0, 0, 0.3)",
143
- flexShrink: 0,
144
- } },
145
- React.createElement("div", { style: {
146
- display: "flex",
147
- alignItems: "center",
148
- gap: "8px",
149
- flex: 1,
150
- minWidth: 0,
151
- } },
152
- React.createElement("div", { style: {
153
- width: "8px",
154
- height: "8px",
155
- borderRadius: "50%",
156
- backgroundColor: isLoading ? "#f59e0b" : "#22c55e",
157
- flexShrink: 0,
158
- } }),
159
- React.createElement("span", { style: {
160
- fontSize: "12px",
161
- color: "rgba(255, 255, 255, 0.6)",
162
- overflow: "hidden",
163
- textOverflow: "ellipsis",
164
- whiteSpace: "nowrap",
165
- fontFamily: "monospace",
166
- } }, previewUrl || "Loading...")),
167
- React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "4px" } },
168
- React.createElement(IconButton, { onClick: onRefresh, disabled: isLoading, themeColor: themeColor, title: "Refresh" }, isLoading ? (React.createElement(LoaderIcon, { size: 14 })) : (React.createElement(RefreshCwIcon, { size: 14 }))),
169
- React.createElement(IconButton, { onClick: onOpenExternal, themeColor: themeColor, title: "Open in new tab" },
170
- React.createElement(ExternalLinkIcon, { size: 14 })))));
171
- }
172
- function IconButton({ children, onClick, disabled, themeColor, title, }) {
173
- const [isHovered, setIsHovered] = useState(false);
174
- return (React.createElement("button", { onClick: onClick, disabled: disabled, title: title, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), style: {
175
- display: "flex",
176
- alignItems: "center",
177
- justifyContent: "center",
178
- width: "28px",
179
- height: "28px",
180
- borderRadius: "6px",
181
- border: "none",
182
- backgroundColor: isHovered ? "rgba(255, 255, 255, 0.1)" : "transparent",
183
- color: isHovered ? themeColor : "rgba(255, 255, 255, 0.7)",
184
- cursor: disabled ? "not-allowed" : "pointer",
185
- opacity: disabled ? 0.5 : 1,
186
- transition: "all 0.15s ease",
187
- } }, children));
188
- }
189
- function CodePanel({ files, activeFile, setActiveFile, themeColor, content, language, }) {
190
- return (React.createElement("div", { style: {
191
- height: "100%",
192
- display: "flex",
193
- flexDirection: "column",
194
- backgroundColor: "#0d0d0d",
195
- } },
196
- files.length > 0 && (React.createElement("div", { style: {
197
- display: "flex",
198
- alignItems: "center",
199
- gap: "4px",
200
- padding: "8px 12px",
201
- borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
202
- backgroundColor: "#18181b",
203
- overflowX: "auto",
204
- flexShrink: 0,
205
- } }, files.map((file) => (React.createElement("button", { key: file.path, onClick: () => setActiveFile(file.path), style: {
206
- padding: "6px 12px",
207
- fontSize: "12px",
208
- fontFamily: "monospace",
209
- borderRadius: "4px",
210
- border: "none",
211
- cursor: "pointer",
212
- whiteSpace: "nowrap",
213
- transition: "all 0.15s ease",
214
- backgroundColor: activeFile === file.path
215
- ? `${themeColor}20`
216
- : "transparent",
217
- color: activeFile === file.path
218
- ? themeColor
219
- : "rgba(255, 255, 255, 0.6)",
220
- } }, file.path.split("/").pop()))))),
221
- React.createElement("div", { style: {
222
- flex: 1,
223
- overflow: "auto",
224
- minHeight: 0,
225
- } }, content ? (React.createElement("pre", { style: {
226
- margin: 0,
227
- padding: "16px",
228
- fontSize: "13px",
229
- fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace',
230
- lineHeight: 1.6,
231
- color: "rgba(255, 255, 255, 0.85)",
232
- whiteSpace: "pre-wrap",
233
- wordBreak: "break-word",
234
- } },
235
- React.createElement("code", null, content))) : (React.createElement("div", { style: {
236
- height: "100%",
237
- display: "flex",
238
- alignItems: "center",
239
- justifyContent: "center",
240
- } },
241
- React.createElement("p", { style: {
242
- fontSize: "13px",
243
- color: "rgba(255, 255, 255, 0.4)",
244
- } }, files.length === 0
245
- ? "No files provided"
246
- : "Select a file to view"))))));
247
- }
@@ -1,32 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- /**
4
- * Sandbox component for displaying code files
5
- */
6
- export const Sandbox = ({ files, defaultFile, height = "400px", theme = "dark", }) => {
7
- var _a;
8
- const [activeFile, setActiveFile] = React.useState(defaultFile || ((_a = files[0]) === null || _a === void 0 ? void 0 : _a.name));
9
- const currentFile = files.find((f) => f.name === activeFile) || files[0];
10
- return (React.createElement("div", { className: "rounded-lg border overflow-hidden", style: {
11
- height: typeof height === "number" ? `${height}px` : height,
12
- backgroundColor: theme === "dark" ? "#1e1e1e" : "#ffffff",
13
- } },
14
- React.createElement("div", { className: "flex border-b", style: {
15
- backgroundColor: theme === "dark" ? "#252526" : "#f3f3f3",
16
- } }, files.map((file) => (React.createElement("button", { key: file.name, onClick: () => setActiveFile(file.name), className: "px-4 py-2 text-sm", style: {
17
- backgroundColor: activeFile === file.name
18
- ? theme === "dark"
19
- ? "#1e1e1e"
20
- : "#ffffff"
21
- : "transparent",
22
- color: theme === "dark" ? "#cccccc" : "#333333",
23
- borderRight: `1px solid ${theme === "dark" ? "#3c3c3c" : "#e0e0e0"}`,
24
- } }, file.name)))),
25
- React.createElement("pre", { className: "p-4 overflow-auto h-full", style: {
26
- color: theme === "dark" ? "#d4d4d4" : "#333333",
27
- fontSize: "14px",
28
- fontFamily: "monospace",
29
- margin: 0,
30
- } },
31
- React.createElement("code", null, currentFile === null || currentFile === void 0 ? void 0 : currentFile.content))));
32
- };
@@ -1,60 +0,0 @@
1
- /**
2
- * Example usage of the API client
3
- *
4
- * This file demonstrates how to use the API client to interact with
5
- * the SampleApp backend API.
6
- *
7
- * The apiKey will be passed in from SandboxProps.apiKey (from types.ts)
8
- */
9
- import { createApiClient } from "./api-client";
10
- // Example: How to use the API client with apiKey from SandboxProps
11
- function createClientFromSandboxProps(props, baseUrl = "http://127.0.0.1:8000") {
12
- return createApiClient({
13
- baseUrl,
14
- apiKey: props.apiKey, // apiKey comes from SandboxProps
15
- });
16
- }
17
- // Initialize the API client (example)
18
- const client = createApiClient({
19
- baseUrl: "http://127.0.0.1:8000", // or your production URL
20
- apiKey: "your-api-key-here", // This will come from SandboxProps.apiKey
21
- });
22
- // Example 1: Get public sandbox content
23
- // Note: sandboxId from SandboxProps maps to sandbox_content_uid
24
- async function getSandboxContentExample(apiKey, sandboxId, baseUrl = "http://127.0.0.1:8000") {
25
- try {
26
- const client = createApiClient({
27
- baseUrl,
28
- apiKey, // apiKey from SandboxProps.apiKey
29
- });
30
- // sandboxId from SandboxProps maps to sandbox_content_uid
31
- const sandboxContent = await client.sandboxContent.getPublic(sandboxId);
32
- console.log("Sandbox content:", sandboxContent);
33
- return sandboxContent;
34
- }
35
- catch (error) {
36
- console.error("Error fetching sandbox content:", error);
37
- throw error;
38
- }
39
- }
40
- // Example 2: Start a sandbox
41
- async function startSandboxExample() {
42
- try {
43
- const response = await client.sdk.startSandbox({
44
- env: {
45
- API_KEY: "your-api-key",
46
- ENVIRONMENT: "production",
47
- },
48
- apiKey: "your-sdk-api-key",
49
- chatUid: "your-chat-uid",
50
- });
51
- console.log("Container URL:", response.container_url);
52
- return response;
53
- }
54
- catch (error) {
55
- console.error("Error starting sandbox:", error);
56
- throw error;
57
- }
58
- }
59
- // Export examples for use in other files
60
- export { getSandboxContentExample, startSandboxExample, createClientFromSandboxProps, };
@@ -1,16 +0,0 @@
1
- /**
2
- * SSR-safe replacement for parse-entities/decode-entity.browser.js
3
- *
4
- * The original package uses document.createElement("i") to decode HTML entities,
5
- * which breaks SSR. This replacement uses a pure JS implementation.
6
- */
7
- // Import the SSR-safe decode function
8
- import { decodeNamedCharacterReference } from "./ssr-safe-decode-named-character-reference";
9
- /**
10
- * Decode an HTML entity.
11
- * @param characters - The entity name (without & and ;)
12
- * @returns The decoded character, or false if not found
13
- */
14
- export default function decodeEntity(characters) {
15
- return decodeNamedCharacterReference(characters);
16
- }