Skip to content

Commit c1f18d9

Browse files
committed
feat(devtools-ui): jsonTree collapsible path
1 parent 39aa447 commit c1f18d9

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

packages/devtools-ui/src/components/tree.tsx

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import { For, Match, Show, Switch, createSignal } from 'solid-js'
22
import clsx from 'clsx'
33
import { css, useStyles } from '../styles/use-styles'
44
import { CopiedCopier, Copier, ErrorCopier } from './icons'
5+
import type { DeepKeys } from '../utils/deep-keys'
56

6-
export function JsonTree(props: {
7-
value: any
7+
export function JsonTree<TData, TName extends DeepKeys<TData>>(props: {
8+
value: TData
89
copyable?: boolean
910
defaultExpansionDepth?: number
11+
collapsePath?: TName
1012
}) {
1113
return (
1214
<JsonValue
@@ -15,6 +17,8 @@ export function JsonTree(props: {
1517
copyable={props.copyable}
1618
depth={0}
1719
defaultExpansionDepth={props.defaultExpansionDepth ?? 1}
20+
path=""
21+
collapsePath={props.collapsePath}
1822
/>
1923
)
2024
}
@@ -25,8 +29,12 @@ function JsonValue(props: {
2529
isRoot?: boolean
2630
isLastKey?: boolean
2731
copyable?: boolean
32+
2833
defaultExpansionDepth: number
2934
depth: number
35+
36+
collapsePath?: string
37+
path: string
3038
}) {
3139
const {
3240
value,
@@ -36,9 +44,13 @@ function JsonValue(props: {
3644
copyable,
3745
defaultExpansionDepth,
3846
depth,
47+
collapsePath,
48+
path,
3949
} = props
4050
const styles = useStyles()
4151

52+
console.log('path jsonval', path, collapsePath)
53+
4254
return (
4355
<span class={styles().tree.valueContainer(isRoot)}>
4456
{keyName && typeof value !== 'object' && !Array.isArray(value) && (
@@ -75,6 +87,8 @@ function JsonValue(props: {
7587
copyable={copyable}
7688
keyName={keyName}
7789
value={value}
90+
collapsePath={collapsePath}
91+
path={path}
7892
/>
7993
)
8094
}
@@ -86,6 +100,8 @@ function JsonValue(props: {
86100
copyable={copyable}
87101
keyName={keyName}
88102
value={value}
103+
collapsePath={collapsePath}
104+
path={path}
89105
/>
90106
)
91107
}
@@ -107,15 +123,22 @@ const ArrayValue = ({
107123
copyable,
108124
defaultExpansionDepth,
109125
depth,
126+
collapsePath,
127+
path,
110128
}: {
111129
value: Array<any>
112130
copyable?: boolean
113131
keyName?: string
114132
defaultExpansionDepth: number
115133
depth: number
134+
collapsePath?: string
135+
path: string
116136
}) => {
117137
const styles = useStyles()
118-
const [expanded, setExpanded] = createSignal(depth <= defaultExpansionDepth)
138+
139+
const [expanded, setExpanded] = createSignal(
140+
depth <= defaultExpansionDepth && collapsePath !== path,
141+
)
119142

120143
if (value.length === 0) {
121144
return (
@@ -161,12 +184,15 @@ const ArrayValue = ({
161184
isLastKey={isLastKey}
162185
defaultExpansionDepth={defaultExpansionDepth}
163186
depth={depth + 1}
187+
collapsePath={collapsePath}
188+
path={path ? `${path}[${i()}]` : `[${i()}]`}
164189
/>
165190
)
166191
}}
167192
</For>
168193
</span>
169194
</Show>
195+
170196
<Show when={!expanded()}>
171197
<span
172198
onClick={(e) => {
@@ -190,15 +216,23 @@ const ObjectValue = ({
190216
copyable,
191217
defaultExpansionDepth,
192218
depth,
219+
collapsePath,
220+
path,
193221
}: {
194222
value: Record<string, any>
195223
keyName?: string
196224
copyable?: boolean
197225
defaultExpansionDepth: number
198226
depth: number
227+
collapsePath?: string
228+
path: string
199229
}) => {
200230
const styles = useStyles()
201-
const [expanded, setExpanded] = createSignal(depth <= defaultExpansionDepth)
231+
232+
const [expanded, setExpanded] = createSignal(
233+
depth <= defaultExpansionDepth && collapsePath !== path,
234+
)
235+
202236
const keys = Object.keys(value)
203237
const lastKeyName = keys[keys.length - 1]
204238

@@ -214,6 +248,7 @@ const ObjectValue = ({
214248
</span>
215249
)
216250
}
251+
217252
return (
218253
<span class={styles().tree.expanderContainer}>
219254
{keyName && (
@@ -248,12 +283,15 @@ const ObjectValue = ({
248283
copyable={copyable}
249284
defaultExpansionDepth={defaultExpansionDepth}
250285
depth={depth + 1}
286+
collapsePath={collapsePath}
287+
path={`${path}${path ? '.' : ''}${k}`}
251288
/>
252289
</>
253290
)}
254291
</For>
255292
</span>
256293
</Show>
294+
257295
<Show when={!expanded()}>
258296
<span
259297
onClick={(e) => {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export type CollapsibleKeys<T, TPrefix extends string = ''> =
2+
T extends ReadonlyArray<infer U>
3+
?
4+
| (TPrefix extends '' ? '' : TPrefix)
5+
| CollapsibleKeys<U, `${TPrefix}[${number}]`>
6+
: T extends object
7+
?
8+
| (TPrefix extends '' ? '' : TPrefix)
9+
| {
10+
[K in Extract<keyof T, string>]: CollapsibleKeys<
11+
T[K],
12+
TPrefix extends '' ? `${K}` : `${TPrefix}.${K}`
13+
>
14+
}[Extract<keyof T, string>]
15+
: never
16+
17+
export type CollapsiblePaths<T> =
18+
CollapsibleKeys<T> extends string ? CollapsibleKeys<T> : never

0 commit comments

Comments
 (0)