@uiw/react-json-view 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -23
- package/cjs/copied.d.ts +1 -0
- package/cjs/copied.js +4 -2
- package/cjs/index.d.ts +4 -0
- package/cjs/node.d.ts +2 -0
- package/cjs/node.js +74 -8
- package/cjs/theme/dark.d.ts +1 -0
- package/cjs/theme/dark.js +1 -0
- package/cjs/theme/light.d.ts +1 -0
- package/cjs/theme/light.js +1 -0
- package/cjs/value.d.ts +1 -1
- package/cjs/value.js +13 -13
- package/esm/copied.d.ts +1 -0
- package/esm/copied.js +4 -2
- package/esm/index.d.ts +4 -0
- package/esm/node.d.ts +2 -0
- package/esm/node.js +72 -8
- package/esm/theme/dark.d.ts +1 -0
- package/esm/theme/dark.js +1 -0
- package/esm/theme/light.d.ts +1 -0
- package/esm/theme/light.js +1 -0
- package/esm/value.d.ts +1 -1
- package/esm/value.js +14 -14
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@ react-json-view
|
|
|
4
4
|
[](https://github.com/uiwjs/react-json-view/actions/workflows/ci.yml)
|
|
5
5
|
[](https://www.npmjs.com/package/@uiw/react-json-view)
|
|
6
6
|
[](https://github.com/facebook/react/releases)
|
|
7
|
+
[](https://uiwjs.github.io/react-json-view/lcov-report/)
|
|
7
8
|
|
|
8
9
|
A React component for displaying and editing javascript arrays and JSON objects.
|
|
9
10
|
|
|
@@ -22,7 +23,8 @@ A React component for displaying and editing javascript arrays and JSON objects.
|
|
|
22
23
|
📚 Use Typescript to write, better code hints.
|
|
23
24
|
🎨 Support theme customization & [`online editing`](https://uiwjs.github.io/react-json-view/#online-editing-theme) theme
|
|
24
25
|
🌒 Support dark/light mode
|
|
25
|
-
📦 Zero dependencies
|
|
26
|
+
📦 Zero dependencies
|
|
27
|
+
♻️ Whether to highlight updates.
|
|
26
28
|
|
|
27
29
|
## Quick Start
|
|
28
30
|
|
|
@@ -111,6 +113,7 @@ const customTheme = {
|
|
|
111
113
|
'--w-rjv-line-color': '#323232',
|
|
112
114
|
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
|
|
113
115
|
'--w-rjv-info-color': '#656565',
|
|
116
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
114
117
|
'--w-rjv-copied-color': '#9cdcfe',
|
|
115
118
|
'--w-rjv-copied-success-color': '#28a745',
|
|
116
119
|
|
|
@@ -140,7 +143,7 @@ export default function Demo() {
|
|
|
140
143
|
Online custom style example, please check in the [documentation website](https://uiwjs.github.io/react-json-view/)
|
|
141
144
|
|
|
142
145
|
```tsx mdx:preview:&title=Online Editing Theme
|
|
143
|
-
import React, { useState, useRef } from 'react';
|
|
146
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
144
147
|
import Colorful from '@uiw/react-color-colorful';
|
|
145
148
|
import JsonView from '@uiw/react-json-view';
|
|
146
149
|
|
|
@@ -172,6 +175,7 @@ const customTheme = {
|
|
|
172
175
|
'--w-rjv-line-color': '#323232',
|
|
173
176
|
'--w-rjv-arrow-color': '#9cdcfe',
|
|
174
177
|
'--w-rjv-info-color': '#656565',
|
|
178
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
175
179
|
'--w-rjv-copied-color': '#0184a6',
|
|
176
180
|
'--w-rjv-copied-success-color': '#28a745',
|
|
177
181
|
|
|
@@ -197,10 +201,23 @@ export default function Demo() {
|
|
|
197
201
|
setHex(hexa);
|
|
198
202
|
setTheme({ ...theme, [cssvar]: hexa });
|
|
199
203
|
};
|
|
204
|
+
|
|
205
|
+
const [src, setSrc] = useState({ ...object })
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
const loop = () => {
|
|
208
|
+
setSrc(src => ({
|
|
209
|
+
...src,
|
|
210
|
+
timer: src.timer + 1
|
|
211
|
+
}))
|
|
212
|
+
}
|
|
213
|
+
const id = setInterval(loop, 1000)
|
|
214
|
+
return () => clearInterval(id)
|
|
215
|
+
}, []);
|
|
216
|
+
|
|
200
217
|
return (
|
|
201
218
|
<React.Fragment>
|
|
202
219
|
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
203
|
-
<JsonView value={
|
|
220
|
+
<JsonView value={src} keyName="root" style={{ flex: 1, ...theme }} />
|
|
204
221
|
<div>
|
|
205
222
|
<Colorful color={hex} onChange={onChange} />
|
|
206
223
|
<div style={{ display: 'flex', gap: '0.4rem', flexWrap: 'wrap' }}>
|
|
@@ -305,6 +322,50 @@ export default function Demo() {
|
|
|
305
322
|
}
|
|
306
323
|
```
|
|
307
324
|
|
|
325
|
+
## Highlight Updates
|
|
326
|
+
|
|
327
|
+
```tsx mdx:preview
|
|
328
|
+
import React, { useState, useEffect } from 'react';
|
|
329
|
+
import JsonView from '@uiw/react-json-view';
|
|
330
|
+
import { TriangleArrow } from '@uiw/react-json-view/triangle-arrow';
|
|
331
|
+
import { TriangleSolidArrow } from '@uiw/react-json-view/triangle-solid-arrow';
|
|
332
|
+
|
|
333
|
+
const object = {
|
|
334
|
+
string: 'Lorem ipsum dolor sit amet',
|
|
335
|
+
integer: 42,
|
|
336
|
+
timer: 0,
|
|
337
|
+
object: { 'first-child': true, 'second-child': false, 'last-child': null },
|
|
338
|
+
}
|
|
339
|
+
export default function Demo() {
|
|
340
|
+
const [src, setSrc] = useState({ ...object })
|
|
341
|
+
useEffect(() => {
|
|
342
|
+
const loop = () => {
|
|
343
|
+
setSrc(src => ({
|
|
344
|
+
...src,
|
|
345
|
+
timer: src.timer + 1
|
|
346
|
+
}))
|
|
347
|
+
}
|
|
348
|
+
const id = setInterval(loop, 1000)
|
|
349
|
+
return () => clearInterval(id)
|
|
350
|
+
}, []);
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<JsonView
|
|
354
|
+
value={src}
|
|
355
|
+
keyName="root"
|
|
356
|
+
style={{
|
|
357
|
+
'--w-rjv-background-color': '#ffffff',
|
|
358
|
+
'--w-rjv-border-left': '1px dashed #ebebeb',
|
|
359
|
+
// ✅ Change default update background color ✅
|
|
360
|
+
'--w-rjv-update-color': '#ff6ffd',
|
|
361
|
+
}}
|
|
362
|
+
/>
|
|
363
|
+
)
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
This feature can be disabled with `highlightUpdates={false}`, and the default color can be changed with `--w-rjv-update-color`.
|
|
368
|
+
|
|
308
369
|
## Modify Icon Style
|
|
309
370
|
|
|
310
371
|
Use built-in default icons.
|
|
@@ -368,34 +429,25 @@ const object = {
|
|
|
368
429
|
}
|
|
369
430
|
|
|
370
431
|
const Arrow = (props) => {
|
|
371
|
-
const { style, 'data-expand': expand,
|
|
372
|
-
const
|
|
373
|
-
cursor: 'pointer',
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
432
|
+
const { style, 'data-expand': expand, ...reset } = props;
|
|
433
|
+
const svgProps = {
|
|
434
|
+
style: { cursor: 'pointer', height: '1em', width: '1em' },
|
|
435
|
+
viewBox: '0 0 24 24',
|
|
436
|
+
fill: 'var(--w-rjv-arrow-color, currentColor)',
|
|
437
|
+
...reset
|
|
438
|
+
}
|
|
377
439
|
if (!expand) {
|
|
378
440
|
return (
|
|
379
|
-
<svg
|
|
380
|
-
viewBox="0 0 24 24"
|
|
381
|
-
fill="var(--w-rjv-arrow-color, currentColor)"
|
|
382
|
-
style={defaultStyle}
|
|
383
|
-
{...reset}
|
|
384
|
-
>
|
|
441
|
+
<svg {...svgProps}>
|
|
385
442
|
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z" />
|
|
386
443
|
</svg>
|
|
387
|
-
)
|
|
444
|
+
);
|
|
388
445
|
}
|
|
389
446
|
return (
|
|
390
|
-
<svg
|
|
391
|
-
viewBox="0 0 24 24"
|
|
392
|
-
fill="var(--w-rjv-arrow-color, currentColor)"
|
|
393
|
-
style={defaultStyle}
|
|
394
|
-
{...reset}
|
|
395
|
-
>
|
|
447
|
+
<svg {...svgProps}>
|
|
396
448
|
<path d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7,13H17V11H7" />
|
|
397
449
|
</svg>
|
|
398
|
-
)
|
|
450
|
+
);
|
|
399
451
|
}
|
|
400
452
|
|
|
401
453
|
export default function Demo() {
|
|
@@ -433,6 +485,8 @@ export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttr
|
|
|
433
485
|
keyName?: string | number;
|
|
434
486
|
/** The user can copy objects and arrays to clipboard by clicking on the clipboard icon. @default true */
|
|
435
487
|
enableClipboard?: boolean;
|
|
488
|
+
/** Whether to highlight updates. @default true */
|
|
489
|
+
highlightUpdates?: boolean;
|
|
436
490
|
/** Display for quotes in object-key @default " */
|
|
437
491
|
quotes?: "'" | '"' | '';
|
|
438
492
|
/** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
|
package/cjs/copied.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
export interface CopiedProps<T = object> extends React.SVGProps<SVGSVGElement> {
|
|
3
3
|
show?: boolean;
|
|
4
4
|
text?: T;
|
|
5
|
+
onCopied?: (text: string, obj: T | '') => void;
|
|
5
6
|
render?: (props: Omit<CopiedProps<T>, 'render'>) => JSX.Element;
|
|
6
7
|
}
|
|
7
8
|
export declare function Copied<T>(props: CopiedProps<T>): JSX.Element | null;
|
package/cjs/copied.js
CHANGED
|
@@ -10,12 +10,13 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
|
|
|
10
10
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
11
11
|
var _react = require("react");
|
|
12
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
-
var _excluded = ["children", "style", "text", "render", "show"];
|
|
13
|
+
var _excluded = ["children", "style", "text", "onCopied", "render", "show"];
|
|
14
14
|
function Copied(props) {
|
|
15
15
|
var children = props.children,
|
|
16
16
|
style = props.style,
|
|
17
17
|
_props$text = props.text,
|
|
18
18
|
text = _props$text === void 0 ? '' : _props$text,
|
|
19
|
+
onCopied = props.onCopied,
|
|
19
20
|
render = props.render,
|
|
20
21
|
show = props.show,
|
|
21
22
|
reset = (0, _objectWithoutProperties2["default"])(props, _excluded);
|
|
@@ -26,7 +27,7 @@ function Copied(props) {
|
|
|
26
27
|
setCopied = _useState2[1];
|
|
27
28
|
var click = function click(event) {
|
|
28
29
|
event.stopPropagation();
|
|
29
|
-
var copyText = JSON.stringify(text, function (key, value) {
|
|
30
|
+
var copyText = JSON.stringify(text || '', function (key, value) {
|
|
30
31
|
if (typeof value === 'bigint') {
|
|
31
32
|
return value.toString();
|
|
32
33
|
}
|
|
@@ -34,6 +35,7 @@ function Copied(props) {
|
|
|
34
35
|
}, 2);
|
|
35
36
|
if (text === Infinity) copyText = Infinity;
|
|
36
37
|
navigator.clipboard.writeText(copyText).then(function () {
|
|
38
|
+
onCopied && onCopied(copyText, text);
|
|
37
39
|
setCopied(true);
|
|
38
40
|
var timer = setTimeout(function () {
|
|
39
41
|
setCopied(false);
|
package/cjs/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
|
|
|
17
17
|
keyName?: string | number;
|
|
18
18
|
/** The user can copy objects and arrays to clipboard by clicking on the clipboard icon. @default true */
|
|
19
19
|
enableClipboard?: boolean;
|
|
20
|
+
/** Whether to highlight updates. @default true */
|
|
21
|
+
highlightUpdates?: boolean;
|
|
20
22
|
/** Display for quotes in object-key @default " */
|
|
21
23
|
quotes?: "'" | '"' | '';
|
|
22
24
|
/** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
|
|
@@ -28,6 +30,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
|
|
|
28
30
|
keyid: string;
|
|
29
31
|
keyName?: string | number;
|
|
30
32
|
}) => void;
|
|
33
|
+
/** Fires event when you copy */
|
|
34
|
+
onCopied?: CopiedProps<T>['onCopied'];
|
|
31
35
|
/** Redefine interface elements to re-render. */
|
|
32
36
|
components?: {
|
|
33
37
|
braces?: MetaProps['render'];
|
package/cjs/node.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface MetaProps extends LabelProps {
|
|
|
6
6
|
start?: boolean;
|
|
7
7
|
render?: (props: Pick<MetaProps, 'start' | 'isArray' | 'className' | 'children'>) => JSX.Element;
|
|
8
8
|
}
|
|
9
|
+
export declare function usePrevious<T>(value: T): T | undefined;
|
|
9
10
|
export declare function Meta(props: MetaProps): JSX.Element;
|
|
10
11
|
export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
11
12
|
render?: (props: EllipsisProps) => JSX.Element;
|
|
@@ -13,6 +14,7 @@ export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
13
14
|
export declare const Ellipsis: FC<PropsWithChildren<EllipsisProps>>;
|
|
14
15
|
export interface SemicolonProps extends LabelProps {
|
|
15
16
|
show?: boolean;
|
|
17
|
+
highlightUpdates?: boolean;
|
|
16
18
|
quotes?: JsonViewProps<object>['quotes'];
|
|
17
19
|
value?: object;
|
|
18
20
|
render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
|
package/cjs/node.js
CHANGED
|
@@ -8,8 +8,9 @@ exports.Ellipsis = exports.CountInfo = void 0;
|
|
|
8
8
|
exports.Meta = Meta;
|
|
9
9
|
exports.RooNode = RooNode;
|
|
10
10
|
exports.Semicolon = void 0;
|
|
11
|
-
|
|
11
|
+
exports.usePrevious = usePrevious;
|
|
12
12
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
13
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
13
14
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
14
15
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
15
16
|
var _react = require("react");
|
|
@@ -20,8 +21,15 @@ var _copied = require("./copied");
|
|
|
20
21
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
22
|
var _excluded = ["isArray", "start", "className", "render"],
|
|
22
23
|
_excluded2 = ["style", "render"],
|
|
23
|
-
_excluded3 = ["children", "render", "color", "value", "className", "show", "quotes"],
|
|
24
|
-
_excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "indentWidth", "collapsed", "level", "keyid", "quotes", "onExpand"];
|
|
24
|
+
_excluded3 = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes"],
|
|
25
|
+
_excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
|
|
26
|
+
function usePrevious(value) {
|
|
27
|
+
var ref = (0, _react.useRef)();
|
|
28
|
+
(0, _react.useEffect)(function () {
|
|
29
|
+
ref.current = value;
|
|
30
|
+
});
|
|
31
|
+
return ref.current;
|
|
32
|
+
}
|
|
25
33
|
function Meta(props) {
|
|
26
34
|
var _props$isArray = props.isArray,
|
|
27
35
|
isArray = _props$isArray === void 0 ? false : _props$isArray,
|
|
@@ -77,8 +85,50 @@ var Semicolon = function Semicolon(_ref2) {
|
|
|
77
85
|
_ref2$className = _ref2.className,
|
|
78
86
|
className = _ref2$className === void 0 ? 'w-rjv-object-key' : _ref2$className,
|
|
79
87
|
show = _ref2.show,
|
|
88
|
+
highlightUpdates = _ref2.highlightUpdates,
|
|
80
89
|
quotes = _ref2.quotes,
|
|
81
90
|
props = (0, _objectWithoutProperties2["default"])(_ref2, _excluded3);
|
|
91
|
+
var prevValue = usePrevious(value);
|
|
92
|
+
var highlightContainer = (0, _react.useRef)(null);
|
|
93
|
+
var isHighlight = (0, _react.useMemo)(function () {
|
|
94
|
+
if (!highlightUpdates || prevValue === undefined) return false;
|
|
95
|
+
// highlight if value type changed
|
|
96
|
+
if ((0, _typeof2["default"])(value) !== (0, _typeof2["default"])(prevValue)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (typeof value === 'number') {
|
|
100
|
+
// notice: NaN !== NaN
|
|
101
|
+
if (isNaN(value) && isNaN(prevValue)) return false;
|
|
102
|
+
return value !== prevValue;
|
|
103
|
+
}
|
|
104
|
+
// highlight if isArray changed
|
|
105
|
+
if (Array.isArray(value) !== Array.isArray(prevValue)) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
// not highlight object/function
|
|
109
|
+
// deep compare they will be slow
|
|
110
|
+
if ((0, _typeof2["default"])(value) === 'object' || typeof value === 'function') {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// highlight if not equal
|
|
115
|
+
if (value !== prevValue) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}, [highlightUpdates, value]);
|
|
120
|
+
(0, _react.useEffect)(function () {
|
|
121
|
+
if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
|
|
122
|
+
highlightContainer.current.animate([{
|
|
123
|
+
backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
|
|
124
|
+
}, {
|
|
125
|
+
backgroundColor: ''
|
|
126
|
+
}], {
|
|
127
|
+
duration: 1000,
|
|
128
|
+
easing: 'ease-in'
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}, [isHighlight, value]);
|
|
82
132
|
var content = show ? "".concat(quotes).concat(children).concat(quotes) : children;
|
|
83
133
|
if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
84
134
|
className: className
|
|
@@ -93,6 +143,7 @@ var Semicolon = function Semicolon(_ref2) {
|
|
|
93
143
|
className: className,
|
|
94
144
|
color: color
|
|
95
145
|
}, props), {}, {
|
|
146
|
+
ref: highlightContainer,
|
|
96
147
|
children: content
|
|
97
148
|
}));
|
|
98
149
|
};
|
|
@@ -105,7 +156,7 @@ var CountInfo = function CountInfo(_ref3) {
|
|
|
105
156
|
fontStyle: 'italic'
|
|
106
157
|
},
|
|
107
158
|
color: "var(--w-rjv-info-color, #0000004d)",
|
|
108
|
-
className: "object-size",
|
|
159
|
+
className: "w-rjv-object-size",
|
|
109
160
|
children: children
|
|
110
161
|
});
|
|
111
162
|
};
|
|
@@ -115,6 +166,7 @@ function RooNode(props) {
|
|
|
115
166
|
var _props$value = props.value,
|
|
116
167
|
value = _props$value === void 0 ? {} : _props$value,
|
|
117
168
|
keyName = props.keyName,
|
|
169
|
+
className = props.className,
|
|
118
170
|
_props$displayDataTyp = props.displayDataTypes,
|
|
119
171
|
displayDataTypes = _props$displayDataTyp === void 0 ? true : _props$displayDataTyp,
|
|
120
172
|
_props$components = props.components,
|
|
@@ -123,6 +175,8 @@ function RooNode(props) {
|
|
|
123
175
|
displayObjectSize = _props$displayObjectS === void 0 ? true : _props$displayObjectS,
|
|
124
176
|
_props$enableClipboar = props.enableClipboard,
|
|
125
177
|
enableClipboard = _props$enableClipboar === void 0 ? true : _props$enableClipboar,
|
|
178
|
+
_props$highlightUpdat = props.highlightUpdates,
|
|
179
|
+
highlightUpdates = _props$highlightUpdat === void 0 ? true : _props$highlightUpdat,
|
|
126
180
|
_props$indentWidth = props.indentWidth,
|
|
127
181
|
indentWidth = _props$indentWidth === void 0 ? 15 : _props$indentWidth,
|
|
128
182
|
collapsed = props.collapsed,
|
|
@@ -132,6 +186,7 @@ function RooNode(props) {
|
|
|
132
186
|
keyid = _props$keyid === void 0 ? 'root' : _props$keyid,
|
|
133
187
|
_props$quotes = props.quotes,
|
|
134
188
|
quotes = _props$quotes === void 0 ? '"' : _props$quotes,
|
|
189
|
+
onCopied = props.onCopied,
|
|
135
190
|
onExpand = props.onExpand,
|
|
136
191
|
reset = (0, _objectWithoutProperties2["default"])(props, _excluded4);
|
|
137
192
|
var isArray = Array.isArray(value);
|
|
@@ -160,6 +215,8 @@ function RooNode(props) {
|
|
|
160
215
|
displayDataTypes: displayDataTypes,
|
|
161
216
|
displayObjectSize: displayObjectSize,
|
|
162
217
|
enableClipboard: enableClipboard,
|
|
218
|
+
highlightUpdates: highlightUpdates,
|
|
219
|
+
onCopied: onCopied,
|
|
163
220
|
onExpand: onExpand,
|
|
164
221
|
collapsed: collapsed,
|
|
165
222
|
quotes: quotes,
|
|
@@ -173,13 +230,16 @@ function RooNode(props) {
|
|
|
173
230
|
displayObjectSize: displayObjectSize,
|
|
174
231
|
enableClipboard: enableClipboard,
|
|
175
232
|
indentWidth: indentWidth,
|
|
233
|
+
renderBraces: components.braces,
|
|
176
234
|
renderValue: components.value
|
|
177
235
|
};
|
|
178
236
|
var arrowView = components.arrow ? /*#__PURE__*/(0, _react.cloneElement)(components.arrow, {
|
|
179
237
|
style: arrowStyle,
|
|
180
|
-
'data-expand': expand
|
|
238
|
+
'data-expand': expand,
|
|
239
|
+
className: "w-rjv-arrow"
|
|
181
240
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_TriangleArrow.TriangleArrow, {
|
|
182
|
-
style: arrowStyle
|
|
241
|
+
style: arrowStyle,
|
|
242
|
+
className: "w-rjv-arrow"
|
|
183
243
|
});
|
|
184
244
|
var _useState = (0, _react.useState)(false),
|
|
185
245
|
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
@@ -188,6 +248,7 @@ function RooNode(props) {
|
|
|
188
248
|
var tools = enableClipboard ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
|
|
189
249
|
show: showTools,
|
|
190
250
|
text: value,
|
|
251
|
+
onCopied: onCopied,
|
|
191
252
|
render: components.copied
|
|
192
253
|
}) : undefined;
|
|
193
254
|
var eventProps = {};
|
|
@@ -199,7 +260,9 @@ function RooNode(props) {
|
|
|
199
260
|
return setShowTools(false);
|
|
200
261
|
};
|
|
201
262
|
}
|
|
202
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset),
|
|
263
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
|
|
264
|
+
className: "".concat(className, " w-rjv-inner")
|
|
265
|
+
}, eventProps), {}, {
|
|
203
266
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_value.Line, {
|
|
204
267
|
style: {
|
|
205
268
|
display: 'inline-flex',
|
|
@@ -228,6 +291,7 @@ function RooNode(props) {
|
|
|
228
291
|
children: [nameKeys.length, " items"]
|
|
229
292
|
}), tools]
|
|
230
293
|
}), expand && /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
|
|
294
|
+
className: "w-rjv-content",
|
|
231
295
|
style: {
|
|
232
296
|
borderLeft: 'var(--w-rjv-border-left-width, 1px) solid var(--w-rjv-line-color, #ebebeb)',
|
|
233
297
|
marginLeft: 6
|
|
@@ -237,6 +301,7 @@ function RooNode(props) {
|
|
|
237
301
|
var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
|
|
238
302
|
value: item,
|
|
239
303
|
quotes: quotes,
|
|
304
|
+
highlightUpdates: highlightUpdates,
|
|
240
305
|
render: components.objectKey,
|
|
241
306
|
color: typeof key === 'number' ? _value.typeMap['number'].color : '',
|
|
242
307
|
show: typeof key === 'string',
|
|
@@ -246,6 +311,7 @@ function RooNode(props) {
|
|
|
246
311
|
if (Array.isArray(item) && !isEmpty) {
|
|
247
312
|
var label = isArray ? idx : key;
|
|
248
313
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
|
|
314
|
+
className: "w-rjv-wrap",
|
|
249
315
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(RooNode, (0, _objectSpread2["default"])({
|
|
250
316
|
value: item,
|
|
251
317
|
keyid: keyid + subkeyid + label,
|
|
@@ -255,6 +321,7 @@ function RooNode(props) {
|
|
|
255
321
|
}
|
|
256
322
|
if ((0, _typeof2["default"])(item) === 'object' && item && !(item instanceof Date) && !isEmpty) {
|
|
257
323
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
|
|
324
|
+
className: "w-rjv-wrap",
|
|
258
325
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(RooNode, (0, _objectSpread2["default"])({
|
|
259
326
|
keyid: keyid + subkeyid + key,
|
|
260
327
|
value: item,
|
|
@@ -266,7 +333,6 @@ function RooNode(props) {
|
|
|
266
333
|
return;
|
|
267
334
|
}
|
|
268
335
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.ValueView, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, valueViewProps), {}, {
|
|
269
|
-
renderBraces: components.braces,
|
|
270
336
|
renderKey: renderKey,
|
|
271
337
|
keyName: key,
|
|
272
338
|
value: item
|
package/cjs/theme/dark.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const darkTheme: {
|
|
|
5
5
|
'--w-rjv-line-color': string;
|
|
6
6
|
'--w-rjv-arrow-color': string;
|
|
7
7
|
'--w-rjv-info-color': string;
|
|
8
|
+
'--w-rjv-update-color': string;
|
|
8
9
|
'--w-rjv-copied-color': string;
|
|
9
10
|
'--w-rjv-copied-success-color': string;
|
|
10
11
|
'--w-rjv-curlybraces-color': string;
|
package/cjs/theme/dark.js
CHANGED
|
@@ -11,6 +11,7 @@ var darkTheme = {
|
|
|
11
11
|
'--w-rjv-line-color': '#323232',
|
|
12
12
|
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
|
|
13
13
|
'--w-rjv-info-color': '#656565',
|
|
14
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
14
15
|
'--w-rjv-copied-color': '#0184a6',
|
|
15
16
|
'--w-rjv-copied-success-color': '#28a745',
|
|
16
17
|
'--w-rjv-curlybraces-color': '#1896b6',
|
package/cjs/theme/light.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const lightTheme: {
|
|
|
5
5
|
'--w-rjv-line-color': string;
|
|
6
6
|
'--w-rjv-arrow-color': string;
|
|
7
7
|
'--w-rjv-info-color': string;
|
|
8
|
+
'--w-rjv-update-color': string;
|
|
8
9
|
'--w-rjv-copied-color': string;
|
|
9
10
|
'--w-rjv-copied-success-color': string;
|
|
10
11
|
'--w-rjv-curlybraces-color': string;
|
package/cjs/theme/light.js
CHANGED
|
@@ -11,6 +11,7 @@ var lightTheme = {
|
|
|
11
11
|
'--w-rjv-line-color': '#ebebeb',
|
|
12
12
|
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
|
|
13
13
|
'--w-rjv-info-color': '#0000004d',
|
|
14
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
14
15
|
'--w-rjv-copied-color': '#002b36',
|
|
15
16
|
'--w-rjv-copied-success-color': '#28a745',
|
|
16
17
|
'--w-rjv-curlybraces-color': '#236a7c',
|
package/cjs/value.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export interface LabelProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
60
60
|
opacity?: number;
|
|
61
61
|
paddingRight?: number;
|
|
62
62
|
}
|
|
63
|
-
export declare const Label:
|
|
63
|
+
export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
64
64
|
export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
|
|
65
65
|
type: keyof typeof typeMap;
|
|
66
66
|
}
|
package/cjs/value.js
CHANGED
|
@@ -142,7 +142,12 @@ function ValueView(props) {
|
|
|
142
142
|
show: showTools,
|
|
143
143
|
text: value
|
|
144
144
|
}) : undefined;
|
|
145
|
-
var eventProps = {
|
|
145
|
+
var eventProps = {
|
|
146
|
+
className: 'w-rjv-line',
|
|
147
|
+
style: {
|
|
148
|
+
paddingLeft: indentWidth
|
|
149
|
+
}
|
|
150
|
+
};
|
|
146
151
|
if (enableClipboard) {
|
|
147
152
|
eventProps.onMouseEnter = function () {
|
|
148
153
|
return setShowTools(true);
|
|
@@ -167,12 +172,9 @@ function ValueView(props) {
|
|
|
167
172
|
className: "w-rjv-value",
|
|
168
173
|
children: content
|
|
169
174
|
});
|
|
170
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
171
|
-
style: {
|
|
172
|
-
paddingLeft: indentWidth
|
|
173
|
-
}
|
|
174
|
-
}, eventProps), {}, {
|
|
175
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, eventProps), {}, {
|
|
175
176
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
|
|
177
|
+
ref: null,
|
|
176
178
|
children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, valueView, tools]
|
|
177
179
|
}))
|
|
178
180
|
}));
|
|
@@ -190,17 +192,14 @@ function ValueView(props) {
|
|
|
190
192
|
children: [length, " items"]
|
|
191
193
|
})]
|
|
192
194
|
});
|
|
193
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
194
|
-
style: {
|
|
195
|
-
paddingLeft: indentWidth
|
|
196
|
-
}
|
|
197
|
-
}, eventProps), {}, {
|
|
195
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, eventProps), {}, {
|
|
198
196
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
|
|
197
|
+
ref: null,
|
|
199
198
|
children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, empty, tools]
|
|
200
199
|
}))
|
|
201
200
|
}));
|
|
202
201
|
}
|
|
203
|
-
var Label = function
|
|
202
|
+
var Label = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, ref) {
|
|
204
203
|
var children = _ref2.children,
|
|
205
204
|
color = _ref2.color,
|
|
206
205
|
fontSize = _ref2.fontSize,
|
|
@@ -216,9 +215,10 @@ var Label = function Label(_ref2) {
|
|
|
216
215
|
paddingRight: paddingRight
|
|
217
216
|
}, style)
|
|
218
217
|
}, reset), {}, {
|
|
218
|
+
ref: ref,
|
|
219
219
|
children: children
|
|
220
220
|
}));
|
|
221
|
-
};
|
|
221
|
+
});
|
|
222
222
|
exports.Label = Label;
|
|
223
223
|
var Type = function Type(props) {
|
|
224
224
|
var _typeMap$type2, _typeMap$type3;
|
package/esm/copied.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
export interface CopiedProps<T = object> extends React.SVGProps<SVGSVGElement> {
|
|
3
3
|
show?: boolean;
|
|
4
4
|
text?: T;
|
|
5
|
+
onCopied?: (text: string, obj: T | '') => void;
|
|
5
6
|
render?: (props: Omit<CopiedProps<T>, 'render'>) => JSX.Element;
|
|
6
7
|
}
|
|
7
8
|
export declare function Copied<T>(props: CopiedProps<T>): JSX.Element | null;
|
package/esm/copied.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
|
|
3
|
-
var _excluded = ["children", "style", "text", "render", "show"];
|
|
3
|
+
var _excluded = ["children", "style", "text", "onCopied", "render", "show"];
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
6
|
export function Copied(props) {
|
|
7
7
|
var {
|
|
8
8
|
style,
|
|
9
9
|
text = '',
|
|
10
|
+
onCopied,
|
|
10
11
|
render,
|
|
11
12
|
show
|
|
12
13
|
} = props,
|
|
@@ -15,7 +16,7 @@ export function Copied(props) {
|
|
|
15
16
|
var [copied, setCopied] = useState(false);
|
|
16
17
|
var click = event => {
|
|
17
18
|
event.stopPropagation();
|
|
18
|
-
var copyText = JSON.stringify(text, (key, value) => {
|
|
19
|
+
var copyText = JSON.stringify(text || '', (key, value) => {
|
|
19
20
|
if (typeof value === 'bigint') {
|
|
20
21
|
return value.toString();
|
|
21
22
|
}
|
|
@@ -23,6 +24,7 @@ export function Copied(props) {
|
|
|
23
24
|
}, 2);
|
|
24
25
|
if (text === Infinity) copyText = Infinity;
|
|
25
26
|
navigator.clipboard.writeText(copyText).then(() => {
|
|
27
|
+
onCopied && onCopied(copyText, text);
|
|
26
28
|
setCopied(true);
|
|
27
29
|
var timer = setTimeout(() => {
|
|
28
30
|
setCopied(false);
|
package/esm/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
|
|
|
17
17
|
keyName?: string | number;
|
|
18
18
|
/** The user can copy objects and arrays to clipboard by clicking on the clipboard icon. @default true */
|
|
19
19
|
enableClipboard?: boolean;
|
|
20
|
+
/** Whether to highlight updates. @default true */
|
|
21
|
+
highlightUpdates?: boolean;
|
|
20
22
|
/** Display for quotes in object-key @default " */
|
|
21
23
|
quotes?: "'" | '"' | '';
|
|
22
24
|
/** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
|
|
@@ -28,6 +30,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
|
|
|
28
30
|
keyid: string;
|
|
29
31
|
keyName?: string | number;
|
|
30
32
|
}) => void;
|
|
33
|
+
/** Fires event when you copy */
|
|
34
|
+
onCopied?: CopiedProps<T>['onCopied'];
|
|
31
35
|
/** Redefine interface elements to re-render. */
|
|
32
36
|
components?: {
|
|
33
37
|
braces?: MetaProps['render'];
|
package/esm/node.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface MetaProps extends LabelProps {
|
|
|
6
6
|
start?: boolean;
|
|
7
7
|
render?: (props: Pick<MetaProps, 'start' | 'isArray' | 'className' | 'children'>) => JSX.Element;
|
|
8
8
|
}
|
|
9
|
+
export declare function usePrevious<T>(value: T): T | undefined;
|
|
9
10
|
export declare function Meta(props: MetaProps): JSX.Element;
|
|
10
11
|
export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
11
12
|
render?: (props: EllipsisProps) => JSX.Element;
|
|
@@ -13,6 +14,7 @@ export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
13
14
|
export declare const Ellipsis: FC<PropsWithChildren<EllipsisProps>>;
|
|
14
15
|
export interface SemicolonProps extends LabelProps {
|
|
15
16
|
show?: boolean;
|
|
17
|
+
highlightUpdates?: boolean;
|
|
16
18
|
quotes?: JsonViewProps<object>['quotes'];
|
|
17
19
|
value?: object;
|
|
18
20
|
render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
|
package/esm/node.js
CHANGED
|
@@ -2,15 +2,22 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
|
|
3
3
|
var _excluded = ["isArray", "start", "className", "render"],
|
|
4
4
|
_excluded2 = ["style", "render"],
|
|
5
|
-
_excluded3 = ["children", "render", "color", "value", "className", "show", "quotes"],
|
|
6
|
-
_excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "indentWidth", "collapsed", "level", "keyid", "quotes", "onExpand"];
|
|
7
|
-
import { Fragment, useId, cloneElement, useState } from 'react';
|
|
5
|
+
_excluded3 = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes"],
|
|
6
|
+
_excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
|
|
7
|
+
import { Fragment, useId, cloneElement, useState, useMemo, useRef, useEffect } from 'react';
|
|
8
8
|
import { ValueView, Colon, Label, Line, typeMap } from './value';
|
|
9
9
|
import { TriangleArrow } from './arrow/TriangleArrow';
|
|
10
10
|
import { useExpandsStatus, store } from './store';
|
|
11
11
|
import { Copied } from './copied';
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
export function usePrevious(value) {
|
|
15
|
+
var ref = useRef();
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
ref.current = value;
|
|
18
|
+
});
|
|
19
|
+
return ref.current;
|
|
20
|
+
}
|
|
14
21
|
export function Meta(props) {
|
|
15
22
|
var {
|
|
16
23
|
isArray = false,
|
|
@@ -67,9 +74,51 @@ export var Semicolon = _ref2 => {
|
|
|
67
74
|
value,
|
|
68
75
|
className = 'w-rjv-object-key',
|
|
69
76
|
show,
|
|
77
|
+
highlightUpdates,
|
|
70
78
|
quotes
|
|
71
79
|
} = _ref2,
|
|
72
80
|
props = _objectWithoutPropertiesLoose(_ref2, _excluded3);
|
|
81
|
+
var prevValue = usePrevious(value);
|
|
82
|
+
var highlightContainer = useRef(null);
|
|
83
|
+
var isHighlight = useMemo(() => {
|
|
84
|
+
if (!highlightUpdates || prevValue === undefined) return false;
|
|
85
|
+
// highlight if value type changed
|
|
86
|
+
if (typeof value !== typeof prevValue) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
if (typeof value === 'number') {
|
|
90
|
+
// notice: NaN !== NaN
|
|
91
|
+
if (isNaN(value) && isNaN(prevValue)) return false;
|
|
92
|
+
return value !== prevValue;
|
|
93
|
+
}
|
|
94
|
+
// highlight if isArray changed
|
|
95
|
+
if (Array.isArray(value) !== Array.isArray(prevValue)) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// not highlight object/function
|
|
99
|
+
// deep compare they will be slow
|
|
100
|
+
if (typeof value === 'object' || typeof value === 'function') {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// highlight if not equal
|
|
105
|
+
if (value !== prevValue) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}, [highlightUpdates, value]);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
|
|
112
|
+
highlightContainer.current.animate([{
|
|
113
|
+
backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
|
|
114
|
+
}, {
|
|
115
|
+
backgroundColor: ''
|
|
116
|
+
}], {
|
|
117
|
+
duration: 1000,
|
|
118
|
+
easing: 'ease-in'
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}, [isHighlight, value]);
|
|
73
122
|
var content = show ? "" + quotes + children + quotes : children;
|
|
74
123
|
if (render) return render(_extends({
|
|
75
124
|
className
|
|
@@ -84,6 +133,7 @@ export var Semicolon = _ref2 => {
|
|
|
84
133
|
className: className,
|
|
85
134
|
color: color
|
|
86
135
|
}, props, {
|
|
136
|
+
ref: highlightContainer,
|
|
87
137
|
children: content
|
|
88
138
|
}));
|
|
89
139
|
};
|
|
@@ -97,7 +147,7 @@ export var CountInfo = _ref3 => {
|
|
|
97
147
|
fontStyle: 'italic'
|
|
98
148
|
},
|
|
99
149
|
color: "var(--w-rjv-info-color, #0000004d)",
|
|
100
|
-
className: "object-size",
|
|
150
|
+
className: "w-rjv-object-size",
|
|
101
151
|
children: children
|
|
102
152
|
});
|
|
103
153
|
};
|
|
@@ -106,15 +156,18 @@ export function RooNode(props) {
|
|
|
106
156
|
var {
|
|
107
157
|
value = {},
|
|
108
158
|
keyName,
|
|
159
|
+
className,
|
|
109
160
|
displayDataTypes = true,
|
|
110
161
|
components = {},
|
|
111
162
|
displayObjectSize = true,
|
|
112
163
|
enableClipboard = true,
|
|
164
|
+
highlightUpdates = true,
|
|
113
165
|
indentWidth = 15,
|
|
114
166
|
collapsed,
|
|
115
167
|
level = 1,
|
|
116
168
|
keyid = 'root',
|
|
117
169
|
quotes = '"',
|
|
170
|
+
onCopied,
|
|
118
171
|
onExpand
|
|
119
172
|
} = props,
|
|
120
173
|
reset = _objectWithoutPropertiesLoose(props, _excluded4);
|
|
@@ -142,6 +195,8 @@ export function RooNode(props) {
|
|
|
142
195
|
displayDataTypes,
|
|
143
196
|
displayObjectSize,
|
|
144
197
|
enableClipboard,
|
|
198
|
+
highlightUpdates,
|
|
199
|
+
onCopied,
|
|
145
200
|
onExpand,
|
|
146
201
|
collapsed,
|
|
147
202
|
quotes,
|
|
@@ -155,18 +210,22 @@ export function RooNode(props) {
|
|
|
155
210
|
displayObjectSize,
|
|
156
211
|
enableClipboard,
|
|
157
212
|
indentWidth,
|
|
213
|
+
renderBraces: components.braces,
|
|
158
214
|
renderValue: components.value
|
|
159
215
|
};
|
|
160
216
|
var arrowView = components.arrow ? /*#__PURE__*/cloneElement(components.arrow, {
|
|
161
217
|
style: arrowStyle,
|
|
162
|
-
'data-expand': expand
|
|
218
|
+
'data-expand': expand,
|
|
219
|
+
className: "w-rjv-arrow"
|
|
163
220
|
}) : /*#__PURE__*/_jsx(TriangleArrow, {
|
|
164
|
-
style: arrowStyle
|
|
221
|
+
style: arrowStyle,
|
|
222
|
+
className: "w-rjv-arrow"
|
|
165
223
|
});
|
|
166
224
|
var [showTools, setShowTools] = useState(false);
|
|
167
225
|
var tools = enableClipboard ? /*#__PURE__*/_jsx(Copied, {
|
|
168
226
|
show: showTools,
|
|
169
227
|
text: value,
|
|
228
|
+
onCopied: onCopied,
|
|
170
229
|
render: components.copied
|
|
171
230
|
}) : undefined;
|
|
172
231
|
var eventProps = {};
|
|
@@ -174,7 +233,9 @@ export function RooNode(props) {
|
|
|
174
233
|
eventProps.onMouseEnter = () => setShowTools(true);
|
|
175
234
|
eventProps.onMouseLeave = () => setShowTools(false);
|
|
176
235
|
}
|
|
177
|
-
return /*#__PURE__*/_jsxs("div", _extends({}, reset,
|
|
236
|
+
return /*#__PURE__*/_jsxs("div", _extends({}, reset, {
|
|
237
|
+
className: className + " w-rjv-inner"
|
|
238
|
+
}, eventProps, {
|
|
178
239
|
children: [/*#__PURE__*/_jsxs(Line, {
|
|
179
240
|
style: {
|
|
180
241
|
display: 'inline-flex',
|
|
@@ -203,6 +264,7 @@ export function RooNode(props) {
|
|
|
203
264
|
children: [nameKeys.length, " items"]
|
|
204
265
|
}), tools]
|
|
205
266
|
}), expand && /*#__PURE__*/_jsx(Line, {
|
|
267
|
+
className: "w-rjv-content",
|
|
206
268
|
style: {
|
|
207
269
|
borderLeft: 'var(--w-rjv-border-left-width, 1px) solid var(--w-rjv-line-color, #ebebeb)',
|
|
208
270
|
marginLeft: 6
|
|
@@ -212,6 +274,7 @@ export function RooNode(props) {
|
|
|
212
274
|
var renderKey = /*#__PURE__*/_jsx(Semicolon, {
|
|
213
275
|
value: item,
|
|
214
276
|
quotes: quotes,
|
|
277
|
+
highlightUpdates: highlightUpdates,
|
|
215
278
|
render: components.objectKey,
|
|
216
279
|
color: typeof key === 'number' ? typeMap['number'].color : '',
|
|
217
280
|
show: typeof key === 'string',
|
|
@@ -221,6 +284,7 @@ export function RooNode(props) {
|
|
|
221
284
|
if (Array.isArray(item) && !isEmpty) {
|
|
222
285
|
var label = isArray ? idx : key;
|
|
223
286
|
return /*#__PURE__*/_jsx(Line, {
|
|
287
|
+
className: "w-rjv-wrap",
|
|
224
288
|
children: /*#__PURE__*/_jsx(RooNode, _extends({
|
|
225
289
|
value: item,
|
|
226
290
|
keyid: keyid + subkeyid + label,
|
|
@@ -230,6 +294,7 @@ export function RooNode(props) {
|
|
|
230
294
|
}
|
|
231
295
|
if (typeof item === 'object' && item && !(item instanceof Date) && !isEmpty) {
|
|
232
296
|
return /*#__PURE__*/_jsx(Line, {
|
|
297
|
+
className: "w-rjv-wrap",
|
|
233
298
|
children: /*#__PURE__*/_jsx(RooNode, _extends({
|
|
234
299
|
keyid: keyid + subkeyid + key,
|
|
235
300
|
value: item,
|
|
@@ -241,7 +306,6 @@ export function RooNode(props) {
|
|
|
241
306
|
return;
|
|
242
307
|
}
|
|
243
308
|
return /*#__PURE__*/_jsx(ValueView, _extends({}, valueViewProps, {
|
|
244
|
-
renderBraces: components.braces,
|
|
245
309
|
renderKey: renderKey,
|
|
246
310
|
keyName: key,
|
|
247
311
|
value: item
|
package/esm/theme/dark.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const darkTheme: {
|
|
|
5
5
|
'--w-rjv-line-color': string;
|
|
6
6
|
'--w-rjv-arrow-color': string;
|
|
7
7
|
'--w-rjv-info-color': string;
|
|
8
|
+
'--w-rjv-update-color': string;
|
|
8
9
|
'--w-rjv-copied-color': string;
|
|
9
10
|
'--w-rjv-copied-success-color': string;
|
|
10
11
|
'--w-rjv-curlybraces-color': string;
|
package/esm/theme/dark.js
CHANGED
|
@@ -5,6 +5,7 @@ export var darkTheme = {
|
|
|
5
5
|
'--w-rjv-line-color': '#323232',
|
|
6
6
|
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
|
|
7
7
|
'--w-rjv-info-color': '#656565',
|
|
8
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
8
9
|
'--w-rjv-copied-color': '#0184a6',
|
|
9
10
|
'--w-rjv-copied-success-color': '#28a745',
|
|
10
11
|
'--w-rjv-curlybraces-color': '#1896b6',
|
package/esm/theme/light.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const lightTheme: {
|
|
|
5
5
|
'--w-rjv-line-color': string;
|
|
6
6
|
'--w-rjv-arrow-color': string;
|
|
7
7
|
'--w-rjv-info-color': string;
|
|
8
|
+
'--w-rjv-update-color': string;
|
|
8
9
|
'--w-rjv-copied-color': string;
|
|
9
10
|
'--w-rjv-copied-success-color': string;
|
|
10
11
|
'--w-rjv-curlybraces-color': string;
|
package/esm/theme/light.js
CHANGED
|
@@ -5,6 +5,7 @@ export var lightTheme = {
|
|
|
5
5
|
'--w-rjv-line-color': '#ebebeb',
|
|
6
6
|
'--w-rjv-arrow-color': 'var(--w-rjv-color)',
|
|
7
7
|
'--w-rjv-info-color': '#0000004d',
|
|
8
|
+
'--w-rjv-update-color': '#ebcb8b',
|
|
8
9
|
'--w-rjv-copied-color': '#002b36',
|
|
9
10
|
'--w-rjv-copied-success-color': '#28a745',
|
|
10
11
|
'--w-rjv-curlybraces-color': '#236a7c',
|
package/esm/value.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export interface LabelProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
|
60
60
|
opacity?: number;
|
|
61
61
|
paddingRight?: number;
|
|
62
62
|
}
|
|
63
|
-
export declare const Label:
|
|
63
|
+
export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLSpanElement>>;
|
|
64
64
|
export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
|
|
65
65
|
type: keyof typeof typeMap;
|
|
66
66
|
}
|
package/esm/value.js
CHANGED
|
@@ -3,7 +3,7 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
3
3
|
var _excluded = ["children", "style"],
|
|
4
4
|
_excluded2 = ["value", "keyName", "indentWidth", "renderKey", "renderValue", "renderBraces", "enableClipboard", "displayObjectSize", "displayDataTypes"],
|
|
5
5
|
_excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
|
|
6
|
-
import { Fragment, useState } from 'react';
|
|
6
|
+
import { Fragment, forwardRef, useState } from 'react';
|
|
7
7
|
import { Meta, CountInfo } from './node';
|
|
8
8
|
import { Copied } from './copied';
|
|
9
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -124,7 +124,12 @@ export function ValueView(props) {
|
|
|
124
124
|
show: showTools,
|
|
125
125
|
text: value
|
|
126
126
|
}) : undefined;
|
|
127
|
-
var eventProps = {
|
|
127
|
+
var eventProps = {
|
|
128
|
+
className: 'w-rjv-line',
|
|
129
|
+
style: {
|
|
130
|
+
paddingLeft: indentWidth
|
|
131
|
+
}
|
|
132
|
+
};
|
|
128
133
|
if (enableClipboard) {
|
|
129
134
|
eventProps.onMouseEnter = () => setShowTools(true);
|
|
130
135
|
eventProps.onMouseLeave = () => setShowTools(false);
|
|
@@ -145,12 +150,9 @@ export function ValueView(props) {
|
|
|
145
150
|
className: "w-rjv-value",
|
|
146
151
|
children: content
|
|
147
152
|
});
|
|
148
|
-
return /*#__PURE__*/_jsx(Line, _extends({
|
|
149
|
-
style: {
|
|
150
|
-
paddingLeft: indentWidth
|
|
151
|
-
}
|
|
152
|
-
}, eventProps, {
|
|
153
|
+
return /*#__PURE__*/_jsx(Line, _extends({}, eventProps, {
|
|
153
154
|
children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
|
|
155
|
+
ref: null,
|
|
154
156
|
children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, valueView, tools]
|
|
155
157
|
}))
|
|
156
158
|
}));
|
|
@@ -168,17 +170,14 @@ export function ValueView(props) {
|
|
|
168
170
|
children: [length, " items"]
|
|
169
171
|
})]
|
|
170
172
|
});
|
|
171
|
-
return /*#__PURE__*/_jsx(Line, _extends({
|
|
172
|
-
style: {
|
|
173
|
-
paddingLeft: indentWidth
|
|
174
|
-
}
|
|
175
|
-
}, eventProps, {
|
|
173
|
+
return /*#__PURE__*/_jsx(Line, _extends({}, eventProps, {
|
|
176
174
|
children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
|
|
175
|
+
ref: null,
|
|
177
176
|
children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, empty, tools]
|
|
178
177
|
}))
|
|
179
178
|
}));
|
|
180
179
|
}
|
|
181
|
-
export var Label = _ref2 => {
|
|
180
|
+
export var Label = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
182
181
|
var {
|
|
183
182
|
children,
|
|
184
183
|
color,
|
|
@@ -196,9 +195,10 @@ export var Label = _ref2 => {
|
|
|
196
195
|
paddingRight
|
|
197
196
|
}, style)
|
|
198
197
|
}, reset, {
|
|
198
|
+
ref: ref,
|
|
199
199
|
children: children
|
|
200
200
|
}));
|
|
201
|
-
};
|
|
201
|
+
});
|
|
202
202
|
export var Type = props => {
|
|
203
203
|
var _typeMap$type2, _typeMap$type3;
|
|
204
204
|
var {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uiw/react-json-view",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "JSON viewer for react.",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -74,7 +74,10 @@
|
|
|
74
74
|
"treeview"
|
|
75
75
|
],
|
|
76
76
|
"devDependencies": {
|
|
77
|
+
"@testing-library/react": "^14.0.0",
|
|
78
|
+
"@types/react-test-renderer": "^18.0.0",
|
|
77
79
|
"react": "^18.2.0",
|
|
78
|
-
"react-dom": "^18.2.0"
|
|
80
|
+
"react-dom": "^18.2.0",
|
|
81
|
+
"react-test-renderer": "^18.2.0"
|
|
79
82
|
}
|
|
80
83
|
}
|