@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/cjs/value.js CHANGED
@@ -4,17 +4,24 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.Type = exports.Label = exports.Colon = void 0;
7
+ exports.Type = exports.Line = exports.Label = exports.Colon = void 0;
8
8
  exports.ValueView = ValueView;
9
9
  exports.typeMap = void 0;
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
11
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
12
12
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
13
14
  var _react = require("react");
15
+ var _node = require("./node");
16
+ var _copied = require("./copied");
14
17
  var _jsxRuntime = require("react/jsx-runtime");
15
18
  var _excluded = ["children", "style"],
16
- _excluded2 = ["value", "keyName", "renderKey", "renderValue", "displayDataTypes"],
19
+ _excluded2 = ["value", "keyName", "indentWidth", "renderKey", "renderValue", "renderBraces", "enableClipboard", "displayObjectSize", "displayDataTypes"],
17
20
  _excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
21
+ var Line = function Line(props) {
22
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", (0, _objectSpread2["default"])({}, props));
23
+ };
24
+ exports.Line = Line;
18
25
  var isFloat = function isFloat(n) {
19
26
  return Number(n) === n && n % 1 !== 0 || isNaN(n);
20
27
  };
@@ -76,8 +83,12 @@ function ValueView(props) {
76
83
  var _typeMap$type;
77
84
  var value = props.value,
78
85
  keyName = props.keyName,
86
+ indentWidth = props.indentWidth,
79
87
  renderKey = props.renderKey,
80
88
  renderValue = props.renderValue,
89
+ renderBraces = props.renderBraces,
90
+ enableClipboard = props.enableClipboard,
91
+ displayObjectSize = props.displayObjectSize,
81
92
  displayDataTypes = props.displayDataTypes,
82
93
  reset = (0, _objectWithoutProperties2["default"])(props, _excluded2);
83
94
  var type = (0, _typeof2["default"])(value);
@@ -123,6 +134,23 @@ function ValueView(props) {
123
134
  typeView = /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Fragment, {});
124
135
  }
125
136
  color = ((_typeMap$type = typeMap[type]) === null || _typeMap$type === void 0 ? void 0 : _typeMap$type.color) || '';
137
+ var _useState = (0, _react.useState)(false),
138
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
139
+ showTools = _useState2[0],
140
+ setShowTools = _useState2[1];
141
+ var tools = enableClipboard ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
142
+ show: showTools,
143
+ text: value
144
+ }) : undefined;
145
+ var eventProps = {};
146
+ if (enableClipboard) {
147
+ eventProps.onMouseEnter = function () {
148
+ return setShowTools(true);
149
+ };
150
+ eventProps.onMouseLeave = function () {
151
+ return setShowTools(false);
152
+ };
153
+ }
126
154
  if (content && typeof content === 'string') {
127
155
  var valueView = renderValue ? renderValue({
128
156
  className: 'w-rjv-value',
@@ -137,12 +165,37 @@ function ValueView(props) {
137
165
  className: "w-rjv-value",
138
166
  children: content
139
167
  });
140
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
141
- children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, valueView]
168
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
169
+ style: {
170
+ paddingLeft: indentWidth
171
+ }
172
+ }, eventProps), {}, {
173
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
174
+ children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, valueView, tools]
175
+ }))
142
176
  }));
143
177
  }
144
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
145
- children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView]
178
+ var length = Array.isArray(value) ? value.length : Object.keys(value).length;
179
+ var empty = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
180
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_node.Meta, {
181
+ render: renderBraces,
182
+ start: true,
183
+ isArray: Array.isArray(value)
184
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_node.Meta, {
185
+ render: renderBraces,
186
+ isArray: Array.isArray(value)
187
+ }), displayObjectSize && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_node.CountInfo, {
188
+ children: [length, " items"]
189
+ })]
190
+ });
191
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
192
+ style: {
193
+ paddingLeft: indentWidth
194
+ }
195
+ }, eventProps), {}, {
196
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
197
+ children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, empty, tools]
198
+ }))
146
199
  }));
147
200
  }
