Skip to content

Commit 70ba1ef

Browse files
committed
Json: auto collapse array
1 parent 0d7682d commit 70ba1ef

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

src/components/CellPanel/CellPanel.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { DataFrame, stringify } from 'hightable'
2-
import { useEffect, useState } from 'react'
2+
import { ReactNode, useEffect, useState } from 'react'
33
import { useConfig } from '../../hooks/useConfig.js'
44
import { cn } from '../../lib/utils.js'
55
import ContentWrapper from '../ContentWrapper/ContentWrapper.js'
6+
import Json from '../Json/Json.js'
67
import SlideCloseButton from '../SlideCloseButton/SlideCloseButton.js'
78
import styles from '../TextView/TextView.module.css'
9+
import jsonStyles from '../Json/Json.module.css'
810

911
interface ViewerProps {
1012
df: DataFrame
@@ -19,7 +21,7 @@ interface ViewerProps {
1921
* Cell viewer displays a single cell from a table.
2022
*/
2123
export default function CellPanel({ df, row, col, setProgress, setError, onClose }: ViewerProps) {
22-
const [text, setText] = useState<string | undefined>()
24+
const [content, setContent] = useState<ReactNode>()
2325
const { customClass } = useConfig()
2426

2527
// Load cell data
@@ -41,8 +43,20 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose
4143
if (asyncCell === undefined) {
4244
throw new Error(`Cell missing at column ${columnName}`)
4345
}
44-
const text = await asyncCell.then(stringify)
45-
setText(text)
46+
const value: unknown = await asyncCell
47+
if (value instanceof Object && !(value instanceof Date)) {
48+
setContent(
49+
<code className={cn(jsonStyles.jsonView, customClass?.jsonView)}>
50+
<Json json={value} />
51+
</code>
52+
)
53+
} else {
54+
setContent(
55+
<code className={cn(styles.textView, customClass?.textView)}>
56+
{stringify(value)}
57+
</code>
58+
)
59+
}
4660
} catch (error) {
4761
setError(error as Error)
4862
} finally {
@@ -51,7 +65,7 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose
5165
}
5266

5367
void loadCellData()
54-
}, [df, col, row, setProgress, setError])
68+
}, [df, col, row, setProgress, setError, customClass])
5569

5670
const headers = <>
5771
<SlideCloseButton onClick={onClose} />
@@ -60,6 +74,6 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose
6074
</>
6175

6276
return <ContentWrapper headers={headers}>
63-
<code className={cn(styles.textView, customClass?.textView)}>{text}</code>
77+
{content}
6478
</ContentWrapper>
6579
}

src/components/Json/Json.module.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.jsonView {
22
background-color: #22222b;
33
color: #d6d6d6;
4+
flex: 1;
5+
overflow: auto;
46
padding: 8px 8px 8px 20px;
57
}
68

src/components/Json/Json.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
import { ReactNode, useState } from 'react'
22
import styles from './Json.module.css'
33
import { isPrimitive, shouldObjectCollapse } from './helpers.js'
4+
import { cn } from '../../lib'
45

56
interface JsonProps {
67
json: unknown
78
label?: string
9+
className?: string
810
}
911

1012
/**
1113
* JSON viewer component with collapsible objects and arrays.
1214
*/
13-
export default function Json({ json, label }: JsonProps): ReactNode {
14-
return <div className={styles.json}><JsonContent json={json} label={label} /></div>
15+
export default function Json({ json, label, className }: JsonProps): ReactNode {
16+
return <div className={cn(styles.json, className)}>
17+
<JsonContent json={json} label={label} />
18+
</div>
1519
}
1620

1721
function JsonContent({ json, label }: JsonProps): ReactNode {
@@ -82,7 +86,7 @@ function CollapsedArray({ array }: {array: unknown[]}): ReactNode {
8286
}
8387

8488
function JsonArray({ array, label }: { array: unknown[], label?: string }): ReactNode {
85-
const [collapsed, setCollapsed] = useState(true)
89+
const [collapsed, setCollapsed] = useState(shouldObjectCollapse(array))
8690
const key = label ? <span className={styles.key}>{label}: </span> : ''
8791
if (collapsed) {
8892
return <div className={styles.clickable} onClick={() => { setCollapsed(false) }}>

src/hooks/useConfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface Config {
1717
fileList?: string
1818
highTable?: string
1919
imageView?: string
20+
jsonView?: string
2021
layout?: string
2122
markdownView?: string
2223
path?: string

0 commit comments

Comments
 (0)