Grant Nestor 6 роки тому
батько
коміт
aec80eca18

+ 42 - 65
packages/json-extension/src/component.tsx

@@ -3,23 +3,20 @@
 
 import * as React from 'react';
 
-import * as ReactDOM from 'react-dom';
-
 import Highlight from 'react-highlighter';
 
 import JSONTree from 'react-json-tree';
 
-import { InputGroup } from '@jupyterlab/ui-components';
-
 import { JSONArray, JSONObject, JSONValue } from '@phosphor/coreutils';
 
+import { InputGroup } from '@jupyterlab/ui-components';
+
 /**
  * The properties for the JSON tree component.
  */
 export interface IProps {
   data: JSONValue;
   metadata?: JSONObject;
-  theme?: string;
 }
 
 /**
@@ -35,30 +32,17 @@ export interface IState {
  */
 export class Component extends React.Component<IProps, IState> {
   state = { filter: '', value: '' };
-  timer: number = 0;
 
-  componentDidMount() {
-    /**
-     * Stop propagation of keyboard events to JupyterLab
-     */
-    ReactDOM.findDOMNode(this.input).addEventListener(
-      'keydown',
-      (event: Event) => {
-        event.stopPropagation();
-      },
-      false
-    );
-  }
+  timer: number = 0;
 
-  componentWillUnmount() {
-    ReactDOM.findDOMNode(this.input).removeEventListener(
-      'keydown',
-      (event: Event) => {
-        event.stopPropagation();
-      },
-      false
-    );
-  }
+  handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+    const { value } = event.target;
+    this.setState({ value });
+    window.clearTimeout(this.timer);
+    this.timer = window.setTimeout(() => {
+      this.setState({ filter: value });
+    }, 300);
+  };
 
   render() {
     const { data, metadata } = this.props;
@@ -81,34 +65,25 @@ export class Component extends React.Component<IProps, IState> {
           collectionLimit={100}
           theme={{
             extend: theme,
-            // TODO: Use Jupyter Notebook's current CodeMirror theme vs. 'cm-s-ipython'
-            tree: `CodeMirror ${this.props.theme || 'cm-s-ipython'}`,
-            // valueLabel: 'cm-variable',
+            valueLabel: 'cm-variable',
             valueText: 'cm-string',
-            // nestedNodeLabel: 'cm-variable-2',
-            nestedNodeItemString: 'cm-comment',
-            // value: {},
-            // label: {},
-            // itemRange: {},
-            // nestedNode: {},
-            // nestedNodeItemType: {},
-            // nestedNodeChildren: {},
-            // rootNodeChildren: {},
-            arrowSign: { color: 'cm-variable' }
+            nestedNodeItemString: 'cm-comment'
           }}
           invertTheme={false}
           keyPath={[root]}
           labelRenderer={([label, type]) => {
-            let className = 'cm-variable';
-            // if (type === 'root') className = 'cm-variable-2';
-            if (type === 'array') {
-              className = 'cm-variable-2';
-            }
-            if (type === 'object') {
-              className = 'cm-variable-3';
-            }
+            // let className = 'cm-variable';
+            // if (type === 'root') {
+            //   className = 'cm-variable-2';
+            // }
+            // if (type === 'array') {
+            //   className = 'cm-variable-2';
+            // }
+            // if (type === 'Object') {
+            //   className = 'cm-variable-3';
+            // }
             return (
-              <span className={className}>
+              <span className="cm-keyword">
                 <Highlight
                   search={this.state.filter}
                   matchStyle={{ backgroundColor: 'yellow' }}
@@ -148,24 +123,26 @@ export class Component extends React.Component<IProps, IState> {
   }
 }
 
+// Provide an invalid theme object (this is on purpose!) to invalidate the
+// react-json-tree's inline styles that override CodeMirror CSS classes
 const theme = {
   scheme: 'jupyter',
-  base00: '#fff',
-  base01: '#fff',
-  base02: '#d7d4f0',
-  base03: '#408080',
-  base04: '#b4b7b4',
-  base05: '#c5c8c6',
-  base06: '#d7d4f0',
-  base07: '#fff',
-  base08: '#000',
-  base09: '#080',
-  base0A: '#fba922',
-  base0B: '#408080',
-  base0C: '#aa22ff',
-  base0D: '#00f',
-  base0E: '#008000',
-  base0F: '#00f'
+  base00: 'invalid',
+  base01: 'invalid',
+  base02: 'invalid',
+  base03: 'invalid',
+  base04: 'invalid',
+  base05: 'invalid',
+  base06: 'invalid',
+  base07: 'invalid',
+  base08: 'invalid',
+  base09: 'invalid',
+  base0A: 'invalid',
+  base0B: 'invalid',
+  base0C: 'invalid',
+  base0D: 'invalid',
+  base0E: 'invalid',
+  base0F: 'invalid'
 };
 
 function objectIncludes(data: JSONValue, query: string): boolean {

+ 9 - 7
packages/json-extension/src/index.tsx

@@ -35,6 +35,8 @@ export class RenderedJSON extends Widget implements IRenderMime.IRenderer {
   constructor(options: IRenderMime.IRendererOptions) {
     super();
     this.addClass(CSS_CLASS);
+    this.addClass('CodeMirror');
+    this.addClass('cm-s-jupyter');
     this._mimeType = options.mimeType;
   }
 
@@ -44,14 +46,14 @@ export class RenderedJSON extends Widget implements IRenderMime.IRenderer {
   renderModel(model: IRenderMime.IMimeModel): Promise<void> {
     const data = model.data[this._mimeType] as any;
     const metadata = (model.metadata[this._mimeType] as any) || {};
-    const props = { data, metadata, theme: 'cm-s-jupyter' };
-
     return new Promise<void>((resolve, reject) => {
-      const component = <Component {...props} />;
-
-      ReactDOM.render(component, this.node, () => {
-        resolve();
-      });
+      ReactDOM.render(
+        <Component data={data} metadata={metadata} />,
+        this.node,
+        () => {
+          resolve();
+        }
+      );
     });
   }