@@ -45,17 +45,6 @@ function isPrimitive(value: unknown): boolean {
4545 )
4646}
4747
48- function InlineArray ( { suffix, children } : { suffix ?: string , children ?: ReactNode } ) : ReactNode {
49- return (
50- < >
51- < span className = { styles . array } > { '[' } </ span >
52- < span className = { styles . array } > { children } </ span >
53- < span className = { styles . array } > { ']' } </ span >
54- { suffix && < span className = { styles . comment } > { suffix } </ span > }
55- </ >
56- )
57- }
58-
5948function CollapsedArray ( { array } : { array : unknown [ ] } ) : ReactNode {
6049 const maxCharacterCount = 40
6150 const separator = ', '
@@ -64,17 +53,17 @@ function CollapsedArray({ array }: {array: unknown[]}): ReactNode {
6453 let suffix : string | undefined = undefined
6554
6655 let characterCount = 0
67- for ( const [ index , item ] of array . entries ( ) ) {
56+ for ( const [ index , value ] of array . entries ( ) ) {
6857 if ( index > 0 ) {
6958 characterCount += separator . length
70- children . push ( < span key = { `separator-${ index - 1 } ` } > , </ span > )
59+ children . push ( < span key = { `separator-${ index - 1 } ` } > { separator } </ span > )
7160 }
7261 // should we continue?
73- if ( isPrimitive ( item ) ) {
74- const asString = typeof item === 'bigint' ? item . toString ( ) : JSON . stringify ( item )
62+ if ( isPrimitive ( value ) ) {
63+ const asString = typeof value === 'bigint' ? value . toString ( ) : JSON . stringify ( value )
7564 characterCount += asString . length
7665 if ( characterCount < maxCharacterCount ) {
77- children . push ( < JsonContent json = { item } key = { `item -${ index } ` } /> )
66+ children . push ( < JsonContent json = { value } key = { `value -${ index } ` } /> )
7867 continue
7968 }
8069 }
@@ -83,7 +72,14 @@ function CollapsedArray({ array }: {array: unknown[]}): ReactNode {
8372 suffix = ` length: ${ array . length } `
8473 break
8574 }
86- return < InlineArray suffix = { suffix } > { children } </ InlineArray >
75+ return (
76+ < >
77+ < span className = { styles . array } > { '[' } </ span >
78+ < span className = { styles . array } > { children } </ span >
79+ < span className = { styles . array } > { ']' } </ span >
80+ { suffix && < span className = { styles . comment } > { suffix } </ span > }
81+ </ >
82+ )
8783}
8884
8985function JsonArray ( { array, label } : { array : unknown [ ] , label ?: string } ) : ReactNode {
@@ -109,14 +105,66 @@ function JsonArray({ array, label }: { array: unknown[], label?: string }): Reac
109105 </ >
110106}
111107
108+ function CollapsedObject ( { obj } : { obj : object } ) : ReactNode {
109+ const maxCharacterCount = 40
110+ const separator = ', '
111+ const kvSeparator = ': '
112+
113+ const children : ReactNode [ ] = [ ]
114+ let suffix : string | undefined = undefined
115+
116+ const entries = Object . entries ( obj )
117+ let characterCount = 0
118+ for ( const [ index , [ key , value ] ] of entries . entries ( ) ) {
119+ if ( index > 0 ) {
120+ characterCount += separator . length
121+ children . push ( < span key = { `separator-${ index - 1 } ` } > { separator } </ span > )
122+ }
123+ // should we continue?
124+ if ( isPrimitive ( value ) ) {
125+ const asString = typeof value === 'bigint' ? value . toString ( ) : JSON . stringify ( value )
126+ characterCount += key . length + kvSeparator . length + asString . length
127+ if ( characterCount < maxCharacterCount ) {
128+ children . push ( < JsonContent json = { value as unknown } label = { key } key = { `value-${ index } ` } /> )
129+ continue
130+ }
131+ }
132+ // no: it was the last entry
133+ children . push ( < span key = "rest" > ...</ span > )
134+ suffix = ` entries: ${ entries . length } `
135+ break
136+ }
137+ return (
138+ < >
139+ < span className = { styles . object } > { '{' } </ span >
140+ < span className = { styles . object } > { children } </ span >
141+ < span className = { styles . object } > { '}' } </ span >
142+ { suffix && < span className = { styles . comment } > { suffix } </ span > }
143+ </ >
144+ )
145+ }
146+
147+ function shouldCollapse ( obj : object ) : boolean {
148+ const values = Object . values ( obj )
149+ if (
150+ // if all the values are primitive
151+ values . every ( value => isPrimitive ( value ) )
152+ // if the object has too many entries
153+ || values . length >= 100
154+ ) {
155+ return true
156+ }
157+ return false
158+ }
159+
112160function JsonObject ( { obj, label } : { obj : object , label ?: string } ) : ReactNode {
113- const [ collapsed , setCollapsed ] = useState ( false )
161+ const [ collapsed , setCollapsed ] = useState ( shouldCollapse ( obj ) )
114162 const key = label ? < span className = { styles . key } > { label } : </ span > : ''
115163 if ( collapsed ) {
116164 return < div className = { styles . clickable } onClick = { ( ) => { setCollapsed ( false ) } } >
117165 < span className = { styles . drill } > { '\u25B6' } </ span >
118166 { key }
119- < span className = { styles . object } > { '{...}' } </ span >
167+ < CollapsedObject obj = { obj } > </ CollapsedObject >
120168 </ div >
121169 }
122170 return < >
0 commit comments