Skip to content

Commit 4121baf

Browse files
committed
feat: add json tree
1 parent 0781b37 commit 4121baf

6 files changed

Lines changed: 110 additions & 2 deletions

File tree

.changeset/thin-cougars-fly.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@tanstack/react-devtools': minor
3+
'@tanstack/solid-devtools': minor
4+
'@tanstack/devtools-ui': minor
5+
---
6+
7+
Added json tree to devtools-ui and adjusted the width for the plugin renderers
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { For } from "solid-js";
2+
import { useStyles } from "../styles/use-styles";
3+
4+
export function JsonTree(props: { value: any }){
5+
return <JsonValue isRoot value={props.value} />
6+
}
7+
8+
export function JsonValue(props: { value: any; keyName?: string, isRoot?: boolean }) {
9+
const { value, keyName, isRoot = false } = props;
10+
const styles = useStyles();
11+
12+
if (typeof value === 'string') {
13+
return <span class={styles().tree.valueContainer(isRoot)}>
14+
<span>{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
15+
<span class={styles().tree.valueString}>&quot;{value}&quot;</span></span>
16+
<span>,</span>
17+
</span>;
18+
}
19+
if (typeof value === 'number') {
20+
return <span class={styles().tree.valueContainer(isRoot)}>
21+
<span>{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
22+
<span class={styles().tree.valueNumber}>{value}</span></span>
23+
<span>,</span>
24+
</span>;
25+
}
26+
if (typeof value === 'boolean') {
27+
return <span class={styles().tree.valueContainer(isRoot)}>
28+
<span>
29+
{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
30+
<span class={styles().tree.valueBoolean}>{String(value)}</span>
31+
</span>
32+
<span>,</span>
33+
</span>;
34+
}
35+
if (value === null) {
36+
return <span class={styles().tree.valueContainer(isRoot)}>
37+
<span>{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
38+
<span class={styles().tree.valueNull}>null</span></span>
39+
<span>,</span>
40+
</span>;
41+
}
42+
if (value === undefined) {
43+
return <span class={styles().tree.valueContainer(isRoot)}>
44+
<span>{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
45+
<span class={styles().tree.valueNull}>undefined</span></span>
46+
<span>,</span>
47+
</span>;
48+
}
49+
if (Array.isArray(value)) {
50+
return <span class={styles().tree.valueContainer(isRoot)}>
51+
<span>{keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
52+
<span class={styles().tree.valueBraces}>[</span>
53+
<For each={value}>{(item) => <>
54+
<JsonValue value={item} />
55+
</>}
56+
</For>
57+
<span class={styles().tree.valueBraces}>]</span></span>
58+
<span>,</span>
59+
</span>;
60+
}
61+
if (typeof value === 'object') {
62+
const keys = Object.keys(value);
63+
return <span class={styles().tree.valueContainer(isRoot)}>
64+
<span> {keyName && <span class={styles().tree.valueKey}>&quot;{keyName}&quot;: </span>}
65+
<span class={styles().tree.valueBraces}>{'{'}</span>
66+
<For each={keys}>{(k,) => <>
67+
<JsonValue value={value[k]} keyName={k} />
68+
</>}
69+
</For>
70+
<span class={styles().tree.valueBraces}>{'}'}</span></span>
71+
72+
</span>;
73+
}
74+
return <span />;
75+
}

packages/devtools-ui/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { Checkbox } from './components/checkbox'
22
export { Input } from './components/input'
33
export { Select } from './components/select'
44
export { TanStackLogo } from './components/logo'
5+
export { JsonTree } from './components/tree'

packages/devtools-ui/src/styles/use-styles.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,31 @@ const stylesFactory = () => {
186186
font-size: 0.8rem;
187187
line-height: 1.3;
188188
`,
189+
tree: {
190+
valueString: css`
191+
color: ${colors.green[400]};
192+
`,
193+
valueNumber: css`
194+
color: ${colors.yellow[400]};
195+
`,
196+
valueBoolean: css`
197+
color: ${colors.pink[400]};
198+
`,
199+
valueNull: css`
200+
color: ${colors.gray[400]};
201+
font-style: italic;
202+
`,
203+
valueKey: css`
204+
color: ${colors.blue[300]};
205+
`,
206+
valueBraces: css`
207+
color: ${colors.gray[500]};
208+
`,
209+
valueContainer: (isRoot: boolean) => css`
210+
display: block;
211+
margin-left: ${isRoot ? '0' : '1rem'};
212+
`
213+
}
189214
}
190215
}
191216

packages/react-devtools/src/devtools.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ export const TanstackDevtools = ({
153153

154154
return (
155155
<>
156-
<div ref={devToolRef} />
156+
<div style={{height: "100%"}} ref={devToolRef} />
157157
{pluginContainer && PluginComponent
158158
? createPortal(<>{PluginComponent}</>, pluginContainer)
159159
: null}

packages/solid-devtools/src/devtools.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,5 @@ export const TanstackDevtools = ({
126126
})
127127
}
128128
})
129-
return <div ref={devToolRef} />
129+
return <div style={{height: '100%'}} ref={devToolRef} />
130130
}

0 commit comments

Comments
 (0)