diff --git a/packages/react-json-tree/src/index.tsx b/packages/react-json-tree/src/index.tsx index c422b9ce..3b3a729c 100644 --- a/packages/react-json-tree/src/index.tsx +++ b/packages/react-json-tree/src/index.tsx @@ -3,13 +3,12 @@ // Dave Vedder http://www.eskimospy.com/ // port by Daniele Zannotti http://www.github.com/dzannotti -import React from 'react'; +import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; import JSONNode from './JSONNode'; import createStylingFromTheme from './createStylingFromTheme'; import { invertTheme, - StylingConfig, StylingFunction, StylingValue, Theme, @@ -47,133 +46,56 @@ const defaultLabelRenderer = ([label]: (string | number)[]) => ( ); const noCustomNode = () => false; -function checkLegacyTheming(theme: Theme | undefined, props: Props) { - const deprecatedStylingMethodsMap = { - getArrowStyle: 'arrow', - getListStyle: 'nestedNodeChildren', - getItemStringStyle: 'nestedNodeItemString', - getLabelStyle: 'label', - getValueStyle: 'valueText', - }; +export function JSONTree(props: Props) { + const { + data: value, + keyPath = ['root'], + postprocessValue = identity, + hideRoot = false, + theme, + invertTheme: invertThemeProp, + shouldExpandNode = expandRootNode, + getItemString = defaultItemString, + labelRenderer = defaultLabelRenderer, + valueRenderer = identity, + isCustomNode = noCustomNode, + collectionLimit = 50, + } = props; - const deprecatedStylingMethods = Object.keys( - deprecatedStylingMethodsMap - ).filter((name) => props[name as keyof Props]); + const styling = useMemo(() => { + const finalTheme = invertThemeProp ? invertTheme(theme) : theme; + return createStylingFromTheme(finalTheme); + }, [theme, invertThemeProp]); - if (deprecatedStylingMethods.length > 0) { - if (typeof theme === 'string') { - theme = { - extend: theme, - }; - } else { - theme = { ...theme }; - } - - deprecatedStylingMethods.forEach((name) => { - // eslint-disable-next-line no-console - console.error( - `Styling method "${name}" is deprecated, use "theme" property instead` - ); - - (theme as StylingConfig)[ - deprecatedStylingMethodsMap[ - name as keyof typeof deprecatedStylingMethodsMap - ] - ] = ({ style }, ...args) => ({ - style: { - ...style, - ...props[name as keyof Props](...args), - }, - }); - }); - } - - return theme; + return ( + + ); } -function getStateFromProps(props: Props) { - let theme = checkLegacyTheming(props.theme, props); - if (props.invertTheme) { - theme = invertTheme(theme); - } - - return { - styling: createStylingFromTheme(theme), - }; -} - -export class JSONTree extends React.Component { - static propTypes = { - data: PropTypes.any, - hideRoot: PropTypes.bool, - theme: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - invertTheme: PropTypes.bool, - keyPath: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.string, PropTypes.number]) - ), - postprocessValue: PropTypes.func, - sortObjectKeys: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), - }; - - static defaultProps = { - shouldExpandNode: expandRootNode, - hideRoot: false, - keyPath: ['root'], - getItemString: defaultItemString, - labelRenderer: defaultLabelRenderer, - valueRenderer: identity, - postprocessValue: identity, - isCustomNode: noCustomNode, - collectionLimit: 50, - invertTheme: true, - }; - - constructor(props: Props) { - super(props); - this.state = getStateFromProps(props); - } - - UNSAFE_componentWillReceiveProps(nextProps: Props) { - if ( - ['theme', 'invertTheme'].find( - (k) => nextProps[k as keyof Props] !== this.props[k as keyof Props] - ) - ) { - this.setState(getStateFromProps(nextProps)); - } - } - - shouldComponentUpdate(nextProps: Props) { - return !!Object.keys(nextProps).find((k) => - k === 'keyPath' - ? nextProps[k].join('/') !== this.props[k].join('/') - : nextProps[k as keyof Props] !== this.props[k as keyof Props] - ); - } - - render() { - const { - data: value, - keyPath, - postprocessValue, - hideRoot, - theme, // eslint-disable-line no-unused-vars - invertTheme: _, // eslint-disable-line no-unused-vars - ...rest - } = this.props; - - const { styling } = this.state; - - return ( -
    - -
- ); - } -} +JSONTree.propTypes = { + data: PropTypes.any, + hideRoot: PropTypes.bool, + theme: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + invertTheme: PropTypes.bool, + keyPath: PropTypes.arrayOf( + PropTypes.oneOfType([PropTypes.string, PropTypes.number]) + ), + postprocessValue: PropTypes.func, + sortObjectKeys: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), +}; export { StylingValue };