瀏覽代碼

Merge pull request #1474 from natankeddem/jsoneditor

Add new element JSONEditor
Falko Schindler 1 年之前
父節點
當前提交
9904164e93

+ 1 - 0
DEPENDENCIES.md

@@ -13,3 +13,4 @@
 - plotly: 2.24.3
 - three: 0.154.0
 - tween: 21.0.0
+- vanilla-jsoneditor: 0.18.0

+ 38 - 0
nicegui/elements/json_editor.js

@@ -0,0 +1,38 @@
+import { JSONEditor } from "index";
+
+export default {
+  template: "<div></div>",
+  mounted() {
+    this.properties.onChange = (updatedContent, previousContent, { contentErrors, patchResult }) => {
+      this.$emit("change", { content: updatedContent, errors: contentErrors });
+    };
+    this.properties.onSelect = (selection) => {
+      this.$emit("select", { selection: selection });
+    };
+    this.editor = new JSONEditor({
+      target: this.$el,
+      props: this.properties,
+    });
+  },
+  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,
+  },
+};

+ 43 - 0
nicegui/elements/json_editor.py

@@ -0,0 +1,43 @@
+from typing import Callable, Dict, Optional
+
+from ..element import Element
+from ..events import GenericEventArguments, JsonEditorChangeEventArguments, JsonEditorSelectEventArguments, handle_event
+
+
+class JsonEditor(Element, component='json_editor.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
+        :param on_select: callback function that is called when some of the content has been selected
+        :param on_change: callback function that is called when the content has changed
+        """
+        super().__init__()
+        self._props['properties'] = properties
+
+        if on_select:
+            def handle_on_select(e: GenericEventArguments) -> None:
+                handle_event(on_select, JsonEditorSelectEventArguments(sender=self, client=self.client, **e.args))
+            self.on('select', handle_on_select, ['selection'])
+
+        if on_change:
+            def handle_on_change(e: GenericEventArguments) -> None:
+                handle_event(on_change, JsonEditorChangeEventArguments(sender=self, client=self.client, **e.args))
+            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')

File diff suppressed because it is too large
+ 0 - 0
nicegui/elements/lib/vanilla-jsoneditor/index.js


File diff suppressed because it is too large
+ 0 - 0
nicegui/elements/lib/vanilla-jsoneditor/index.js.map


+ 11 - 0
nicegui/events.py

@@ -351,6 +351,17 @@ class ScrollEventArguments(UiEventArguments):
     horizontal_container_size: float
 
 
+@dataclass(**KWONLY_SLOTS)
+class JsonEditorSelectEventArguments(UiEventArguments):
+    selection: Dict
+
+
+@dataclass(**KWONLY_SLOTS)
+class JsonEditorChangeEventArguments(UiEventArguments):
+    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',
+    'json_editor',
     '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.json_editor import JsonEditor as json_editor
 from .elements.keyboard import Keyboard as keyboard
 from .elements.knob import Knob as knob
 from .elements.label import Label as label

+ 7 - 0
npm.json

@@ -112,5 +112,12 @@
     "rename": {
       "package/dist/": ""
     }
+  },
+  "vanilla-jsoneditor": {
+    "destination": "elements/lib",
+    "keep": ["package/index\\.js", "package/index\\.js\\.map"],
+    "rename": {
+      "package/": ""
+    }
   }
 }

+ 1 - 0
website/documentation.py

@@ -143,6 +143,7 @@ def create_full() -> None:
     load_demo(ui.scene)
     load_demo(ui.tree)
     load_demo(ui.log)
+    load_demo(ui.json_editor)
 
     heading('Layout')
 

+ 20 - 0
website/more_documentation/json_editor_documentation.py

@@ -0,0 +1,20 @@
+from nicegui import ui
+
+
+def main_demo() -> None:
+    json = {
+        'array': [1, 2, 3],
+        'boolean': True,
+        'color': '#82b92c',
+        None: None,
+        'number': 123,
+        'object': {
+            'a': 'b',
+            'c': 'd',
+        },
+        'time': 1575599819000,
+        'string': 'Hello World',
+    }
+    ui.json_editor({'content': {'json': json}},
+                   on_select=lambda e: ui.notify(f'Select: {e}'),
+                   on_change=lambda e: ui.notify(f'Change: {e}'))

Some files were not shown because too many files changed in this diff