shouldExpandNode => shouldExpandNodeInitially

This commit is contained in:
Nathan Bierema 2023-01-03 09:05:13 -05:00
parent 9c4307780f
commit 5175bc0a00
4 changed files with 83 additions and 123 deletions

View File

@ -35,6 +35,7 @@ const JSONIterableNode: React.FunctionComponent<Props> = ({ ...props }) => {
nodeType="Iterable"
nodeTypeIndicator="()"
createItemString={createItemString}
expandable
/>
);
};

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useCallback, useState } from 'react';
import JSONArrow from './JSONArrow';
import getCollectionEntries from './getCollectionEntries';
import JSONNode from './JSONNode';
@ -91,74 +91,39 @@ interface Props extends CommonInternalProps {
nodeTypeIndicator: string;
createItemString: (data: any, collectionLimit: number) => string;
expandable: boolean;
circularCache: CircularCache;
level: number;
}
interface State {
expanded: boolean;
}
function getStateFromProps(props: Props) {
// calculate individual node expansion if necessary
const expanded = !props.isCircular
? props.shouldExpandNode(props.keyPath, props.data, props.level)
: false;
return {
expanded,
};
}
export default class JSONNestedNode extends React.Component<Props, State> {
static defaultProps = {
data: [],
circularCache: [],
level: 0,
expandable: true,
};
constructor(props: Props) {
super(props);
this.state = getStateFromProps(props);
}
UNSAFE_componentWillReceiveProps(nextProps: Props) {
const nextState = getStateFromProps(nextProps);
if (getStateFromProps(this.props).expanded !== nextState.expanded) {
this.setState(nextState);
}
}
shouldComponentUpdate(nextProps: Props, nextState: State) {
return (
!!Object.keys(nextProps).find(
(key) =>
key !== 'circularCache' &&
(key === 'keyPath'
? nextProps[key].join('/') !== this.props[key].join('/')
: nextProps[key as keyof Props] !== this.props[key as keyof Props])
) || nextState.expanded !== this.state.expanded
);
}
render() {
export default function JSONNestedNode(props: Props) {
const {
getItemString,
nodeTypeIndicator,
nodeType,
data,
hideRoot,
createItemString,
styling,
circularCache = [],
collectionLimit,
createItemString,
data,
expandable,
getItemString,
hideRoot,
isCircular,
keyPath,
labelRenderer,
expandable,
} = this.props;
const { expanded } = this.state;
level = 0,
nodeType,
nodeTypeIndicator,
shouldExpandNodeInitially,
styling,
} = props;
const [expanded, setExpanded] = useState<boolean>(
// calculate individual node expansion if necessary
isCircular ? false : shouldExpandNodeInitially(keyPath, data, level)
);
const handleClick = useCallback(() => {
if (expandable) setExpanded(!expanded);
}, [expandable, expanded]);
const renderedChildren =
expanded || (hideRoot && this.props.level === 0)
? renderChildNodes({ ...this.props, level: this.props.level + 1 })
expanded || (hideRoot && level === 0)
? renderChildNodes({ ...props, circularCache, level: level + 1 })
: null;
const itemType = (
@ -188,18 +153,18 @@ export default class JSONNestedNode extends React.Component<Props, State> {
styling={styling}
nodeType={nodeType}
expanded={expanded}
onClick={this.handleClick}
onClick={handleClick}
/>
)}
<label
{...styling(['label', 'nestedNodeLabel'], ...stylingArgs)}
onClick={this.handleClick}
onClick={handleClick}
>
{labelRenderer(...stylingArgs)}
</label>
<span
{...styling('nestedNodeItemString', ...stylingArgs)}
onClick={this.handleClick}
onClick={handleClick}
>
{renderedItemString}
</span>
@ -208,11 +173,4 @@ export default class JSONNestedNode extends React.Component<Props, State> {
</ul>
</li>
);
}
handleClick = () => {
if (this.props.expandable) {
this.setState({ expanded: !this.state.expanded });
}
};
}

View File

@ -13,7 +13,7 @@ import type {
GetItemString,
IsCustomNode,
LabelRenderer,
ShouldExpandNode,
ShouldExpandNodeInitially,
} from './types';
interface Props extends Partial<CommonExternalProps> {
@ -23,7 +23,8 @@ interface Props extends Partial<CommonExternalProps> {
}
const identity = (value: any) => value;
const expandRootNode: ShouldExpandNode = (keyPath, data, level) => level === 0;
const expandRootNode: ShouldExpandNodeInitially = (keyPath, data, level) =>
level === 0;
const defaultItemString: GetItemString = (type, data, itemType, itemString) => (
<span>
{itemType} {itemString}
@ -39,7 +40,7 @@ export function JSONTree({
keyPath = ['root'],
labelRenderer = defaultLabelRenderer,
valueRenderer = identity,
shouldExpandNode = expandRootNode,
shouldExpandNodeInitially = expandRootNode,
hideRoot = false,
getItemString = defaultItemString,
postprocessValue = identity,
@ -62,7 +63,7 @@ export function JSONTree({
styling={styling}
labelRenderer={labelRenderer}
valueRenderer={valueRenderer}
shouldExpandNode={shouldExpandNode}
shouldExpandNodeInitially={shouldExpandNodeInitially}
hideRoot={hideRoot}
getItemString={getItemString}
postprocessValue={postprocessValue}

View File

@ -26,7 +26,7 @@ export type ValueRenderer = (
...keyPath: KeyPath
) => React.ReactNode;
export type ShouldExpandNode = (
export type ShouldExpandNodeInitially = (
keyPath: KeyPath,
data: any,
level: number
@ -46,7 +46,7 @@ export interface CommonExternalProps {
keyPath: KeyPath;
labelRenderer: LabelRenderer;
valueRenderer: ValueRenderer;
shouldExpandNode: ShouldExpandNode;
shouldExpandNodeInitially: ShouldExpandNodeInitially;
hideRoot: boolean;
getItemString: GetItemString;
postprocessValue: PostprocessValue;