148
201
  var Label = function Label(_ref2) {
@@ -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/esm/copied.js ADDED
@@ -0,0 +1,63 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
3
+ var _excluded = ["children", "style", "text", "render", "show"];
4
+ import { useState } from 'react';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ export function Copied(props) {
7
+ var {
8
+ style,
9
+ text = '',
10
+ render,
11
+ show
12
+ } = props,
13
+ reset = _objectWithoutPropertiesLoose(props, _excluded);
14
+ if (!show) return null;
15
+ var [copied, setCopied] = useState(false);
16
+ var click = event => {
17
+ event.stopPropagation();
18
+ var copyText = JSON.stringify(text, (key, value) => {
19
+ if (typeof value === 'bigint') {
20
+ return value.toString();
21
+ }
22
+ return value;
23
+ }, 2);
24
+ if (text === Infinity) copyText = Infinity;
25
+ navigator.clipboard.writeText(copyText).then(() => {
26
+ setCopied(true);
27
+ var timer = setTimeout(() => {
28
+ setCopied(false);
29
+ clearTimeout(timer);
30
+ }, 3000);
31
+ }).catch(error => {});
32
+ };
33
+ var defalutStyle = _extends({}, style, {
34
+ cursor: 'pointer',
35
+ marginLeft: 5
36
+ });
37
+ var svgProps = _extends({
38
+ height: '1em',
39
+ width: '1em',
40
+ fill: 'var(--w-rjv-copied-color, currentColor)',
41
+ onClick: click,
42
+ style: defalutStyle,
43
+ className: 'w-rjv-copied'
44
+ }, reset);
45
+ if (render) return render(_extends({}, props, svgProps));
46
+ if (copied) {
47
+ return /*#__PURE__*/_jsx("svg", _extends({
48
+ viewBox: "0 0 38 38"
49
+ }, svgProps, {
50
+ fill: "var(--w-rjv-copied-success-color, #28a745)",
51
+ children: /*#__PURE__*/_jsx("path", {
52
+ 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"
53
+ })
54
+ }));
55
+ }
56
+ return /*#__PURE__*/_jsx("svg", _extends({
57
+ viewBox: "0 0 38 38"
58
+ }, svgProps, {
59
+ children: /*#__PURE__*/_jsx("path", {
60
+ 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"
61
+ })
62
+ }));
63
+ }
package/esm/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/esm/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/esm/node.js CHANGED
@@ -2,12 +2,13 @@ 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"],
6
- _excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "indentWidth", "keyid"];
7
- import { Fragment, useId, cloneElement } from 'react';
8
- import { ValueView, Colon, Label, typeMap } from './value';
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';
8
+ import { ValueView, Colon, Label, Line, typeMap } from './value';
9
9
  import { TriangleArrow } from './arrow/TriangleArrow';
10
10
  import { useExpandsStatus, store } from './store';
11
+ import { Copied } from './copied';
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
14
  export function Meta(props) {
@@ -36,7 +37,6 @@ export function Meta(props) {
36
37
  children: start ? mark.charAt(0) : mark.charAt(1)
37
38
  }));
38
39
  }
