From 79f1fee048b49f7f23414cd6388f2aa9f03583aa Mon Sep 17 00:00:00 2001 From: Bill Noon Date: Thu, 13 Aug 2015 12:16:51 -0400 Subject: [PATCH] Add support for Map nodes --- src/react/JSONTree/JSONMapNode.js | 124 ++++++++++++++++++++++++++++++ src/react/JSONTree/grab-node.js | 3 + src/react/JSONTree/index.js | 3 + 3 files changed, 130 insertions(+) create mode 100644 src/react/JSONTree/JSONMapNode.js diff --git a/src/react/JSONTree/JSONMapNode.js b/src/react/JSONTree/JSONMapNode.js new file mode 100644 index 00000000..bc633702 --- /dev/null +++ b/src/react/JSONTree/JSONMapNode.js @@ -0,0 +1,124 @@ +import React from 'react'; +import reactMixin from 'react-mixin'; +import { ExpandedStateHandlerMixin } from './mixins'; +import JSONArrow from './JSONArrow'; +import grabNode from './grab-node'; + +const styles = { + base: { + position: 'relative', + paddingTop: 3, + paddingBottom: 3, + marginLeft: 14 + }, + label: { + margin: 0, + padding: 0, + display: 'inline-block' + }, + span: { + cursor: 'default' + }, + spanType: { + marginLeft: 5, + marginRight: 5 + } +}; + +@reactMixin.decorate(ExpandedStateHandlerMixin) +export default class JSONMapNode extends React.Component { + defaultProps = { + data: [], + initialExpanded: false + }; + // cache store for the number of items string we display + itemString = false; + + // flag to see if we still need to render our child nodes + needsChildNodes = true; + + // cache store for our child nodes + renderedChildren = []; + + constructor(props) { + super(props); + this.state = { + expanded: this.props.initialExpanded, + createdChildNodes: false + }; + } + + // Returns the child nodes for each element in the object. If we have + // generated them previously, we return from cache, otherwise we create + // them. + getChildNodes() { + if (this.state.expanded && this.needsChildNodes) { + const map = this.props.data; + let childNodes = []; + map.forEach( (v, k) => { + let prevData; + if (typeof this.props.previousData !== 'undefined') { + if (this.props.previousData.has(k)) prevData = this.props.previousData.get(k); + } + const node = grabNode(k, v, prevData, this.props.theme); + if (node !== false) { + childNodes.push(node); + } + }); + this.needsChildNodes = false; + this.renderedChildren = childNodes; + } + return this.renderedChildren; + } + + // Returns the "n Items" string for this node, generating and + // caching it if it hasn't been created yet. + getItemString() { + if (!this.itemString) { + const len = this.props.data.size; + this.itemString = len + ' item' + (len !== 1 ? 's' : ''); + } + return this.itemString; + } + + render() { + let childListStyle = { + padding: 0, + margin: 0, + listStyle: 'none', + display: (this.state.expanded) ? 'block' : 'none' + }; + let containerStyle; + let spanStyle = { + ...styles.span, + color: this.props.theme.base0B + }; + containerStyle = { + ...styles.base + }; + if (this.state.expanded) { + spanStyle = { + ...spanStyle, + color: this.props.theme.base03 + }; + } + return ( +
  • + + + + Map + {this.getItemString()} + +
      + {this.getChildNodes()} +
    +
  • + ); + } +} diff --git a/src/react/JSONTree/grab-node.js b/src/react/JSONTree/grab-node.js index d3851433..9b257d79 100644 --- a/src/react/JSONTree/grab-node.js +++ b/src/react/JSONTree/grab-node.js @@ -2,6 +2,7 @@ import React from 'react'; import objType from './obj-type'; import JSONObjectNode from './JSONObjectNode'; import JSONArrayNode from './JSONArrayNode'; +import JSONMapNode from './JSONMapNode'; import JSONStringNode from './JSONStringNode'; import JSONNumberNode from './JSONNumberNode'; import JSONBooleanNode from './JSONBooleanNode'; @@ -13,6 +14,8 @@ export default function(key, value, prevValue, theme) { return ; } else if (nodeType === 'Array') { return ; + } else if (nodeType === 'Map') { + return ; } else if (nodeType === 'String') { return ; } else if (nodeType === 'Number') { diff --git a/src/react/JSONTree/index.js b/src/react/JSONTree/index.js index bbac9580..6179da30 100644 --- a/src/react/JSONTree/index.js +++ b/src/react/JSONTree/index.js @@ -7,6 +7,7 @@ import React from 'react'; import objectType from './obj-type'; import JSONObjectNode from './JSONObjectNode'; import JSONArrayNode from './JSONArrayNode'; +import JSONMapNode from './JSONMapNode'; const styles = { tree: { @@ -43,6 +44,8 @@ export default class JSONTree extends React.Component { rootNode = ; } else if (nodeType === 'Array') { rootNode = ; + } else if (nodeType === 'Map') { + rootNode = ; } return (