Skip to content

Commit

Permalink
feat: backport support for v1
Browse files Browse the repository at this point in the history
Support `props.rootName`, `props.collapseStringsAfterLength`
  • Loading branch information
himself65 committed Sep 20, 2022
1 parent 4f8b32f commit ff729a6
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 89 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const Component = () => (
- [ ] custom metadata
- [X] Support `Next.js` SSR
- [X] `onChange` props allow users to edit value
- [X] Object, array, string and function values can be collapsed and expanded
- [X] Inspect `object`, `Array`, primitive type, even `Map` and `Set` by default.
- [X] Metadata preview, like total items, length of string...
- [X] `Copy to Clipboard` on Click
- [ ] Editor for basic types
Expand Down
9 changes: 7 additions & 2 deletions examples/basic/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ map.set('goo', 'hello')

const set = new Set([1, 2, 3])

const superLongString = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'

const example = {
loopObject,
loopArray,
Expand All @@ -57,6 +59,7 @@ const example = {
set,
float: 114.514,
undefined,
superLongString,
object: {
'first-child': true,
'second-child': false,
Expand All @@ -70,7 +73,8 @@ const example = {
}

const KeyRenderer: JsonViewerKeyRenderer = ({ path }) => {
return <del aria-label='I dont like this number'>&quot;{path.slice(-1)}&quot;</del>
return <del aria-label='I dont like this number'>&quot;{path.slice(
-1)}&quot;</del>
}
KeyRenderer.when = (props) => props.value === 114.514

Expand Down Expand Up @@ -139,7 +143,8 @@ const IndexPage: React.FC = () => {
keyRenderer={KeyRenderer}
valueTypes={[
{
is: (value): value is string => typeof value === 'string' && value.startsWith('https://i.imgur.com'),
is: (value): value is string => typeof value === 'string' &&
value.startsWith('https://i.imgur.com'),
Component: (props) => {
return <img height='50px' src={props.value} alt={props.value}/>
}
Expand Down
160 changes: 81 additions & 79 deletions src/components/DataKeyPair.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
const rootName = useJsonViewerStore(store => store.rootName)
const isRoot = root === value
const isNumberKey = Number.isInteger(Number(key))
const displayKey = isRoot ? rootName : key
const downstreamProps: DataItemProps = useMemo(() => ({
path,
inspect,
Expand All @@ -64,86 +63,87 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
const actionIcons = useMemo(() => {
if (editing) {
return (
<>
<IconBox>
<CloseIcon
sx={{
fontSize: '.8rem'
}}
onClick={() => {
// abort editing
setEditing(false)
setTempValue(value)
}}
/>
</IconBox>
<IconBox>
<CheckIcon
sx={{
fontSize: '.8rem'
}}
onClick={() => {
// finish editing, save data
setEditing(false)
onChange(path, value, tempValue)
}}
/>
</IconBox>
</>
<>
<IconBox>
<CloseIcon
sx={{
fontSize: '.8rem'
}}
onClick={() => {
// abort editing
setEditing(false)
setTempValue(value)
}}
/>
</IconBox>
<IconBox>
<CheckIcon
sx={{
fontSize: '.8rem'
}}
onClick={() => {
// finish editing, save data
setEditing(false)
onChange(path, value, tempValue)
}}
/>
</IconBox>
</>
)
}
return (
<>
<IconBox
onClick={event => {
copy(
JSON.stringify(
value,
null,
' '
)
)
event.preventDefault()
}}
>
{
copied
? (
<CheckIcon
sx={{
fontSize: '.8rem'
}}
/>
<>
<IconBox
onClick={event => {
copy(
JSON.stringify(
value,
null,
' '
)
: (
<ContentCopyIcon
)
event.preventDefault()
}}
>
{
copied
? (
<CheckIcon
sx={{
fontSize: '.8rem'
}}
/>
)
: (
<ContentCopyIcon
sx={{
fontSize: '.8rem'
}}
/>
)
}
</IconBox>
{/* todo: support edit object */}
{(Editor && editable) &&
(
<IconBox
onClick={event => {
event.preventDefault()
setEditing(true)
}}
>
<EditIcon
sx={{
fontSize: '.8rem'
}}
/>
)
</IconBox>
)
}
</IconBox>
{/* todo: support edit object */}
{(Editor && editable) &&
(
<IconBox
onClick={event => {
event.preventDefault()
setEditing(true)
}}
>
<EditIcon
sx={{
fontSize: '.8rem'
}}
/>
</IconBox>
)
}
</>
</>
)
}, [Editor, copied, copy, editable, editing, onChange, path, tempValue, value])
},
[Editor, copied, copy, editable, editing, onChange, path, tempValue, value])

const expandable = PreComponent && PostComponent
const KeyRenderer = useJsonViewerStore(store => store.keyRenderer)
Expand Down Expand Up @@ -173,14 +173,16 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
}
>
{
KeyRenderer.when(downstreamProps)
? <KeyRenderer {...downstreamProps} />
: nestedIndex === undefined && (
isNumberKey
? <Box component='span'
style={{ color: numberKeyColor }}>{displayKey}</Box>
: <>&quot;{displayKey}&quot;</>
)
(isRoot && rootName !== false)
? <>&quot;{rootName}&quot;</>
: !isRoot && KeyRenderer.when(downstreamProps)
? <KeyRenderer {...downstreamProps} />
: nestedIndex === undefined && (
isNumberKey
? <Box component='span'
style={{ color: numberKeyColor }}>{key}</Box>
: <>&quot;{key}&quot;</>
)
}
{
nestedIndex === undefined && (
Expand Down
2 changes: 1 addition & 1 deletion src/components/DataTypes/createEasyType.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { InputBase } from '@mui/material'
import React, { useCallback } from 'react'

import type { ColorNamespace } from '../../stores/JsonViewerStore'
import { useJsonViewerStore } from '../../stores/JsonViewerStore'
import type { ColorNamespace } from '../../theme/base16'
import type { DataItemProps, DataType, EditorProps } from '../../type'
import { DataTypeLabel } from '../DataTypeLabel'
import { DataBox } from '../mui/DataBox'
Expand Down
6 changes: 4 additions & 2 deletions src/stores/JsonViewerStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ export type JsonViewerState<T = unknown> = {
groupArraysAfterLength: number
maxDisplayLength: number
defaultInspectDepth: number
collapseStringsAfterLength: number
colorNamespace: ColorNamespace
expanded: string[]
rootName: string
rootName: false | string
value: T
onChange: JsonViewerOnChange
keyRenderer: JsonViewerKeyRenderer
Expand All @@ -41,8 +42,9 @@ export const createJsonViewerStore = <T = unknown>(props: JsonViewerProps<T>) =>
hoverPath: null,
indentWidth: props.indentWidth ?? 2,
groupArraysAfterLength: props.groupArraysAfterLength ?? 100,
collapseStringsAfterLength: props.collapseStringsAfterLength ?? 50,
maxDisplayLength: props.maxDisplayLength ?? 30,
rootName: 'root',
rootName: props.rootName ?? 'root',
defaultInspectDepth: 5,
colorNamespace: lightColorNamespace,
expanded: ['data-viewer-root'],
Expand Down
27 changes: 25 additions & 2 deletions src/stores/typeRegistry.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Box } from '@mui/material'
import { DevelopmentError } from '@textea/dev-kit/utils'
import React, { useMemo } from 'react'
import React, { useMemo, useState } from 'react'

import { createEasyType } from '../components/DataTypes/createEasyType'
import {
Expand Down Expand Up @@ -145,7 +145,30 @@ registerType<string>(
is: (value): value is string => typeof value === 'string',
...createEasyType(
'string',
({ value }) => <>&quot;{`${value}`}&quot;</>,
(props) => {
const [showRest, setShowRest] = useState(false)
const collapseStringsAfterLength = useJsonViewerStore(
store => store.collapseStringsAfterLength)
const value = showRest ? props.value : props.value.slice(0, collapseStringsAfterLength)
const hasRest = props.value.length > collapseStringsAfterLength
return (
<Box
component='span'
sx={{
overflowWrap: 'break-word',
cursor: hasRest ? 'pointer' : 'inherit'
}}
onClick={() => {
setShowRest(value => !value)
}}
>
&quot;
{value}
{hasRest && <span>...</span>}
&quot;
</Box>
)
},
{
colorKey: 'base09',
fromString: value => value
Expand Down
19 changes: 17 additions & 2 deletions src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ export type JsonViewerTheme = 'light' | 'dark' | 'auto'

export type JsonViewerProps<T = unknown> = {
/**
* any value
* Name of the root value
*
* @default "root"
*/
rootName?: false | string
/**
* Any value, `object`, `Array`, primitive type, even `Map` or `Set`.
*/
value: T
/**
* indent width for nested objects
* Indent width for nested objects
* @default 2
*/
indentWidth?: number
Expand Down Expand Up @@ -71,6 +77,15 @@ export type JsonViewerProps<T = unknown> = {
* @default 100
*/
groupArraysAfterLength?: number
/**
* When an integer value is assigned, strings will be cut off at that length.
* Collapsed strings are followed by an ellipsis.
*
* String content can be expanded and collapsed by clicking on the string value.
*
* @default 100
*/
collapseStringsAfterLength?: number
className?: string
style?: React.CSSProperties
/**
Expand Down

0 comments on commit ff729a6

Please sign in to comment.