-
Notifications
You must be signed in to change notification settings - Fork 18
feat: add pro component MonacoEditor
#112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2735be4
b908822
7ac243a
540ecc9
f70defa
fe4b3a1
dc9c77b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| '@modelscope-studio/pro': minor | ||
| '@modelscope-studio/frontend': minor | ||
| 'modelscope_studio': minor | ||
| --- | ||
|
|
||
| feat: add pro component `MonacoEditor` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| from .chatbot import ModelScopeProChatbot as Chatbot | ||
| from .monaco_editor import ModelScopeProMonacoEditor as MonacoEditor | ||
| from .monaco_editor.diff_editor import \ | ||
| ModelScopeProMonacoEditorDiffEditor as MonacoEditorDiffEditor | ||
| from .multimodal_input import ModelScopeProMultimodalInput as MultimodalInput | ||
| from .web_sandbox import ModelScopeProWebSandbox as WebSandbox |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,7 @@ | ||
| from .chatbot import ModelScopeProChatbot as ProChatbot | ||
| from .monaco_editor import ModelScopeProMonacoEditor as ProMonacoEditor | ||
| from .monaco_editor.diff_editor import \ | ||
| ModelScopeProMonacoEditorDiffEditor as ProMonacoEditorDiffEditor | ||
| from .multimodal_input import \ | ||
| ModelScopeProMultimodalInput as ProMultimodalInput | ||
| from .web_sandbox import ModelScopeProWebSandbox as ProWebSandbox |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import Any, Literal, TypedDict, Union | ||
|
|
||
| from gradio.events import EventListener | ||
|
|
||
| from ....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir | ||
| from .diff_editor import ModelScopeProMonacoEditorDiffEditor | ||
|
|
||
|
|
||
| class LoaderConfig(TypedDict): | ||
| mode: Literal['cdn', 'local'] | None = None | ||
| cdn_url: str | None = None | ||
|
|
||
|
|
||
| class ModelScopeProMonacoEditor(ModelScopeDataLayoutComponent): | ||
| """ | ||
| """ | ||
| DiffEditor = ModelScopeProMonacoEditorDiffEditor | ||
|
|
||
| EVENTS = [ | ||
| EventListener("mount", | ||
| callback=lambda block: block._internal.update( | ||
| bind_mount_event=True), | ||
| doc="An event is emitted when the editor is mounted."), | ||
| EventListener( | ||
| "change", | ||
| callback=lambda block: block._internal.update(bind_change_event= | ||
| True), | ||
| doc="An event is emitted when the editor value is changed."), | ||
| EventListener( | ||
| "validate", | ||
| callback=lambda block: block._internal.update(bind_validate_event= | ||
| True), | ||
| doc= | ||
| "An event is emitted when the editor value is changed and the validation markers are ready." | ||
| ), | ||
| ] | ||
|
|
||
| # supported slots | ||
| SLOTS = ["loading"] | ||
|
|
||
| # or { "mode": "cdn" }, default cdn: https://cdn.jsdelivr.net/npm/monaco-editor@xxx/min/vs | ||
| LOADER: Union[LoaderConfig, dict, None] = {"mode": "local"} | ||
|
|
||
| def __init__( | ||
| self, | ||
| value: str | None = None, | ||
| *, | ||
| # python, javascript etc. | ||
| language: str | None = None, | ||
| before_mount: str | None = None, | ||
| after_mount: str | None = None, | ||
| override_services: dict | None = None, | ||
| loading: str | None = "Editor is loading...", | ||
| options: dict | None = None, | ||
| line: int | None = None, | ||
| read_only: bool | None = None, | ||
| height: str | int | float | None = 400, | ||
| _loader: None = None, | ||
| _internal: None = None, | ||
| # gradio properties | ||
| visible: bool = True, | ||
| elem_id: str | None = None, | ||
| elem_classes: list[str] | str | None = None, | ||
| elem_style: dict | None = None, | ||
| render: bool = True, | ||
| **kwargs): | ||
| super().__init__(visible=visible, | ||
| value=value, | ||
| elem_id=elem_id, | ||
| elem_classes=elem_classes, | ||
| render=render, | ||
| elem_style=elem_style, | ||
| **kwargs) | ||
| self.line = line | ||
| self.loading = loading | ||
| self._loader = ModelScopeProMonacoEditor.LOADER | ||
| self.override_services = override_services | ||
| self.options = options | ||
| self.read_only = read_only | ||
| self.before_mount = before_mount | ||
| self.after_mount = after_mount | ||
| self.language = language | ||
| self.height = height | ||
|
|
||
| FRONTEND_DIR = resolve_frontend_dir("monaco-editor", type='pro') | ||
|
|
||
| @property | ||
| def skip_api(self): | ||
| return False | ||
|
|
||
| def api_info(self) -> dict[str, Any]: | ||
| return {"type": "string"} | ||
|
|
||
| def preprocess(self, payload: None | str) -> None | str: | ||
| return payload | ||
|
|
||
| def postprocess(self, value: None | str) -> None | str: | ||
| return value | ||
|
|
||
| def example_payload(self) -> Any: | ||
| return None | ||
|
|
||
| def example_value(self) -> Any: | ||
| return None | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import Any | ||
|
|
||
| from gradio.events import EventListener | ||
|
|
||
| from .....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir | ||
|
|
||
|
|
||
| class ModelScopeProMonacoEditorDiffEditor(ModelScopeDataLayoutComponent): | ||
| """ | ||
| """ | ||
|
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| EVENTS = [ | ||
| EventListener("mount", | ||
| callback=lambda block: block._internal.update( | ||
| bind_mount_event=True), | ||
| doc="An event is emitted when the editor is mounted."), | ||
| EventListener( | ||
| "change", | ||
| callback=lambda block: block._internal.update(bind_change_event= | ||
| True), | ||
| doc="An event is emitted when the editor value is changed."), | ||
| EventListener( | ||
| "validate", | ||
| callback=lambda block: block._internal.update(bind_validate_event= | ||
| True), | ||
| doc= | ||
| "An event is emitted when the editor value is changed and the validation markers are ready." | ||
| ), | ||
| ] | ||
|
|
||
| # supported slots | ||
| SLOTS = ["loading"] | ||
|
|
||
| def __init__( | ||
| self, | ||
| value: str | None = None, | ||
| *, | ||
| original: str | None = None, | ||
| # python, javascript etc. | ||
| language: str | None = None, | ||
| original_language: str | None = None, | ||
| modified_language: str | None = None, | ||
| before_mount: str | None = None, | ||
| after_mount: str | None = None, | ||
| override_services: dict | None = None, | ||
| loading: str | None = "Editor is loading...", | ||
| read_only: bool | None = None, | ||
| options: dict | None = None, | ||
| line: int | None = None, | ||
| height: str | int | float | None = 400, | ||
| _loader: None = None, | ||
| _internal: None = None, | ||
| # gradio properties | ||
| visible: bool = True, | ||
| elem_id: str | None = None, | ||
| elem_classes: list[str] | str | None = None, | ||
| elem_style: dict | None = None, | ||
| render: bool = True, | ||
| **kwargs): | ||
| super().__init__(value=value, | ||
| visible=visible, | ||
| elem_id=elem_id, | ||
| elem_classes=elem_classes, | ||
| render=render, | ||
| elem_style=elem_style, | ||
| **kwargs) | ||
| from .. import ModelScopeProMonacoEditor | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The local import Example refactor:
|
||
| self._loader = ModelScopeProMonacoEditor.LOADER | ||
| self.original = original | ||
| self.line = line | ||
| self.loading = loading | ||
| self.override_services = override_services | ||
| self.options = options | ||
| self.read_only = read_only | ||
| self.before_mount = before_mount | ||
| self.after_mount = after_mount | ||
| self.language = language | ||
| self.original_language = original_language | ||
| self.modified_language = modified_language | ||
| self.height = height | ||
|
|
||
| FRONTEND_DIR = resolve_frontend_dir("monaco-editor", | ||
| 'diff-editor', | ||
| type='pro') | ||
|
|
||
| @property | ||
| def skip_api(self): | ||
| return False | ||
|
|
||
| def api_info(self) -> dict[str, Any]: | ||
| return {"type": "string"} | ||
|
|
||
| def preprocess(self, payload: None | str) -> None | str: | ||
| return payload | ||
|
|
||
| def postprocess(self, value: None | str) -> None | str: | ||
| return value | ||
|
|
||
| def example_payload(self) -> Any: | ||
| return None | ||
|
|
||
| def example_value(self) -> Any: | ||
| return None | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| # MonacoEditor | ||
|
|
||
| 代码编辑器,[Monaco Editor](https://microsoft.github.io/monaco-editor/) 的 Gradio 实现,基于 [@monaco-editor/react](https://github.com/suren-atoyan/monaco-react) 集成。 | ||
|
|
||
| ## 示例 | ||
|
|
||
| ### 基本使用 | ||
|
|
||
| <demo name="basic"></demo> | ||
|
|
||
| ### Diff 编辑器 | ||
|
|
||
| <demo name="diff_editor"></demo> | ||
|
|
||
| ### Monaco Editor 配置项 | ||
|
|
||
| 可以直接传入 Monaco Editor 的配置项 [IStandaloneEditorConstructionOptions](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html)。 | ||
|
|
||
| 在这个示例中,我们关闭了编辑器的`minimap`与 `lineNumbers`。 | ||
|
|
||
| <demo name="monaco_editor_options"></demo> | ||
|
|
||
| ### 通过 JavaScript 定制化配置 | ||
|
|
||
| 如果你还需要更进一步地操作 Monaco Editor,你可以通过传入 JavaScript 函数字符串来进一步定制化配置。 | ||
|
|
||
| <demo name="javascript_customize"></demo> | ||
|
|
||
| ## API | ||
|
|
||
| ### 属性 | ||
|
|
||
| #### MonacoEditor | ||
|
|
||
| | 属性 | 类型 | 默认值 | 描述 | | ||
| | ---------------- | --------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | value | `str\| None` | None | 编辑器的值。 | | ||
| | language | `str\| None` | None | 编辑器的语言(monaco-editor [支持](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages)的所有语言)。 | | ||
| | line | `number\| None` | None | 垂直滚动编辑器到指定行。 | | ||
| | read_only | `bool\| None` | None | 编辑器是否只读。 | | ||
| | loading | `str\| None` | 'Editor is loading...' | 编辑器初始化加载时的加载文案。 | | ||
| | options | `dict \| None` | None | [IStandaloneEditorConstructionOptions](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html) | | ||
| | overrideServices | `dict \| None` | None | [IEditorOverrideServices](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOverrideServices.html) | | ||
| | height | `str \| float \| int` | 400 | 组件的高度,如果值为数字,则以像素为单位指定,如果传递的是字符串,则以 CSS 单位指定。 | | ||
| | before_mount | `str \| None` | None | 传入 JavaScript 函数字符串,在编辑器加载前执行,可以获取到 `monaco` 对象。 | | ||
| | after_mount | `str \| None` | None | 传入 JavaScript 函数字符串,在编辑器加载后执行,可以获取到`editor`对象与`monaco` 对象。 | | ||
|
|
||
| #### MonacoEditor.DiffEditor | ||
|
|
||
| | 属性 | 类型 | 默认值 | 描述 | | ||
| | ----------------- | --------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | value | `str\| None` | None | 修改后的源的值(右侧)。 | | ||
| | original | `str\| None` | None | 原始源的值(左侧)。 | | ||
| | language | `str\| None` | None | 编辑器的语言(monaco-editor [支持](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages)的所有语言)。 | | ||
| | original_language | `str\| None` | None | 单独指定原始源的语言。否则,它将获取 language 属性的值。 | | ||
| | modified_language | `str\| None` | None | 单独指定修改后的源的语言。否则,它将获取 language 属性的值。 | | ||
| | line | `number\| None` | None | 垂直滚动编辑器到指定行。 | | ||
| | read_only | `bool\| None` | None | 编辑器是否只读。 | | ||
| | loading | `str\| None` | 'Editor is loading...' | 编辑器初始化加载时的加载文案。 | | ||
| | options | `dict \| None` | None | [IStandaloneEditorConstructionOptions](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html) | | ||
| | overrideServices | `dict \| None` | None | [IEditorOverrideServices](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IEditorOverrideServices.html) | | ||
| | height | `str \| float \| int` | 400 | 组件的高度,如果值为数字,则以像素为单位指定,如果传递的是字符串,则以 CSS 单位指定。 | | ||
| | before_mount | `str \| None` | None | 传入 JavaScript 函数字符串,在编辑器加载前执行,可以获取到 `monaco` 对象。 | | ||
| | after_mount | `str \| None` | None | 传入 JavaScript 函数字符串,在编辑器加载后执行,可以获取到`editor`对象与`monaco` 对象。 | | ||
|
|
||
| ### 事件 | ||
|
|
||
| | 事件 | 描述 | | ||
| | ----------------------------------------------------------------- | ---------------------------------------- | | ||
| | `pro.(MonacoEditor \| MonacoEditor.DiffEditor).mount(fn, ···)` | 当编辑器加载完成时触发。 | | ||
| | `pro.(MonacoEditor \| MonacoEditor.DiffEditor).change(fn, ···)` | 当编辑器值改变时触发。 | | ||
| | `pro.(MonacoEditor \| MonacoEditor.DiffEditor).validate(fn, ···)` | 当编辑器触发校验并且校错误记存在时触发。 | | ||
|
|
||
| **注:** 根据 [monaco-editor](https://microsoft.github.io/monaco-editor/),只有具备丰富智能感知的语言才会触发 validate 事件。 | ||
|
|
||
| - TypeScript | ||
| - JavaScript | ||
| - CSS | ||
| - LESS | ||
| - SCSS | ||
| - JSON | ||
| - HTML | ||
|
|
||
| ### 插槽 | ||
|
|
||
| ```python | ||
| SLOTS=['loading'] | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring for the
ModelScopeProMonacoEditorclass is empty. Please add a comprehensive docstring explaining what the component does, its parameters, and how to use it. This is important for maintainability and for other developers to understand the component.