diff --git a/src/components/CellPanel/CellPanel.tsx b/src/components/CellPanel/CellPanel.tsx index bc35da10..a91006d4 100644 --- a/src/components/CellPanel/CellPanel.tsx +++ b/src/components/CellPanel/CellPanel.tsx @@ -1,10 +1,12 @@ import { DataFrame, stringify } from 'hightable' -import { useEffect, useState } from 'react' +import { ReactNode, useEffect, useState } from 'react' import { useConfig } from '../../hooks/useConfig.js' import { cn } from '../../lib/utils.js' import ContentWrapper from '../ContentWrapper/ContentWrapper.js' +import Json from '../Json/Json.js' import SlideCloseButton from '../SlideCloseButton/SlideCloseButton.js' import styles from '../TextView/TextView.module.css' +import jsonStyles from '../Json/Json.module.css' interface ViewerProps { df: DataFrame @@ -19,7 +21,7 @@ interface ViewerProps { * Cell viewer displays a single cell from a table. */ export default function CellPanel({ df, row, col, setProgress, setError, onClose }: ViewerProps) { - const [text, setText] = useState() + const [content, setContent] = useState() const { customClass } = useConfig() // Load cell data @@ -41,8 +43,20 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose if (asyncCell === undefined) { throw new Error(`Cell missing at column ${columnName}`) } - const text = await asyncCell.then(stringify) - setText(text) + const value: unknown = await asyncCell + if (value instanceof Object && !(value instanceof Date)) { + setContent( + + + + ) + } else { + setContent( + + {stringify(value)} + + ) + } } catch (error) { setError(error as Error) } finally { @@ -51,7 +65,7 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose } void loadCellData() - }, [df, col, row, setProgress, setError]) + }, [df, col, row, setProgress, setError, customClass]) const headers = <> @@ -60,6 +74,6 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose return - {text} + {content} } diff --git a/src/components/Json/Json.module.css b/src/components/Json/Json.module.css index 59fae5d7..1646e5cc 100644 --- a/src/components/Json/Json.module.css +++ b/src/components/Json/Json.module.css @@ -1,6 +1,8 @@ .jsonView { background-color: #22222b; color: #d6d6d6; + flex: 1; + overflow: auto; padding: 8px 8px 8px 20px; } diff --git a/src/components/Json/Json.tsx b/src/components/Json/Json.tsx index 66bbbc73..e93c8018 100644 --- a/src/components/Json/Json.tsx +++ b/src/components/Json/Json.tsx @@ -1,17 +1,21 @@ import { ReactNode, useState } from 'react' import styles from './Json.module.css' import { isPrimitive, shouldObjectCollapse } from './helpers.js' +import { cn } from '../../lib' interface JsonProps { json: unknown label?: string + className?: string } /** * JSON viewer component with collapsible objects and arrays. */ -export default function Json({ json, label }: JsonProps): ReactNode { - return
+export default function Json({ json, label, className }: JsonProps): ReactNode { + return
+ +
} function JsonContent({ json, label }: JsonProps): ReactNode { @@ -82,7 +86,7 @@ function CollapsedArray({ array }: {array: unknown[]}): ReactNode { } function JsonArray({ array, label }: { array: unknown[], label?: string }): ReactNode { - const [collapsed, setCollapsed] = useState(true) + const [collapsed, setCollapsed] = useState(shouldObjectCollapse(array)) const key = label ? {label}: : '' if (collapsed) { return
{ setCollapsed(false) }}> diff --git a/src/hooks/useConfig.ts b/src/hooks/useConfig.ts index 22c27636..3a6e6091 100644 --- a/src/hooks/useConfig.ts +++ b/src/hooks/useConfig.ts @@ -17,6 +17,7 @@ export interface Config { fileList?: string highTable?: string imageView?: string + jsonView?: string layout?: string markdownView?: string path?: string