From 05e345bf4b1064975ba7c264f970c7a73f680635 Mon Sep 17 00:00:00 2001 From: amcdnl Date: Tue, 16 Apr 2024 08:03:50 -0400 Subject: [PATCH] json tree theme --- docs/components/layout/JsonTree.mdx | 26 +++++ src/layout/Tree/JsonTree/JsonTree.story.tsx | 119 ++++++++++++++++++-- src/layout/Tree/JsonTree/JsonTree.tsx | 43 +++++++ src/layout/Tree/JsonTree/JsonTreeNode.tsx | 34 +++++- src/layout/Tree/JsonTree/JsonTreeTheme.ts | 1 + 5 files changed, 206 insertions(+), 17 deletions(-) create mode 100644 docs/components/layout/JsonTree.mdx diff --git a/docs/components/layout/JsonTree.mdx b/docs/components/layout/JsonTree.mdx new file mode 100644 index 00000000..89071f15 --- /dev/null +++ b/docs/components/layout/JsonTree.mdx @@ -0,0 +1,26 @@ +import { Meta, Canvas, ArgTypes } from '@storybook/addon-docs'; +import { jsonTreeTheme, JsonTree, JsonTreeNode } from '../../../src/layout/Tree'; +import * as TreeStories from '../../../src/layout/Tree/JsonTree/JsonTree.story.tsx'; +import ThemeRender from '../../ThemeRender.tsx'; + + + +# Json Tree +Tree component designed for showing JSON data. + +## Example + + +## Theme +This component uses the following default theme: + + + +Learn more about how to customize in the [Theme documentation](?path=/docs/docs-theme-getting-started--docs). + +## API +### Tree + + +### TreeNode + diff --git a/src/layout/Tree/JsonTree/JsonTree.story.tsx b/src/layout/Tree/JsonTree/JsonTree.story.tsx index cc784bb0..d56f3746 100644 --- a/src/layout/Tree/JsonTree/JsonTree.story.tsx +++ b/src/layout/Tree/JsonTree/JsonTree.story.tsx @@ -6,16 +6,113 @@ export default { components: JsonTree }; -const data = { - name: 'John Doe', - age: 30, - over21: true, - children: [ - { name: 'Jane Doe', age: 25 }, - { name: 'Jim Doe', age: 33 } - ] -}; +export const Simple = () => ( + +); -export const Simple = () => ; +export const Expanded = () => ( + +); -export const Expanded = () => ; +export const Complex = () => ( + +); diff --git a/src/layout/Tree/JsonTree/JsonTree.tsx b/src/layout/Tree/JsonTree/JsonTree.tsx index 032d92a8..c6244320 100644 --- a/src/layout/Tree/JsonTree/JsonTree.tsx +++ b/src/layout/Tree/JsonTree/JsonTree.tsx @@ -4,15 +4,54 @@ import { JsonTreeNode } from './JsonTreeNode'; import { parseJsonTree } from './utils'; export interface JsonTreeProps { + /** + * The data to be rendered as a JSON tree. + */ data: { [key: string]: any }; + + /** + * If true, all nodes in the JSON tree will be expanded by default. + */ showAll?: boolean; + + /** + * The limit for the number of nodes to show when `showAll` is true. + */ showAllLimit?: number; + + /** + * The threshold for the number of nodes at which `showAll` will take effect. + */ showAllThreshold?: number; + + /** + * If true, the count of child nodes will be shown next to each node. + */ showCount?: boolean; + + /** + * If true, empty nodes will be shown in the JSON tree. + */ showEmpty?: boolean; + + /** + * If true, long text in nodes will be truncated and replaced with an ellipsis. + */ ellipsisText?: boolean; + + /** + * The maximum length of text in a node before it is truncated and replaced with an ellipsis. + */ ellipsisTextLength?: number; + + /** + * The depth at which the JSON tree nodes should be expanded by default. + */ expandDepth?: number; + + /** + * The CSS class name to be applied to the JSON tree. + */ className?: string; } @@ -20,6 +59,8 @@ export const JsonTree: FC = ({ data, className, expandDepth, + ellipsisText, + ellipsisTextLength, ...rest }) => { const tree = parseJsonTree({ data }); @@ -32,6 +73,8 @@ export const JsonTree: FC = ({ depth={1} data={tree} expandDepth={expandDepth} + ellipsisText={ellipsisText} + ellipsisTextLength={ellipsisTextLength} /> diff --git a/src/layout/Tree/JsonTree/JsonTreeNode.tsx b/src/layout/Tree/JsonTree/JsonTreeNode.tsx index fa4ee47b..74cda9d1 100644 --- a/src/layout/Tree/JsonTree/JsonTreeNode.tsx +++ b/src/layout/Tree/JsonTree/JsonTreeNode.tsx @@ -4,6 +4,7 @@ import { JsonTreeData } from './utils'; import { useComponentTheme } from '../../../utils/Theme/hooks'; import { JsonTreeTheme } from './JsonTreeTheme'; import { twMerge } from 'tailwind-merge'; +import { Ellipsis } from '../../../data/Ellipsis'; export interface JsonTreeNodeProps { /** @@ -30,6 +31,16 @@ export interface JsonTreeNodeProps { * Theme for the Json Tree */ theme?: JsonTreeTheme; + + /** + * If true, long text in nodes will be truncated and replaced with an ellipsis. + */ + ellipsisText?: boolean; + + /** + * The maximum length of text in a node before it is truncated and replaced with an ellipsis. + */ + ellipsisTextLength?: number; } export const JsonTreeNode: FC = ({ @@ -37,6 +48,8 @@ export const JsonTreeNode: FC = ({ data, expandDepth, className, + ellipsisText, + ellipsisTextLength, theme: customTheme }) => { const theme = useComponentTheme('jsonTree', customTheme); @@ -49,22 +62,29 @@ export const JsonTreeNode: FC = ({ <> {data.label} {symbol} - {`(${data.data.length.toLocaleString()} ${label})`} + + {`(${data.data.length.toLocaleString()} ${label})`} + ); - }, [data]); + }, [data, theme, type]); const renderPrimativeNode = useCallback(() => { + const ellipsis = type === 'string' && ellipsisText; return ( <> {data.label} : - {`${data.data}`} + + {ellipsis ? ( + + ) : ( + data.data + )} + ); - }, [data]); + }, [data, ellipsisText, ellipsisTextLength, theme, type]); return ( = ({ depth={depth + 1} expandDepth={expandDepth} type={item.type} + ellipsisText={ellipsisText} + ellipsisTextLength={ellipsisTextLength} /> ))} diff --git a/src/layout/Tree/JsonTree/JsonTreeTheme.ts b/src/layout/Tree/JsonTree/JsonTreeTheme.ts index 5c101621..5d22d882 100644 --- a/src/layout/Tree/JsonTree/JsonTreeTheme.ts +++ b/src/layout/Tree/JsonTree/JsonTreeTheme.ts @@ -1,5 +1,6 @@ export interface JsonTreeTheme { node: { + base: string; label: string; value: string; delimiter: string;