Skip to content

Commit

Permalink
feat: collapse all empty iterables and disable expanding them (#123)
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz committed Dec 5, 2022
1 parent 0e7292d commit 105b002
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 46 deletions.
4 changes: 4 additions & 0 deletions docs/pages/full/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ const example = {
string: 'this is a string',
integer: 42,
array: [19, 19, 810, 'test', NaN],
emptyArray: [],
nestedArray: [
[1, 2],
[3, 4]
],
map,
emptyMap: new Map(),
set,
emptySet: new Set(),
float: 114.514,
undefined,
superLongString,
Expand All @@ -81,6 +84,7 @@ const example = {
'second-child': false,
'last-child': null
},
emptyObject: {},
function: aPlusB,
constFunction: aPlusBConst,
anonymousFunction: function (a: number, b: number) {
Expand Down
14 changes: 8 additions & 6 deletions src/components/DataKeyPair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useInspect } from '../hooks/useInspect'
import { useJsonViewerStore } from '../stores/JsonViewerStore'
import { useTypeComponents } from '../stores/typeRegistry'
import type { DataItemProps } from '../type'
import { getValueSize } from '../utils'
import { DataBox } from './mui/DataBox'

export type DataKeyPairProps = {
Expand Down Expand Up @@ -62,10 +63,8 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
const [editing, setEditing] = useState(false)
const onChange = useJsonViewerStore(store => store.onChange)
const keyColor = useTextColor()
const numberKeyColor = useJsonViewerStore(
store => store.colorspace.base0C)
const { Component, PreComponent, PostComponent, Editor } = useTypeComponents(
value, path)
const numberKeyColor = useJsonViewerStore(store => store.colorspace.base0C)
const { Component, PreComponent, PostComponent, Editor } = useTypeComponents(value, path)
const quotesOnKeys = useJsonViewerStore(store => store.quotesOnKeys)
const rootName = useJsonViewerStore(store => store.rootName)
const isRoot = root === value
Expand Down Expand Up @@ -176,7 +175,8 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
value
])

const expandable = !!(PreComponent && PostComponent)
const isEmptyValue = useMemo(() => getValueSize(value) === 0, [value])
const expandable = !isEmptyValue && !!(PreComponent && PostComponent)
const KeyRenderer = useJsonViewerStore(store => store.keyRenderer)
const downstreamProps: DataItemProps = useMemo(() => ({
path,
Expand Down Expand Up @@ -206,7 +206,9 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
if (event.isDefaultPrevented()) {
return
}
setInspect(state => !state)
if (!isEmptyValue) {
setInspect(state => !state)
}
}, [setInspect])
}
>
Expand Down
69 changes: 31 additions & 38 deletions src/components/DataTypes/Object.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useTextColor } from '../../hooks/useColor'
import { useIsCycleReference } from '../../hooks/useIsCycleReference'
import { useJsonViewerStore } from '../../stores/JsonViewerStore'
import type { DataItemProps } from '../../type'
import { getValueSize } from '../../utils'
import { DataKeyPair } from '../DataKeyPair'
import { CircularArrowsIcon } from '../icons/CircularArrowsIcon'
import { DataBox } from '../mui/DataBox'
Expand All @@ -16,15 +17,11 @@ const objectRb = '}'
const arrayRb = ']'

