diff --git a/README.md b/README.md index 1265082..a72ff6f 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Name | Type | Description `tabs` | Array or function | Overrides list of tabs (see below) `diffObjectHash` | Function | Optional callback for better array handling in diffs (see [jsondiffpatch docs](https://github.com/benjamine/jsondiffpatch/blob/master/docs/arrays.md)) `diffPropertyFilter` | Function | Optional callback for ignoring particular props in diff (see [jsondiffpatch docs](https://github.com/benjamine/jsondiffpatch#options)) +`formatItem` | Function | Optional formatting function for JSON tree nodes. (see below) If `tabs` is a function, it receives a list of default tabs and should return updated list, for example: @@ -59,6 +60,11 @@ defaultTabs => [...defaultTabs, { name: 'My Tab', component: MyTab }] ``` If `tabs` is an array, only provided tabs are rendered. +`formatItem` is used for formatting labels of generated JSON tree nodes (see [react-json-tree](https://github.com/alexkuz/react-json-tree#customize-labels-for-arrays-objects-and-iterables)). It takes the following arguments: `type`, `data`, `isWideLayout` (`true` if the width of the inspector is greater than 500 px, `false` otherwise), `isDiff` (whether Diff is the active tab). It must return a `string` or `null`, in the latter case default formatting will be used. The following example overrides label formatting for Arrays in Action and State tabs: +``` +(type, data, isWideLayout, isDiff) => !isDiff && type === "Array" ? "// Array" : null +``` + `component` is provided with `action` and other props, see [`ActionPreview.jsx`](src/ActionPreview.jsx#L42) for reference. Usage example: [`redux-devtools-test-generator`](https://github.com/zalmoxisus/redux-devtools-test-generator#containersdevtoolsjs). diff --git a/src/ActionPreview.jsx b/src/ActionPreview.jsx index 395329a..e277198 100644 --- a/src/ActionPreview.jsx +++ b/src/ActionPreview.jsx @@ -6,14 +6,15 @@ import StateTab from './tabs/StateTab'; import ActionTab from './tabs/ActionTab'; import type { LabelRenderer } from 'react-json-tree'; -import type { Tab, TabName } from './types'; +import type { Tab, TabName, FormatItemFunction } from './types'; type DefaultProps = { tabName: TabName }; type Props = DefaultProps & { - tabs: ((defaultTabs: Tab[]) => Tab[]) | Tab[] + tabs: ((defaultTabs: Tab[]) => Tab[]) | Tab[], + formatItem: FormatItemFunction, }; const DEFAULT_TABS: Tab[] = [{ @@ -36,7 +37,7 @@ class ActionPreview extends Component { const { styling, delta, error, nextState, onInspectPath, inspectedPath, tabName, isWideLayout, onSelectTab, action, actions, selectedActionId, startActionId, - computedStates, base16Theme, invertTheme, tabs + computedStates, base16Theme, invertTheme, tabs, formatItem } = this.props; const renderedTabs = (typeof tabs === 'function') ? @@ -70,6 +71,7 @@ class ActionPreview extends Component { base16Theme, invertTheme, isWideLayout, + formatItem, delta, action, nextState diff --git a/src/DevtoolsInspector.js b/src/DevtoolsInspector.js index e305af0..a7d4271 100644 --- a/src/DevtoolsInspector.js +++ b/src/DevtoolsInspector.js @@ -172,7 +172,7 @@ export default class DevtoolsInspector extends PureComponent { } getItemString = (type: string, data: any) => { - return getItemString(this.props.styling, type, data, this.props.isWideLayout); + const { styling, isWideLayout, formatItem } = this.props; + return getItemString(styling, type, data, isWideLayout, false, formatItem); }; } diff --git a/src/tabs/DiffTab.jsx b/src/tabs/DiffTab.jsx index bfed13d..92ba8ce 100644 --- a/src/tabs/DiffTab.jsx +++ b/src/tabs/DiffTab.jsx @@ -5,6 +5,7 @@ import JSONDiff from './JSONDiff'; import type { LabelRenderer } from 'react-json-tree'; import type { Delta } from 'jsondiffpatch'; import type { StylingFunction, Base16Theme } from 'react-base16-styling'; +import type { FormatItemFunction } from '../types'; type Props = { delta: Delta, @@ -12,14 +13,15 @@ type Props = { base16Theme: Base16Theme, invertTheme: boolean, labelRenderer: LabelRenderer, - isWideLayout: boolean + isWideLayout: boolean, + formatItem: FormatItemFunction }; const DiffTab = ( - { delta, styling, base16Theme, invertTheme, labelRenderer, isWideLayout }: Props + { delta, styling, base16Theme, invertTheme, labelRenderer, isWideLayout, formatItem }: Props ): React$Element<*> => ; export default DiffTab; diff --git a/src/tabs/JSONDiff.jsx b/src/tabs/JSONDiff.jsx index 9d5fc1d..783d608 100644 --- a/src/tabs/JSONDiff.jsx +++ b/src/tabs/JSONDiff.jsx @@ -8,6 +8,7 @@ import getJsonTreeTheme from './getJsonTreeTheme'; import type { LabelRenderer } from 'react-json-tree'; import type { Delta, ArrayDelta } from 'jsondiffpatch'; import type { StylingFunction, Base16Theme, StylingConfig } from 'react-base16-styling'; +import type { FormatItemFunction } from '../types'; type Props = { delta: Delta, @@ -15,7 +16,8 @@ type Props = { base16Theme: Base16Theme, invertTheme: boolean, labelRenderer: LabelRenderer, - isWideLayout: boolean + isWideLayout: boolean, + formatItem: FormatItemFunction }; type State = { @@ -138,6 +140,7 @@ export default class JSONDiff extends PureComponent { } getItemString = (type: string, data: any) => { - return getItemString(this.props.styling, type, data, this.props.isWideLayout, true); + const { styling, isWideLayout, formatItem } = this.props; + return getItemString(styling, type, data, isWideLayout, true, formatItem); }; } diff --git a/src/tabs/StateTab.jsx b/src/tabs/StateTab.jsx index 4a420f3..17149da 100644 --- a/src/tabs/StateTab.jsx +++ b/src/tabs/StateTab.jsx @@ -6,6 +6,7 @@ import getJsonTreeTheme from './getJsonTreeTheme'; import type { LabelRenderer } from 'react-json-tree'; import type { StylingFunction, Base16Theme, StylingConfig } from 'react-base16-styling'; +import type { FormatItemFunction } from '../types'; type Props = { styling: StylingFunction, @@ -13,6 +14,7 @@ type Props = { invertTheme: boolean, labelRenderer: LabelRenderer, isWideLayout: boolean, + formatItem: FormatItemFunction, nextState: Object }; @@ -53,6 +55,7 @@ export default class StateTab extends PureComponent { } getItemString = (type: string, data: any) => { - return getItemString(this.props.styling, type, data, this.props.isWideLayout); + const { styling, isWideLayout, formatItem } = this.props; + return getItemString(styling, type, data, isWideLayout, false, formatItem); }; } diff --git a/src/tabs/getItemString.js b/src/tabs/getItemString.js index 04ebbbd..e9e56b2 100644 --- a/src/tabs/getItemString.js +++ b/src/tabs/getItemString.js @@ -3,6 +3,7 @@ import React from 'react'; import getType from '../utils/getType'; import type { StylingFunction } from 'react-base16-styling'; +import type { FormatItemFunction } from '../types'; function getShortTypeString(val: any, diff?: boolean): string { const type = getType(val); @@ -130,10 +131,12 @@ const getItemString = ( type: string, data: Object, isWideLayout: boolean, - isDiff: boolean = false + isDiff: boolean = false, + formatItem?: FormatItemFunction, ): React$Element<*> => - {getText(type, data, isWideLayout, isDiff)} + {(formatItem && formatItem(type, data, isWideLayout, isDiff)) || + getText(type, data, isWideLayout, isDiff)} ; export default getItemString; diff --git a/src/types.js b/src/types.js index abf25fd..289f0c5 100644 --- a/src/types.js +++ b/src/types.js @@ -20,3 +20,5 @@ export type ReduxState = { export type MonitorState = { initialScrollTop: number }; + +export type FormatItemFunction = () => string | null