@uiw/react-json-view 1.3.0 → 1.4.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
@@ -487,6 +487,8 @@ export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttr
487
487
  enableClipboard?: boolean;
488
488
  /** Whether to highlight updates. @default true */
489
489
  highlightUpdates?: boolean;
490
+ /** Whether sort keys through `String.prototype.localeCompare()` @default false */
491
+ objectSortKeys?: boolean | ((a: string, b: string) => number);
490
492
  /** Display for quotes in object-key @default " */
491
493
  quotes?: "'" | '"' | '';
492
494
  /** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
@@ -498,6 +500,8 @@ export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttr
498
500
  keyid: string;
499
501
  keyName?: string | number;
500
502
  }) => void;
503
+ /** Fires event when you copy */
504
+ onCopied?: CopiedProps<T>['onCopied'];
501
505
  /** Redefine interface elements to re-render. */
502
506
  components?: {
503
507
  braces?: MetaProps['render'];
@@ -505,6 +509,7 @@ export interface JsonViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttr
505
509
  arrow?: JSX.Element;
506
510
  objectKey?: SemicolonProps['render'];
507
511
  value?: ValueViewProps<T>['renderValue'];
512
+ copied?: CopiedProps<T>['render'];
508
513
  };
509
514
  }
510
515
  declare const JsonView: React.ForwardRefExoticComponent<Omit<JsonViewProps<object>, "ref"> & React.RefAttributes<HTMLDivElement>>;
package/cjs/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { MetaProps, SemicolonProps, EllipsisProps } from './node';
2
+ import { MetaProps, EllipsisProps } from './node';
3
+ import { SemicolonProps } from './semicolon';
3
4
  import { ValueViewProps } from './value';
4
5
  import { CopiedProps } from './copied';
5
6
  export * from './node';
@@ -19,6 +20,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
19
20
  enableClipboard?: boolean;
20
21
  /** Whether to highlight updates. @default true */
21
22
  highlightUpdates?: boolean;
23
+ /** Whether sort keys through `String.prototype.localeCompare()` @default false */
24
+ objectSortKeys?: boolean | ((a: string, b: string) => number);
22
25
  /** Display for quotes in object-key @default " */
23
26
  quotes?: "'" | '"' | '';