function inspectMetadata (value: object) {
let length
const length = getValueSize(value)

let name = ''
if (Array.isArray(value)) {
length = value.length
} else if (value instanceof Map || value instanceof Set) {
if (value instanceof Map || value instanceof Set) {
name = value[Symbol.toStringTag]
length = value.size
} else {
length = Object.keys(value).length
}
if (Object.prototype.hasOwnProperty.call(value, Symbol.toStringTag)) {
name = (value as any)[Symbol.toStringTag]
Expand All @@ -36,9 +33,8 @@ export const PreObjectType: React.FC<DataItemProps<object>> = (props) => {
const metadataColor = useJsonViewerStore(store => store.colorspace.base04)
const textColor = useTextColor()
const isArray = useMemo(() => Array.isArray(props.value), [props.value])
const sizeOfValue = useMemo(
() => props.inspect ? inspectMetadata(props.value) : '',
[props.inspect, props.value]
const isEmptyValue = useMemo(() => getValueSize(props.value) === 0, [props.value])
const sizeOfValue = useMemo(() => inspectMetadata(props.value), [props.inspect, props.value]
)
const displayObjectSize = useJsonViewerStore(store => store.displayObjectSize)
const isTrap = useIsCycleReference(props.path, props.value)
Expand All @@ -50,20 +46,18 @@ export const PreObjectType: React.FC<DataItemProps<object>> = (props) => {
}}
>
{isArray ? arrayLb : objectLb}
{displayObjectSize
? (
<Box
component='span'
sx={{
pl: 0.5,
fontStyle: 'italic',
color: metadataColor
}}
>
{sizeOfValue}
</Box>
)
: null}
{displayObjectSize && props.inspect && !isEmptyValue && (
<Box
component='span'
sx={{
pl: 0.5,
fontStyle: 'italic',
color: metadataColor
}}
>
{sizeOfValue}
</Box>
)}

{isTrap && !props.inspect
? (
Expand All @@ -85,14 +79,13 @@ export const PostObjectType: React.FC<DataItemProps<object>> = (props) => {
const metadataColor = useJsonViewerStore(store => store.colorspace.base04)
const isArray = useMemo(() => Array.isArray(props.value), [props.value])
const displayObjectSize = useJsonViewerStore(store => store.displayObjectSize)
const sizeOfValue = useMemo(
() => !props.inspect ? inspectMetadata(props.value) : '',
[props.inspect, props.value]
)
const isEmptyValue = useMemo(() => getValueSize(props.value) === 0, [props.value])
const sizeOfValue = useMemo(() => inspectMetadata(props.value), [props.inspect, props.value])

return (
<Box component='span' className='data-object-end'>
{isArray ? arrayRb : objectRb}
{displayObjectSize
{displayObjectSize && (isEmptyValue || !props.inspect)
? (
<Box
component='span'
Expand All @@ -118,12 +111,9 @@ function getIterator (value: any): value is Iterable<unknown> {
export const ObjectType: React.FC<DataItemProps<object>> = (props) => {
const keyColor = useTextColor()
const borderColor = useJsonViewerStore(store => store.colorspace.base02)
const groupArraysAfterLength = useJsonViewerStore(
store => store.groupArraysAfterLength)
const groupArraysAfterLength = useJsonViewerStore(store => store.groupArraysAfterLength)
const isTrap = useIsCycleReference(props.path, props.value)
const [displayLength, setDisplayLength] = useState(
useJsonViewerStore(store => store.maxDisplayLength)
)
const [displayLength, setDisplayLength] = useState(useJsonViewerStore(store => store.maxDisplayLength))
const objectSortKeys = useJsonViewerStore(store => store.objectSortKeys)
const elements = useMemo(() => {
if (!props.inspect) {
Expand Down Expand Up @@ -201,10 +191,9 @@ export const ObjectType: React.FC<DataItemProps<object>> = (props) => {
// object
let entries: [key: string, value: unknown][] = Object.entries(value)
if (objectSortKeys) {
entries = entries.sort(([a], [b]) => objectSortKeys === true
? a.localeCompare(b)
: objectSortKeys(a, b)
)
entries = objectSortKeys === true
? entries.sort(([a], [b]) => a.localeCompare(b))
: entries.sort(([a], [b]) => objectSortKeys(a, b))
}
const elements = entries.slice(0, displayLength).map(([key, value]) => {
const path = [...props.path, key]
Expand Down Expand Up @@ -243,6 +232,10 @@ export const ObjectType: React.FC<DataItemProps<object>> = (props) => {
const marginLeft = props.inspect ? 0.6 : 0
const width = useJsonViewerStore(store => store.indentWidth)
const indentWidth = props.inspect ? width - marginLeft : width
const isEmptyValue = useMemo(() => getValueSize(props.value) === 0, [props.value])
if (isEmptyValue) {
return null
}
return (
<Box
className='data-object'
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/useInspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ export function useInspect (path: (string | number)[], value: any, nestedIndex?:
const isTrap = useIsCycleReference(path, value)
const getInspectCache = useJsonViewerStore(store => store.getInspectCache)
const setInspectCache = useJsonViewerStore(store => store.setInspectCache)
const defaultInspectDepth = useJsonViewerStore(
store => store.defaultInspectDepth)
const defaultInspectDepth = useJsonViewerStore(store => store.defaultInspectDepth)
useEffect(() => {
const inspect = getInspectCache(path, nestedIndex)
if (inspect !== undefined) {
Expand Down
17 changes: 17 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,20 @@ export const isCycleReference = (
}
return false
}

export function getValueSize (value: any): number {
if (value === null || undefined) {
return 0
} else if (Array.isArray(value)) {
return value.length
} else if (value instanceof Map || value instanceof Set) {
return value.size
} else if (value instanceof Date) {
return 1
} else if (typeof value === 'object') {
return Object.keys(value).length
} else if (typeof value === 'string') {
return value.length
}
return 1
}
Loading

0 comments on commit 105b002

Please sign in to comment.