diff --git a/example/interactive-selection.js b/example/interactive-selection.js index 928fed9..58dac8d 100644 --- a/example/interactive-selection.js +++ b/example/interactive-selection.js @@ -1,7 +1,8 @@ var React = require('react'); -var input = React.DOM.input; +var input = React.createElement('input'); +var createClass = require('create-react-class'); -module.exports = React.createClass({ +module.exports = createClass({ getDefaultProps: function() { return { value: '' diff --git a/json-inspector.js b/json-inspector.js index 9b3c0f3..461c5fb 100644 --- a/json-inspector.js +++ b/json-inspector.js @@ -1,5 +1,6 @@ var React = require('react'); -var D = React.DOM; +var PropTypes = require('prop-types'); +var createClass = require('create-react-class'); var Leaf = require('./lib/leaf'); var leaf = React.createFactory(Leaf); @@ -11,129 +12,142 @@ var isEmpty = require('./lib/is-empty'); var lens = require('./lib/lens'); var noop = require('./lib/noop'); -module.exports = React.createClass({ - propTypes: { - data: React.PropTypes.any.isRequired, - // For now it expects a factory function, not element. - search: React.PropTypes.oneOfType([ - React.PropTypes.func, - React.PropTypes.bool - ]), - onClick: React.PropTypes.func, - validateQuery: React.PropTypes.func, - isExpanded: React.PropTypes.func, - filterOptions: React.PropTypes.object, - query: React.PropTypes.string - }, +module.exports = createClass({ + propTypes: { + data: PropTypes.any.isRequired, + // For now it expects a factory function, not element. + search: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.bool + ]), + onClick: PropTypes.func, + validateQuery: PropTypes.func, + isExpanded: PropTypes.func, + isRootCollapsed: PropTypes.bool, + filterOptions: PropTypes.object, + query: PropTypes.string, + filterFunc: PropTypes.func, + shouldHighlight: PropTypes.func, + highlightRenderer: PropTypes.func + }, - getDefaultProps: function() { - return { - data: null, - search: searchBar, - className: '', - id: 'json-' + Date.now(), - onClick: noop, - filterOptions: {}, - validateQuery: function(query) { - return query.length >= 2; - }, - /** - * Decide whether the leaf node at given `keypath` should be - * expanded initially. - * @param {String} keypath - * @param {Any} value - * @return {Boolean} - */ - isExpanded: function(keypath, value) { - return false; - } - }; - }, - getInitialState: function() { - return { - query: this.props.query || '' - }; - }, - render: function() { - var p = this.props; - var s = this.state; + getDefaultProps: function() { + return { + data: null, + search: searchBar, + className: '', + id: 'json-' + Date.now(), + onClick: noop, + filterOptions: {}, + validateQuery: function(query) { + return query !== null && query !== undefined; + }, + /** + * Decide whether the leaf node at given `keypath` should be + * expanded initially. + * @param {String} keypath + * @param {Any} value + * @return {Boolean} + */ + isExpanded: function(keypath, value) { + return false; + }, + highlightRenderer: null + }; + }, + render: function() { + var p = this.props; + var s = this.state; - var isQueryValid = ( - s.query !== '' && - p.validateQuery(s.query) - ); + var isQueryValid = ( + p.query !== '' && + p.validateQuery(p.query) + ); - var data = ( - isQueryValid ? - s.filterer(s.query) : - p.data - ); + var data = ( + isQueryValid ? + s.filterer(p.query) : + p.data + ); - var isNotFound = ( - isQueryValid && - isEmpty(data) - ); + var isNotFound = ( + isQueryValid && + isEmpty(data) + ); - return D.div({ className: 'json-inspector ' + p.className }, - this.renderToolbar(), - ( - isNotFound ? - D.div({ className: 'json-inspector__not-found' }, 'Nothing found') : - leaf({ - data: data, - onClick: p.onClick, - id: p.id, - getOriginal: this.getOriginal, - query: ( - isQueryValid ? - s.query : - null - ), - label: 'root', - root: true, - isExpanded: p.isExpanded, - interactiveLabel: p.interactiveLabel - }) - ) - ); - }, - renderToolbar: function() { - var search = this.props.search; + return React.createElement('div', { className: 'json-inspector ' + p.className }, + this.renderToolbar(), + ( + isNotFound ? + React.createElement('div', { className: 'json-inspector__not-found' }, 'Nothing found') : + leaf({ + data: data, + onClick: p.onClick, + id: p.id, + getOriginal: this.getOriginal, + query: ( + isQueryValid ? + p.query : + null + ), + label: 'root', + root: true, + isRootCollapsed: p.isRootCollapsed, + isExpanded: p.isExpanded, + interactiveLabel: p.interactiveLabel, + shouldHighlight: p.shouldHighlight, + highlightRenderer: p.highlightRenderer, + }) + ) + ); + }, + renderToolbar: function() { + var search = this.props.search; - if (search) { - return D.div({ className: 'json-inspector__toolbar' }, - search({ - onChange: this.search, - data: this.props.data, - query: this.state.query - }) - ); - } - }, - search: function(query) { - this.setState({ - query: query - }); - }, - componentWillMount: function() { - this.createFilterer(this.props.data, this.props.filterOptions); - }, - componentWillReceiveProps: function(p) { - this.createFilterer(p.data, p.filterOptions); - }, - shouldComponentUpdate: function (p, s) { - return ( - s.query !== this.state.query || - p.data !== this.props.data || - p.onClick !== this.props.onClick - ); - }, - createFilterer: function(data, options) { - this.setState({ - filterer: filterer(data, options) - }); - }, - getOriginal: function(path) { - return lens(this.props.data, path); + if (search) { + return React.createElement('div', { className: 'json-inspector__toolbar' }, + search({ + onChange: this.search, + data: this.props.data, + query: this.state.query + }) + ); } + }, + search: function(query) { + this.setState({ + query: query + }); + }, + componentWillMount: function() { + this.createFilterer(this.props.data, this.props.filterOptions, this.props.filterFunc); + }, + componentWillReceiveProps: function(p) { + this.createFilterer(p.data, p.filterOptions, p.filterFunc); + this.setState({query: p.query}); + }, + shouldComponentUpdate: function (p, s) { + return ( + p.filterFunc !== this.props.filterFunc || + p.query !== this.props.query || + p.data !== this.props.data || + p.onClick !== this.props.onClick + ); + }, + getFilterer: function(pFilterFunc) { + var filterFunc = pFilterFunc; + if (!filterFunc) { + filterFunc = filterer + } + return filterFunc; + }, + createFilterer: function(data, options, filterFunc) { + var f = this.getFilterer(filterFunc); + this.setState({ + filterer: f(data, options) + }); + }, + getOriginal: function(path) { + return lens(this.props.data, path); + } }); diff --git a/lib/highlighter.js b/lib/highlighter.js index 2cd3904..2ac8575 100644 --- a/lib/highlighter.js +++ b/lib/highlighter.js @@ -1,30 +1,49 @@ var React = require('react'); -var span = React.DOM.span; +var createClass = require('create-react-class'); -module.exports = React.createClass({ + +module.exports = createClass({ getDefaultProps: function() { return { string: '', - highlight: '' + highlight: '', + fullKey: '', + shouldHighlight: null, + highlightRenderer: null }; }, shouldComponentUpdate: function(p) { - return p.highlight !== this.props.highlight; + return p.highlight !== this.props.highlight || + p.shouldHighlight !== this.props.shouldHighlight || + p.highlightRenderer !== this.props.highlightRenderer || + p.fullKey !== this.props.fullKey; }, render: function() { var p = this.props; - - if (!p.highlight || p.string.indexOf(p.highlight) === -1) { - return span(null, p.string); + if (p.shouldHighlight) { + if (!p.shouldHighlight(p.string, p.highlight, p.fullKey)) { + return React.createElement('span', null, p.string); + } else { + if (p.highlightRenderer) { + return React.createElement('span', null, p.highlightRenderer(p.string, p.highlight, p.fullKey)); + } else { + return React.createElement('span', {className: 'json-inspector__hl'}, p.string) + } + } } + else { + if (!p.highlight || p.string.indexOf(p.highlight) === -1) { + return React.createElement('span', null, p.string); + } - return span(null, - p.string.split(p.highlight).map(function(part, index) { - return span({ key: index }, + return React.createElement('span', null, + p.string.split(p.highlight).map(function (part, index) { + return React.createElement('span', {key: index}, index > 0 ? - span({ className: 'json-inspector__hl' }, p.highlight) : - null, + React.createElement('span', {className: 'json-inspector__hl'}, p.highlight) : + null, part); - })); + })); + } } }); diff --git a/lib/leaf.js b/lib/leaf.js index 0d13a9b..7bcb7f9 100644 --- a/lib/leaf.js +++ b/lib/leaf.js @@ -1,5 +1,5 @@ var React = require('react'); -var D = React.DOM; +var createClass = require('create-react-class'); var md5omatic = require('md5-o-matic'); @@ -12,7 +12,7 @@ var highlighter = React.createFactory(Highlighter); var PATH_PREFIX = '.root.'; -var Leaf = React.createClass({ +var Leaf = createClass({ getInitialState: function() { return { expanded: this._isInitiallyExpanded(this.props) @@ -36,18 +36,18 @@ var Leaf = React.createClass({ var onLabelClick = this._onClick.bind(this, d); - return D.div({ className: this.getClassName(), id: 'leaf-' + this._rootPath() }, - D.input({ className: 'json-inspector__radio', type: 'radio', name: p.id, id: id, tabIndex: -1 }), - D.label({ className: 'json-inspector__line', htmlFor: id, onClick: onLabelClick }, - D.div({ className: 'json-inspector__flatpath' }, - d.path), - D.span({ className: 'json-inspector__key' }, - this.format(d.key), - ':', - this.renderInteractiveLabel(d.key, true)), - this.renderTitle(), - this.renderShowOriginalButton()), - this.renderChildren()); + return React.createElement('div', { className: this.getClassName(), id: 'leaf-' + this._rootPath() }, + React.createElement('input', { className: 'json-inspector__radio', type: 'radio', name: p.id, id: id, tabIndex: -1 }), + React.createElement('label', { className: 'json-inspector__line', htmlFor: id, onClick: onLabelClick }, + React.createElement('div', { className: 'json-inspector__flatpath' }, + d.path), + React.createElement('span', { className: 'json-inspector__key' }, + this.format(d.key), + ':', + this.renderInteractiveLabel(d.key, true)), + this.renderTitle(), + this.renderShowOriginalButton()), + this.renderChildren()); }, renderTitle: function() { var data = this.data(); @@ -55,15 +55,15 @@ var Leaf = React.createClass({ switch (t) { case 'Array': - return D.span({ className: 'json-inspector__value json-inspector__value_helper' }, - '[] ' + items(data.length)); + return React.createElement('span', { className: 'json-inspector__value json-inspector__value_helper' }, + '[] ' + items(data.length)); case 'Object': - return D.span({ className: 'json-inspector__value json-inspector__value_helper' }, - '{} ' + items(Object.keys(data).length)); + return React.createElement('span', { className: 'json-inspector__value json-inspector__value_helper' }, + '{} ' + items(Object.keys(data).length)); default: - return D.span({ className: 'json-inspector__value json-inspector__value_' + t.toLowerCase() }, - this.format(String(data)), - this.renderInteractiveLabel(data, false)); + return React.createElement('span', { className: 'json-inspector__value json-inspector__value_' + t.toLowerCase() }, + this.format(String(data)), + this.renderInteractiveLabel(data, false)); } }, renderChildren: function() { @@ -85,7 +85,9 @@ var Leaf = React.createClass({ getOriginal: this.state.original ? null : p.getOriginal, key: getLeafKey(key, value), isExpanded: p.isExpanded, - interactiveLabel: p.interactiveLabel + interactiveLabel: p.interactiveLabel, + shouldHighlight: p.shouldHighlight, + highlightRenderer: p.highlightRenderer, }); }, this); } @@ -99,7 +101,7 @@ var Leaf = React.createClass({ return null; } - return D.span({ + return React.createElement('span', { className: 'json-inspector__show-original', onClick: this._onShowOriginalClick }); @@ -145,7 +147,10 @@ var Leaf = React.createClass({ format: function(string) { return highlighter({ string: string, - highlight: this.props.query + highlight: this.props.query, + shouldHighlight: this.props.shouldHighlight, + highlightRenderer: this.props.highlightRenderer, + fullKey: this.keypath() }); }, getClassName: function() { @@ -187,7 +192,7 @@ var Leaf = React.createClass({ var keypath = this.keypath(); if (p.root) { - return true; + return !p.isRootCollapsed; } if (!p.query) { diff --git a/lib/search-bar.js b/lib/search-bar.js index 4d4e7ab..19d40fc 100644 --- a/lib/search-bar.js +++ b/lib/search-bar.js @@ -1,17 +1,17 @@ var debounce = require('debounce'); var React = require('react'); -var input = React.DOM.input; +var createClass = require('create-react-class'); var noop = require('./noop'); -module.exports = React.createClass({ +module.exports = createClass({ getDefaultProps: function() { return { onChange: noop }; }, render: function() { - return input({ + return React.createElement('input',{ className: 'json-inspector__search', type: 'search', placeholder: 'Search', diff --git a/package.json b/package.json index 25653ca..7c5bcdf 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,14 @@ { - "name": "react-json-inspector", - "version": "6.1.1", + "name": "react-json-inspector-demisto", + "version": "1.0.1", "description": "React JSON inspector component", "main": "json-inspector.js", "author": { - "name": "Aziz Yuldoshev", - "email": "yuldoshev.aziz@gmail.com", - "url": "http://lapple.me" + "name": "Demisto" }, "repository": { "type": "git", - "url": "git://github.com/Lapple/react-json-inspector.git" + "url": "git://github.com/aviadl/react-json-inspector.git" }, "license": "MIT", "dependencies": { @@ -21,11 +19,12 @@ "devDependencies": { "browserify": "^6.1.0", "http-server": "^0.7.2", - "react-dom": "^0.14.0", "watchify": "^2.0.0" }, "peerDependencies": { - "react": "^0.14.0" + "react": "^16.1.1", + "prop-types": "^15.6.0", + "create-react-class": "^15.6.2" }, "keywords": [ "react-component"