Skip to content

Commit 40372b8

Browse files
committed
fix: fix editable props. (#3)
1 parent c2f4c20 commit 40372b8

File tree

8 files changed

+62
-33
lines changed

8 files changed

+62
-33
lines changed

core/README.md

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ const customTheme = {
112112
'--w-rjv-background-color': '#1e1e1e',
113113
'--w-rjv-line-color': '#323232',
114114
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
115+
'--w-rjv-edit-color': 'var(--w-rjv-color)',
115116
'--w-rjv-info-color': '#656565',
116117
'--w-rjv-update-color': '#ebcb8b',
117118
'--w-rjv-copied-color': '#9cdcfe',
@@ -144,9 +145,9 @@ export default function Demo() {
144145
Online custom style example, please check in the [documentation website](https://uiwjs.github.io/react-json-view/)
145146

146147
```tsx mdx:preview:&title=Online Editing Theme
147-
import React, { useState, useEffect, useRef } from 'react';
148+
import React, { useState, useEffect } from 'react';
148149
import Colorful from '@uiw/react-color-colorful';
149-
import JsonView from '@uiw/react-json-view';
150+
import JsonView from '@uiw/react-json-view/editor';
150151

151152
const object = {
152153
avatar: 'https://i.imgur.com/MK3eW3As.jpg',
@@ -176,6 +177,7 @@ const customTheme = {
176177
'--w-rjv-background-color': '#1e1e1e',
177178
'--w-rjv-line-color': '#323232',
178179
'--w-rjv-arrow-color': '#9cdcfe',
180+
'--w-rjv-edit-color': '#9cdcfe',
179181
'--w-rjv-info-color': '#656565',
180182
'--w-rjv-update-color': '#ebcb8b',
181183
'--w-rjv-copied-color': '#0184a6',
@@ -199,6 +201,7 @@ const customTheme = {
199201
export default function Demo() {
200202
const [cssvar, setCssvar] = useState('--w-rjv-background-color');
201203
const [hex, setHex] = useState("#1e1e1e");
204+
const [editable, setEditable] = useState(false);
202205
const [theme, setTheme] = useState(customTheme);
203206
const onChange = ({ hexa }) => {
204207
setHex(hexa);
@@ -217,13 +220,17 @@ export default function Demo() {
217220
return () => clearInterval(id)
218221
}, []);
219222

223+
const changeEditable = (evn) => setEditable(evn.target.checked);
220224
return (
221225
<React.Fragment>
222-
<div style={{ display: 'flex', gap: '1rem' }}>
223-
<JsonView value={src} keyName="root" style={{ flex: 1, ...theme }} />
226+
<label>
227+
<input type="checkbox" checked={editable} onChange={changeEditable} /> Editable
228+
</label>
229+
<div style={{ display: 'flex', gap: '1rem', alignItems: 'flex-start' }}>
230+
<JsonView editable={editable} value={src} keyName="root" style={{ flex: 1, overflow: 'auto', ...theme }} />
224231
<div>
225232
<Colorful color={hex} onChange={onChange} />
226-
<div style={{ display: 'flex', gap: '0.4rem', flexWrap: 'wrap' }}>
233+
<div style={{ display: 'flex', gap: '0.4rem', flexDirection: 'column' }}>
227234
{Object.keys(customTheme).map((varname, idx) => {
228235
const click = () => {
229236
setCssvar(varname);
@@ -577,6 +584,8 @@ export default function Demo() {
577584

578585
## Props
579586

587+
### JsonView Props
588+
580589
```ts
581590
import React from 'react';
582591
import { MetaProps, SemicolonProps, EllipsisProps, ValueViewProps } from '@uiw/react-json-view';
@@ -624,6 +633,26 @@ declare const JsonView: React.ForwardRefExoticComponent<Omit<JsonViewProps<objec
624633
export default JsonView;
625634
```
626635

636+
### JsonView Editor Props
637+
638+
```ts
639+
import { JsonViewProps } from '@uiw/react-json-view';
640+
export interface JsonViewEditorProps<T extends object> extends JsonViewProps<T> {
641+
/** Callback when value edit functionality */
642+
onEdit?: (option: {
643+
value: unknown;
644+
oldValue: unknown;
645+
keyName?: string | number;
646+
parentName?: string | number;
647+
type?: 'value' | 'key';
648+
}) => void;
649+
/** Whether enable edit feature. @default true */
650+
editable?: boolean;
651+
}
652+
declare const JsonViewEditor: import("react").ForwardRefExoticComponent<Omit<JsonViewEditorProps<object>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
653+
export default JsonViewEditor;
654+
```
655+
627656
## Size and dependencies
628657

629658
Here is the size benchmark (using [bundlephobia.com](https://bundlephobia.com)) against similar React libraries (found by [`npmjs.com/search`](https://www.npmjs.com/search?q=react%20json&ranking=popularity)):

core/src/editor/index.tsx

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ import JsonView, { JsonViewProps } from '../';
33
import { ObjectKey } from './objectKey';
44
import { ReValue } from './value';
55

6-
type Option = {
7-
value: unknown;
8-
oldValue: unknown;
9-
keyName?: string | number;
10-
parentName?: string | number;
11-
type?: 'value' | 'key'
12-
}
13-
146
export interface JsonViewEditorProps<T extends object> extends JsonViewProps<T> {
157
/** Callback when value edit functionality */
16-
onEdit?: (option: Option) => void;
8+
onEdit?: (option: {
9+
value: unknown;
10+
oldValue: unknown;
11+
keyName?: string | number;
12+
parentName?: string | number;
13+
type?: 'value' | 'key';
14+
}) => void;
1715
/** Whether enable edit feature. @default true */
1816
editable?: boolean;
1917
}
@@ -22,16 +20,14 @@ const JsonViewEditor = forwardRef<HTMLDivElement, JsonViewEditorProps<object>>((
2220
const { onEdit, components, editable = true, displayDataTypes = true, ...reset } = props;
2321
const comps: JsonViewEditorProps<object>['components'] = {
2422
...components,
25-
}
26-
if (editable) {
27-
comps.objectKey = (reprops) => <ObjectKey {...reprops} onEdit={onEdit} render={components?.objectKey} />;
28-
comps.value = (reprops) => {
29-
return <ReValue {...reprops} displayDataTypes={displayDataTypes} onEdit={onEdit} />
30-
};
23+
objectKey: (reprops) => <ObjectKey {...reprops} editableValue={editable} onEdit={onEdit} render={components?.objectKey} />,
24+
value: (reprops) => {
25+
return <ReValue {...reprops} editableValue={editable} displayDataTypes={displayDataTypes} onEdit={onEdit} />
26+
}
3127
}
3228
return (
33-
<JsonView {...reset} displayDataTypes={false} components={{...comps}} ref={ref} />
34-
)
29+
<JsonView {...reset} displayDataTypes={false} components={comps} ref={ref} />
30+
);
3531
});
3632

3733
export default JsonViewEditor;

core/src/editor/objectKey.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ import { JsonViewEditorProps } from './';
66
export interface ObjectKeyProps<T extends object> extends SemicolonProps {
77
onEdit?: JsonViewEditorProps<T>['onEdit'];
88
render?: (props: SemicolonProps & { ref?: React.RefObject<HTMLElement> }) => React.ReactNode;
9+
editableValue?: boolean;
910
}
1011

1112
export const ObjectKey: FC<ObjectKeyProps<object>>= (props) => {
12-
const { className, value, keyName, parentName, quotes, label, onEdit, highlightUpdates = true, render, ...reset } = props;
13+
const { className, value, keyName, parentName, quotes, label, editableValue, onEdit, highlightUpdates = true, render, ...reset } = props;
1314
const [editable, setEditable] = useState(false);
1415
const [curentLabel, setCurentLabel] = useState(label);
1516
useEffect(() => setCurentLabel(label), [label]);
1617
const $edit = useRef<HTMLSpanElement>(null);
1718
useHighlight({ value, highlightUpdates: highlightUpdates, highlightContainer: $edit });
1819
const click = (evn: React.MouseEvent<HTMLSpanElement, MouseEvent>) => {
1920
evn.stopPropagation();
21+
if (!editableValue) return;
2022
if (typeof keyName !== 'string') return;
2123
if (editable) return;
2224
setEditable(true);

core/src/editor/value.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,28 @@ export interface ReValueProps<T extends object> extends React.HTMLAttributes<HTM
1616
type: TypeProps['type'];
1717
value?: unknown;
1818
visible?: boolean;
19+
editableValue?: boolean;
1920
displayDataTypes?: boolean;
2021
}
2122

2223
export function ReValue<T extends object>(props: ReValueProps<T>) {
23-
const { type, value, keyName, visible, quotes, style, content, children, displayDataTypes, onEdit, ...reset } = props;
24+
const { type, value, keyName, visible, quotes, style, content, children, displayDataTypes, editableValue, onEdit, ...reset } = props;
2425
const [editable, setEditable] = useState(false);
2526
const $edit = useRef<HTMLSpanElement>(null);
2627
const [curentType, setCurentType] = useState(type);
2728
const [curentChild, setCurentChild] = useState(value);
2829
useEffect(() => setCurentChild(value), [value]);
2930
const click = (evn: React.MouseEvent<SVGElement, MouseEvent>) => {
3031
evn.stopPropagation();
32+
if (!editableValue) return;
3133
if ($edit.current) {
3234
setEditable(true);
3335
$edit.current!.contentEditable = 'true';
3436
$edit.current?.focus();
3537
}
3638
}
3739
const keyDown = (evn: React.KeyboardEvent<HTMLSpanElement>) => {
40+
if (!editableValue) return;
3841
if (evn.key === 'Enter') {
3942
evn.stopPropagation();
4043
evn.preventDefault();
@@ -43,6 +46,7 @@ export function ReValue<T extends object>(props: ReValueProps<T>) {
4346
}
4447
}
4548
const blur = () => {
49+
if (!editableValue) return;
4650
setEditable(false);
4751
if ($edit.current) {
4852
$edit.current.contentEditable = 'false';
@@ -107,7 +111,7 @@ export function ReValue<T extends object>(props: ReValueProps<T>) {
107111
<span {...spanProps} ref={$edit} data-value={content}>{typeof curentChild === 'string' ? curentChild : childStr}</span>
108112
<Quotes style={style} quotes={quotes} show={typeStr === 'string'} />
109113
</Fragment>
110-
{visible && <EditIcon onClick={click} />}
114+
{visible && editableValue && <EditIcon onClick={click} />}
111115
</Fragment>
112116
);
113117

core/src/node.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,7 @@ export function RooNode<T extends object>(props: RooNodeProps<T>) {
109109
keyName={keyName}
110110
parentName={keyName}
111111
color={typeof keyName === 'number' ? typeMap['number'].color : ''}
112-
>
113-
{keyName}
114-
</Semicolon>
112+
/>
115113
<Colon />
116114
</Fragment>
117115
)}
@@ -142,9 +140,7 @@ export function RooNode<T extends object>(props: RooNodeProps<T>) {
142140
render={components.objectKey}
143141
color={typeof key === 'number' ? typeMap['number'].color : ''}
144142
keyName={key}
145-
>
146-
{key}
147-
</Semicolon>
143+
/>
148144
);
149145
const isEmpty = (Array.isArray(item) && (item as []).length === 0) || (typeof item === 'object' && item && !((item as any) instanceof Date) && Object.keys(item).length === 0);
150146
if (Array.isArray(item) && !isEmpty) {

core/src/semicolon.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ export const Semicolon: FC<PropsWithChildren<SemicolonProps>> = ({
8787
...props
8888
}) => {
8989
const highlightContainer = useRef<HTMLSpanElement>(null);
90-
const content = typeof keyName === 'string' ? `${quotes}${children}${quotes}` : children;
90+
const content = typeof keyName === 'string' ? `${quotes}${keyName}${quotes}` : keyName;
9191
if (render) {
92-
return render({ className, ...props, value, style: { ...style, color }, parentName, keyName, quotes, label: children as string, children: content });
92+
return render({ className, ...props, value, style: { ...style, color }, parentName, keyName, quotes, label: keyName as string, children: content });
9393
};
9494
useHighlight({ value, highlightUpdates, highlightContainer });
9595
return (

core/src/theme/dark.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const darkTheme = {
44
'--w-rjv-background-color': '#202020',
55
'--w-rjv-line-color': '#323232',
66
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
7+
'--w-rjv-edit-color': 'var(--w-rjv-color)',
78
'--w-rjv-info-color': '#656565',
89
'--w-rjv-update-color': '#ebcb8b',
910
'--w-rjv-copied-color': '#0184a6',

core/src/theme/light.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export const lightTheme = {
44
'--w-rjv-background-color': '#ffffff',
55
'--w-rjv-line-color': '#ebebeb',
66
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
7+
'--w-rjv-edit-color': 'var(--w-rjv-color)',
78
'--w-rjv-info-color': '#0000004d',
89
'--w-rjv-update-color': '#ebcb8b',
910
'--w-rjv-copied-color': '#002b36',

0 commit comments

Comments
 (0)