39
- export var Line = props => /*#__PURE__*/_jsx("div", _extends({}, props));
40
40
  export var Ellipsis = _ref => {
41
41
  var {
42
42
  style,
@@ -66,10 +66,11 @@ export var Semicolon = _ref2 => {
66
66
  color,
67
67
  value,
68
68
  className = 'w-rjv-object-key',
69
- show
69
+ show,
70
+ quotes
70
71
  } = _ref2,
71
72
  props = _objectWithoutPropertiesLoose(_ref2, _excluded3);
72
- var content = show ? "\"" + children + "\"" : children;
73
+ var content = show ? "" + quotes + children + quotes : children;
73
74
  if (render) return render(_extends({
74
75
  className
75
76
  }, props, {
@@ -108,20 +109,31 @@ export function RooNode(props) {
108
109
  displayDataTypes = true,
109
110
  components = {},
110
111
  displayObjectSize = true,
112
+ enableClipboard = true,
111
113
  indentWidth = 15,
112
- keyid = 'root'
114
+ collapsed,
115
+ level = 1,
116
+ keyid = 'root',
117
+ quotes = '"',
118
+ onExpand
113
119
  } = props,
114
120
  reset = _objectWithoutPropertiesLoose(props, _excluded4);
115
121
  var isArray = Array.isArray(value);
116
122
  var nameKeys = isArray ? Object.keys(value).map(m => Number(m)) : Object.keys(value);
117
123
  var subkeyid = useId();
118
124
  var expands = useExpandsStatus();
119
- var expand = (_expands$keyid = expands[keyid]) != null ? _expands$keyid : true;
125
+ var expand = (_expands$keyid = expands[keyid]) != null ? _expands$keyid : typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level <= collapsed : true;
120
126
  var arrowStyle = {
121
127
  transform: "rotate(" + (expand ? '0' : '-90') + "deg)",
122
128
  transition: 'all 0.3s'
123
129
  };
124
130
  var handle = () => {
131
+ onExpand && typeof onExpand === 'function' && onExpand({
132
+ expand: !expand,
133
+ keyid,
134
+ keyName,
135
+ value: value
136
+ });
125
137
  !expand ? store.expand(keyid) : store.collapse(keyid);
126
138
  };
127
139
  var subNodeProps = {
@@ -129,12 +141,20 @@ export function RooNode(props) {
129
141
  indentWidth,
130
142
  displayDataTypes,
131
143
  displayObjectSize,
144
+ enableClipboard,
145
+ onExpand,
146
+ collapsed,
147
+ quotes,
148
+ level: level + 1,
132
149
  style: {
133
150
  paddingLeft: indentWidth
134
151
  }
135
152
  };
136
153
  var valueViewProps = {
137
154
  displayDataTypes,
155
+ displayObjectSize,
156
+ enableClipboard,
157
+ indentWidth,
138
158
  renderValue: components.value
139
159
  };
140
160
  var arrowView = components.arrow ? /*#__PURE__*/cloneElement(components.arrow, {
@@ -143,7 +163,18 @@ export function RooNode(props) {
143
163
  }) : /*#__PURE__*/_jsx(TriangleArrow, {
144
164
  style: arrowStyle
145
165
  });
146
- return /*#__PURE__*/_jsxs("div", _extends({}, reset, {
166
+ var [showTools, setShowTools] = useState(false);
167
+ var tools = enableClipboard ? /*#__PURE__*/_jsx(Copied, {
168
+ show: showTools,
169
+ text: value,
170
+ render: components.copied
171
+ }) : undefined;
172
+ var eventProps = {};
173
+ if (enableClipboard) {
174
+ eventProps.onMouseEnter = () => setShowTools(true);
175
+ eventProps.onMouseLeave = () => setShowTools(false);
176
+ }
177
+ return /*#__PURE__*/_jsxs("div", _extends({}, reset, eventProps, {
147
178
  children: [/*#__PURE__*/_jsxs(Line, {
148
179
  style: {
149
180
  display: 'inline-flex',
@@ -153,6 +184,7 @@ export function RooNode(props) {
153
184
  children: [arrowView, (typeof keyName === 'string' || typeof keyName === 'number') && /*#__PURE__*/_jsxs(Fragment, {
154
185
  children: [/*#__PURE__*/_jsx(Semicolon, {
155
186
  value: value,
187
+ quotes: quotes,
156
188
  render: components.objectKey,
157
189
  color: typeof keyName === 'number' ? typeMap['number'].color : '',
158
190
  show: typeof keyName === 'string',
@@ -169,15 +201,24 @@ export function RooNode(props) {
169
201
  render: components.braces
170
202
  }), displayObjectSize && /*#__PURE__*/_jsxs(CountInfo, {
171
203
  children: [nameKeys.length, " items"]
172
- })]
204
+ }), tools]
173
205
  }), expand && /*#__PURE__*/_jsx(Line, {
174
206
  style: {
175
- borderLeft: 'var(--w-rjv-border-left, 1px solid #ebebeb)',
207
+ borderLeft: '1px solid var(--w-rjv-line-color, #ebebeb)',
176
208
  marginLeft: 6
177
209
  },
178
210
  children: nameKeys.length > 0 && nameKeys.map((key, idx) => {
179
211
  var item = value[key];
180
- if (Array.isArray(item)) {
212
+ var renderKey = /*#__PURE__*/_jsx(Semicolon, {
213
+ value: item,
214
+ quotes: quotes,
215
+ render: components.objectKey,
216
+ color: typeof key === 'number' ? typeMap['number'].color : '',
217
+ show: typeof key === 'string',
218
+ children: key
219
+ });
220
+ var isEmpty = Array.isArray(item) && item.length === 0 || typeof item === 'object' && item && !(item instanceof Date) && Object.keys(item).length === 0;
221
+ if (Array.isArray(item) && !isEmpty) {
181
222
  var label = isArray ? idx : key;
182
223
  return /*#__PURE__*/_jsx(Line, {
183
224
  children: /*#__PURE__*/_jsx(RooNode, _extends({
@@ -187,35 +228,7 @@ export function RooNode(props) {
187
228
  }, subNodeProps))
188
229
  }, label + idx);
189
230
  }
190
- var renderKey = /*#__PURE__*/_jsx(Semicolon, {
191
- value: item,
192
- render: components.objectKey,
193
- color: typeof key === 'number' ? typeMap['number'].color : '',
194
- show: typeof key === 'string',
195
- children: key
196
- });
197
- if (typeof item === 'object' && item && !(item instanceof Date)) {
198
- if (Object.keys(item).length === 0) {
199
- return /*#__PURE__*/_jsxs(Line, {
200
- style: {
201
- paddingLeft: indentWidth
202
- },
203
- children: [/*#__PURE__*/_jsx(ValueView, _extends({}, valueViewProps, {
204
- renderKey: renderKey,
205
- keyName: key,
206
- value: item
207
- })), /*#__PURE__*/_jsx(Meta, {
208
- render: components.braces,
209
- start: true,
210
- isArray: isArray
211
- }), /*#__PURE__*/_jsx(Meta, {
212
- render: components.braces,
213
- isArray: isArray
214
- }), displayObjectSize && /*#__PURE__*/_jsxs(CountInfo, {
215
- children: [Object.keys(item).length, " items"]
216
- })]
217
- }, key + idx);
218
- }
231
+ if (typeof item === 'object' && item && !(item instanceof Date) && !isEmpty) {
219
232
  return /*#__PURE__*/_jsx(Line, {
220
233
  children: /*#__PURE__*/_jsx(RooNode, _extends({
221
234
  keyid: keyid + subkeyid + key,
@@ -227,16 +240,12 @@ export function RooNode(props) {
227
240
  if (typeof item === 'function') {
228
241
  return;
229
242
  }
230
- return /*#__PURE__*/_jsx(Line, {
231
- style: {
232
- paddingLeft: indentWidth
233
- },
234
- children: /*#__PURE__*/_jsx(ValueView, _extends({}, valueViewProps, {
235
- renderKey: renderKey,
236
- keyName: key,
237
- value: item
238
- }))
239
- }, idx);
243
+ return /*#__PURE__*/_jsx(ValueView, _extends({}, valueViewProps, {
244
+ renderBraces: components.braces,
245
+ renderKey: renderKey,
246
+ keyName: key,
247
+ value: item
248
+ }), idx);
240
249
  })
241
250
  }), expand && /*#__PURE__*/_jsx(Line, {
242
251
  style: {
@@ -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/esm/theme/dark.js CHANGED
@@ -2,9 +2,11 @@ export var darkTheme = {
2
2
  '--w-rjv-font-family': 'monospace',
3
3
  '--w-rjv-color': '#0184a6',
4
4
  '--w-rjv-background-color': '#202020',
5
- '--w-rjv-border-left': '1px solid #323232',
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-copied-color': '#0184a6',
9
+ '--w-rjv-copied-success-color': '#28a745',
8
10
  '--w-rjv-curlybraces-color': '#1896b6',
9
11
  '--w-rjv-brackets-color': '#1896b6',
10
12
  '--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;
@@ -2,9 +2,11 @@ export var lightTheme = {
2
2
  '--w-rjv-font-family': 'monospace',
3
3
  '--w-rjv-color': '#002b36',
4
4
  '--w-rjv-background-color': '#ffffff',
5
- '--w-rjv-border-left': '1px solid #ebebeb',
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-copied-color': '#002b36',
9
+ '--w-rjv-copied-success-color': '#28a745',
8
10
  '--w-rjv-curlybraces-color': '#236a7c',
9
11
  '--w-rjv-brackets-color': '#236a7c',
10
12
  '--w-rjv-type-string-color': '#cb4b16',
package/esm/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;
package/esm/value.js CHANGED
@@ -1,11 +1,14 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
2
+ import _extends from "@babel/runtime/helpers/extends";
3
3
  var _excluded = ["children", "style"],
4
- _excluded2 = ["value", "keyName", "renderKey", "renderValue", "displayDataTypes"],
4
+ _excluded2 = ["value", "keyName", "indentWidth", "renderKey", "renderValue", "renderBraces", "enableClipboard", "displayObjectSize", "displayDataTypes"],
5
5
  _excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
6
- import { Fragment } from 'react';
6
+ import { Fragment, useState } from 'react';
7
+ import { Meta, CountInfo } from './node';
8
+ import { Copied } from './copied';
7
9
  import { jsx as _jsx } from "react/jsx-runtime";
8
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ export var Line = props => /*#__PURE__*/_jsx("div", _extends({}, props));
9
12
  var isFloat = n => Number(n) === n && n % 1 !== 0 || isNaN(n);
10
13
  export var typeMap = {
11
14
  string: {
@@ -64,8 +67,12 @@ export function ValueView(props) {
64
67
  var _typeMap$type;
65
68
  var {
66
69
  value,
70
+ indentWidth,
67
71
  renderKey,
68
72
  renderValue,
73
+ renderBraces,
74
+ enableClipboard,
75
+ displayObjectSize,
69
76
  displayDataTypes
70
77
  } = props,
71
78
  reset = _objectWithoutPropertiesLoose(props, _excluded2);
@@ -112,6 +119,16 @@ export function ValueView(props) {
112
119
  typeView = /*#__PURE__*/_jsx(Fragment, {});
113
120
  }
114
121
  color = ((_typeMap$type = typeMap[type]) == null ? void 0 : _typeMap$type.color) || '';
122
+ var [showTools, setShowTools] = useState(false);
123
+ var tools = enableClipboard ? /*#__PURE__*/_jsx(Copied, {
124
+ show: showTools,
125
+ text: value
126
+ }) : undefined;
127
+ var eventProps = {};
128
+ if (enableClipboard) {
129
+ eventProps.onMouseEnter = () => setShowTools(true);
130
+ eventProps.onMouseLeave = () => setShowTools(false);
131
+ }
115
132
  if (content && typeof content === 'string') {
116
133
  var valueView = renderValue ? renderValue({
117
134
  className: 'w-rjv-value',
@@ -126,12 +143,37 @@ export function ValueView(props) {
126
143
  className: "w-rjv-value",
127
144
  children: content
128
145
  });
129
- return /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
130
- children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, valueView]
146
+ return /*#__PURE__*/_jsx(Line, _extends({
147
+ style: {
148
+ paddingLeft: indentWidth
149
+ }
150
+ }, eventProps, {
151
+ children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
152
+ children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, valueView, tools]
153
+ }))
131
154
  }));
132
155
  }
133
- return /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
134
- children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView]
156
+ var length = Array.isArray(value) ? value.length : Object.keys(value).length;
157
+ var empty = /*#__PURE__*/_jsxs(Fragment, {
158
+ children: [/*#__PURE__*/_jsx(Meta, {
159
+ render: renderBraces,
160
+ start: true,
161
+ isArray: Array.isArray(value)
162
+ }), /*#__PURE__*/_jsx(Meta, {
163
+ render: renderBraces,
164
+ isArray: Array.isArray(value)
165
+ }), displayObjectSize && /*#__PURE__*/_jsxs(CountInfo, {
166
+ children: [length, " items"]
167
+ })]
168
+ });
169
+ return /*#__PURE__*/_jsx(Line, _extends({
170
+ style: {
171
+ paddingLeft: indentWidth
172
+ }
173
+ }, eventProps, {
174
+ children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
175
+ children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, empty, tools]
176
+ }))
135
177
  }));
136
178
  }
137
179
  export var Label = _ref2 => {