1
- import { Box , createTheme , Stack , ThemeProvider } from '@mui/material'
1
+ import ChevronRightIcon from '@mui/icons-material/ChevronRight'
2
+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
3
+ import { TreeItem , TreeView } from '@mui/lab'
4
+ import { Box , createTheme , ThemeProvider } from '@mui/material'
2
5
import type React from 'react'
3
- import { useDebugValue , useEffect , useMemo } from 'react'
6
+ import { useCallback , useDebugValue , useEffect , useMemo } from 'react'
4
7
5
8
import {
6
9
createJsonViewerStore ,
@@ -9,6 +12,8 @@ import {
9
12
import type { ReactJsonViewProps } from './type'
10
13
11
14
export type DataProps < Data = unknown > = {
15
+ father : string
16
+ isRoot : boolean
12
17
value : Data
13
18
currentIndent : number
14
19
}
@@ -24,40 +29,88 @@ function getType (value: unknown) {
24
29
return 'date'
25
30
} else if ( value === null ) {
26
31
return 'null'
32
+ } else if ( Array . isArray ( value ) ) {
33
+ return 'array'
27
34
}
28
35
}
29
36
return type
30
37
}
31
38
32
39
const ObjectJson : React . FC < DataProps > = ( {
33
40
value,
34
- currentIndent
41
+ currentIndent,
42
+ isRoot,
43
+ father
35
44
} ) => {
36
45
const type = useMemo ( ( ) => getType ( value ) , [ value ] )
37
46
useDebugValue ( type , type => `value type: ${ type } ` )
38
47
const indentWidth = useJsonViewerStore ( store => store . indentWidth )
48
+ const expanded = useJsonViewerStore ( store => store . expanded )
49
+ const setExpanded = useJsonViewerStore ( store => store . setExpanded )
50
+ const handleToggle = useCallback (
51
+ ( event : React . SyntheticEvent , nodeIds : string [ ] ) => {
52
+ setExpanded ( nodeIds )
53
+ } , [ setExpanded ] )
39
54
const elements = useMemo ( ( ) => {
40
55
if ( type === 'object' ) {
41
- return Object . entries ( value as object ) . map ( ( [ key , value ] ) => (
42
- < Box
43
- key = { key }
44
- sx = { {
45
- pl : currentIndent
46
- } }
47
- >
48
- < Stack direction = 'row' spacing = { 1 } >
49
- < Box > { key } </ Box >
50
- < Box component = 'div' >
51
- < ObjectJson value = { value }
52
- currentIndent = { currentIndent + indentWidth } />
53
- </ Box >
54
- </ Stack >
55
- </ Box >
56
- ) )
56
+ if ( isRoot ) {
57
+ return (
58
+ < TreeView
59
+ defaultCollapseIcon = { < ExpandMoreIcon /> }
60
+ defaultExpandIcon = { < ChevronRightIcon /> }
61
+ expanded = { expanded }
62
+ onNodeToggle = { handleToggle }
63
+ >
64
+ < TreeItem nodeId = 'data-viewer-root' label = 'root' >
65
+ {
66
+ Object . entries ( value as object ) . map ( ( [ key , value ] ) => {
67
+ const path = `${ father } ${ father ? '.' : '' } ${ key } `
68
+ const isExpend = expanded . includes ( path )
69
+ return (
70
+ < TreeItem
71
+ nodeId = { path }
72
+ key = { key }
73
+ label = { isExpend ? path : `${ key } : ${ value } ` }
74
+ >
75
+ < ObjectJson
76
+ father = { key }
77
+ value = { value }
78
+ currentIndent = { currentIndent + indentWidth }
79
+ isRoot = { false }
80
+ />
81
+ </ TreeItem >
82
+ )
83
+ } )
84
+ }
85
+ </ TreeItem >
86
+ </ TreeView >
87
+ )
88
+ } else {
89
+ return (
90
+ Object . entries ( value as object ) . map ( ( [ key , value ] ) => {
91
+ const path = `${ father } ${ father ? '.' : '' } ${ key } `
92
+ return (
93
+ < TreeItem
94
+ nodeId = { path }
95
+ key = { key }
96
+ label = { `${ value } ` }
97
+ >
98
+ < ObjectJson
99
+ father = { key }
100
+ value = { value }
101
+ currentIndent = { currentIndent + indentWidth }
102
+ isRoot = { false }
103
+ />
104
+ </ TreeItem >
105
+ )
106
+ } )
107
+ )
108
+ }
57
109
} else {
58
- return `${ value } `
110
+ const path = `${ father } ${ father ? '.' : '' } ${ value } `
111
+ return < TreeItem nodeId = { path } label = { `${ value } ` } />
59
112
}
60
- } , [ currentIndent , indentWidth , type , value ] )
113
+ } , [ currentIndent , expanded , father , handleToggle , indentWidth , isRoot , type , value ] )
61
114
return < > { elements } </ >
62
115
}
63
116
@@ -73,7 +126,12 @@ const JsonViewerInner: React.FC<ReactJsonViewProps> = (props) => {
73
126
// todo: still working on it
74
127
return (
75
128
< Box >
76
- < ObjectJson value = { props . src } currentIndent = { 0 } />
129
+ < ObjectJson
130
+ value = { props . src }
131
+ currentIndent = { 0 }
132
+ isRoot
133
+ father = ''
134
+ />
77
135
</ Box >
78
136
)
79
137
}
0 commit comments