Skip to content

Commit 9a1b14b

Browse files
committed
feat(WebSandbox): add custom event to allow sending notifications from sandbox to Python
1 parent a4bea44 commit 9a1b14b

File tree

6 files changed

+62
-10
lines changed

6 files changed

+62
-10
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modelscope-studio/pro': patch
3+
'modelscope_studio': patch
4+
---
5+
6+
feat: add `custom` event to allow sending notifications from sandbox to Python

backend/modelscope_studio/components/pro/web_sandbox/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class ModelScopeProWebSandbox(ModelScopeLayoutComponent):
2626
EventListener("render_error",
2727
callback=lambda block: block._internal.update(
2828
bind_renderError_event=True)),
29+
EventListener("custom",
30+
callback=lambda block: block._internal.update(
31+
bind_custom_event=True)),
2932
]
3033

3134
# supported slots

docs/components/pro/web_sandbox/README-zh_CN.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323

2424
<demo name="html"></demo>
2525

26+
### 自定义 Sandbox 事件
27+
28+
<demo name="custom_sandbox_event"></demo>
29+
2630
### 处理错误
2731

2832
<demo name="error_handling"></demo>
@@ -43,11 +47,12 @@
4347

4448
### 事件
4549

46-
| 事件 | 描述 |
47-
| ----------------------------------------- | --------------------------- |
48-
| `pro.WebSandbox.compile_success(fn, ···)` | 当 Sandbox 编译成功时触发。 |
49-
| `pro.WebSandbox.compile_error(fn, ···)` | 当 Sandbox 编译失败时触发。 |
50-
| `pro.WebSandbox.render_error(fn, ···)` | 当 Sandbox 渲染抛错时触发。 |
50+
| 事件 | 描述 |
51+
| ----------------------------------------- | ------------------------------------------------------------------------------------------- |
52+
| `pro.WebSandbox.compile_success(fn, ···)` | 当 Sandbox 编译成功时触发。 |
53+
| `pro.WebSandbox.compile_error(fn, ···)` | 当 Sandbox 编译失败时触发。 |
54+
| `pro.WebSandbox.render_error(fn, ···)` | 当 Sandbox 渲染抛错时触发。 |
55+
| `pro.WebSandbox.custom(fn, ···)` | 在 Sandbox 内触发的自定义事件,在 Sandbox 内通过 JavaScript 调用 `window.dispatch` 时触发。 |
5156

5257
### 插槽
5358

docs/components/pro/web_sandbox/README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ When `template` is set to `react`, the following dependencies will be automatica
2323

2424
<demo name="html"></demo>
2525

26+
### Custom Sandbox Event
27+
28+
<demo name="custom_sandbox_event"></demo>
29+
2630
### Error Handling
2731

2832
<demo name="error_handling"></demo>
@@ -43,11 +47,13 @@ When `template` is set to `react`, the following dependencies will be automatica
4347

4448
### Events
4549

46-
| Event | Description |
47-
| ----------------------------------------- | ------------------------------------------------- |
48-
| `pro.WebSandbox.compile_success(fn, ···)` | Triggered when Sandbox compilation succeeds. |
49-
| `pro.WebSandbox.compile_error(fn, ···)` | Triggered when Sandbox compilation fails. |
50-
| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
50+
| Event | Description |
51+
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
52+
| `pro.WebSandbox.compile_success(fn, ···)` | Triggered when Sandbox compilation succeeds. |
53+
| `pro.WebSandbox.compile_error(fn, ···)` | Triggered when Sandbox compilation fails. |
54+
| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
55+
| `pro.WebSandbox.render_error(fn, ···)` | Triggered when Sandbox rendering throws an error. |
56+
| `pro.WebSandbox.custom(fn, ···)` | Custom events triggered within the Sandbox are invoked via JavaScript when `window.dispatch` is called within the Sandbox. |
5157

5258
### Slots
5359

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import gradio as gr
2+
import modelscope_studio.components.antd as antd
3+
import modelscope_studio.components.base as ms
4+
import modelscope_studio.components.pro as pro
5+
6+
7+
def on_custom(e: gr.EventData):
8+
print(e._data)
9+
10+
11+
with gr.Blocks() as demo, ms.Application(), antd.ConfigProvider():
12+
sandbox = pro.WebSandbox(value={
13+
"index.tsx":
14+
"""
15+
export default function App() {
16+
return <button onClick={() => {
17+
window.dispatch({ type: 'custom', payload: { value: 'test' } })
18+
} }>Click to emit custom event to Python</button>;
19+
}
20+
"""
21+
},
22+
template="react")
23+
sandbox.custom(fn=on_custom)
24+
25+
if __name__ == "__main__":
26+
demo.queue().launch()

frontend/pro/web-sandbox/web-sandbox.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface WebSandboxProps {
2828
onCompileError?: (message: string) => void;
2929
onCompileSuccess?: () => void;
3030
onRenderError?: (message: string) => void;
31+
onCustom?: (...args: any[]) => void;
3132
height?: string | number;
3233
themeMode: string;
3334
setSlotParams: SetSlotParams;
@@ -53,6 +54,7 @@ export const WebSandbox = sveltify<WebSandboxProps, ['compileErrorRender']>(
5354
onRenderError,
5455
onCompileSuccess,
5556
compileErrorRender,
57+
onCustom,
5658
}) => {
5759
const iframeRef = React.useRef<HTMLIFrameElement>(null);
5860
const divRef = React.useRef<HTMLDivElement>(null);
@@ -75,6 +77,7 @@ export const WebSandbox = sveltify<WebSandboxProps, ['compileErrorRender']>(
7577
const onCompileErrorMemoized = useMemoizedFn(onCompileError);
7678
const onRenderErrorMemoized = useMemoizedFn(onRenderError);
7779
const onCompileSuccessMemoized = useMemoizedFn(onCompileSuccess);
80+
const onCustomMemoized = useMemoizedFn(onCustom);
7881

7982
// Build import map (only includes third-party dependencies)
8083
const resolvedImportMap = useMemo(() => {
@@ -248,6 +251,8 @@ export const WebSandbox = sveltify<WebSandboxProps, ['compileErrorRender']>(
248251
try {
249252
// Inject theme
250253
(iframeRef.current.contentWindow as any).gradio_theme = themeMode;
254+
(iframeRef.current.contentWindow as any).dispatch =
255+
onCustomMemoized;
251256
} catch {
252257
//
253258
}
@@ -288,6 +293,7 @@ export const WebSandbox = sveltify<WebSandboxProps, ['compileErrorRender']>(
288293
iframeUrl,
289294
notificationApi,
290295
onCompileSuccessMemoized,
296+
onCustomMemoized,
291297
onRenderErrorMemoized,
292298
showRenderError,
293299
themeMode,

0 commit comments

Comments
 (0)