Natan 1 ano atrás
pai
commit
3462c3b6ef
4 arquivos alterados com 135 adições e 0 exclusões
  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
     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:
 def handle_event(handler: Optional[Callable[..., Any]], arguments: EventArguments) -> None:
     if handler is None:
     if handler is None:
         return
         return

+ 2 - 0
nicegui/ui.py

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