@@ -10,6 +10,7 @@ export function JsonTree<TData, TName extends CollapsiblePaths<TData>>(props: {
1010 defaultExpansionDepth ?: number
1111 collapsePaths ?: Array < TName >
1212} ) {
13+
1314 return (
1415 < JsonValue
1516 isRoot
@@ -36,94 +37,76 @@ function JsonValue(props: {
3637 collapsePaths ?: Array < string >
3738 path : string
3839} ) {
39- const {
40- value,
41- keyName,
42- isRoot = false ,
43- isLastKey,
44- copyable,
45- defaultExpansionDepth,
46- depth,
47- collapsePaths,
48- path,
49- } = props
40+
5041 const styles = useStyles ( )
5142
5243 return (
53- < span class = { styles ( ) . tree . valueContainer ( isRoot ) } >
54- { keyName && typeof value !== 'object' && ! Array . isArray ( value ) && (
55- < span class = { styles ( ) . tree . valueKey } > "{ keyName } ": </ span >
44+ < span class = { styles ( ) . tree . valueContainer ( props . isRoot ?? false ) } >
45+ { props . keyName && typeof props . value !== 'object' && ! Array . isArray ( props . value ) && (
46+ < span class = { styles ( ) . tree . valueKey } > "{ props . keyName } ": </ span >
5647 ) }
5748 { ( ( ) => {
58- if ( typeof value === 'string' ) {
49+ if ( typeof props . value === 'string' ) {
5950 return (
60- < span class = { styles ( ) . tree . valueString } > "{ value } "</ span >
51+ < span class = { styles ( ) . tree . valueString } > "{ props . value } "</ span >
6152 )
6253 }
63- if ( typeof value === 'number' ) {
64- return < span class = { styles ( ) . tree . valueNumber } > { value } </ span >
54+ if ( typeof props . value === 'number' ) {
55+ return < span class = { styles ( ) . tree . valueNumber } > { props . value } </ span >
6556 }
66- if ( typeof value === 'boolean' ) {
67- return < span class = { styles ( ) . tree . valueBoolean } > { String ( value ) } </ span >
57+ if ( typeof props . value === 'boolean' ) {
58+ return < span class = { styles ( ) . tree . valueBoolean } > { String ( props . value ) } </ span >
6859 }
69- if ( value === null ) {
60+ if ( props . value === null ) {
7061 return < span class = { styles ( ) . tree . valueNull } > null</ span >
7162 }
72- if ( value === undefined ) {
63+ if ( props . value === undefined ) {
7364 return < span class = { styles ( ) . tree . valueNull } > undefined</ span >
7465 }
75- if ( typeof value === 'function' ) {
66+ if ( typeof props . value === 'function' ) {
7667 return (
77- < span class = { styles ( ) . tree . valueFunction } > { String ( value ) } </ span >
68+ < span class = { styles ( ) . tree . valueFunction } > { String ( props . value ) } </ span >
7869 )
7970 }
80- if ( Array . isArray ( value ) ) {
71+ if ( Array . isArray ( props . value ) ) {
8172 return (
8273 < ArrayValue
83- defaultExpansionDepth = { defaultExpansionDepth }
84- depth = { depth }
85- copyable = { copyable }
86- keyName = { keyName }
87- value = { value }
88- collapsePaths = { collapsePaths }
89- path = { path }
74+ defaultExpansionDepth = { props . defaultExpansionDepth }
75+ depth = { props . depth }
76+ copyable = { props . copyable }
77+ keyName = { props . keyName }
78+ value = { props . value }
79+ collapsePaths = { props . collapsePaths }
80+ path = { props . path }
9081 />
9182 )
9283 }
93- if ( typeof value === 'object' ) {
84+ if ( typeof props . value === 'object' ) {
9485 return (
9586 < ObjectValue
96- defaultExpansionDepth = { defaultExpansionDepth }
97- depth = { depth }
98- copyable = { copyable }
99- keyName = { keyName }
100- value = { value }
101- collapsePaths = { collapsePaths }
102- path = { path }
87+ defaultExpansionDepth = { props . defaultExpansionDepth }
88+ depth = { props . depth }
89+ copyable = { props . copyable }
90+ keyName = { props . keyName }
91+ value = { props . value }
92+ collapsePaths = { props . collapsePaths }
93+ path = { props . path }
10394 />
10495 )
10596 }
10697 return < span />
10798 } ) ( ) }
108- { copyable && (
99+ { props . copyable && (
109100 < div class = { clsx ( styles ( ) . tree . actions , 'actions' ) } >
110- < CopyButton value = { value } />
101+ < CopyButton value = { props . value } />
111102 </ div >
112103 ) }
113- { isLastKey || isRoot ? '' : < span > ,</ span > }
104+ { props . isLastKey || props . isRoot ? '' : < span > ,</ span > }
114105 </ span >
115106 )
116107}
117108
118- const ArrayValue = ( {
119- value,
120- keyName,
121- copyable,
122- defaultExpansionDepth,
123- depth,
124- collapsePaths,
125- path,
126- } : {
109+ const ArrayValue = ( props : {
127110 value : Array < any >
128111 copyable ?: boolean
129112 keyName ?: string
@@ -135,15 +118,15 @@ const ArrayValue = ({
135118 const styles = useStyles ( )
136119
137120 const [ expanded , setExpanded ] = createSignal (
138- depth <= defaultExpansionDepth && ! collapsePaths ?. includes ( path ) ,
121+ props . depth <= props . defaultExpansionDepth && ! props . collapsePaths ?. includes ( props . path ) ,
139122 )
140123
141- if ( value . length === 0 ) {
124+ if ( props . value . length === 0 ) {
142125 return (
143126 < span class = { styles ( ) . tree . expanderContainer } >
144- { keyName && (
127+ { props . keyName && (
145128 < span class = { clsx ( styles ( ) . tree . valueKey , styles ( ) . tree . collapsible ) } >
146- "{ keyName } ":{ ' ' }
129+ "{ props . keyName } ":{ ' ' }
147130 </ span >
148131 ) }
149132
@@ -158,7 +141,7 @@ const ArrayValue = ({
158141 expanded = { expanded ( ) }
159142 />
160143
161- { keyName && (
144+ { props . keyName && (
162145 < span
163146 onclick = { ( e ) => {
164147 e . stopPropagation ( )
@@ -167,27 +150,27 @@ const ArrayValue = ({
167150 } }
168151 class = { clsx ( styles ( ) . tree . valueKey , styles ( ) . tree . collapsible ) }
169152 >
170- "{ keyName } ":{ ' ' }
171- < span class = { styles ( ) . tree . info } > { value . length } items</ span >
153+ "{ props . keyName } ":{ ' ' }
154+ < span class = { styles ( ) . tree . info } > { props . value . length } items</ span >
172155 </ span >
173156 ) }
174157
175158 < span class = { styles ( ) . tree . valueBraces } > [</ span >
176159
177160 < Show when = { expanded ( ) } >
178- < span class = { styles ( ) . tree . expandedLine ( Boolean ( keyName ) ) } >
179- < For each = { value } >
161+ < span class = { styles ( ) . tree . expandedLine ( Boolean ( props . keyName ) ) } >
162+ < For each = { props . value } >
180163 { ( item , i ) => {
181- const isLastKey = i ( ) === value . length - 1
164+ const isLastKey = i ( ) === props . value . length - 1
182165 return (
183166 < JsonValue
184- copyable = { copyable }
167+ copyable = { props . copyable }
185168 value = { item }
186169 isLastKey = { isLastKey }
187- defaultExpansionDepth = { defaultExpansionDepth }
188- depth = { depth + 1 }
189- collapsePaths = { collapsePaths }
190- path = { path ? `${ path } [${ i ( ) } ]` : `[${ i ( ) } ]` }
170+ defaultExpansionDepth = { props . defaultExpansionDepth }
171+ depth = { props . depth + 1 }
172+ collapsePaths = { props . collapsePaths }
173+ path = { props . path ? `${ props . path } [${ i ( ) } ]` : `[${ i ( ) } ]` }
191174 />
192175 )
193176 } }
@@ -212,15 +195,7 @@ const ArrayValue = ({
212195 )
213196}
214197
215- const ObjectValue = ( {
216- value,
217- keyName,
218- copyable,
219- defaultExpansionDepth,
220- depth,
221- collapsePaths,
222- path,
223- } : {
198+ const ObjectValue = ( props : {
224199 value : Record < string , any >
225200 keyName ?: string
226201 copyable ?: boolean
@@ -232,18 +207,18 @@ const ObjectValue = ({
232207 const styles = useStyles ( )
233208
234209 const [ expanded , setExpanded ] = createSignal (
235- depth <= defaultExpansionDepth && ! collapsePaths ?. includes ( path ) ,
210+ props . depth <= props . defaultExpansionDepth && ! props . collapsePaths ?. includes ( props . path ) ,
236211 )
237212
238- const keys = Object . keys ( value )
213+ const keys = Object . keys ( props . value )
239214 const lastKeyName = keys [ keys . length - 1 ]
240215
241216 if ( keys . length === 0 ) {
242217 return (
243218 < span class = { styles ( ) . tree . expanderContainer } >
244- { keyName && (
219+ { props . keyName && (
245220 < span class = { clsx ( styles ( ) . tree . valueKey , styles ( ) . tree . collapsible ) } >
246- "{ keyName } ":{ ' ' }
221+ "{ props . keyName } ":{ ' ' }
247222 </ span >
248223 ) }
249224
@@ -254,14 +229,14 @@ const ObjectValue = ({
254229
255230 return (
256231 < span class = { styles ( ) . tree . expanderContainer } >
257- { keyName && (
232+ { props . keyName && (
258233 < Expander
259234 onClick = { ( ) => setExpanded ( ! expanded ( ) ) }
260235 expanded = { expanded ( ) }
261236 />
262237 ) }
263238
264- { keyName && (
239+ { props . keyName && (
265240 < span
266241 onClick = { ( e ) => {
267242 e . stopPropagation ( )
@@ -270,27 +245,27 @@ const ObjectValue = ({
270245 } }
271246 class = { clsx ( styles ( ) . tree . valueKey , styles ( ) . tree . collapsible ) }
272247 >
273- "{ keyName } ":{ ' ' }
248+ "{ props . keyName } ":{ ' ' }
274249 < span class = { styles ( ) . tree . info } > { keys . length } items</ span >
275250 </ span >
276251 ) }
277252
278253 < span class = { styles ( ) . tree . valueBraces } > { '{' } </ span >
279254
280255 < Show when = { expanded ( ) } >
281- < span class = { styles ( ) . tree . expandedLine ( Boolean ( keyName ) ) } >
256+ < span class = { styles ( ) . tree . expandedLine ( Boolean ( props . keyName ) ) } >
282257 < For each = { keys } >
283258 { ( k ) => (
284259 < >
285260 < JsonValue
286- value = { value [ k ] }
261+ value = { props . value [ k ] }
287262 keyName = { k }
288263 isLastKey = { lastKeyName === k }
289- copyable = { copyable }
290- defaultExpansionDepth = { defaultExpansionDepth }
291- depth = { depth + 1 }
292- collapsePaths = { collapsePaths }
293- path = { `${ path } ${ path ? '.' : '' } ${ k } ` }
264+ copyable = { props . copyable }
265+ defaultExpansionDepth = { props . defaultExpansionDepth }
266+ depth = { props . depth + 1 }
267+ collapsePaths = { props . collapsePaths }
268+ path = { `${ props . path } ${ props . path ? '.' : '' } ${ k } ` }
294269 />
295270 </ >
296271 ) }
@@ -326,34 +301,33 @@ const CopyButton = (props: { value: unknown }) => {
326301 < button
327302 class = { styles ( ) . tree . actionButton }
328303 title = "Copy object to clipboard"
329- aria-label = { `${
330- copyState ( ) === 'NoCopy'
331- ? 'Copy object to clipboard'
332- : copyState ( ) === 'SuccessCopy'
333- ? 'Object copied to clipboard'
334- : 'Error copying object to clipboard'
335- } `}
304+ aria-label = { `${ copyState ( ) === 'NoCopy'
305+ ? 'Copy object to clipboard'
306+ : copyState ( ) === 'SuccessCopy'
307+ ? 'Object copied to clipboard'
308+ : 'Error copying object to clipboard'
309+ } `}
336310 onClick = {
337311 copyState ( ) === 'NoCopy'
338312 ? ( ) => {
339- navigator . clipboard
340- . writeText ( JSON . stringify ( props . value , null , 2 ) )
341- . then (
342- ( ) => {
343- setCopyState ( 'SuccessCopy' )
344- setTimeout ( ( ) => {
345- setCopyState ( 'NoCopy' )
346- } , 1500 )
347- } ,
348- ( err ) => {
349- console . error ( 'Failed to copy: ' , err )
350- setCopyState ( 'ErrorCopy' )
351- setTimeout ( ( ) => {
352- setCopyState ( 'NoCopy' )
353- } , 1500 )
354- } ,
355- )
356- }
313+ navigator . clipboard
314+ . writeText ( JSON . stringify ( props . value , null , 2 ) )
315+ . then (
316+ ( ) => {
317+ setCopyState ( 'SuccessCopy' )
318+ setTimeout ( ( ) => {
319+ setCopyState ( 'NoCopy' )
320+ } , 1500 )
321+ } ,
322+ ( err ) => {
323+ console . error ( 'Failed to copy: ' , err )
324+ setCopyState ( 'ErrorCopy' )
325+ setTimeout ( ( ) => {
326+ setCopyState ( 'NoCopy' )
327+ } , 1500 )
328+ } ,
329+ )
330+ }
357331 : undefined
358332 }
359333 >
@@ -383,7 +357,7 @@ const Expander = (props: { expanded: boolean; onClick: () => void }) => {
383357 transform : rotate (${ props . expanded ? 90 : 0 } deg);
384358 ` ,
385359 props . expanded &&
386- css `
360+ css `
387361 & svg {
388362 top : -1px ;
389363 }
0 commit comments