24
27
  /** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
package/cjs/node.d.ts CHANGED
@@ -6,20 +6,11 @@ export interface MetaProps extends LabelProps {
6
6
  start?: boolean;
7
7
  render?: (props: Pick<MetaProps, 'start' | 'isArray' | 'className' | 'children'>) => JSX.Element;
8
8
  }
9
- export declare function usePrevious<T>(value: T): T | undefined;
10
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
- export interface SemicolonProps extends LabelProps {
16
- show?: boolean;
17
- highlightUpdates?: boolean;
18
- quotes?: JsonViewProps<object>['quotes'];
19
- value?: object;
20
- render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
21
- }
22
- export declare const Semicolon: FC<PropsWithChildren<SemicolonProps>>;
23
14
  export declare const CountInfo: FC<PropsWithChildren<LabelProps>>;
24
15
  export interface RooNodeProps<T extends object> extends JsonViewProps<T> {
25
16
  keyName?: string | number;
package/cjs/node.js CHANGED
@@ -7,10 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.Ellipsis = exports.CountInfo = void 0;
8
8
  exports.Meta = Meta;
9
9
  exports.RooNode = RooNode;
10
- exports.Semicolon = void 0;
11
- exports.usePrevious = usePrevious;
12
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
10
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
14
12
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
15
13
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
16
14
  var _react = require("react");
@@ -18,18 +16,11 @@ var _value = require("./value");
18
16
  var _TriangleArrow = require("./arrow/TriangleArrow");
19
17
  var _store = require("./store");
20
18
  var _copied = require("./copied");
19
+ var _semicolon = require("./semicolon");
21
20
  var _jsxRuntime = require("react/jsx-runtime");
22
21
  var _excluded = ["isArray", "start", "className", "render"],
23
22
  _excluded2 = ["style", "render"],
24
- _excluded3 = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes"],
25
- _excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
26
- function usePrevious(value) {
27
- var ref = (0, _react.useRef)();
28
- (0, _react.useEffect)(function () {
29
- ref.current = value;
30
- });
31
- return ref.current;
32
- }
23
+ _excluded3 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "objectSortKeys", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
33
24
  function Meta(props) {
34
25
  var _props$isArray = props.isArray,
35
26
  isArray = _props$isArray === void 0 ? false : _props$isArray,
@@ -77,79 +68,8 @@ var Ellipsis = function Ellipsis(_ref) {
77
68
  }));
78
69
  };
79
70
  exports.Ellipsis = Ellipsis;
80
- var Semicolon = function Semicolon(_ref2) {
81
- var children = _ref2.children,
82
- render = _ref2.render,
83
- color = _ref2.color,
84
- value = _ref2.value,
85
- _ref2$className = _ref2.className,
86
- className = _ref2$className === void 0 ? 'w-rjv-object-key' : _ref2$className,
87
- show = _ref2.show,
88
- highlightUpdates = _ref2.highlightUpdates,
89
- quotes = _ref2.quotes,
90
- props = (0, _objectWithoutProperties2["default"])(_ref2, _excluded3);
91
- var prevValue = usePrevious(value);
92
- var highlightContainer = (0, _react.useRef)(null);
93
- var isHighlight = (0, _react.useMemo)(function () {
94
- if (!highlightUpdates || prevValue === undefined) return false;
95
- // highlight if value type changed
96
- if ((0, _typeof2["default"])(value) !== (0, _typeof2["default"])(prevValue)) {
97
- return true;
98
- }
99
- if (typeof value === 'number') {
100
- // notice: NaN !== NaN
101
- if (isNaN(value) && isNaN(prevValue)) return false;
102
- return value !== prevValue;
103
- }
104
- // highlight if isArray changed
105
- if (Array.isArray(value) !== Array.isArray(prevValue)) {
106
- return true;
107
- }
108
- // not highlight object/function
109
- // deep compare they will be slow
110
- if ((0, _typeof2["default"])(value) === 'object' || typeof value === 'function') {
111
- return false;
112
- }
113
-
114
- // highlight if not equal
115
- if (value !== prevValue) {
116
- return true;
117
- }
118
- return false;
119
- }, [highlightUpdates, value]);
120
- (0, _react.useEffect)(function () {
121
- if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
122
- highlightContainer.current.animate([{
123
- backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
124
- }, {
125
- backgroundColor: ''
126
- }], {
127
- duration: 1000,
128
- easing: 'ease-in'
129
- });
130
- }
131
- }, [isHighlight, value]);
132
- var content = show ? "".concat(quotes).concat(children).concat(quotes) : children;
133
- if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({
134
- className: className
135
- }, props), {}, {
136
- value: value,
137
- style: {
138
- color: color
139
- },
140
- children: content
141
- }));
142
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
143
- className: className,
144
- color: color
145
- }, props), {}, {
146
- ref: highlightContainer,
147
- children: content
148
- }));
149
- };
150
- exports.Semicolon = Semicolon;
151
- var CountInfo = function CountInfo(_ref3) {
152
- var children = _ref3.children;
71
+ var CountInfo = function CountInfo(_ref2) {
72
+ var children = _ref2.children;
153
73
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Label, {
154
74
  style: {
155
75
  paddingLeft: 4,
@@ -177,6 +97,8 @@ function RooNode(props) {
177
97
  enableClipboard = _props$enableClipboar === void 0 ? true : _props$enableClipboar,
178
98
  _props$highlightUpdat = props.highlightUpdates,
179
99
  highlightUpdates = _props$highlightUpdat === void 0 ? true : _props$highlightUpdat,
100
+ _props$objectSortKeys = props.objectSortKeys,
101
+ objectSortKeys = _props$objectSortKeys === void 0 ? false : _props$objectSortKeys,
180
102
  _props$indentWidth = props.indentWidth,
181
103
  indentWidth = _props$indentWidth === void 0 ? 15 : _props$indentWidth,
182
104
  collapsed = props.collapsed,
@@ -188,11 +110,8 @@ function RooNode(props) {
188
110
  quotes = _props$quotes === void 0 ? '"' : _props$quotes,
189
111
  onCopied = props.onCopied,
190
112
  onExpand = props.onExpand,
191
- reset = (0, _objectWithoutProperties2["default"])(props, _excluded4);
113
+ reset = (0, _objectWithoutProperties2["default"])(props, _excluded3);
192
114
  var isArray = Array.isArray(value);
193
- var nameKeys = isArray ? Object.keys(value).map(function (m) {
194
- return Number(m);
195
- }) : Object.keys(value);
196
115
  var subkeyid = (0, _react.useId)();
197
116
  var expands = (0, _store.useExpandsStatus)();
198
117
  var expand = (_expands$keyid = expands[keyid]) !== null && _expands$keyid !== void 0 ? _expands$keyid : typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level <= collapsed : true;
@@ -260,6 +179,29 @@ function RooNode(props) {
260
179
  return setShowTools(false);
261
180
  };
262
181
  }
182
+ var nameKeys = isArray ? Object.keys(value).map(function (m) {
183
+ return Number(m);
184
+ }) : Object.keys(value);
185
+
186
+ // object
187
+ var entries = isArray ? Object.entries(value).map(function (m) {
188
+ return [Number(m[0]), m[1]];
189
+ }) : Object.entries(value);
190
+ if (objectSortKeys) {
191
+ entries = objectSortKeys === true ? entries.sort(function (_ref3, _ref4) {
192
+ var _ref5 = (0, _slicedToArray2["default"])(_ref3, 1),
193
+ a = _ref5[0];
194
+ var _ref6 = (0, _slicedToArray2["default"])(_ref4, 1),
195
+ b = _ref6[0];
196
+ return typeof a === 'string' && typeof b === 'string' ? a.localeCompare(b) : 0;
197
+ }) : entries.sort(function (_ref7, _ref8) {
198
+ var _ref9 = (0, _slicedToArray2["default"])(_ref7, 1),
199
+ a = _ref9[0];
200
+ var _ref10 = (0, _slicedToArray2["default"])(_ref8, 1),
201
+ b = _ref10[0];
202
+ return typeof a === 'string' && typeof b === 'string' ? objectSortKeys(a, b) : 0;
203
+ });
204
+ }
263
205
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
264
206
  className: "".concat(className, " w-rjv-inner")
265
207
  }, eventProps), {}, {
@@ -270,7 +212,7 @@ function RooNode(props) {
270
212
  },
271
213
  onClick: handle,
272
214
  children: [arrowView, (typeof keyName === 'string' || typeof keyName === 'number') && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
273
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
215
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_semicolon.Semicolon, {
274
216
  value: value,
275
217
  quotes: quotes,
276
218
  render: components.objectKey,
@@ -296,9 +238,12 @@ function RooNode(props) {
296
238
  borderLeft: 'var(--w-rjv-border-left-width, 1px) solid var(--w-rjv-line-color, #ebebeb)',
297
239
  marginLeft: 6
298
240
  },
299
- children: nameKeys.length > 0 && nameKeys.map(function (key, idx) {
300
- var item = value[key];
301
- var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(Semicolon, {
241
+ children: entries.length > 0 && entries.map(function (_ref11, idx) {
242
+ var _ref12 = (0, _slicedToArray2["default"])(_ref11, 2),
243
+ key = _ref12[0],
244
+ itemVal = _ref12[1];
245
+ var item = itemVal;
246
+ var renderKey = /*#__PURE__*/(0, _jsxRuntime.jsx)(_semicolon.Semicolon, {
302
247
  value: item,
303
248
  quotes: quotes,
304
249
  highlightUpdates: highlightUpdates,
@@ -327,7 +272,7 @@ function RooNode(props) {
327
272
  value: item,
328
273
  keyName: key
329
274
  }, subNodeProps))
