瀏覽代碼

add element

Natan 1 年之前
父節點
當前提交
3462c3b6ef
共有 4 個文件被更改,包括 135 次插入0 次删除
  1. 46 0
      nicegui/elements/jsoneditor.js
  2. 62 0
      nicegui/elements/jsoneditor.py
  3. 25 0
      nicegui/events.py
  4. 2 0
      nicegui/ui.py

+ 46 - 0
nicegui/elements/jsoneditor.js

@@ -0,0 +1,46 @@
+import { JSONEditor } from "index";
+
+export default {
+  template: "<div></div>",
+  mounted() {
+    setTimeout(() => {
+      this.properties.onChange = (updatedContent, previousContent, { contentErrors, patchResult }) => {
+        console.log("onChange", { updatedContent, previousContent, contentErrors, patchResult });
+        this.$emit("change", { content: updatedContent, errors: contentErrors });
+      };
+      this.properties.onSelect = (selection) => {
+        console.log("onSelect", { selection });
+        if (selection.type === "text") {
+          this.$emit("select_text", { main: selection.main, ranges: selection.ranges, type: selection.type });
+        } else {
+          this.$emit("select_json", { edit: selection.edit, path: selection.path, type: selection.type });
+        }
+      };
+      this.editor = new JSONEditor({
+        target: this.$el,
+        props: this.properties,
+      });
+    }, 0); // NOTE: wait for window.path_prefix to be set in app.mounted()
+  },
+  beforeDestroy() {
+    this.destroyEditor();
+  },
+  beforeUnmount() {
+    this.destroyEditor();
+  },
+  methods: {
+    update_editor() {
+      if (this.editor) {
+        this.editor.updateProps(this.properties);
+      }
+    },
+    destroyEditor() {
+      if (this.editor) {
+        this.editor.dispose();
+      }
+    },
+  },
+  props: {
+    properties: Object,
+  },
+};

+ 62 - 0
nicegui/elements/jsoneditor.py

@@ -0,0 +1,62 @@
+from typing import Callable, Dict, List, Optional
+
+from ..element import Element
+from ..events import (GenericEventArguments, JSONEditorOnChangeEventArguments, JSONEditorOnSelectJSONEventArguments,
+                      JSONEditorOnSelectTextEventArguments, handle_event)
+
+
+class JSONeditor(Element, component='jsoneditor.js', exposed_libraries=['lib/vanilla-jsoneditor/index.js']):
+    def __init__(
+            self, properties: Dict, on_select: Optional[Callable] = None, on_change: Optional[Callable] = None) -> None:
+        """JSONEditor
+
+        An element to create a JSON editor using `JSONEditor <https://github.com/josdejong/svelte-jsoneditor>`_.
+        Updates can be pushed to the editor by changing the `properties` property.
+        After data has changed, call the `update` method to refresh the editor.
+
+        :param properties: dictionary of JSONEditor properties
+        """
+        super().__init__()
+        self._props['properties'] = properties
+        self._classes = ['nicegui-jsoneditor']
+
+        if on_select:
+            def handle_on_select_json(e: GenericEventArguments) -> None:
+                handle_event(on_select, JSONEditorOnSelectJSONEventArguments(
+                    sender=self,
+                    client=self.client,
+                    event_type='select',
+                    edit=e.args['edit'],
+                    path=e.args['path'],
+                    type=e.args['type']
+                ))
+            self.on('select_json', handle_on_select_json, ['edit', 'path', 'type'])
+
+            def handle_on_select_text(e: GenericEventArguments) -> None:
+                handle_event(on_select, JSONEditorOnSelectTextEventArguments(
+                    sender=self,
+                    client=self.client,
+                    event_type='select',
+                    main=e.args['main'],
+                    ranges=e.args['ranges'],
+                    type=e.args['type']
+                ))
+            self.on('select_text', handle_on_select_text, ['main', 'ranges', 'type'])
+        if on_change:
+            def handle_on_change(e: GenericEventArguments) -> None:
+                handle_event(on_change, JSONEditorOnChangeEventArguments(
+                    sender=self,
+                    client=self.client,
+                    event_type='change',
+                    content=e.args['content'],
+                    errors=e.args['errors']
+                ))
+            self.on('change', handle_on_change, ['content', 'errors'])
+
+    @property
+    def properties(self) -> Dict:
+        return self._props['properties']
+
+    def update(self) -> None:
+        super().update()
+        self.run_method('update_editor')

+ 25 - 0
nicegui/events.py

@@ -351,6 +351,31 @@ class ScrollEventArguments(UiEventArguments):
     horizontal_container_size: float
 
 
+@dataclass(**KWONLY_SLOTS)
+class JSONEditorEventArguments(UiEventArguments):
+    event_type: str
+
+
+@dataclass(**KWONLY_SLOTS)
+class JSONEditorOnSelectJSONEventArguments(JSONEditorEventArguments):
+    edit: bool
+    path: dict
+    type: str
+
+
+@dataclass(**KWONLY_SLOTS)
+class JSONEditorOnSelectTextEventArguments(JSONEditorEventArguments):
+    main: int
+    ranges: dict
+    type: str
+
+
+@dataclass(**KWONLY_SLOTS)
+class JSONEditorOnChangeEventArguments(JSONEditorEventArguments):
+    content: dict
+    errors: dict
+
+
 def handle_event(handler: Optional[Callable[..., Any]], arguments: EventArguments) -> None:
     if handler is None:
         return

+ 2 - 0
nicegui/ui.py

@@ -29,6 +29,7 @@ __all__ = [
     'input',
     'interactive_image',
     'joystick',
+    'jsoneditor',
     'keyboard',
     'knob',
     'label',
@@ -121,6 +122,7 @@ from .elements.image import Image as image
 from .elements.input import Input as input
 from .elements.interactive_image import InteractiveImage as interactive_image
 from .elements.joystick import Joystick as joystick
+from .elements.jsoneditor import JSONeditor as jsoneditor
 from .elements.keyboard import Keyboard as keyboard
 from .elements.knob import Knob as knob
 from .elements.label import Label as label