@uiw/react-json-view 0.1.0 → 1.1.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 CHANGED
@@ -3,6 +3,7 @@ react-json-view
3
3
 
4
4
  [![CI](https://github.com/uiwjs/react-json-view/actions/workflows/ci.yml/badge.svg)](https://github.com/uiwjs/react-json-view/actions/workflows/ci.yml)
5
5
  [![npm version](https://img.shields.io/npm/v/@uiw/react-json-view.svg)](https://www.npmjs.com/package/@uiw/react-json-view)
6
+ [![react@^18](https://shields.io/badge/react-^18-green?style=flat&logo=react)](https://github.com/facebook/react/releases)
6
7
 
7
8
  A React component for displaying and editing javascript arrays and JSON objects.
8
9
 
@@ -21,6 +22,7 @@ A React component for displaying and editing javascript arrays and JSON objects.
21
22
  📚 Use Typescript to write, better code hints.
22
23
  🎨 Support theme customization & [`online editing`](https://uiwjs.github.io/react-json-view/#online-editing-theme) theme
23
24
  🌒 Support dark/light mode
25
+ 📦 Zero dependencies
24
26
 
25
27
  ## Quick Start
26
28
 
@@ -106,9 +108,11 @@ const customTheme = {
106
108
  '--w-rjv-font-family': 'monospace',
107
109
  '--w-rjv-color': '#9cdcfe',
108
110
  '--w-rjv-background-color': '#1e1e1e',
109
- '--w-rjv-border-left': '1px solid #323232',
111
+ '--w-rjv-line-color': '#323232',
110
112
  '--w-rjv-arrow-color': 'var(--w-rjv-color)',
111
113
  '--w-rjv-info-color': '#656565',
114
+ '--w-rjv-copied-color': '#9cdcfe',
115
+ '--w-rjv-copied-success-color': '#28a745',
112
116
 
113
117
  '--w-rjv-curlybraces-color': '#d4d4d4',
114
118
  '--w-rjv-brackets-color': '#d4d4d4',
@@ -135,7 +139,7 @@ export default function Demo() {
135
139
 
136
140
  Online custom style example, please check in the [documentation website](https://uiwjs.github.io/react-json-view/)
137
141
 
138
- ```tsx mdx:preview
142
+ ```tsx mdx:preview:&title=Online Editing Theme
139
143
  import React, { useState, useRef } from 'react';
140
144
  import Colorful from '@uiw/react-color-colorful';
141
145
  import JsonView from '@uiw/react-json-view';
@@ -165,9 +169,11 @@ const object = {
165
169
  const customTheme = {
166
170
  '--w-rjv-color': '#9cdcfe',
167
171
  '--w-rjv-background-color': '#1e1e1e',
168
- '--w-rjv-border-left': '1px solid #323232',
169
- '--w-rjv-arrow-color': 'var(--w-rjv-color)',
172
+ '--w-rjv-line-color': '#323232',
173
+ '--w-rjv-arrow-color': '#9cdcfe',
170
174
  '--w-rjv-info-color': '#656565',
175
+ '--w-rjv-copied-color': '#0184a6',
176
+ '--w-rjv-copied-success-color': '#28a745',
171
177
 
172
178
  '--w-rjv-curlybraces-color': '#d4d4d4',
173
179
  '--w-rjv-brackets-color': '#d4d4d4',
@@ -188,9 +194,8 @@ export default function Demo() {
188
194
  const [hex, setHex] = useState("#1e1e1e");
189
195
  const [theme, setTheme] = useState(customTheme);
190
196
  const onChange = ({ hexa }) => {
191
- const value = cssvar === '--w-rjv-border-left' ? `1px solid ${hexa}` : hexa;
192
197
  setHex(hexa);
193
- setTheme({ ...theme, [cssvar]: value });
198
+ setTheme({ ...theme, [cssvar]: hexa });
194
199
  };
195
200
  return (
196
201
  <React.Fragment>
@@ -200,7 +205,10 @@ export default function Demo() {
200
205
  <Colorful color={hex} onChange={onChange} />
201
206
  <div style={{ display: 'flex', gap: '0.4rem', flexWrap: 'wrap' }}>
202
207
  {Object.keys(customTheme).map((varname, idx) => {
203
- const click = () => setCssvar(varname);
208
+ const click = () => {
209
+ setCssvar(varname);
210
+ setHex(customTheme[varname]);
211
+ };
204
212
  const active = cssvar === varname ? '#a8a8a8' : '';
205
213
  return <button key={idx} style={{ background: active }} onClick={click}>{varname}</button>
206
214
  })}
@@ -236,6 +244,7 @@ export default function Demo() {
236
244
  <JsonView
237
245
  value={object}
238
246
  keyName="root"
247
+ quotes=""
239
248
  displayObjectSize={false}
240
249
  displayDataTypes={false}
241
250
  style={{
@@ -375,14 +384,26 @@ import { MetaProps, SemicolonProps, EllipsisProps, ValueViewProps } from '@uiw/r
375
384
  export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
376
385
  /** This property contains your input JSON */
377
386
  value?: T;
378
- /** Set the indent-width for nested objects @default `15`*/
387
+ /** Set the indent-width for nested objects @default 15 */
379
388
  indentWidth?: number;
380
- /** When set to `true`, data type labels prefix values @default `true` */
389
+ /** When set to `true`, data type labels prefix values @default true */
381
390
  displayDataTypes?: boolean;
382
- /** When set to `true`, `objects` and `arrays` are labeled with size @default `true` */
391
+ /** When set to `true`, `objects` and `arrays` are labeled with size @default true */
383
392
  displayObjectSize?: boolean;
384
- /** Define the root node name. @default `undefined` */
393
+ /** Define the root node name. @default undefined */
385
394
  keyName?: string | number;
395
+ /** The user can copy objects and arrays to clipboard by clicking on the clipboard icon. @default true */
396
+ enableClipboard?: boolean;
397
+ /** Display for quotes in object-key @default " */
398
+ quotes?: "'" | '"' | '';
399
+ /** Callback function for when a treeNode is expanded or collapsed */
400
+ onExpand?: (props: {
401
+ expand: boolean;
402
+ value: T;
403
+ keyid: string;
404
+ keyName?: string | number;
405
+ }) => void;
406
+ /** Redefine interface elements to re-render. */
386
407
  components?: {
387
408
  braces?: MetaProps['render'];
388
409
  ellipsis?: EllipsisProps['render'];
@@ -395,6 +416,22 @@ declare const JsonView: React.ForwardRefExoticComponent<Omit<JsonViewProps<objec
395
416
  export default JsonView;
396
417
  ```
397
418
 
419
+ ## Size and dependencies
420
+
421
+ 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)):
422
+
423
+ | Library | Bundle size | Bundle size (gzip) | Deps | Last commit |
424
+ | ------- | ------- | ------- | ------- | ------- |
425
+ | **@uiw/react-json-view** | [![](https://img.shields.io/bundlephobia/min/@uiw/react-json-view?color=6ead0a&label=)](https://bundlephobia.com/result?p=@uiw/react-json-view) | [![](https://img.shields.io/bundlephobia/minzip/@uiw/react-json-view?color=6ead0a&label=)](https://bundlephobia.com/result?p=@uiw/react-json-view) | [![](https://badgen.net/bundlephobia/dependency-count/%40uiw%2Freact-json-view?color=6ead0a&label=)](https://bundlephobia.com/result?p=@uiw/react-json-view) | [![GitHub last commit](https://img.shields.io/github/last-commit/uiwjs/react-json-view?style=flat&label=last)](https://github.com/uiwjs/react-json-view/commits) |
426
+ | react-json-view-lite | [![](https://img.shields.io/bundlephobia/min/react-json-view-lite?color=red&label=)](https://bundlephobia.com/result?p=react-json-view-lite) | [![](https://img.shields.io/bundlephobia/minzip/react-json-view-lite?color=red&label=)](https://bundlephobia.com/result?p=react-json-view-lite) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-view-lite?color=red&label=)](https://bundlephobia.com/result?p=react-json-view-lite) | [![GitHub last commit](https://img.shields.io/github/last-commit/AnyRoad/react-json-view-lite?style=flat&label=last)](https://github.com/AnyRoad/react-json-view-lite/commits) |
427
+ | react-json-pretty | [![](https://img.shields.io/bundlephobia/min/react-json-pretty?color=red&label=)](https://bundlephobia.com/result?p=react-json-pretty) | [![](https://img.shields.io/bundlephobia/minzip/react-json-pretty?color=red&label=)](https://bundlephobia.com/result?p=react-json-pretty) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-pretty?color=red&label=)](https://bundlephobia.com/result?p=react-json-pretty) | [![GitHub last commit](https://img.shields.io/github/last-commit/chenckang/react-json-pretty?style=flat&label=last)](https://github.com/chenckang/react-json-pretty/commits) |
428
+ | react-json-inspector | [![](https://img.shields.io/bundlephobia/min/react-json-inspector?color=red&label=)](https://bundlephobia.com/result?p=react-json-inspector) | [![](https://img.shields.io/bundlephobia/minzip/react-json-inspector?color=red&label=)](https://bundlephobia.com/result?p=react-json-inspector) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-inspector?color=red&label=)](https://bundlephobia.com/result?p=react-json-inspector) | [![GitHub last commit](https://img.shields.io/github/last-commit/Lapple/react-json-inspector?style=flat&label=last)](https://github.com/Lapple/react-json-inspector/commits) |
429
+ | react-json-tree | [![](https://img.shields.io/bundlephobia/min/react-json-tree?color=red&label=)](https://bundlephobia.com/result?p=react-json-tree) | [![](https://img.shields.io/bundlephobia/minzip/react-json-tree?color=red&label=)](https://bundlephobia.com/result?p=react-json-tree) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-tree?color=red&label=)](https://bundlephobia.com/result?p=react-json-tree) | [![GitHub last commit](https://img.shields.io/github/last-commit/reduxjs/redux-devtools?style=flat&label=last)](https://github.com/reduxjs/redux-devtools/commits) |
430
+ | react-json-view | [![](https://img.shields.io/bundlephobia/min/react-json-view?color=red&label=)](https://bundlephobia.com/result?p=react-json-view) | [![](https://img.shields.io/bundlephobia/minzip/react-json-view?color=red&label=)](https://bundlephobia.com/result?p=react-json-view) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-view?color=red&label=&t=123)](https://bundlephobia.com/result?p=react-json-view) | [![GitHub last commit](https://img.shields.io/github/last-commit/mac-s-g/react-json-view?style=flat&label=last)](https://github.com/mac-s-g/react-json-view/commits) |
431
+ | react-json-tree-viewer | [![](https://img.shields.io/bundlephobia/min/react-json-tree-viewer?color=red&label=)](https://bundlephobia.com/result?p=react-json-tree-viewer) | [![](https://img.shields.io/bundlephobia/minzip/react-json-tree-viewer?color=red&label=)](https://bundlephobia.com/result?p=react-json-tree-viewer) | [![](https://badgen.net/bundlephobia/dependency-count/react-json-tree-viewer?color=red&label=&t=123)](https://bundlephobia.com/result?p=react-json-tree-viewer) | [![GitHub last commit](https://img.shields.io/github/last-commit/nsisodiya/react-json-viewer?style=flat&label=last)](https://github.com/nsisodiya/react-json-viewer/commits) |
432
+ | react-domify | [![](https://img.shields.io/bundlephobia/min/react-domify?color=red&label=)](https://bundlephobia.com/result?p=react-domify) | [![](https://img.shields.io/bundlephobia/minzip/react-domify?color=red&label=)](https://bundlephobia.com/result?p=react-domify) | [![](https://badgen.net/bundlephobia/dependency-count/react-domify?color=red&label=)](https://bundlephobia.com/result?p=react-domify) | [![GitHub last commit](https://img.shields.io/github/last-commit/JedWatson/react-domify?style=flat&label=last)](https://github.com/JedWatson/react-domify/commits) |
433
+ | react18-json-view | [![](https://img.shields.io/bundlephobia/min/react18-json-view?color=red&label=)](https://bundlephobia.com/result?p=react18-json-view) | [![](https://img.shields.io/bundlephobia/minzip/react18-json-view?color=red&label=)](https://bundlephobia.com/result?p=react18-json-view) | [![](https://badgen.net/bundlephobia/dependency-count/react18-json-view?color=red&label=)](https://bundlephobia.com/result?p=react18-json-view) | [![GitHub last commit](https://img.shields.io/github/last-commit/YYsuni/react18-json-view?style=flat&label=last)](https://github.com/YYsuni/react18-json-view/commits) |
434
+
398
435
  ## Development
399
436
 
400
437
  Runs the project in development mode.
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ export interface CopiedProps<T = object> extends React.SVGProps<SVGSVGElement> {
3
+ show?: boolean;
4
+ text?: T;
5
+ render?: (props: Omit<CopiedProps<T>, 'render'>) => JSX.Element;
6
+ }
7
+ export declare function Copied<T>(props: CopiedProps<T>): JSX.Element | null;
package/cjs/copied.js ADDED
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.Copied = Copied;
8
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
+ var _react = require("react");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ var _excluded = ["children", "style", "text", "render", "show"];
14
+ function Copied(props) {
15
+ var children = props.children,
16
+ style = props.style,
17
+ _props$text = props.text,
18
+ text = _props$text === void 0 ? '' : _props$text,
19
+ render = props.render,
20
+ show = props.show,
21
+ reset = (0, _objectWithoutProperties2["default"])(props, _excluded);
22
+ if (!show) return null;
23
+ var _useState = (0, _react.useState)(false),
24
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
25
+ copied = _useState2[0],
26
+ setCopied = _useState2[1];
27
+ var click = function click(event) {
28
+ event.stopPropagation();
29
+ var copyText = JSON.stringify(text, function (key, value) {
30
+ if (typeof value === 'bigint') {
31
+ return value.toString();
32
+ }
33
+ return value;
34
+ }, 2);
35
+ if (text === Infinity) copyText = Infinity;
36
+ navigator.clipboard.writeText(copyText).then(function () {
37
+ setCopied(true);
38
+ var timer = setTimeout(function () {
39
+ setCopied(false);
40
+ clearTimeout(timer);
41
+ }, 3000);
42
+ })["catch"](function (error) {});
43
+ };
44
+ var defalutStyle = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, style), {}, {
45
+ cursor: 'pointer',
46
+ marginLeft: 5
47
+ });
48
+ var svgProps = (0, _objectSpread2["default"])({
49
+ height: '1em',
50
+ width: '1em',
51
+ fill: 'var(--w-rjv-copied-color, currentColor)',
52
+ onClick: click,
53
+ style: defalutStyle,
54
+ className: 'w-rjv-copied'
55
+ }, reset);
56
+ if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, props), svgProps));
57
+ if (copied) {
58
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
59
+ viewBox: "0 0 38 38"
60
+ }, svgProps), {}, {
61
+ fill: "var(--w-rjv-copied-success-color, #28a745)",
62
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
63
+ d: "M27.5,35 L2.5,35 L2.5,12.5 L27.5,12.5 L27.5,15.2249049 C29.1403264,13.8627542 29.9736597,13.1778155 30,13.1700887 C30,11.9705278 30,10.0804982 30,7.5 C30,6.1 28.9,5 27.5,5 L20,5 C20,2.2 17.8,0 15,0 C12.2,0 10,2.2 10,5 L2.5,5 C1.1,5 0,6.1 0,7.5 L0,35 C0,36.4 1.1,37.5 2.5,37.5 L27.5,37.5 C28.9,37.5 30,36.4 30,35 L30,30 L27.5,30 L27.5,35 Z M7.5,7.5 L10,7.5 C10,7.5 12.5,6.4 12.5,5 C12.5,3.6 13.6,2.5 15,2.5 C16.4,2.5 17.5,3.6 17.5,5 C17.5,6.4 18.8,7.5 20,7.5 L22.5,7.5 C22.5,7.5 25,8.6 25,10 L5,10 C5,8.5 6.1,7.5 7.5,7.5 Z M5,27.5 L10,27.5 L10,25 L5,25 L5,27.5 Z M31.5589286,15 L35.1589286,18.6 L21.0160714,33 L12.5303571,24.2571429 L16.1303571,20.6571429 L21.0160714,25.5428571 L31.5589286,15 Z M12.5,30 L12.5,32.5 L5,32.5 L5,30 L12.5,30 Z M17.5,15 L5,15 L5,17.5 L17.5,17.5 L17.5,15 Z M10,20 L5,20 L5,22.5 L10,22.5 L10,20 Z"
64
+ })
65
+ }));
66
+ }
67
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
68
+ viewBox: "0 0 38 38"
69
+ }, svgProps), {}, {
70
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
71
+ d: "M27.5,35 L2.5,35 L2.5,12.5 L27.5,12.5 L27.5,20 L30,20 L30,7.5 C30,6.1 28.9,5 27.5,5 L20,5 C20,2.2 17.8,0 15,0 C12.2,0 10,2.2 10,5 L2.5,5 C1.1,5 0,6.1 0,7.5 L0,35 C0,36.4 1.1,37.5 2.5,37.5 L27.5,37.5 C28.9,37.5 30,36.4 30,35 L30,30 L27.5,30 L27.5,35 Z M7.5,7.5 L10,7.5 C10,7.5 12.5,6.4 12.5,5 C12.5,3.6 13.6,2.5 15,2.5 C16.4,2.5 17.5,3.6 17.5,5 C17.5,6.4 18.8,7.5 20,7.5 L22.5,7.5 C22.5,7.5 25,8.6 25,10 L5,10 C5,8.5 6.1,7.5 7.5,7.5 Z M5,27.5 L10,27.5 L10,25 L5,25 L5,27.5 Z M22.5,22.5 L22.5,17.5 L12.5,25 L22.5,32.5 L22.5,27.5 L35,27.5 L35,22.5 L22.5,22.5 Z M5,32.5 L12.5,32.5 L12.5,30 L5,30 L5,32.5 Z M17.5,15 L5,15 L5,17.5 L17.5,17.5 L17.5,15 Z M10,20 L5,20 L5,22.5 L10,22.5 L10,20 Z"
72
+ })
73
+ }));
74
+ }
package/cjs/index.d.ts CHANGED
@@ -1,25 +1,41 @@
1
1
  import React from 'react';
2
2
  import { MetaProps, SemicolonProps, EllipsisProps } from './node';
3
3
  import { ValueViewProps } from './value';
4
+ import { CopiedProps } from './copied';
4
5
  export * from './node';
5
6
  export * from './value';
6
- export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
7
+ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
7
8
  /** This property contains your input JSON */
8
9
  value?: T;
9
- /** Set the indent-width for nested objects @default `15`*/
10
+ /** Set the indent-width for nested objects @default 15 */
10
11
  indentWidth?: number;
11
- /** When set to `true`, data type labels prefix values @default `true` */
12
+ /** When set to `true`, data type labels prefix values @default true */
12
13
  displayDataTypes?: boolean;
13
- /** When set to `true`, `objects` and `arrays` are labeled with size @default `true` */
14
+ /** When set to `true`, `objects` and `arrays` are labeled with size @default true */
14
15
  displayObjectSize?: boolean;
15
- /** Define the root node name. @default `undefined` */
16
+ /** Define the root node name. @default undefined */
16
17
  keyName?: string | number;
18
+ /** The user can copy objects and arrays to clipboard by clicking on the clipboard icon. @default true */
19
+ enableClipboard?: boolean;
20
+ /** Display for quotes in object-key @default " */
21
+ quotes?: "'" | '"' | '';
22
+ /** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
23
+ collapsed?: boolean | number;
24
+ /** Callback function for when a treeNode is expanded or collapsed */
25
+ onExpand?: (props: {
26
+ expand: boolean;
27
+ value: T;
28
+ keyid: string;
29
+ keyName?: string | number;
30
+ }) => void;
31
+ /** Redefine interface elements to re-render. */
17
32
  components?: {
18
33
  braces?: MetaProps['render'];
19
34
  ellipsis?: EllipsisProps['render'];
20
35
  arrow?: JSX.Element;
21
36
  objectKey?: SemicolonProps['render'];
22
37
  value?: ValueViewProps<T>['renderValue'];
38
+ copied?: CopiedProps<T>['render'];
23
39
  };
24
40
  }
25
41
  declare const JsonView: React.ForwardRefExoticComponent<Omit<JsonViewProps<object>, "ref"> & React.RefAttributes<HTMLDivElement>>;
package/cjs/node.d.ts CHANGED
@@ -6,21 +6,22 @@ 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 Meta(props: MetaProps): import("react/jsx-runtime").JSX.Element;
10
- export declare const Line: FC<PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>>;
9
+ export declare function Meta(props: MetaProps): JSX.Element;
11
10
  export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {
12
11
  render?: (props: EllipsisProps) => JSX.Element;
13
12
  }
14
13
  export declare const Ellipsis: FC<PropsWithChildren<EllipsisProps>>;
15
14
  export interface SemicolonProps extends LabelProps {
16
15
  show?: boolean;
16
+ quotes?: JsonViewProps<object>['quotes'];
17
17
  value?: object;
18
18
  render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
19
19
  }
20
20
  export declare const Semicolon: FC<PropsWithChildren<SemicolonProps>>;
21
21
  export declare const CountInfo: FC<PropsWithChildren<LabelProps>>;
22
- export interface RooNodeProps<T> extends JsonViewProps<T> {
22
+ export interface RooNodeProps<T extends object> extends JsonViewProps<T> {
23
23
  keyName?: string | number;
24
24
  keyid?: string;
25
+ level?: number;
25
26
  }
26
27
  export declare function RooNode<T extends object>(props: RooNodeProps<T>): import("react/jsx-runtime").JSX.Element;
package/cjs/node.js CHANGED
@@ -4,22 +4,24 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.Line = exports.Ellipsis = exports.CountInfo = void 0;
7
+ exports.Ellipsis = exports.CountInfo = void 0;
8
8
  exports.Meta = Meta;
9
9
  exports.RooNode = RooNode;
10
10
  exports.Semicolon = void 0;
11
11
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
12
13
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
13
14
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
14
15
  var _react = require("react");
15
16
  var _value = require("./value");
16
17
  var _TriangleArrow = require("./arrow/TriangleArrow");
17
18
  var _store = require("./store");
19
+ var _copied = require("./copied");
18
20
  var _jsxRuntime = require("react/jsx-runtime");
19
21
  var _excluded = ["isArray", "start", "className", "render"],
20
22
  _excluded2 = ["style", "render"],
21
- _excluded3 = ["children", "render", "color", "value", "className", "show"],
22
- _excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "indentWidth", "keyid"];
23
+ _excluded3 = ["children", "render", "color", "value", "className", "show", "quotes"],
24
+ _excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "indentWidth", "collapsed", "level", "keyid", "quotes", "onExpand"];
23
25
  function Meta(props) {
24
26
  var _props$isArray = props.isArray,
25
27
  isArray = _props$isArray === void 0 ? false : _props$isArray,
@@ -46,10 +48,6 @@ function Meta(props) {
46
48
  children: start ? mark.charAt(0) : mark.charAt(1)
47
49
  }));
48
50
  }
49
- var Line = function Line(props) {
50
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", (0, _objectSpread2["default"])({}, props));
51
- };
52
- exports.Line = Line;
53
51
  var Ellipsis = function Ellipsis(_ref) {
54
52
  var style = _ref.style,
55
53
  render = _ref.render,
@@ -79,8 +77,9 @@ var Semicolon = function Semicolon(_ref2) {
79
77
  _ref2$className = _ref2.className,
80
78
  className = _ref2$className === void 0 ? 'w-rjv-object-key' : _ref2$className,
81
79
  show = _ref2.show,
80
+ quotes = _ref2.quotes,
82
81
  props = (0, _objectWithoutProperties2["default"])(_ref2, _excluded3);
83
- var content = show ? "\"".concat(children, "\"") : children;
82
+ var content = show ? "".concat(quotes).concat(children).concat(quotes) : children;
84
83
  if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({
85
84
  className: className
86
85
  }, props), {}, {
@@ -122,10 +121,18 @@ function RooNode(props) {
122
121
  components = _props$components === void 0 ? {} : _props$components,
123
122
  _props$displayObjectS = props.displayObjectSize,
124
123
  displayObjectSize = _props$displayObjectS === void 0 ? true : _props$displayObjectS,
124
+ _props$enableClipboar = props.enableClipboard,
125
+ enableClipboard = _props$enableClipboar === void 0 ? true : _props$enableClipboar,
125
126
  _props$indentWidth = props.indentWidth,
126
127
  indentWidth = _props$indentWidth === void 0 ? 15 : _props$indentWidth,
128
+ collapsed = props.collapsed,
129
+ _props$level = props.level,
130
+ level = _props$level === void 0 ? 1 : _props$level,
127
131
  _props$keyid = props.keyid,
128
132
  keyid = _props$keyid === void 0 ? 'root' : _props$keyid,
133
+ _props$quotes = props.quotes,
134
+ quotes = _props$quotes === void 0 ? '"' : _props$quotes,
135
+ onExpand = props.onExpand,
129
136
  reset = (0, _objectWithoutProperties2["default"])(props, _excluded4);
130
137
  var isArray = Array.isArray(value);
131
138
  var nameKeys = isArray ? Object.keys(value).map(function (m) {
@@ -133,12 +140,18 @@ function RooNode(props) {
133
140
  }) : Object.keys(value);
134
141
  var subkeyid = (0, _react.useId)();
135
142
  var expands = (0, _store.useExpandsStatus)();
136
- var expand = (_expands$keyid = expands[keyid]) !== null && _expands$keyid !== void 0 ? _expands$keyid : true;
143
+ var expand = (_expands$keyid = expands[keyid]) !== null && _expands$keyid !== void 0 ? _expands$keyid : typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level <= collapsed : true;
137
144
  var arrowStyle = {
138
145
  transform: "rotate(".concat(expand ? '0' : '-90', "deg)"),
139
146
  transition: 'all 0.3s'
140
147
  };
141
148
  var handle = function handle() {
149
+ onExpand && typeof onExpand === 'function' && onExpand({
150
+ expand: !expand,
151
+ keyid: keyid,
152
+ keyName: keyName,
153
+ value: value
154
+ });
142
155
  !expand ? _store.store.expand(keyid) : _store.store.collapse(keyid);
143
156
  };
144
157
  var subNodeProps = {
@@ -146,12 +159,20 @@ function RooNode(props) {
146
159
  indentWidth: indentWidth,
147
160
  displayDataTypes: displayDataTypes,
148
161
  displayObjectSize: displayObjectSize,
162
+ enableClipboard: enableClipboard,
163
+ onExpand: onExpand,
164
+ collapsed: collapsed,
165
+ quotes: quotes,
166
+ level: level + 1,
149
167
  style: {
150
168
  paddingLeft: indentWidth
151
169
  }
152
170
  };
153
171
  var valueViewProps = {
154
172
  displayDataTypes: displayDataTypes,
173
+ displayObjectSize: displayObjectSize,
174
+ enableClipboard: enableClipboard,
175
+ indentWidth: indentWidth,
155
176
  renderValue: components.value
156
177
  };
157
178
  var arrowView = components.arrow ? /*#__PURE__*/(0, _react.cloneElement)(components.arrow, {
@@ -160,8 +181,26 @@ function RooNode(props) {
160
181
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_TriangleArrow.TriangleArrow, {
161
182
  style: arrowStyle
162
183
  });
163
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
164
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, {
184
+ var _useState = (0, _react.useState)(false),
185
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
186
+ showTools = _useState2[0],
187
+ setShowTools = _useState2[1];
188
+ var tools = enableClipboard ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
189
+ show: showTools,
190
+ text: value,
191
+ render: components.copied
192
+ }) : undefined;
193
+ var eventProps = {};
194
+ if (enableClipboard) {
195
+ eventProps.onMouseEnter = function () {
196
+ return setShowTools(true);
197
+ };
198
+ eventProps.onMouseLeave = function () {
199
+ return setShowTools(false);
200
+ };
201
+ }
202
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), eventProps), {}, {
203
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_value.Line, {
165
204
  style: {
166
205
  display: 'inline-flex',
167
206
  alignItems: 'center'
@@ -170,6 +209,7 @@ function RooNode(props) {
170
209
  children: [arrowView, (typeof keyName === 'string' || typeof keyName === 'number') && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
171
210
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
172
211
  value: value,
212
+ quotes: quotes,
173
213
  render: components.objectKey,
174
214
  color: typeof keyName === 'number' ? _value.typeMap['number'].color : '',
175
215
  show: typeof keyName === 'string',
@@ -186,17 +226,26 @@ function RooNode(props) {
186
226
  render: components.braces
187
227
  }), displayObjectSize && /*#__PURE__*/(0, _jsxRuntime.jsxs)(CountInfo, {
188
228
  children: [nameKeys.length, " items"]
189
- })]
190
- }), expand && /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, {
229
+ }), tools]
230
+ }), expand && /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
191
231
  style: {
192
- borderLeft: 'var(--w-rjv-border-left, 1px solid #ebebeb)',
232
+ borderLeft: '1px solid var(--w-rjv-line-color, #ebebeb)',
193
233
  marginLeft: 6
194
234
  },
195
235
  children: nameKeys.length > 0 && nameKeys.map(function (key, idx) {
196
236
  var item = value[key];
197
- if (Array.isArray(item)) {
237
+ var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
238
+ value: item,
239
+ quotes: quotes,
240
+ render: components.objectKey,
241
+ color: typeof key === 'number' ? _value.typeMap['number'].color : '',
242
+ show: typeof key === 'string',
243
+ children: key
244
+ });
245
+ var isEmpty = Array.isArray(item) && item.length === 0 || (0, _typeof2["default"])(item) === 'object' && item && !(item instanceof Date) && Object.keys(item).length === 0;
246
+ if (Array.isArray(item) && !isEmpty) {
198
247
  var label = isArray ? idx : key;
199
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, {
248
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
200
249
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(RooNode, (0, _objectSpread2["default"])({
201
250
  value: item,
202
251
  keyid: keyid + subkeyid + label,
@@ -204,36 +253,8 @@ function RooNode(props) {
204
253
  }, subNodeProps))
205
254
  }, label + idx);
206
255
  }
207
- var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
208
- value: item,
209
- render: components.objectKey,
210
- color: typeof key === 'number' ? _value.typeMap['number'].color : '',
211
- show: typeof key === 'string',
212
- children: key
213
- });
214
- if ((0, _typeof2["default"])(item) === 'object' && item && !(item instanceof Date)) {
215
- if (Object.keys(item).length === 0) {
216
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Line, {
217
- style: {
218
- paddingLeft: indentWidth
219
- },
220
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_value.ValueView, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, valueViewProps), {}, {
221
- renderKey: renderKey,
222
- keyName: key,
223
- value: item
224
- })), /*#__PURE__*/(0, _jsxRuntime.jsx)(Meta, {
225
- render: components.braces,
226
- start: true,
227
- isArray: isArray
228
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Meta, {
229
- render: components.braces,
230
- isArray: isArray
231
- }), displayObjectSize && /*#__PURE__*/(0, _jsxRuntime.jsxs)(CountInfo, {
232
- children: [Object.keys(item).length, " items"]
233
- })]
234
- }, key + idx);
235
- }
236
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, {
256
+ if ((0, _typeof2["default"])(item) === 'object' && item && !(item instanceof Date) && !isEmpty) {
257
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
237
258
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(RooNode, (0, _objectSpread2["default"])({
238
259
  keyid: keyid + subkeyid + key,
239
260
  value: item,
@@ -244,18 +265,14 @@ function RooNode(props) {
244
265
  if (typeof item === 'function') {
245
266
  return;
246
267
  }
247
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, {
248
- style: {
249
- paddingLeft: indentWidth
250
- },
251
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.ValueView, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, valueViewProps), {}, {
252
- renderKey: renderKey,
253
- keyName: key,
254
- value: item
255
- }))
256
- }, idx);
268
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.ValueView, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, valueViewProps), {}, {
269
+ renderBraces: components.braces,
270
+ renderKey: renderKey,
271
+ keyName: key,
272
+ value: item
273
+ }), idx);
257
274
  })
258
- }), expand && /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, {
275
+ }), expand && /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Line, {
259
276
  style: {
260
277
  paddingLeft: 2
261
278
  },
@@ -2,9 +2,11 @@ export declare const darkTheme: {
2
2
  '--w-rjv-font-family': string;
3
3
  '--w-rjv-color': string;
4
4
  '--w-rjv-background-color': string;
5
- '--w-rjv-border-left': string;
5
+ '--w-rjv-line-color': string;
6
6
  '--w-rjv-arrow-color': string;
7
7
  '--w-rjv-info-color': string;
8
+ '--w-rjv-copied-color': string;
9
+ '--w-rjv-copied-success-color': string;
8
10
  '--w-rjv-curlybraces-color': string;
9
11
  '--w-rjv-brackets-color': string;
10
12
  '--w-rjv-type-string-color': string;
package/cjs/theme/dark.js CHANGED
@@ -8,9 +8,11 @@ var darkTheme = {
8
8
  '--w-rjv-font-family': 'monospace',
9
9
  '--w-rjv-color': '#0184a6',
10
10
  '--w-rjv-background-color': '#202020',
11
- '--w-rjv-border-left': '1px solid #323232',
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-copied-color': '#0184a6',
15
+ '--w-rjv-copied-success-color': '#28a745',
14
16
  '--w-rjv-curlybraces-color': '#1896b6',
15
17
  '--w-rjv-brackets-color': '#1896b6',
16
18
  '--w-rjv-type-string-color': '#cb4b16',
@@ -2,9 +2,11 @@ export declare const lightTheme: {
2
2
  '--w-rjv-font-family': string;
3
3
  '--w-rjv-color': string;
4
4
  '--w-rjv-background-color': string;
5
- '--w-rjv-border-left': string;
5
+ '--w-rjv-line-color': string;
6
6
  '--w-rjv-arrow-color': string;
7
7
  '--w-rjv-info-color': string;
8
+ '--w-rjv-copied-color': string;
9
+ '--w-rjv-copied-success-color': string;
8
10
  '--w-rjv-curlybraces-color': string;
9
11
  '--w-rjv-brackets-color': string;
10
12
  '--w-rjv-type-string-color': string;
@@ -8,9 +8,11 @@ var lightTheme = {
8
8
  '--w-rjv-font-family': 'monospace',
9
9
  '--w-rjv-color': '#002b36',
10
10
  '--w-rjv-background-color': '#ffffff',
11
- '--w-rjv-border-left': '1px solid #ebebeb',
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-copied-color': '#002b36',
15
+ '--w-rjv-copied-success-color': '#28a745',
14
16
  '--w-rjv-curlybraces-color': '#236a7c',
15
17
  '--w-rjv-brackets-color': '#236a7c',
16
18
  '--w-rjv-type-string-color': '#cb4b16',
package/cjs/value.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { FC, PropsWithChildren } from 'react';
2
+ import { MetaProps } from './node';
3
+ export declare const Line: FC<PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>>;
2
4
  export declare const typeMap: {
3
5
  string: {
4
6
  color: string;
@@ -40,14 +42,18 @@ export declare const typeMap: {
40
42
  export declare const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>>;
41
43
  export interface ValueViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
42
44
  keyName?: string;
43
- value: T;
45
+ value?: T;
44
46
  displayDataTypes: boolean;
47
+ displayObjectSize: boolean;
48
+ enableClipboard: boolean;
49
+ indentWidth: number;
45
50
  renderKey?: JSX.Element;
51
+ renderBraces?: MetaProps['render'];
46
52
  renderValue?: (props: React.HTMLAttributes<HTMLSpanElement> & {
47
53
  type: TypeProps['type'];
48
54
  }) => JSX.Element;
49
55
  }
50
- export declare function ValueView<T>(props: ValueViewProps<T>): import("react/jsx-runtime").JSX.Element;
56
+ export declare function ValueView<T = object>(props: ValueViewProps<T>): import("react/jsx-runtime").JSX.Element;
51
57
  export interface LabelProps extends React.HTMLAttributes<HTMLSpanElement> {
52
58
  color?: string;
53
59
  fontSize?: number;