330
- }, key + idx);
275
+ }, key + '' + idx);
331
276
  }
332
277
  if (typeof item === 'function') {
333
278
  return;
@@ -0,0 +1,12 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { LabelProps } from './value';
3
+ import { JsonViewProps } from './';
4
+ export declare function usePrevious<T>(value: T): T | undefined;
5
+ export interface SemicolonProps extends LabelProps {
6
+ show?: boolean;
7
+ highlightUpdates?: boolean;
8
+ quotes?: JsonViewProps<object>['quotes'];
9
+ value?: object;
10
+ render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
11
+ }
12
+ export declare const Semicolon: FC<PropsWithChildren<SemicolonProps>>;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.Semicolon = void 0;
8
+ exports.usePrevious = usePrevious;
9
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
10
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
+ var _react = require("react");
13
+ var _value = require("./value");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ var _excluded = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes", "style"];
16
+ function usePrevious(value) {
17
+ var ref = (0, _react.useRef)();
18
+ (0, _react.useEffect)(function () {
19
+ ref.current = value;
20
+ });
21
+ return ref.current;
22
+ }
23
+ var Semicolon = function Semicolon(_ref) {
24
+ var children = _ref.children,
25
+ render = _ref.render,
26
+ color = _ref.color,
27
+ value = _ref.value,
28
+ _ref$className = _ref.className,
29
+ className = _ref$className === void 0 ? 'w-rjv-object-key' : _ref$className,
30
+ show = _ref.show,
31
+ highlightUpdates = _ref.highlightUpdates,
32
+ quotes = _ref.quotes,
33
+ style = _ref.style,
34
+ props = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
35
+ var prevValue = usePrevious(value);
36
+ var highlightContainer = (0, _react.useRef)(null);
37
+ var isHighlight = (0, _react.useMemo)(function () {
38
+ if (!highlightUpdates || prevValue === undefined) return false;
39
+ // highlight if value type changed
40
+ if ((0, _typeof2["default"])(value) !== (0, _typeof2["default"])(prevValue)) {
41
+ return true;
42
+ }
43
+ if (typeof value === 'number') {
44
+ // notice: NaN !== NaN
45
+ if (isNaN(value) && isNaN(prevValue)) return false;
46
+ return value !== prevValue;
47
+ }
48
+ // highlight if isArray changed
49
+ if (Array.isArray(value) !== Array.isArray(prevValue)) {
50
+ return true;
51
+ }
52
+ // not highlight object/function
53
+ // deep compare they will be slow
54
+ if ((0, _typeof2["default"])(value) === 'object' || typeof value === 'function') {
55
+ return false;
56
+ }
57
+
58
+ // highlight if not equal
59
+ if (value !== prevValue) {
60
+ return true;
61
+ }
62
+ return false;
63
+ }, [highlightUpdates, value]);
64
+ (0, _react.useEffect)(function () {
65
+ if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
66
+ highlightContainer.current.animate([{
67
+ backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
68
+ }, {
69
+ backgroundColor: ''
70
+ }], {
71
+ duration: 1000,
72
+ easing: 'ease-in'
73
+ });
74
+ }
75
+ }, [isHighlight, value]);
76
+ var content = show ? "".concat(quotes).concat(children).concat(quotes) : children;
77
+ if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({
78
+ className: className
79
+ }, props), {}, {
80
+ value: value,
81
+ style: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, style), {}, {
82
+ color: color
83
+ }),
84
+ children: content
85
+ }));
86
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_value.Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
87
+ className: className,
88
+ color: color
89
+ }, props), {}, {
90
+ ref: highlightContainer,
91
+ children: content
92
+ }));
93
+ };
94
+ exports.Semicolon = Semicolon;
package/cjs/value.d.ts CHANGED
@@ -41,7 +41,7 @@ export declare const typeMap: {
41
41
  };
