@uiw/react-json-view 1.8.2 → 1.8.3

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
@@ -280,47 +280,6 @@ export default function Demo() {
280
280
 
281
281
  ## Render
282
282
 
283
- ```tsx mdx:preview
284
- import React from 'react';
285
- import JsonView from '@uiw/react-json-view';
286
-
287
- const object = {
288
- string: 'Lorem ipsum dolor sit amet',
289
- integer: 42,
290
- float: 114.514,
291
- object: {
292
- 'first-child': true,
293
- 'second-child': false,
294
- 'last-child': null,
295
- },
296
- }
297
- export default function Demo() {
298
- return (
299
- <JsonView
300
- value={object}
301
- keyName="root"
302
- quotes=""
303
- displayObjectSize={false}
304
- displayDataTypes={false}
305
- style={{
306
- '--w-rjv-background-color': '#ffffff',
307
- '--w-rjv-border-left-width': '0',
308
- }}
309
- components={{
310
- braces: () => <span />,
311
- ellipsis: () => <React.Fragment />,
312
- objectKey: ({ value, keyName, parentName, ...props}) => {
313
- if (keyName === 'integer' && typeof value === 'number' && value > 40) {
314
- return <del {...props} />
315
- }
316
- return <span {...props} />
317
- }
318
- }}
319
- />
320
- )
321
- }
322
- ```
323
-
324
283
  **Preview Picture**
325
284
 
326
285
  ```tsx mdx:preview
@@ -333,7 +292,7 @@ const object = {
333
292
  integer: 42,
334
293
  }
335
294
 
336
- function value({ type, children, value, setValue, keyName, visible, ...props }) {
295
+ function value({ type, children, value, setValue, keyName, parentValue, visible, ...props }) {
337
296
  if (type === 'string' && /\.(jpg)$/.test(value)) {
338
297
  return (
339
298
  <span {...props}>
@@ -386,7 +345,7 @@ export default function Demo() {
386
345
  import React from 'react';
387
346
  import JsonView from '@uiw/react-json-view';
388
347
 
389
- function value({ type, children, visible, keyName, value, setValue, ...props }) {
348
+ function value({ type, children, visible, keyName, parentValue, value, setValue, ...props }) {
390
349
  if (value instanceof URL) {
391
350
  return (
392
351
  <span {...props}>
@@ -513,7 +472,7 @@ const object = {
513
472
  nestedArray: [ [1, 2], [3, 4], { a: 1} ],
514
473
  }
515
474
 
516
- const ObjectKey = ({ value, keyName, parentName, ...reset }) => {
475
+ const ObjectKey = ({ value, keyName, parentName, parentValue, ...reset }) => {
517
476
  if (keyName === 'integer' && typeof value === 'number' && value > 40) {
518
477
  return <del {...reset} />
519
478
  }
@@ -731,12 +690,23 @@ export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttr
731
690
  ellipsis?: EllipsisProps['render'];
732
691
  arrow?: JSX.Element;
733
692
  objectKey?: SemicolonProps['render'];
734
- value?: ValueViewProps<T>['renderValue'];
693
+ value?: (props: RenderValueProps<T>) => JSX.Element;
735
694
  copied?: CopiedProps<T>['render'];
736
695
  countInfo?: (props: CountInfoProps) => JSX.Element;
737
696
  countInfoExtra?: (props: Omit<CountInfoExtraProps<T>, 'editable'>) => JSX.Element;
738
697
  };
739
698
  }
699
+ interface RenderValueProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement> {
700
+ type: TypeProps['type'];
701
+ value?: unknown;
702
+ parentValue?: T;
703
+ data?: T;
704
+ visible?: boolean;
705
+ quotes?: JsonViewProps<T>['quotes'];
706
+ namespace?: Array<string | number>;
707
+ setValue?: React.Dispatch<React.SetStateAction<T>>;
708
+ keyName?: ValueViewProps<T>['keyName'];
709
+ }
740
710
  declare const JsonView: React.ForwardRefExoticComponent<Omit<JsonViewProps<object>, "ref"> & React.RefAttributes<HTMLDivElement>>;
741
711
  export default JsonView;
742
712
  export interface CountInfoProps {
@@ -6,6 +6,7 @@ export interface CountInfoExtraProps<T> extends Partial<CountInfoProps> {
6
6
  value: T;
7
7
  parentValue?: T;
8
8
  keyName?: string | number;
9
+ namespace?: Array<string | number>;
9
10
  setValue?: React.Dispatch<React.SetStateAction<T>>;
10
11
  setParentValue?: React.Dispatch<React.SetStateAction<T>>;
11
12
  /**
@@ -17,6 +18,8 @@ export interface CountInfoExtraProps<T> extends Partial<CountInfoProps> {
17
18
  * When a callback function is passed in, delete functionality is enabled. The callback is invoked before deletions are completed.
18
19
  * @returns Returning false from onDelete will prevent the change from being made.
19
20
  */
20
- onDelete?: (keyName: string | number, value: T, parentValue: T) => boolean;
21
+ onDelete?: (keyName: string | number, value: T, parentValue: T | null, opt: {
22
+ namespace?: Array<string | number>;
23
+ }) => boolean;
21
24
  }
22
25
  export declare function CountInfoExtra<T extends object>(props: CountInfoExtraProps<T>): import("react/jsx-runtime").JSX.Element | null;
@@ -20,6 +20,7 @@ function CountInfoExtra(props) {
20
20
  editable = props.editable,
21
21
  keyName = props.keyName,
22
22
  value = props.value,
23
+ namespace = props.namespace,
23
24
  parentValue = props.parentValue,
24
25
  setValue = props.setValue,
25
26
  setParentValue = props.setParentValue,
@@ -70,7 +71,9 @@ function CountInfoExtra(props) {
70
71
  break;
71
72
  }
72
73
  _context2.next = 4;
73
- return onDelete(keyName, value, parentValue);
74
+ return onDelete(keyName, value, parentValue, {
75
+ namespace: namespace
76
+ });
74
77
  case 4:
75
78
  maybeDelete = _context2.sent;
76
79
  if (maybeDelete && setParentValue) {
@@ -7,6 +7,7 @@ export interface ReValueProps<T extends object> extends React.HTMLAttributes<HTM
7
7
  keyName?: JsonViewEditorProps<T>['keyName'];
8
8
  type: TypeProps['type'];
9
9
  value?: unknown;
10
+ parentValue?: T;
10
11
  data?: T;
11
12
  visible?: boolean;
12
13
  namespace?: Array<string | number>;
@@ -15,7 +15,7 @@ var _value = require("../value");
15
15
  var _edit = require("./icon/edit");
16
16
  var _delete = require("./icon/delete");
17
17
  var _jsxRuntime = require("react/jsx-runtime");
18
- var _excluded = ["type", "value", "setValue", "data", "keyName", "visible", "quotes", "style", "children", "namespace", "displayDataTypes", "editableValue", "onDelete", "onEdit"];
18
+ var _excluded = ["type", "value", "setValue", "data", "keyName", "visible", "quotes", "style", "children", "namespace", "displayDataTypes", "editableValue", "parentValue", "onDelete", "onEdit"];
19
19
  var Quotes = function Quotes(_ref) {
20
20
  var show = _ref.show,
21
21
  style = _ref.style,
@@ -40,6 +40,7 @@ function ReValue(props) {
40
40
  namespace = props.namespace,
41
41
  displayDataTypes = props.displayDataTypes,
42
42
  editableValue = props.editableValue,
43
+ parentValue = props.parentValue,
43
44
  onDelete = props.onDelete,
44
45
  onEdit = props.onEdit,
45
46
  reset = (0, _objectWithoutProperties2["default"])(props, _excluded);
@@ -190,15 +191,26 @@ function ReValue(props) {
190
191
  }
191
192
  var deleteHandle = /*#__PURE__*/function () {
192
193
  var _ref3 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/(0, _regeneratorRuntime2["default"])().mark(function _callee2(evn) {
194
+ var maybeDelete;
193
195
  return (0, _regeneratorRuntime2["default"])().wrap(function _callee2$(_context2) {
194
196
  while (1) switch (_context2.prev = _context2.next) {
195
197
  case 0:
196
198
  evn.stopPropagation();
197
- if (data && keyName && keyName in data && setValue) {
199
+ if (!(data && keyName && keyName in data && setValue && onDelete)) {
200
+ _context2.next = 6;
201
+ break;
202
+ }
203
+ _context2.next = 4;
204
+ return onDelete(keyName, value, parentValue, {
205
+ namespace: namespace
206
+ });
207
+ case 4:
208
+ maybeDelete = _context2.sent;
209
+ if (maybeDelete) {
198
210
  delete data[keyName];
199
211
  setValue((0, _objectSpread2["default"])({}, data));
200
212
  }
201
- case 2:
213
+ case 6:
202
214
  case "end":
203
215
  return _context2.stop();
204
216
  }
package/cjs/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { SemicolonProps } from './semicolon';
3
- import type { ValueViewProps } from './value';
3
+ import type { ValueViewProps, TypeProps } from './value';
4
4
  import type { CopiedProps } from './copied';
5
5
  import type { EllipsisProps } from './comps/ellipsis';
6
6
  import type { MetaProps } from './comps/meta';
@@ -12,6 +12,17 @@ export interface CountInfoProps {
12
12
  level: number;
13
13
  visible: boolean;
14
14
  }
15
+ interface RenderValueProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement> {
16
+ type: TypeProps['type'];
17
+ value?: unknown;
18
+ parentValue?: T;
19
+ data?: T;
20
+ visible?: boolean;
21
+ quotes?: JsonViewProps<T>['quotes'];
22
+ namespace?: Array<string | number>;
23
+ setValue?: React.Dispatch<React.SetStateAction<T>>;
24
+ keyName?: ValueViewProps<T>['keyName'];
25
+ }
15
26
  export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
16
27
  /** This property contains your input JSON */
17
28
  value?: T;
@@ -48,7 +59,7 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
48
59
  ellipsis?: EllipsisProps['render'];
49
60
  arrow?: JSX.Element;
50
61
  objectKey?: SemicolonProps['render'];
51
- value?: ValueViewProps<T>['renderValue'];
62
+ value?: (props: RenderValueProps<T>) => JSX.Element;
52
63
  copied?: CopiedProps<T>['render'];
53
64
  countInfo?: (props: CountInfoProps) => JSX.Element;
54
65
  countInfoExtra?: (props: Omit<CountInfoExtraProps<T>, 'editable'>) => JSX.Element;
package/cjs/node.js CHANGED
@@ -21,16 +21,23 @@ var _ellipsis = require("./comps/ellipsis");
21
21
  var _meta = require("./comps/meta");
22
22
  var _jsxRuntime = require("react/jsx-runtime");
23
23
  var _excluded = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "objectSortKeys", "indentWidth", "collapsed", "level", "keyid", "quotes", "namespace", "onCopied", "onExpand", "parentValue", "setParentValue"];
24
+ function getLength(obj) {
25
+ try {
26
+ return Object.keys(obj).length;
27
+ } catch (error) {
28
+ return -1;
29
+ }
30
+ }
24
31
  var CountInfo = function CountInfo(_ref) {
25
32
  var children = _ref.children;
26
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Label, {
33
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_value.Label, {
27
34
  style: {
28
35
  paddingLeft: 4,
29
36
  fontStyle: 'italic'
30
37
  },
31
38
  color: "var(--w-rjv-info-color, #0000004d)",
32
39
  className: "w-rjv-object-size",
33
- children: children
40
+ children: [children, " items"]
34
41
  });
35
42
  };
36
43
  exports.CountInfo = CountInfo;
@@ -107,12 +114,12 @@ function RooNode(props) {
107
114
  displayDataTypes: displayDataTypes,
108
115
  displayObjectSize: displayObjectSize,
109
116
  enableClipboard: enableClipboard,
117
+ level: level + 1,
118
+ parentValue: value,
110
119
  indentWidth: indentWidth,
111
120
  data: valueData,
112
121
  quotes: quotes,
113
- setValue: setValueData,
114
- renderBraces: components.braces,
115
- renderValue: components.value
122
+ setValue: setValueData
116
123
  };
117
124
  var arrowStyle = {
118
125
  transform: "rotate(".concat(expand ? '0' : '-90', "deg)"),
@@ -165,8 +172,8 @@ function RooNode(props) {
165
172
  return typeof a === 'string' && typeof b === 'string' ? objectSortKeys(a, b) : 0;
166
173
  });
167
174
  }
168
- var countInfo = /*#__PURE__*/(0, _jsxRuntime.jsxs)(CountInfo, {
169
- children: [nameKeys.length, " items"]
175
+ var countInfo = /*#__PURE__*/(0, _jsxRuntime.jsx)(CountInfo, {
176
+ children: nameKeys.length
170
177
  });
171
178
  if (components.countInfo) {
172
179
  countInfo = components.countInfo({
@@ -175,6 +182,19 @@ function RooNode(props) {
175
182
  visible: expand
176
183
  }) || countInfo;
177
184
  }
185
+ if (!displayObjectSize) countInfo = null;
186
+ var countInfoExtra = components.countInfoExtra && components.countInfoExtra({
187
+ count: nameKeys.length,
188
+ level: level,
189
+ showTools: showTools,
190
+ keyName: keyName,
191
+ visible: expand,
192
+ value: valueData,
193
+ namespace: (0, _toConsumableArray2["default"])(namespace),
194
+ parentValue: parentValue,
195
+ setParentValue: setParentValue,
196
+ setValue: setValueData
197
+ });
178
198
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
179
199
  className: "".concat(className, " w-rjv-inner")
180
200
  }, eventProps), {}, {
@@ -208,17 +228,7 @@ function RooNode(props) {
208
228
  isArray: isArray,
209
229
  level: level,
210
230
  render: components.braces
211
- }), displayObjectSize && countInfo, components.countInfoExtra && components.countInfoExtra({
212
- count: nameKeys.length,
213
- level: level,
214
- showTools: showTools,
215
- keyName: keyName,
216
- visible: expand,
217
- value: valueData,
218
- parentValue: parentValue,
219
- setParentValue: setParentValue,
220
- setValue: setValueData
221
- }), enableClipboard && /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
231
+ }), countInfo, countInfoExtra, enableClipboard && /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
222
232
  show: showTools,
223
233
  text: valueData,
224
234
  onCopied: onCopied,
@@ -235,17 +245,6 @@ function RooNode(props) {
235
245
  key = _ref11[0],
236
246
  itemVal = _ref11[1];
237
247
  var item = itemVal;
238
- var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(_semicolon.Semicolon, {
239
- value: item,
240
- "data-keys": keyid,
241
- quotes: quotes,
242
- namespace: [].concat((0, _toConsumableArray2["default"])(namespace), [key]),
243
- parentName: keyName,
244
- highlightUpdates: highlightUpdates,
245
- render: components.objectKey,
246
- color: typeof key === 'number' ? _value.typeMap['number'].color : '',
247
- keyName: key
248
- });
249
248
  var isEmpty = Array.isArray(item) && item.length === 0 || (0, _typeof2["default"])(item) === 'object' && item && !(item instanceof Date) && Object.keys(item).length === 0;
250
249
  if (Array.isArray(item) && !isEmpty) {
251
250
  var label = isArray ? idx : key;
@@ -273,9 +272,53 @@ function RooNode(props) {
273
272
  if (typeof item === 'function') {
274
273
  return;
275
274
  }
275
+ var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(_semicolon.Semicolon, {
276
+ value: item,
277
+ "data-keys": keyid,
278
+ quotes: quotes,
279
+ namespace: [].concat((0, _toConsumableArray2["default"])(namespace), [key]),
280
+ parentName: keyName,
281
+ highlightUpdates: highlightUpdates,
282
+ render: components.objectKey,
283
+ color: typeof key === 'number' ? _value.typeMap['number'].color : '',
284
+ keyName: key
285
+ });
286
+ var length = Array.isArray(item) ? item.length : getLength(item);
287
+ countInfo = /*#__PURE__*/(0, _jsxRuntime.jsx)(CountInfo, {
288
+ children: length
289
+ });
290
+ if (components.countInfo) {
291
+ countInfo = components.countInfo({
292
+ count: length,
293
+ level: level,
294
+ visible: expand
295
+ }) || countInfo;
296
+ }
297
+ // if (length > -1) {
298
+ // countInfo = (
299
+ // <Fragment>
300
+ // {countInfo}
301
+ // {components.countInfoExtra &&
302
+ // components.countInfoExtra({
303
+ // count: length,
304
+ // level,
305
+ // showTools,
306
+ // keyName,
307
+ // visible: expand,
308
+ // value: valueData,
309
+ // namespace: [...namespace],
310
+ // parentValue,
311
+ // setParentValue,
312
+ // setValue: setValueData,
313
+ // })}
314
+ // </Fragment>
315
+ // )
316
+ // }
276
317
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.ValueView, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
318
+ components: components,
277
319
  namespace: [].concat((0, _toConsumableArray2["default"])(namespace), [key])
278
320
  }, valueViewProps), {}, {
321
+ countInfo: countInfo,
279
322
  renderKey: renderKey,
280
323
  keyName: key,
281
324
  value: item
package/cjs/value.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { FC, PropsWithChildren } from 'react';
2
- import type { MetaProps } from './comps/meta';
3
2
  import type { JsonViewProps } from './';
4
3
  export declare const Line: FC<PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>>;
5
4
  export declare const isFloat: (n: number) => boolean;
@@ -46,19 +45,10 @@ export declare const typeMap: {
46
45
  };
47
46
  };
48
47
  export declare const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>>;
49
- interface RenderValueProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement> {
50
- type: TypeProps['type'];
51
- value?: unknown;
52
- data?: T;
53
- visible?: boolean;
54
- quotes?: JsonViewProps<T>['quotes'];
55
- namespace?: Array<string | number>;
56
- setValue?: React.Dispatch<React.SetStateAction<T>>;
57
- keyName?: ValueViewProps<T>['keyName'];
58
- }
59
48
  export interface ValueViewProps<T extends object> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
60
49
  keyName?: string | number;
61
50
  value?: unknown;
51
+ parentValue?: T;
62
52
  data?: T;
63
53
  displayDataTypes: boolean;
64
54
  displayObjectSize: boolean;
@@ -67,10 +57,10 @@ export interface ValueViewProps<T extends object> extends React.DetailedHTMLProp
67
57
  level?: number;
68
58
  namespace?: Array<string | number>;
69
59
  quotes?: JsonViewProps<T>['quotes'];
60
+ components?: JsonViewProps<T>['components'];
70
61
  renderKey?: JSX.Element;
71
- renderBraces?: MetaProps['render'];
62
+ countInfo?: JSX.Element;
72
63
  setValue?: React.Dispatch<React.SetStateAction<T>>;
73
- renderValue?: (props: RenderValueProps<T>) => JSX.Element;
74
64
  }
75
65
  export declare function getValueString<T>(value: T): {
76
66
  type: "string" | "number" | "bigint" | "boolean" | "undefined" | "date" | "url" | "float" | "null" | "NaN";
@@ -88,4 +78,3 @@ export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<
88
78
  type: keyof typeof typeMap;
89
79
  }
90
80
  export declare const Type: FC<PropsWithChildren<TypeProps>>;
91
- export {};
package/cjs/value.js CHANGED
@@ -13,12 +13,11 @@ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
13
13
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
14
14
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
15
15
  var _react = require("react");
16
- var _node = require("./node");
17
16
  var _meta = require("./comps/meta");
18
17
  var _copied = require("./copied");
19
18
  var _jsxRuntime = require("react/jsx-runtime");
20
19
  var _excluded = ["children", "style"],
21
- _excluded2 = ["value", "setValue", "data", "keyName", "indentWidth", "namespace", "renderKey", "quotes", "level", "renderValue", "renderBraces", "enableClipboard", "displayObjectSize", "displayDataTypes"],
20
+ _excluded2 = ["value", "parentValue", "setValue", "countInfo", "data", "keyName", "indentWidth", "namespace", "renderKey", "components", "quotes", "level", "enableClipboard", "displayObjectSize", "displayDataTypes"],
22
21
  _excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
23
22
  var Line = function Line(props) {
24
23
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", (0, _objectSpread2["default"])({}, props));
@@ -129,16 +128,18 @@ function getValueString(value) {
129
128
  function ValueView(props) {
130
129
  var _typeMap$type;
131
130
  var value = props.value,
131
+ parentValue = props.parentValue,
132
132
  setValue = props.setValue,
133
+ countInfo = props.countInfo,
133
134
  data = props.data,
134
135
  keyName = props.keyName,
135
136
  indentWidth = props.indentWidth,
136
137
  namespace = props.namespace,
137
138
  renderKey = props.renderKey,
139
+ _props$components = props.components,
140
+ components = _props$components === void 0 ? {} : _props$components,
138
141
  quotes = props.quotes,
139
142
  level = props.level,
140
- renderValue = props.renderValue,
141
- renderBraces = props.renderBraces,
142
143
  enableClipboard = props.enableClipboard,
143
144
  displayObjectSize = props.displayObjectSize,
144
145
  displayDataTypes = props.displayDataTypes,
@@ -169,10 +170,13 @@ function ValueView(props) {
169
170
  _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
170
171
  showTools = _useState2[0],
171
172
  setShowTools = _useState2[1];
172
- var tools = enableClipboard ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
173
- show: showTools,
174
- text: value
175
- }) : undefined;
173
+ var tools = (0, _react.useMemo)(function () {
174
+ return enableClipboard && showTools && /*#__PURE__*/(0, _jsxRuntime.jsx)(_copied.Copied, {
175
+ show: showTools,
176
+ text: value
177
+ });
178
+ }, [enableClipboard, showTools, value]);
179
+ // const tools = enableClipboard ? <Copied show={showTools} text={value} /> : undefined;
176
180
  var eventProps = {
177
181
  className: 'w-rjv-line',
178
182
  style: {
@@ -188,7 +192,7 @@ function ValueView(props) {
188
192
  };
189
193
  }
190
194
  if (content && typeof content === 'string') {
191
- var reView = renderValue && renderValue({
195
+ var reView = components.value && components.value({
192
196
  className: 'w-rjv-value',
193
197
  style: (0, _objectSpread2["default"])({
194
198
  color: color
@@ -197,6 +201,7 @@ function ValueView(props) {
197
201
  value: value,
198
202
  setValue: setValue,
199
203
  data: data,
204
+ parentValue: parentValue,
200
205
  quotes: quotes,
201
206
  keyName: keyName,
202
207
  namespace: namespace,
@@ -225,18 +230,15 @@ function ValueView(props) {
225
230
  }))
226
231
  }));
227
232
  }
228
- var length = Array.isArray(value) ? value.length : Object.keys(value).length;
229
233
  var empty = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
230
234
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_meta.Meta, {
231
- render: renderBraces,
235
+ render: components.braces,
232
236
  start: true,
233
237
  isArray: Array.isArray(value)
234
238
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_meta.Meta, {
235
- render: renderBraces,
239
+ render: components.braces,
236
240
  isArray: Array.isArray(value)
237
- }), displayObjectSize && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_node.CountInfo, {
238
- children: [length, " items"]
239
- })]
241
+ }), countInfo]
240
242
  });
241
243
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Line, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, eventProps), {}, {
242
244
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
@@ -6,6 +6,7 @@ export interface CountInfoExtraProps<T> extends Partial<CountInfoProps> {
6
6
  value: T;
7
7
  parentValue?: T;
8
8
  keyName?: string | number;
9
+ namespace?: Array<string | number>;
9
10
  setValue?: React.Dispatch<React.SetStateAction<T>>;
10
11
  setParentValue?: React.Dispatch<React.SetStateAction<T>>;
11
12
  /**
@@ -17,6 +18,8 @@ export interface CountInfoExtraProps<T> extends Partial<CountInfoProps> {
17
18
  * When a callback function is passed in, delete functionality is enabled. The callback is invoked before deletions are completed.
18
19
  * @returns Returning false from onDelete will prevent the change from being made.
19
20
  */
20
- onDelete?: (keyName: string | number, value: T, parentValue: T) => boolean;
21
+ onDelete?: (keyName: string | number, value: T, parentValue: T | null, opt: {
22
+ namespace?: Array<string | number>;
23
+ }) => boolean;
21
24
  }
22
25
  export declare function CountInfoExtra<T extends object>(props: CountInfoExtraProps<T>): import("react/jsx-runtime").JSX.Element | null;
@@ -12,6 +12,7 @@ export function CountInfoExtra(props) {
12
12
  editable,
13
13
  keyName,
14
14
  value,
15
+ namespace,
15
16
  parentValue,
16
17
  setValue,
17
18
  setParentValue,
@@ -43,7 +44,9 @@ export function CountInfoExtra(props) {
43
44
  var _ref2 = _asyncToGenerator(function* (event) {
44
45
  event.stopPropagation();
45
46
  if (onDelete && (keyName || typeof keyName === 'number') && parentValue) {
46
- var maybeDelete = yield onDelete(keyName, value, parentValue);
47
+ var maybeDelete = yield onDelete(keyName, value, parentValue, {
48
+ namespace
49
+ });
47
50
  if (maybeDelete && setParentValue) {
48
51
  if (Array.isArray(parentValue)) {
49
52
  parentValue.splice(keyName, 1);
@@ -7,6 +7,7 @@ export interface ReValueProps<T extends object> extends React.HTMLAttributes<HTM
7
7
  keyName?: JsonViewEditorProps<T>['keyName'];
8
8
  type: TypeProps['type'];
9
9
  value?: unknown;
10
+ parentValue?: T;
10
11
  data?: T;
11
12
  visible?: boolean;
12
13
  namespace?: Array<string | number>;
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
3
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
4
- var _excluded = ["type", "value", "setValue", "data", "keyName", "visible", "quotes", "style", "children", "namespace", "displayDataTypes", "editableValue", "onDelete", "onEdit"];
4
+ var _excluded = ["type", "value", "setValue", "data", "keyName", "visible", "quotes", "style", "children", "namespace", "displayDataTypes", "editableValue", "parentValue", "onDelete", "onEdit"];
5
5
  import { Fragment, useEffect, useRef, useState } from 'react';
6
6
  import { getValueString, isFloat, Type, typeMap } from '../value';
7
7
  import { EditIcon } from './icon/edit';
@@ -34,6 +34,7 @@ export function ReValue(props) {
34
34
  namespace,
35
35
  displayDataTypes,
36
36
  editableValue,
37
+ parentValue,
37
38
  onDelete,
38
39
  onEdit
39
40
  } = props,
@@ -157,9 +158,14 @@ export function ReValue(props) {
157
158
  var deleteHandle = /*#__PURE__*/function () {
158
159
  var _ref3 = _asyncToGenerator(function* (evn) {
159
160
  evn.stopPropagation();
160
- if (data && keyName && keyName in data && setValue) {
161
- delete data[keyName];
162
- setValue(_extends({}, data));
161
+ if (data && keyName && keyName in data && setValue && onDelete) {
162
+ var maybeDelete = yield onDelete(keyName, value, parentValue, {
163
+ namespace
164
+ });
165
+ if (maybeDelete) {
166
+ delete data[keyName];
167
+ setValue(_extends({}, data));
168
+ }
163
169
  }
164
170
  });
165
171
  return function deleteHandle(_x) {
package/esm/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { SemicolonProps } from './semicolon';
3
- import type { ValueViewProps } from './value';
3
+ import type { ValueViewProps, TypeProps } from './value';
4
4
  import type { CopiedProps } from './copied';
5
5
  import type { EllipsisProps } from './comps/ellipsis';
6
6
  import type { MetaProps } from './comps/meta';
@@ -12,6 +12,17 @@ export interface CountInfoProps {
12
12
  level: number;
13
13
  visible: boolean;
14
14
  }
15
+ interface RenderValueProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement> {
16
+ type: TypeProps['type'];
17
+ value?: unknown;
18
+ parentValue?: T;
19
+ data?: T;
20
+ visible?: boolean;
21
+ quotes?: JsonViewProps<T>['quotes'];
22
+ namespace?: Array<string | number>;
23
+ setValue?: React.Dispatch<React.SetStateAction<T>>;
24
+ keyName?: ValueViewProps<T>['keyName'];
25
+ }
15
26
  export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
16
27
  /** This property contains your input JSON */
17
28
  value?: T;
@@ -48,7 +59,7 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
48
59
  ellipsis?: EllipsisProps['render'];
49
60
  arrow?: JSX.Element;
50
61
  objectKey?: SemicolonProps['render'];
51
- value?: ValueViewProps<T>['renderValue'];
62
+ value?: (props: RenderValueProps<T>) => JSX.Element;
52
63
  copied?: CopiedProps<T>['render'];
53
64
  countInfo?: (props: CountInfoProps) => JSX.Element;
54
65
  countInfoExtra?: (props: Omit<CountInfoExtraProps<T>, 'editable'>) => JSX.Element;
package/esm/node.js CHANGED
@@ -9,20 +9,27 @@ import { Semicolon } from './semicolon';
9
9
  import { Copied } from './copied';
10
10
  import { Ellipsis } from './comps/ellipsis';
11
11
  import { Meta } from './comps/meta';
12
- import { jsx as _jsx } from "react/jsx-runtime";
13
12
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ function getLength(obj) {
15
+ try {
16
+ return Object.keys(obj).length;
17
+ } catch (error) {
18
+ return -1;
19
+ }
20
+ }
14
21
  export var CountInfo = _ref => {
15
22
  var {
16
23
  children
17
24
  } = _ref;
18
- return /*#__PURE__*/_jsx(Label, {
25
+ return /*#__PURE__*/_jsxs(Label, {
19
26
  style: {
20
27
  paddingLeft: 4,
21
28
  fontStyle: 'italic'
22
29
  },
23
30
  color: "var(--w-rjv-info-color, #0000004d)",
24
31
  className: "w-rjv-object-size",
25
- children: children
32
+ children: [children, " items"]
26
33
  });
27
34
  };
28
35
  export function RooNode(props) {
@@ -85,12 +92,12 @@ export function RooNode(props) {
85
92
  displayDataTypes,
86
93
  displayObjectSize,
87
94
  enableClipboard,
95
+ level: level + 1,
96
+ parentValue: value,
88
97
  indentWidth,
89
98
  data: valueData,
90
99
  quotes,
91
- setValue: setValueData,
92
- renderBraces: components.braces,
93
- renderValue: components.value
100
+ setValue: setValueData
94
101
  };
95
102
  var arrowStyle = {
96
103
  transform: "rotate(" + (expand ? '0' : '-90') + "deg)",
@@ -126,8 +133,8 @@ export function RooNode(props) {
126
133
  return typeof a === 'string' && typeof b === 'string' ? objectSortKeys(a, b) : 0;
127
134
  });
128
135
  }
129
- var countInfo = /*#__PURE__*/_jsxs(CountInfo, {
130
- children: [nameKeys.length, " items"]
136
+ var countInfo = /*#__PURE__*/_jsx(CountInfo, {
137
+ children: nameKeys.length
131
138
  });
132
139
  if (components.countInfo) {
133
140
  countInfo = components.countInfo({
@@ -136,6 +143,19 @@ export function RooNode(props) {
136
143
  visible: expand
137
144
  }) || countInfo;
138
145
  }
146
+ if (!displayObjectSize) countInfo = null;
147
+ var countInfoExtra = components.countInfoExtra && components.countInfoExtra({
148
+ count: nameKeys.length,
149
+ level,
150
+ showTools,
151
+ keyName,
152
+ visible: expand,
153
+ value: valueData,
154
+ namespace: [...namespace],
155
+ parentValue,
156
+ setParentValue,
157
+ setValue: setValueData
158
+ });
139
159
  return /*#__PURE__*/_jsxs("div", _extends({}, reset, {
140
160
  className: className + " w-rjv-inner"
141
161
  }, eventProps, {
@@ -169,17 +189,7 @@ export function RooNode(props) {
169
189
  isArray: isArray,
170
190
  level: level,
171
191
  render: components.braces
172
- }), displayObjectSize && countInfo, components.countInfoExtra && components.countInfoExtra({
173
- count: nameKeys.length,
174
- level,
175
- showTools,
176
- keyName,
177
- visible: expand,
178
- value: valueData,
179
- parentValue,
180
- setParentValue,
181
- setValue: setValueData
182
- }), enableClipboard && /*#__PURE__*/_jsx(Copied, {
192
+ }), countInfo, countInfoExtra, enableClipboard && /*#__PURE__*/_jsx(Copied, {
183
193
  show: showTools,
184
194
  text: valueData,
185
195
  onCopied: onCopied,
@@ -194,17 +204,6 @@ export function RooNode(props) {
194
204
  children: entries.length > 0 && [...entries].map((_ref6, idx) => {
195
205
  var [key, itemVal] = _ref6;
196
206
  var item = itemVal;
197
- var renderKey = /*#__PURE__*/_jsx(Semicolon, {
198
- value: item,
199
- "data-keys": keyid,
200
- quotes: quotes,
201
- namespace: [...namespace, key],
202
- parentName: keyName,
203
- highlightUpdates: highlightUpdates,
204
- render: components.objectKey,
205
- color: typeof key === 'number' ? typeMap['number'].color : '',
206
- keyName: key
207
- });
208
207
  var isEmpty = Array.isArray(item) && item.length === 0 || typeof item === 'object' && item && !(item instanceof Date) && Object.keys(item).length === 0;
209
208
  if (Array.isArray(item) && !isEmpty) {
210
209
  var label = isArray ? idx : key;
@@ -232,9 +231,53 @@ export function RooNode(props) {
232
231
  if (typeof item === 'function') {
233
232
  return;
234
233
  }
234
+ var renderKey = /*#__PURE__*/_jsx(Semicolon, {
235
+ value: item,
236
+ "data-keys": keyid,
237
+ quotes: quotes,
238
+ namespace: [...namespace, key],
239
+ parentName: keyName,
240
+ highlightUpdates: highlightUpdates,
241
+ render: components.objectKey,
242
+ color: typeof key === 'number' ? typeMap['number'].color : '',
243
+ keyName: key
244
+ });
245
+ var length = Array.isArray(item) ? item.length : getLength(item);
246
+ countInfo = /*#__PURE__*/_jsx(CountInfo, {
247
+ children: length
248
+ });
249
+ if (components.countInfo) {
250
+ countInfo = components.countInfo({
251
+ count: length,
252
+ level,
253
+ visible: expand
254
+ }) || countInfo;
255
+ }
256
+ // if (length > -1) {
257
+ // countInfo = (
258
+ // <Fragment>
259
+ // {countInfo}
260
+ // {components.countInfoExtra &&
261
+ // components.countInfoExtra({
262
+ // count: length,
263
+ // level,
264
+ // showTools,
265
+ // keyName,
266
+ // visible: expand,
267
+ // value: valueData,
268
+ // namespace: [...namespace],
269
+ // parentValue,
270
+ // setParentValue,
271
+ // setValue: setValueData,
272
+ // })}
273
+ // </Fragment>
274
+ // )
275
+ // }
235
276
  return /*#__PURE__*/_jsx(ValueView, _extends({
277
+ components: components,
236
278
  namespace: [...namespace, key]
237
279
  }, valueViewProps, {
280
+ countInfo: countInfo,
238
281
  renderKey: renderKey,
239
282
  keyName: key,
240
283
  value: item
package/esm/value.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import type { FC, PropsWithChildren } from 'react';
2
- import type { MetaProps } from './comps/meta';
3
2
  import type { JsonViewProps } from './';
4
3
  export declare const Line: FC<PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>>;
5
4
  export declare const isFloat: (n: number) => boolean;
@@ -46,19 +45,10 @@ export declare const typeMap: {
46
45
  };
47
46
  };
48
47
  export declare const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>>;
49
- interface RenderValueProps<T extends object> extends React.HTMLAttributes<HTMLSpanElement> {
50
- type: TypeProps['type'];
51
- value?: unknown;
52
- data?: T;
53
- visible?: boolean;
54
- quotes?: JsonViewProps<T>['quotes'];
55
- namespace?: Array<string | number>;
56
- setValue?: React.Dispatch<React.SetStateAction<T>>;
57
- keyName?: ValueViewProps<T>['keyName'];
58
- }
59
48
  export interface ValueViewProps<T extends object> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
60
49
  keyName?: string | number;
61
50
  value?: unknown;
51
+ parentValue?: T;
62
52
  data?: T;
63
53
  displayDataTypes: boolean;
64
54
  displayObjectSize: boolean;
@@ -67,10 +57,10 @@ export interface ValueViewProps<T extends object> extends React.DetailedHTMLProp
67
57
  level?: number;
68
58
  namespace?: Array<string | number>;
69
59
  quotes?: JsonViewProps<T>['quotes'];
60
+ components?: JsonViewProps<T>['components'];
70
61
  renderKey?: JSX.Element;
71
- renderBraces?: MetaProps['render'];
62
+ countInfo?: JSX.Element;
72
63
  setValue?: React.Dispatch<React.SetStateAction<T>>;
73
- renderValue?: (props: RenderValueProps<T>) => JSX.Element;
74
64
  }
75
65
  export declare function getValueString<T>(value: T): {
76
66
  type: "string" | "number" | "bigint" | "boolean" | "undefined" | "date" | "url" | "float" | "null" | "NaN";
@@ -88,4 +78,3 @@ export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<
88
78
  type: keyof typeof typeMap;
89
79
  }
90
80
  export declare const Type: FC<PropsWithChildren<TypeProps>>;
91
- export {};
package/esm/value.js CHANGED
@@ -1,10 +1,9 @@
1
1
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
2
2
  import _extends from "@babel/runtime/helpers/extends";
3
3
  var _excluded = ["children", "style"],
4
- _excluded2 = ["value", "setValue", "data", "keyName", "indentWidth", "namespace", "renderKey", "quotes", "level", "renderValue", "renderBraces", "enableClipboard", "displayObjectSize", "displayDataTypes"],
4
+ _excluded2 = ["value", "parentValue", "setValue", "countInfo", "data", "keyName", "indentWidth", "namespace", "renderKey", "components", "quotes", "level", "enableClipboard", "displayObjectSize", "displayDataTypes"],
5
5
  _excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
6
- import { Fragment, forwardRef, useState } from 'react';
7
- import { CountInfo } from './node';
6
+ import { Fragment, forwardRef, useMemo, useState } from 'react';
8
7
  import { Meta } from './comps/meta';
9
8
  import { Copied } from './copied';
10
9
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -112,17 +111,17 @@ export function ValueView(props) {
112
111
  var _typeMap$type;
113
112
  var {
114
113
  value,
114
+ parentValue,
115
115
  setValue,
116
+ countInfo,
116
117
  data,
117
118
  keyName,
118
119
  indentWidth,
119
120
  namespace,
120
121
  renderKey,
122
+ components = {},
121
123
  quotes,
122
- renderValue,
123
- renderBraces,
124
124
  enableClipboard,
125
- displayObjectSize,
126
125
  displayDataTypes
127
126
  } = props,
128
127
  reset = _objectWithoutPropertiesLoose(props, _excluded2);
@@ -150,10 +149,11 @@ export function ValueView(props) {
150
149
  }
151
150
  color = ((_typeMap$type = typeMap[type]) == null ? void 0 : _typeMap$type.color) || '';
152
151
  var [showTools, setShowTools] = useState(false);
153
- var tools = enableClipboard ? /*#__PURE__*/_jsx(Copied, {
152
+ var tools = useMemo(() => enableClipboard && showTools && /*#__PURE__*/_jsx(Copied, {
154
153
  show: showTools,
155
154
  text: value
156
- }) : undefined;
155
+ }), [enableClipboard, showTools, value]);
156
+ // const tools = enableClipboard ? <Copied show={showTools} text={value} /> : undefined;
157
157
  var eventProps = {
158
158
  className: 'w-rjv-line',
159
159
  style: {
@@ -165,7 +165,7 @@ export function ValueView(props) {
165
165
  eventProps.onMouseLeave = () => setShowTools(false);
166
166
  }
167
167
  if (content && typeof content === 'string') {
168
- var reView = renderValue && renderValue({
168
+ var reView = components.value && components.value({
169
169
  className: 'w-rjv-value',
170
170
  style: _extends({
171
171
  color
@@ -174,6 +174,7 @@ export function ValueView(props) {
174
174
  value,
175
175
  setValue,
176
176
  data,
177
+ parentValue,
177
178
  quotes,
178
179
  keyName,
179
180
  namespace,
@@ -202,18 +203,15 @@ export function ValueView(props) {
202
203
  }))
203
204
  }));
204
205
  }
205
- var length = Array.isArray(value) ? value.length : Object.keys(value).length;
206
206
  var empty = /*#__PURE__*/_jsxs(Fragment, {
207
207
  children: [/*#__PURE__*/_jsx(Meta, {
208
- render: renderBraces,
208
+ render: components.braces,
209
209
  start: true,
210
210
  isArray: Array.isArray(value)
211
211
  }), /*#__PURE__*/_jsx(Meta, {
212
- render: renderBraces,
212
+ render: components.braces,
213
213
  isArray: Array.isArray(value)
214
- }), displayObjectSize && /*#__PURE__*/_jsxs(CountInfo, {
215
- children: [length, " items"]
216
- })]
214
+ }), countInfo]
217
215
  });
218
216
  return /*#__PURE__*/_jsx(Line, _extends({}, eventProps, {
219
217
  children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uiw/react-json-view",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "JSON viewer for react.",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",