diff --git a/src/ActionPreview.jsx b/src/ActionPreview.jsx index ee7fc11..b5e81c1 100644 --- a/src/ActionPreview.jsx +++ b/src/ActionPreview.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Component } from 'react'; import JSONTree from 'react-json-tree'; import ActionPreviewHeader from './ActionPreviewHeader'; import JSONDiff from './JSONDiff'; @@ -61,55 +61,60 @@ function getItemString(createTheme, type, data) { return {immutableStr} {text}; } -const ActionPreview = ({ - styling, delta, nextState, onInspectPath, inspectedPath, tab, - onSelectTab, action, base16Theme, isLightTheme -}) => { - const labelRenderer = (key, ...rest) => - - - {key} - - onInspectPath([ - ...inspectedPath.slice(0, inspectedPath.length - 1), - ...[key, ...rest].reverse() - ])}> - {'(pin)'} - - ; +class ActionPreview extends Component { + render() { + const { + styling, delta, nextState, onInspectPath, inspectedPath, tab, + onSelectTab, action, base16Theme, isLightTheme + } = this.props; + + return ( +
+ + {tab === 'Diff' && + + } + {(tab === 'State' && nextState || tab === 'Action') && + ({ + style: { + ...style, + display: expanded ? 'none' : 'inline' + } + }) + }} + data={tab === 'Action' ? action : nextState} + getItemString={(type, data) => getItemString(styling, type, data)} + isLightTheme={isLightTheme} + hideRoot /> + } +
+ ); + } - return ( -
- - {tab === 'Diff' && delta && - - } - {tab === 'Diff' && !delta && -
- (states are equal) -
- } - {(tab === 'State' && nextState || tab === 'Action') && - ({ - style: { - ...style, - display: expanded ? 'none' : 'inline' - } - }) - }} - data={tab === 'Action' ? action : nextState} - getItemString={(type, data) => getItemString(styling, type, data)} - isLightTheme={isLightTheme} - hideRoot /> - } -
- ); + labelRenderer = (key, ...rest) => { + const { styling, onInspectPath, inspectedPath } = this.props; + + return ( + + + {key} + + onInspectPath([ + ...inspectedPath.slice(0, inspectedPath.length - 1), + ...[key, ...rest].reverse() + ])}> + {'(pin)'} + + + ); + } } export default ActionPreview; diff --git a/src/DevtoolsInspector.js b/src/DevtoolsInspector.js index 7e6c9c6..012f822 100644 --- a/src/DevtoolsInspector.js +++ b/src/DevtoolsInspector.js @@ -53,12 +53,7 @@ function createThemeState(props) { export default class DevtoolsInspector extends Component { state = { - isWideLayout: false, - selectedActionId: null, - inspectedActionPath: [], - inspectedStatePath: [], - tab: 'Diff', - isLightTheme: true + themeState: {} }; static propTypes = { @@ -85,16 +80,15 @@ export default class DevtoolsInspector extends Component { static defaultProps = { select: (state) => state, supportImmutable: false, - theme: 'inspector' + theme: 'inspector', + isLightTheme: true }; shouldComponentUpdate = shouldPureComponentUpdate; componentWillMount() { - this.props.dispatch(updateMonitorState({ - ...createState(this.props), - ...createThemeState(this.props) - })); + this.props.dispatch(updateMonitorState(createState(this.props))); + this.setState({ themeState: createThemeState(this.props) }); } componentDidMount() { @@ -122,16 +116,13 @@ export default class DevtoolsInspector extends Component { this.props.monitorState.inspectedActionPath !== nextProps.monitorState.inspectedActionPath) { state = { ...state, ...createState(nextProps) }; - } - if (this.props.theme !== nextProps.theme || - this.props.isLightTheme !== nextProps.isLightTheme) { - - state = { ...state, ...createThemeState(nextProps) }; + nextProps.dispatch(updateMonitorState(state)); } - if (state !== nextProps.monitorState) { - nextProps.dispatch(updateMonitorState(state)); + if (this.props.theme !== nextProps.theme || + this.props.isLightTheme !== nextProps.isLightTheme) { + this.setState({ themeState: createThemeState(nextProps) }); } } @@ -139,8 +130,9 @@ export default class DevtoolsInspector extends Component { const { stagedActionIds: actionIds, actionsById: actions, monitorState, isLightTheme } = this.props; const { isWideLayout, selectedActionId, nextState, action, - searchValue, tab, delta, base16Theme, styling } = monitorState; + searchValue, tab, delta } = monitorState; const inspectedPathType = tab === 'Action' ? 'inspectedActionPath' : 'inspectedStatePath'; + const { base16Theme, styling } = this.state.themeState; return (
22 ? `${str.substr(0, 15)}…${str.substr(-5)}` : str; } +const returnEmptyString = () => ''; +const expandFirstLevel = (keyName, data, level) => level <= 1; + function prepareDelta(value) { if (value && value._t === 'a') { const res = {}; @@ -31,23 +34,49 @@ function prepareDelta(value) { } export default class JSONDiff extends Component { + state = { data: {} } + + componentDidMount() { + this.updateData(); + } + + componentDidUpdate(prevProps) { + if (prevProps.delta !== this.props.delta) { + this.updateData(); + } + } + + updateData() { + this.setState({ data: this.props.delta }); + } + render() { - const { delta, styling, base16Theme, ...props } = this.props; + const { styling, base16Theme, ...props } = this.props; + + if (!this.state.data) { + return ( +
+ (states are equal) +
+ ); + } return ( ''} - valueRenderer={(raw, value) => this.valueRenderer(raw, value, styling)} + data={this.state.data} + getItemString={returnEmptyString} + valueRenderer={this.valueRenderer} postprocessValue={prepareDelta} - isCustomNode={value => Array.isArray(value)} - shouldExpandNode={(keyName, data, level) => level <= 1} + isCustomNode={Array.isArray} + shouldExpandNode={expandFirstLevel} hideRoot /> ); } - valueRenderer(raw, value, styling) { + valueRenderer = (raw, value) => { + const { styling } = this.props; + function renderSpan(name, body) { return ( {body}