42
42
  export declare const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>>;
43
43
  export interface ValueViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
44
- keyName?: string;
44
+ keyName?: string | number;
45
45
  value?: T;
46
46
  displayDataTypes: boolean;
47
47
  displayObjectSize: boolean;
package/esm/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { MetaProps, SemicolonProps, EllipsisProps } from './node';
2
+ import { MetaProps, EllipsisProps } from './node';
3
+ import { SemicolonProps } from './semicolon';
3
4
  import { ValueViewProps } from './value';
4
5
  import { CopiedProps } from './copied';
5
6
  export * from './node';
@@ -19,6 +20,8 @@ export interface JsonViewProps<T extends object> extends React.DetailedHTMLProps
19
20
  enableClipboard?: boolean;
20
21
  /** Whether to highlight updates. @default true */
21
22
  highlightUpdates?: boolean;
23
+ /** Whether sort keys through `String.prototype.localeCompare()` @default false */
24
+ objectSortKeys?: boolean | ((a: string, b: string) => number);
22
25
  /** Display for quotes in object-key @default " */
23
26
  quotes?: "'" | '"' | '';
24
27
  /** When set to true, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. @default false */
package/esm/node.d.ts CHANGED
@@ -6,20 +6,11 @@ export interface MetaProps extends LabelProps {
6
6
  start?: boolean;
7
7
  render?: (props: Pick<MetaProps, 'start' | 'isArray' | 'className' | 'children'>) => JSX.Element;
8
8
  }
