From 9a1b14b2d722c22d24eec6764a4f617b231e9d90 Mon Sep 17 00:00:00 2001
From: Col0ring <1561999073@qq.com>
Date: Thu, 20 Nov 2025 11:08:57 +0800
Subject: [PATCH 1/3] feat(WebSandbox): add `custom` event to allow sending
notifications from sandbox to Python
---
.changeset/violet-candles-switch.md | 6 +++++
.../components/pro/web_sandbox/__init__.py | 3 +++
.../pro/web_sandbox/README-zh_CN.md | 15 +++++++----
docs/components/pro/web_sandbox/README.md | 16 ++++++++----
.../web_sandbox/demos/custom_sandbox_event.py | 26 +++++++++++++++++++
frontend/pro/web-sandbox/web-sandbox.tsx | 6 +++++
6 files changed, 62 insertions(+), 10 deletions(-)
create mode 100644 .changeset/violet-candles-switch.md
create mode 100644 docs/components/pro/web_sandbox/demos/custom_sandbox_event.py
diff --git a/.changeset/violet-candles-switch.md b/.changeset/violet-candles-switch.md
new file mode 100644
index 00000000..efb367eb
--- /dev/null
+++ b/.changeset/violet-candles-switch.md
@@ -0,0 +1,6 @@
+---
+'@modelscope-studio/pro': patch
+'modelscope_studio': patch
+---
+
+feat: add `custom` event to allow sending notifications from sandbox to Python
diff --git a/backend/modelscope_studio/components/pro/web_sandbox/__init__.py b/backend/modelscope_studio/components/pro/web_sandbox/__init__.py
index 6bb4db60..dabcafd1 100644
--- a/backend/modelscope_studio/components/pro/web_sandbox/__init__.py
+++ b/backend/modelscope_studio/components/pro/web_sandbox/__init__.py
@@ -26,6 +26,9 @@ class ModelScopeProWebSandbox(ModelScopeLayoutComponent):
EventListener("render_error",
callback=lambda block: block._internal.update(
bind_renderError_event=True)),
+ EventListener("custom",
+ callback=lambda block: block._internal.update(
+ bind_custom_event=True)),
]
# supported slots
diff --git a/docs/components/pro/web_sandbox/README-zh_CN.md b/docs/components/pro/web_sandbox/README-zh_CN.md
index 1415d1ef..acdfeb15 100644
--- a/docs/components/pro/web_sandbox/README-zh_CN.md
+++ b/docs/components/pro/web_sandbox/README-zh_CN.md
@@ -23,6 +23,10 @@
+### 自定义 Sandbox 事件
+
+
+
### 处理错误
@@ -43,11 +47,12 @@
### 事件
-| 事件 | 描述 |
-| ----------------------------------------- | --------------------------- |
-| `pro.WebSandbox.compile_success(fn, ···)` | 当 Sandbox 编译成功时触发。 |
-| `pro.WebSandbox.compile_error(fn, ···)` | 当 Sandbox 编译失败时触发。 |
-| `pro.WebSandbox.render_error(fn, ···)` | 当 Sandbox 渲染抛错时触发。 |
+| 事件 | 描述 |
+| ----------------------------------------- | ------------------------------------------------------------------------------------------- |
+| `pro.WebSandbox.compile_success(fn, ···)` | 当 Sandbox 编译成功时触发。 |
+| `pro.WebSandbox.compile_error(fn, ···)` | 当 Sandbox 编译失败时触发。 |
+| `pro.WebSandbox.render_error(fn, ···)` | 当 Sandbox 渲染抛错时触发。 |
+| `pro.WebSandbox.custom(fn, ···)` | 在 Sandbox 内触发的自定义事件,在 Sandbox 内通过 JavaScript 调用 `window.dispatch` 时触发。 |
### 插槽
diff --git a/docs/components/pro/web_sandbox/README.md b/docs/components/pro/web_sandbox/README.md
index 48661ea3..6646fe61 100644
--- a/docs/components/pro/web_sandbox/README.md
+++ b/docs/components/pro/web_sandbox/README.md
@@ -23,6 +23,10 @@ When `template` is set to `react`, the following dependencies will be automatica
+### Custom Sandbox Event
+
+
+
### Error Handling
@@ -43,11 +47,13 @@ When `template` is set to `react`, the following dependencies will be automatica
### Events
-| Event | Description |
-| ----------------------------------------- | ------------------------------------------------- |
-| `pro.WebSandbox.compile_success(fn, ···)` | Triggered when Sandbox compilation succeeds. |
-| `pro.WebSandbox.compile_error(fn, ···)` | Triggered when Sandbox compilation fails. |
-| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
+| Event | Description |
+| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
+| `pro.WebSandbox.compile_success(fn, ···)` | Triggered when Sandbox compilation succeeds. |
+| `pro.WebSandbox.compile_error(fn, ···)` | Triggered when Sandbox compilation fails. |
+| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
+| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
+| `pro.WebSandbox.custom(fn, ···)` | Custom events triggered within the Sandbox are invoked via JavaScript when `window.dispatch` is called within the Sandbox. |
### Slots
diff --git a/docs/components/pro/web_sandbox/demos/custom_sandbox_event.py b/docs/components/pro/web_sandbox/demos/custom_sandbox_event.py
new file mode 100644
index 00000000..f9390434
--- /dev/null
+++ b/docs/components/pro/web_sandbox/demos/custom_sandbox_event.py
@@ -0,0 +1,26 @@
+import gradio as gr
+import modelscope_studio.components.antd as antd
+import modelscope_studio.components.base as ms
+import modelscope_studio.components.pro as pro
+
+
+def on_custom(e: gr.EventData):
+ print(e._data)
+
+
+with gr.Blocks() as demo, ms.Application(), antd.ConfigProvider():
+ sandbox = pro.WebSandbox(value={
+ "index.tsx":
+ """
+export default function App() {
+ return ;
+}
+"""
+ },
+ template="react")
+ sandbox.custom(fn=on_custom)
+
+if __name__ == "__main__":
+ demo.queue().launch()
diff --git a/frontend/pro/web-sandbox/web-sandbox.tsx b/frontend/pro/web-sandbox/web-sandbox.tsx
index 42c5f05b..9ad1be37 100644
--- a/frontend/pro/web-sandbox/web-sandbox.tsx
+++ b/frontend/pro/web-sandbox/web-sandbox.tsx
@@ -28,6 +28,7 @@ export interface WebSandboxProps {
onCompileError?: (message: string) => void;
onCompileSuccess?: () => void;
onRenderError?: (message: string) => void;
+ onCustom?: (...args: any[]) => void;
height?: string | number;
themeMode: string;
setSlotParams: SetSlotParams;
@@ -53,6 +54,7 @@ export const WebSandbox = sveltify(
onRenderError,
onCompileSuccess,
compileErrorRender,
+ onCustom,
}) => {
const iframeRef = React.useRef(null);
const divRef = React.useRef(null);
@@ -75,6 +77,7 @@ export const WebSandbox = sveltify(
const onCompileErrorMemoized = useMemoizedFn(onCompileError);
const onRenderErrorMemoized = useMemoizedFn(onRenderError);
const onCompileSuccessMemoized = useMemoizedFn(onCompileSuccess);
+ const onCustomMemoized = useMemoizedFn(onCustom);
// Build import map (only includes third-party dependencies)
const resolvedImportMap = useMemo(() => {
@@ -248,6 +251,8 @@ export const WebSandbox = sveltify(
try {
// Inject theme
(iframeRef.current.contentWindow as any).gradio_theme = themeMode;
+ (iframeRef.current.contentWindow as any).dispatch =
+ onCustomMemoized;
} catch {
//
}
@@ -288,6 +293,7 @@ export const WebSandbox = sveltify(
iframeUrl,
notificationApi,
onCompileSuccessMemoized,
+ onCustomMemoized,
onRenderErrorMemoized,
showRenderError,
themeMode,
From c0ac6f5f5f6912d39ad717f3557a75ce13adb261 Mon Sep 17 00:00:00 2001
From: Col0ring <1561999073@qq.com>
Date: Thu, 20 Nov 2025 11:11:58 +0800
Subject: [PATCH 2/3] fix: drop container of MulimodalInput
---
.changeset/great-places-post.md | 6 ++++++
frontend/pro/multimodal-input/multimodal-input.tsx | 10 +++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
create mode 100644 .changeset/great-places-post.md
diff --git a/.changeset/great-places-post.md b/.changeset/great-places-post.md
new file mode 100644
index 00000000..a0d3bf4d
--- /dev/null
+++ b/.changeset/great-places-post.md
@@ -0,0 +1,6 @@
+---
+'@modelscope-studio/pro': patch
+'modelscope_studio': patch
+---
+
+fix: drop container of MulimodalInput
diff --git a/frontend/pro/multimodal-input/multimodal-input.tsx b/frontend/pro/multimodal-input/multimodal-input.tsx
index 3fbad501..bb762d33 100644
--- a/frontend/pro/multimodal-input/multimodal-input.tsx
+++ b/frontend/pro/multimodal-input/multimodal-input.tsx
@@ -392,9 +392,13 @@ export const MultimodalInput = sveltify<
...uploadConfig?.imageProps,
}}
disabled={uploadDisabled}
- getDropContainer={() => {
- return uploadConfig?.fullscreenDrop ? document.body : null;
- }}
+ getDropContainer={
+ uploadConfig?.fullscreenDrop
+ ? () => {
+ return document.body;
+ }
+ : undefined
+ }
items={validFileList}
placeholder={(type) => {
const isDrop = type === 'drop';
From e58779e7c055ed7c1cb6478f6c11d4d169c2f803 Mon Sep 17 00:00:00 2001
From: Col0ring <1561999073@qq.com>
Date: Thu, 20 Nov 2025 11:50:55 +0800
Subject: [PATCH 3/3] fix: docs
---
docs/components/pro/web_sandbox/README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/components/pro/web_sandbox/README.md b/docs/components/pro/web_sandbox/README.md
index 6646fe61..0f0a7143 100644
--- a/docs/components/pro/web_sandbox/README.md
+++ b/docs/components/pro/web_sandbox/README.md
@@ -52,7 +52,6 @@ When `template` is set to `react`, the following dependencies will be automatica
| `pro.WebSandbox.compile_success(fn, ···)` | Triggered when Sandbox compilation succeeds. |
| `pro.WebSandbox.compile_error(fn, ···)` | Triggered when Sandbox compilation fails. |
| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
-| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
| `pro.WebSandbox.custom(fn, ···)` | Custom events triggered within the Sandbox are invoked via JavaScript when `window.dispatch` is called within the Sandbox. |
### Slots