Skip to content

Commit e41102c

Browse files
committed
feat: support props.enableClipboard
1 parent d3fb54e commit e41102c

File tree

4 files changed

+64
-44
lines changed

4 files changed

+64
-44
lines changed

src/components/DataKeyPair.tsx

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,8 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
6868
const rootName = useJsonViewerStore(store => store.rootName)
6969
const isRoot = root === value
7070
const isNumberKey = Number.isInteger(Number(key))
71-
const downstreamProps: DataItemProps = useMemo(() => ({
72-
path,
73-
inspect,
74-
setInspect,
75-
value
76-
}), [inspect, path, setInspect, value])
71+
72+
const enableClipboard = useJsonViewerStore(store => store.enableClipboard)
7773
const { copy, copied } = useClipboard()
7874

7975
const actionIcons = useMemo(() => {
@@ -109,36 +105,45 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
109105
}
110106
return (
111107
<>
112-
<IconBox
113-
onClick={event => {
114-
copy(
115-
JSON.stringify(
116-
value,
117-
null,
118-
' '
119-
)
120-
)
121-
event.preventDefault()
122-
}}
123-
>
124-
{
125-
copied
126-
? (
127-
<CheckIcon
128-
sx={{
129-
fontSize: '.8rem'
130-
}}
131-
/>
108+
{enableClipboard && (
109+
<IconBox
110+
onClick={event => {
111+
event.preventDefault()
112+
try {
113+
copy(
114+
JSON.stringify(
115+
value,
116+
null,
117+
' '
118+
)
132119
)
133-
: (
134-
<ContentCopyIcon
135-
sx={{
136-
fontSize: '.8rem'
137-
}}
138-
/>
139-
)
140-
}
141-
</IconBox>
120+
} catch (e) {
121+
// in some case, this will throw error
122+
// for example: circular structure
123+
// fixme: `useAlert` hook
124+
console.error(e)
125+
}
126+
}}
127+
>
128+
{
129+
copied
130+
? (
131+
<CheckIcon
132+
sx={{
133+
fontSize: '.8rem'
134+
}}
135+
/>
136+
)
137+
: (
138+
<ContentCopyIcon
139+
sx={{
140+
fontSize: '.8rem'
141+
}}
142+
/>
143+
)
144+
}
145+
</IconBox>
146+
)}
142147
{/* todo: support edit object */}
143148
{(Editor && editable) &&
144149
(
@@ -159,10 +164,16 @@ export const DataKeyPair: React.FC<DataKeyPairProps> = (props) => {
159164
</>
160165
)
161166
},
162-
[Editor, copied, copy, editable, editing, onChange, path, tempValue, value])
167+
[Editor, copied, copy, editable, editing, enableClipboard, onChange, path, tempValue, value])
163168

164169
const expandable = !!(PreComponent && PostComponent)
165170
const KeyRenderer = useJsonViewerStore(store => store.keyRenderer)
171+
const downstreamProps: DataItemProps = useMemo(() => ({
172+
path,
173+
inspect,
174+
setInspect,
175+
value
176+
}), [inspect, path, setInspect, value])
166177
return (
167178
<Box className='data-key-pair'
168179
onMouseEnter={

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const JsonViewerInner: React.FC<JsonViewerProps> = (props) => {
4949
useSetIfNotUndefinedEffect('groupArraysAfterLength', props.groupArraysAfterLength)
5050
useSetIfNotUndefinedEffect('keyRenderer', props.keyRenderer)
5151
useSetIfNotUndefinedEffect('maxDisplayLength', props.maxDisplayLength)
52+
useSetIfNotUndefinedEffect('enableClipboard', props.enableClipboard)
5253
useEffect(() => {
5354
if (props.theme === 'light') {
5455
api.setState({

src/stores/JsonViewerStore.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ export type JsonViewerState<T = unknown> = {
1616
hoverPath: { path: Path; nestedIndex?: number } | null
1717
indentWidth: number
1818
groupArraysAfterLength: number
19+
enableClipboard: boolean
1920
maxDisplayLength: number
2021
defaultInspectDepth: number
2122
collapseStringsAfterLength: number
2223
colorNamespace: ColorNamespace
23-
expanded: string[]
2424
editable: boolean | (<U>(path: Path, currentValue: U) => boolean)
2525
rootName: false | string
2626
value: T
@@ -39,20 +39,22 @@ export const createJsonViewerStore = <T = unknown>(props: JsonViewerProps<T>) =>
3939
create(
4040
combine<JsonViewerState<T>, JsonViewerActions>(
4141
{
42-
inspectCache: {},
43-
hoverPath: null,
42+
// provided by user
43+
enableClipboard: props.enableClipboard ?? true,
4444
indentWidth: props.indentWidth ?? 3,
4545
groupArraysAfterLength: props.groupArraysAfterLength ?? 100,
4646
collapseStringsAfterLength: props.collapseStringsAfterLength ?? 50,
4747
maxDisplayLength: props.maxDisplayLength ?? 30,
4848
rootName: props.rootName ?? 'root',
49+
onChange: props.onChange ?? (() => {}),
50+
keyRenderer: props.keyRenderer ?? DefaultKeyRenderer,
51+
editable: props.editable ?? true,
52+
// internal state
53+
inspectCache: {},
54+
hoverPath: null,
4955
defaultInspectDepth: 5,
5056
colorNamespace: lightColorNamespace,
51-
editable: props.editable ?? true,
52-
expanded: ['data-viewer-root'],
53-
value: props.value,
54-
onChange: props.onChange ?? (() => {}),
55-
keyRenderer: props.keyRenderer ?? DefaultKeyRenderer
57+
value: props.value
5658
},
5759
(set, get) => ({
5860
getInspectCache: (path, nestedIndex) => {

src/type.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export type JsonViewerProps<T = unknown> = {
6161
* @param newValue
6262
*/
6363
onChange?: <U>(path: Path, oldValue: U, newValue: U) => void
64+
/**
65+
* Whether enable clipboard feature.
66+
*
67+
* @default true
68+
*/
69+
enableClipboard?: boolean
6470
/**
6571
* Whether this value can be edited.
6672
*

0 commit comments

Comments
 (0)