9
- export declare function usePrevious<T>(value: T): T | undefined;
10
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
- export interface SemicolonProps extends LabelProps {
16
- show?: boolean;
17
- highlightUpdates?: boolean;
18
- quotes?: JsonViewProps<object>['quotes'];
19
- value?: object;
20
- render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
21
- }
22
- export declare const Semicolon: FC<PropsWithChildren<SemicolonProps>>;
23
14
  export declare const CountInfo: FC<PropsWithChildren<LabelProps>>;
24
15
  export interface RooNodeProps<T extends object> extends JsonViewProps<T> {
25
16
  keyName?: string | number;
package/esm/node.js CHANGED
@@ -2,22 +2,15 @@ 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", "highlightUpdates", "quotes"],
6
- _excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
7
- import { Fragment, useId, cloneElement, useState, useMemo, useRef, useEffect } from 'react';
5
+ _excluded3 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "objectSortKeys", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
6
+ import { Fragment, useId, cloneElement, useState } from 'react';
8
7
  import { ValueView, Colon, Label, Line, typeMap } from './value';
9
8
  import { TriangleArrow } from './arrow/TriangleArrow';
10
9
  import { useExpandsStatus, store } from './store';
11
10
  import { Copied } from './copied';
11
+ import { Semicolon } from './semicolon';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
14
- export function usePrevious(value) {
15
- var ref = useRef();
16
- useEffect(() => {
17
- ref.current = value;
18
- });
19
- return ref.current;
20
- }
21
14
  export function Meta(props) {
22
15
  var {
23
16
  isArray = false,
@@ -66,81 +59,10 @@ export var Ellipsis = _ref => {
66
59
  children: "..."
67
60
  }));
68
61
  };
