2021-11-08 08:48:23 +03:00
|
|
|
import { createSelector, Selector } from '@reduxjs/toolkit';
|
2021-08-26 22:33:06 +03:00
|
|
|
import React, { ComponentProps, ReactNode } from 'react';
|
2022-01-10 18:41:53 +03:00
|
|
|
import { JSONTree } from 'react-json-tree';
|
2023-12-14 03:45:53 +03:00
|
|
|
import { Base16Theme } from 'react-base16-styling';
|
|
|
|
import { getJsonTreeTheme, StyleUtilsContext } from '../styles/themes';
|
|
|
|
import { getItemString, labelRenderer } from '../styles/tree';
|
2021-08-26 22:33:06 +03:00
|
|
|
import { identity } from '../utils/object';
|
|
|
|
|
|
|
|
export interface TreeViewProps
|
|
|
|
extends Partial<
|
|
|
|
Pick<
|
|
|
|
ComponentProps<typeof JSONTree>,
|
2023-01-05 07:17:44 +03:00
|
|
|
'keyPath' | 'shouldExpandNodeInitially' | 'hideRoot'
|
2021-08-26 22:33:06 +03:00
|
|
|
>
|
|
|
|
> {
|
|
|
|
data: unknown;
|
|
|
|
isWideLayout: boolean;
|
|
|
|
before?: ReactNode;
|
|
|
|
after?: ReactNode;
|
|
|
|
children?: ReactNode;
|
2022-07-05 16:31:38 +03:00
|
|
|
rootProps?: Partial<
|
|
|
|
Omit<React.HTMLAttributes<HTMLDivElement>, 'className' | 'style'>
|
|
|
|
>;
|
2021-08-26 22:33:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
export class TreeView extends React.PureComponent<TreeViewProps> {
|
|
|
|
static defaultProps = {
|
|
|
|
hideRoot: true,
|
2023-01-05 07:17:44 +03:00
|
|
|
shouldExpandNodeInitially: (
|
2021-08-26 22:33:06 +03:00
|
|
|
keyPath: (string | number)[],
|
|
|
|
value: unknown,
|
2023-07-12 21:03:20 +03:00
|
|
|
layer: number,
|
2021-08-26 22:33:06 +03:00
|
|
|
): boolean => {
|
|
|
|
return layer < 2;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-11-08 08:48:23 +03:00
|
|
|
readonly selectTheme: Selector<
|
|
|
|
Base16Theme,
|
|
|
|
ReturnType<typeof getJsonTreeTheme>,
|
|
|
|
never
|
|
|
|
> = createSelector<
|
2021-11-01 16:59:32 +03:00
|
|
|
[(base16Theme: Base16Theme) => Base16Theme],
|
2021-08-26 22:33:06 +03:00
|
|
|
ReturnType<typeof getJsonTreeTheme>
|
|
|
|
>(identity, getJsonTreeTheme);
|
|
|
|
|
|
|
|
constructor(props: TreeViewProps) {
|
|
|
|
super(props);
|
|
|
|
}
|
|
|
|
|
|
|
|
render(): ReactNode {
|
|
|
|
const {
|
|
|
|
data,
|
|
|
|
before,
|
|
|
|
after,
|
|
|
|
children,
|
|
|
|
keyPath,
|
2023-01-05 07:17:44 +03:00
|
|
|
shouldExpandNodeInitially,
|
2021-08-26 22:33:06 +03:00
|
|
|
hideRoot,
|
2022-07-05 16:31:38 +03:00
|
|
|
rootProps,
|
2021-08-26 22:33:06 +03:00
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<StyleUtilsContext.Consumer>
|
2023-12-14 03:45:53 +03:00
|
|
|
{({ invertTheme, base16Theme }) => {
|
2021-08-26 22:33:06 +03:00
|
|
|
return (
|
2023-12-14 03:45:53 +03:00
|
|
|
<div
|
|
|
|
{...rootProps}
|
|
|
|
css={{
|
|
|
|
overflowX: 'auto',
|
|
|
|
overflowY: 'auto',
|
|
|
|
padding: '0.5em 1em',
|
|
|
|
}}
|
|
|
|
>
|
2021-08-26 22:33:06 +03:00
|
|
|
{before}
|
|
|
|
<JSONTree
|
|
|
|
keyPath={keyPath}
|
2023-01-05 07:17:44 +03:00
|
|
|
shouldExpandNodeInitially={shouldExpandNodeInitially}
|
2021-08-26 22:33:06 +03:00
|
|
|
data={data}
|
2023-12-14 03:45:53 +03:00
|
|
|
labelRenderer={labelRenderer}
|
2021-08-26 22:33:06 +03:00
|
|
|
theme={this.selectTheme(base16Theme)}
|
|
|
|
invertTheme={invertTheme}
|
2023-12-14 03:45:53 +03:00
|
|
|
getItemString={getItemString}
|
2021-08-26 22:33:06 +03:00
|
|
|
hideRoot={hideRoot}
|
|
|
|
/>
|
|
|
|
{after}
|
|
|
|
{children}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
</StyleUtilsContext.Consumer>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|