69
- export var Semicolon = _ref2 => {
70
- var {
71
- children,
72
- render,
73
- color,
74
- value,
75
- className = 'w-rjv-object-key',
76
- show,
77
- highlightUpdates,
78
- quotes
79
- } = _ref2,
80
- props = _objectWithoutPropertiesLoose(_ref2, _excluded3);
81
- var prevValue = usePrevious(value);
82
- var highlightContainer = useRef(null);
83
- var isHighlight = useMemo(() => {
84
- if (!highlightUpdates || prevValue === undefined) return false;
85
- // highlight if value type changed
86
- if (typeof value !== typeof prevValue) {
87
- return true;
88
- }
89
- if (typeof value === 'number') {
90
- // notice: NaN !== NaN
91
- if (isNaN(value) && isNaN(prevValue)) return false;
92
- return value !== prevValue;
93
- }
94
- // highlight if isArray changed
95
- if (Array.isArray(value) !== Array.isArray(prevValue)) {
96
- return true;
97
- }
98
- // not highlight object/function
99
- // deep compare they will be slow
100
- if (typeof value === 'object' || typeof value === 'function') {
101
- return false;
102
- }
103
-
104
- // highlight if not equal
105
- if (value !== prevValue) {
106
- return true;
107
- }
108
- return false;
109
- }, [highlightUpdates, value]);
110
- useEffect(() => {
111
- if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
112
- highlightContainer.current.animate([{
113
- backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
114
- }, {
115
- backgroundColor: ''
116
- }], {
117
- duration: 1000,
118
- easing: 'ease-in'
119
- });
120
- }
121
- }, [isHighlight, value]);
122
- var content = show ? "" + quotes + children + quotes : children;
123
- if (render) return render(_extends({
124
- className
125
- }, props, {
126
- value,
127
- style: {
128
- color
129
- },
130
- children: content
131
- }));
132
- return /*#__PURE__*/_jsx(Label, _extends({
133
- className: className,
134
- color: color
135
- }, props, {
136
- ref: highlightContainer,
137
- children: content
138
- }));
139
- };
140
- export var CountInfo = _ref3 => {
62
+ export var CountInfo = _ref2 => {
141
63
  var {
142
64
  children
143
- } = _ref3;
65
+ } = _ref2;
144
66
  return /*#__PURE__*/_jsx(Label, {
145
67
  style: {
146
68
  paddingLeft: 4,
@@ -162,6 +84,7 @@ export function RooNode(props) {
162
84
  displayObjectSize = true,
163
85
  enableClipboard = true,
164
86
  highlightUpdates = true,
87
+ objectSortKeys = false,
165
88
  indentWidth = 15,
166
89
  collapsed,
167
90
  level = 1,
@@ -170,9 +93,8 @@ export function RooNode(props) {
170
93
  onCopied,
171
94
  onExpand
172
95
  } = props,
173
- reset = _objectWithoutPropertiesLoose(props, _excluded4);
96
+ reset = _objectWithoutPropertiesLoose(props, _excluded3);
174
97
  var isArray = Array.isArray(value);
175
- var nameKeys = isArray ? Object.keys(value).map(m => Number(m)) : Object.keys(value);
176
98
  var subkeyid = useId();
177
99
  var expands = useExpandsStatus();
178
100
  var expand = (_expands$keyid = expands[keyid]) != null ? _expands$keyid : typeof collapsed === 'boolean' ? collapsed : typeof collapsed === 'number' ? level <= collapsed : true;
@@ -233,6 +155,21 @@ export function RooNode(props) {
233
155
  eventProps.onMouseEnter = () => setShowTools(true);
234
156
  eventProps.onMouseLeave = () => setShowTools(false);
235
157
  }
158
+ var nameKeys = isArray ? Object.keys(value).map(m => Number(m)) : Object.keys(value);
159
+
160
+ // object
161
+ var entries = isArray ? Object.entries(value).map(m => [Number(m[0]), m[1]]) : Object.entries(value);
162
+ if (objectSortKeys) {
163
+ entries = objectSortKeys === true ? entries.sort((_ref3, _ref4) => {
164
+ var [a] = _ref3;
165
+ var [b] = _ref4;
166
+ return typeof a === 'string' && typeof b === 'string' ? a.localeCompare(b) : 0;
167
+ }) : entries.sort((_ref5, _ref6) => {
168
+ var [a] = _ref5;
169
+ var [b] = _ref6;
170
+ return typeof a === 'string' && typeof b === 'string' ? objectSortKeys(a, b) : 0;
171
+ });
172
+ }
236
173
  return /*#__PURE__*/_jsxs("div", _extends({}, reset, {
237
174
  className: className + " w-rjv-inner"
238
175
  }, eventProps, {
@@ -269,8 +206,9 @@ export function RooNode(props) {
269
206
  borderLeft: 'var(--w-rjv-border-left-width, 1px) solid var(--w-rjv-line-color, #ebebeb)',
270
207
  marginLeft: 6
271
208
  },
272
- children: nameKeys.length > 0 && nameKeys.map((key, idx) => {
273
- var item = value[key];
209
+ children: entries.length > 0 && entries.map((_ref7, idx) => {
210
+ var [key, itemVal] = _ref7;
211
+ var item = itemVal;
274
212
  var renderKey = /*#__PURE__*/_jsx(Semicolon, {
275
213
  value: item,
276
214
  quotes: quotes,
@@ -300,7 +238,7 @@ export function RooNode(props) {
300
238
  value: item,
301
239
  keyName: key
302
240
  }, subNodeProps))
303
- }, key + idx);
241
+ }, key + '' + idx);
304
242
  }
305
243
  if (typeof item === 'function') {
306
244
  return;
@@ -0,0 +1,12 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { LabelProps } from './value';
3
+ import { JsonViewProps } from './';
4
+ export declare function usePrevious<T>(value: T): T | undefined;
5
+ export interface SemicolonProps extends LabelProps {
6
+ show?: boolean;
7
+ highlightUpdates?: boolean;
8
+ quotes?: JsonViewProps<object>['quotes'];
9
+ value?: object;
10
+ render?: (props: Omit<SemicolonProps, 'show'> & {}) => JSX.Element;
11
+ }
12
+ export declare const Semicolon: FC<PropsWithChildren<SemicolonProps>>;
@@ -0,0 +1,85 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
3
+ var _excluded = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes", "style"];
4
+ import { useMemo, useRef, useEffect } from 'react';
5
+ import { Label } from './value';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ export function usePrevious(value) {
8
+ var ref = useRef();
9
+ useEffect(() => {
10
+ ref.current = value;
11
+ });
12
+ return ref.current;
13
+ }
14
+ export var Semicolon = _ref => {
15
+ var {
16
+ children,
17
+ render,
18
+ color,
19
+ value,
20
+ className = 'w-rjv-object-key',
21
+ show,
22
+ highlightUpdates,
23
+ quotes,
24
+ style
25
+ } = _ref,
26
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
27
+ var prevValue = usePrevious(value);
28
+ var highlightContainer = useRef(null);
29
+ var isHighlight = useMemo(() => {
30
+ if (!highlightUpdates || prevValue === undefined) return false;
31
+ // highlight if value type changed
32
+ if (typeof value !== typeof prevValue) {
33
+ return true;
34
+ }
35
+ if (typeof value === 'number') {
36
+ // notice: NaN !== NaN
37
+ if (isNaN(value) && isNaN(prevValue)) return false;
38
+ return value !== prevValue;
39
+ }
40
+ // highlight if isArray changed
41
+ if (Array.isArray(value) !== Array.isArray(prevValue)) {
42
+ return true;
43
+ }
44
+ // not highlight object/function
45
+ // deep compare they will be slow
46
+ if (typeof value === 'object' || typeof value === 'function') {
47
+ return false;
48
+ }
49
+
50
+ // highlight if not equal
51
+ if (value !== prevValue) {
52
+ return true;
53
+ }
54
+ return false;
55
+ }, [highlightUpdates, value]);
56
+ useEffect(() => {
57
+ if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
58
+ highlightContainer.current.animate([{
59
+ backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
60
+ }, {
61
+ backgroundColor: ''
62
+ }], {
63
+ duration: 1000,
64
+ easing: 'ease-in'
65
+ });
66
+ }
67
+ }, [isHighlight, value]);
68
+ var content = show ? "" + quotes + children + quotes : children;
69
+ if (render) return render(_extends({
70
+ className
71
+ }, props, {
72
+ value,
73
+ style: _extends({}, style, {
74
+ color
75
+ }),
76
+ children: content
77
+ }));
78
+ return /*#__PURE__*/_jsx(Label, _extends({
79
+ className: className,
80
+ color: color
81
+ }, props, {
82
+ ref: highlightContainer,
83
+ children: content
84
+ }));
85
+ };
package/esm/value.d.ts CHANGED
@@ -41,7 +41,7 @@ export declare const typeMap: {
41
41
  };
42
42
  export declare const Colon: FC<PropsWithChildren<React.HTMLAttributes<HTMLSpanElement>>>;
43
43
  export interface ValueViewProps<T> extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
44
- keyName?: string;
44
+ keyName?: string | number;
45
45
  value?: T;
46
46
  displayDataTypes: boolean;
47
47
  displayObjectSize: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uiw/react-json-view",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "JSON viewer for react.",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",