Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@uiw/react-json-view

Package Overview
Dependencies
Maintainers
2
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uiw/react-json-view - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

2

cjs/copied.d.ts

@@ -5,5 +5,5 @@ /// <reference types="react" />

text?: T;
onCopied?: (text: string, obj: T) => void;
onCopied?: (text: string, obj: T | '') => void;
render?: (props: Omit<CopiedProps<T>, 'render'>) => JSX.Element;
}
export declare function Copied<T>(props: CopiedProps<T>): JSX.Element | null;

@@ -13,3 +13,3 @@ "use strict";

var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["children", "style", "text", "render", "show"];
var _excluded = ["children", "style", "text", "onCopied", "render", "show"];
function Copied(props) {

@@ -20,2 +20,3 @@ var children = props.children,

text = _props$text === void 0 ? '' : _props$text,
onCopied = props.onCopied,
render = props.render,

@@ -31,3 +32,3 @@ show = props.show,

event.stopPropagation();
var copyText = JSON.stringify(text, function (key, value) {
var copyText = JSON.stringify(text || '', function (key, value) {
if (typeof value === 'bigint') {

@@ -40,2 +41,3 @@ return value.toString();

navigator.clipboard.writeText(copyText).then(function () {
onCopied && onCopied(copyText, text);
setCopied(true);

@@ -42,0 +44,0 @@ var timer = setTimeout(function () {

@@ -20,2 +20,4 @@ import React from 'react';

enableClipboard?: boolean;
/** Whether to highlight updates. @default true */
highlightUpdates?: boolean;
/** Display for quotes in object-key @default " */

@@ -22,0 +24,0 @@ quotes?: "'" | '"' | '';

@@ -9,2 +9,3 @@ import { FC, PropsWithChildren } from 'react';

}
export declare function usePrevious<T>(value: T): T | undefined;
export declare function Meta(props: MetaProps): JSX.Element;

@@ -17,2 +18,3 @@ export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {

show?: boolean;
highlightUpdates?: boolean;
quotes?: JsonViewProps<object>['quotes'];

@@ -19,0 +21,0 @@ value?: object;

@@ -11,4 +11,5 @@ "use strict";

exports.Semicolon = void 0;
exports.usePrevious = usePrevious;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));

@@ -24,4 +25,11 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

_excluded2 = ["style", "render"],
_excluded3 = ["children", "render", "color", "value", "className", "show", "quotes"],
_excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
_excluded3 = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes"],
_excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
function usePrevious(value) {
var ref = (0, _react.useRef)();
(0, _react.useEffect)(function () {
ref.current = value;
});
return ref.current;
}
function Meta(props) {

@@ -82,4 +90,46 @@ var _props$isArray = props.isArray,

show = _ref2.show,
highlightUpdates = _ref2.highlightUpdates,
quotes = _ref2.quotes,
props = (0, _objectWithoutProperties2["default"])(_ref2, _excluded3);
var prevValue = usePrevious(value);
var highlightContainer = (0, _react.useRef)(null);
var isHighlight = (0, _react.useMemo)(function () {
if (!highlightUpdates || prevValue === undefined) return false;
// highlight if value type changed
if ((0, _typeof2["default"])(value) !== (0, _typeof2["default"])(prevValue)) {
return true;
}
if (typeof value === 'number') {
// notice: NaN !== NaN
if (isNaN(value) && isNaN(prevValue)) return false;
return value !== prevValue;
}
// highlight if isArray changed
if (Array.isArray(value) !== Array.isArray(prevValue)) {
return true;
}
// not highlight object/function
// deep compare they will be slow
if ((0, _typeof2["default"])(value) === 'object' || typeof value === 'function') {
return false;
}
// highlight if not equal
if (value !== prevValue) {
return true;
}
return false;
}, [highlightUpdates, value]);
(0, _react.useEffect)(function () {
if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
highlightContainer.current.animate([{
backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
}, {
backgroundColor: ''
}], {
duration: 1000,
easing: 'ease-in'
});
}
}, [isHighlight, value]);
var content = show ? "".concat(quotes).concat(children).concat(quotes) : children;

@@ -99,2 +149,3 @@ if (render) return render((0, _objectSpread2["default"])((0, _objectSpread2["default"])({

}, props), {}, {
ref: highlightContainer,
children: content

@@ -122,2 +173,3 @@ }));

keyName = props.keyName,
className = props.className,
_props$displayDataTyp = props.displayDataTypes,

@@ -131,2 +183,4 @@ displayDataTypes = _props$displayDataTyp === void 0 ? true : _props$displayDataTyp,

enableClipboard = _props$enableClipboar === void 0 ? true : _props$enableClipboar,
_props$highlightUpdat = props.highlightUpdates,
highlightUpdates = _props$highlightUpdat === void 0 ? true : _props$highlightUpdat,
_props$indentWidth = props.indentWidth,

@@ -170,2 +224,3 @@ indentWidth = _props$indentWidth === void 0 ? 15 : _props$indentWidth,

enableClipboard: enableClipboard,
highlightUpdates: highlightUpdates,
onCopied: onCopied,

@@ -216,3 +271,3 @@ onExpand: onExpand,

return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
className: "w-rjv-inner"
className: "".concat(className, " w-rjv-inner")
}, eventProps), {}, {

@@ -257,2 +312,3 @@ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_value.Line, {

quotes: quotes,
highlightUpdates: highlightUpdates,
render: components.objectKey,

@@ -259,0 +315,0 @@ color: typeof key === 'number' ? _value.typeMap['number'].color : '',

@@ -8,2 +8,3 @@ export declare const darkTheme: {

'--w-rjv-info-color': string;
'--w-rjv-update-color': string;
'--w-rjv-copied-color': string;

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': string;

@@ -14,2 +14,3 @@ "use strict";

'--w-rjv-info-color': '#656565',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#0184a6',

@@ -16,0 +17,0 @@ '--w-rjv-copied-success-color': '#28a745',

@@ -8,2 +8,3 @@ export declare const lightTheme: {

'--w-rjv-info-color': string;
'--w-rjv-update-color': string;
'--w-rjv-copied-color': string;

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': string;

@@ -14,2 +14,3 @@ "use strict";

'--w-rjv-info-color': '#0000004d',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#002b36',

@@ -16,0 +17,0 @@ '--w-rjv-copied-success-color': '#28a745',

@@ -63,3 +63,3 @@ import { FC, PropsWithChildren } from 'react';

}
export declare const Label: FC<PropsWithChildren<LabelProps>>;
export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLSpanElement>>;
export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {

@@ -66,0 +66,0 @@ type: keyof typeof typeMap;

@@ -177,2 +177,3 @@ "use strict";

children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
ref: null,
children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, valueView, tools]

@@ -197,2 +198,3 @@ }))

children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(Label, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, reset), {}, {
ref: null,
children: [renderKey, /*#__PURE__*/(0, _jsxRuntime.jsx)(Colon, {}), typeView, empty, tools]

@@ -202,3 +204,3 @@ }))

}
var Label = function Label(_ref2) {
var Label = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, ref) {
var children = _ref2.children,

@@ -219,5 +221,6 @@ color = _ref2.color,

}, reset), {}, {
ref: ref,
children: children
}));
};
});
exports.Label = Label;

@@ -224,0 +227,0 @@ var Type = function Type(props) {

@@ -5,5 +5,5 @@ /// <reference types="react" />

text?: T;
onCopied?: (text: string, obj: T) => void;
onCopied?: (text: string, obj: T | '') => void;
render?: (props: Omit<CopiedProps<T>, 'render'>) => JSX.Element;
}
export declare function Copied<T>(props: CopiedProps<T>): JSX.Element | null;
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";
var _excluded = ["children", "style", "text", "render", "show"];
var _excluded = ["children", "style", "text", "onCopied", "render", "show"];
import { useState } from 'react';

@@ -10,2 +10,3 @@ import { jsx as _jsx } from "react/jsx-runtime";

text = '',
onCopied,
render,

@@ -19,3 +20,3 @@ show

event.stopPropagation();
var copyText = JSON.stringify(text, (key, value) => {
var copyText = JSON.stringify(text || '', (key, value) => {
if (typeof value === 'bigint') {

@@ -28,2 +29,3 @@ return value.toString();

navigator.clipboard.writeText(copyText).then(() => {
onCopied && onCopied(copyText, text);
setCopied(true);

@@ -30,0 +32,0 @@ var timer = setTimeout(() => {

@@ -20,2 +20,4 @@ import React from 'react';

enableClipboard?: boolean;
/** Whether to highlight updates. @default true */
highlightUpdates?: boolean;
/** Display for quotes in object-key @default " */

@@ -22,0 +24,0 @@ quotes?: "'" | '"' | '';

@@ -9,2 +9,3 @@ import { FC, PropsWithChildren } from 'react';

}
export declare function usePrevious<T>(value: T): T | undefined;
export declare function Meta(props: MetaProps): JSX.Element;

@@ -17,2 +18,3 @@ export interface EllipsisProps extends React.HTMLAttributes<HTMLSpanElement> {

show?: boolean;
highlightUpdates?: boolean;
quotes?: JsonViewProps<object>['quotes'];

@@ -19,0 +21,0 @@ value?: object;

@@ -5,5 +5,5 @@ import _extends from "@babel/runtime/helpers/extends";

_excluded2 = ["style", "render"],
_excluded3 = ["children", "render", "color", "value", "className", "show", "quotes"],
_excluded4 = ["value", "keyName", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
import { Fragment, useId, cloneElement, useState } from 'react';
_excluded3 = ["children", "render", "color", "value", "className", "show", "highlightUpdates", "quotes"],
_excluded4 = ["value", "keyName", "className", "displayDataTypes", "components", "displayObjectSize", "enableClipboard", "highlightUpdates", "indentWidth", "collapsed", "level", "keyid", "quotes", "onCopied", "onExpand"];
import { Fragment, useId, cloneElement, useState, useMemo, useRef, useEffect } from 'react';
import { ValueView, Colon, Label, Line, typeMap } from './value';

@@ -15,2 +15,9 @@ import { TriangleArrow } from './arrow/TriangleArrow';

import { jsxs as _jsxs } from "react/jsx-runtime";
export function usePrevious(value) {
var ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
export function Meta(props) {

@@ -72,5 +79,47 @@ var {

show,
highlightUpdates,
quotes
} = _ref2,
props = _objectWithoutPropertiesLoose(_ref2, _excluded3);
var prevValue = usePrevious(value);
var highlightContainer = useRef(null);
var isHighlight = useMemo(() => {
if (!highlightUpdates || prevValue === undefined) return false;
// highlight if value type changed
if (typeof value !== typeof prevValue) {
return true;
}
if (typeof value === 'number') {
// notice: NaN !== NaN
if (isNaN(value) && isNaN(prevValue)) return false;
return value !== prevValue;
}
// highlight if isArray changed
if (Array.isArray(value) !== Array.isArray(prevValue)) {
return true;
}
// not highlight object/function
// deep compare they will be slow
if (typeof value === 'object' || typeof value === 'function') {
return false;
}
// highlight if not equal
if (value !== prevValue) {
return true;
}
return false;
}, [highlightUpdates, value]);
useEffect(() => {
if (highlightContainer.current && isHighlight && 'animate' in highlightContainer.current) {
highlightContainer.current.animate([{
backgroundColor: 'var(--w-rjv-update-color, #ebcb8b)'
}, {
backgroundColor: ''
}], {
duration: 1000,
easing: 'ease-in'
});
}
}, [isHighlight, value]);
var content = show ? "" + quotes + children + quotes : children;

@@ -90,2 +139,3 @@ if (render) return render(_extends({

}, props, {
ref: highlightContainer,
children: content

@@ -113,2 +163,3 @@ }));

keyName,
className,
displayDataTypes = true,

@@ -118,2 +169,3 @@ components = {},

enableClipboard = true,
highlightUpdates = true,
indentWidth = 15,

@@ -152,2 +204,3 @@ collapsed,

enableClipboard,
highlightUpdates,
onCopied,

@@ -191,3 +244,3 @@ onExpand,

return /*#__PURE__*/_jsxs("div", _extends({}, reset, {
className: "w-rjv-inner"
className: className + " w-rjv-inner"
}, eventProps, {

@@ -232,2 +285,3 @@ children: [/*#__PURE__*/_jsxs(Line, {

quotes: quotes,
highlightUpdates: highlightUpdates,
render: components.objectKey,

@@ -234,0 +288,0 @@ color: typeof key === 'number' ? typeMap['number'].color : '',

@@ -8,2 +8,3 @@ export declare const darkTheme: {

'--w-rjv-info-color': string;
'--w-rjv-update-color': string;
'--w-rjv-copied-color': string;

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': string;

@@ -8,2 +8,3 @@ export var darkTheme = {

'--w-rjv-info-color': '#656565',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#0184a6',

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': '#28a745',

@@ -8,2 +8,3 @@ export declare const lightTheme: {

'--w-rjv-info-color': string;
'--w-rjv-update-color': string;
'--w-rjv-copied-color': string;

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': string;

@@ -8,2 +8,3 @@ export var lightTheme = {

'--w-rjv-info-color': '#0000004d',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#002b36',

@@ -10,0 +11,0 @@ '--w-rjv-copied-success-color': '#28a745',

@@ -63,3 +63,3 @@ import { FC, PropsWithChildren } from 'react';

}
export declare const Label: FC<PropsWithChildren<LabelProps>>;
export declare const Label: import("react").ForwardRefExoticComponent<LabelProps & import("react").RefAttributes<HTMLSpanElement>>;
export interface TypeProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {

@@ -66,0 +66,0 @@ type: keyof typeof typeMap;

@@ -6,3 +6,3 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose";

_excluded3 = ["children", "color", "fontSize", "opacity", "paddingRight", "style"];
import { Fragment, useState } from 'react';
import { Fragment, forwardRef, useState } from 'react';
import { Meta, CountInfo } from './node';

@@ -156,2 +156,3 @@ import { Copied } from './copied';

children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
ref: null,
children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, valueView, tools]

@@ -176,2 +177,3 @@ }))

children: /*#__PURE__*/_jsxs(Label, _extends({}, reset, {
ref: null,
children: [renderKey, /*#__PURE__*/_jsx(Colon, {}), typeView, empty, tools]

@@ -181,3 +183,3 @@ }))

}
export var Label = _ref2 => {
export var Label = /*#__PURE__*/forwardRef((_ref2, ref) => {
var {

@@ -200,5 +202,6 @@ children,

}, reset, {
ref: ref,
children: children
}));
};
});
export var Type = props => {

@@ -205,0 +208,0 @@ var _typeMap$type2, _typeMap$type3;

{
"name": "@uiw/react-json-view",
"version": "1.2.0",
"version": "1.3.0",
"description": "JSON viewer for react.",

@@ -77,5 +77,8 @@ "main": "cjs/index.js",

"devDependencies": {
"@testing-library/react": "^14.0.0",
"@types/react-test-renderer": "^18.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0"
}
}

@@ -7,2 +7,3 @@ react-json-view

[![react@^18](https://shields.io/badge/react-^18-green?style=flat&logo=react)](https://github.com/facebook/react/releases)
[![Coverage Status](https://uiwjs.github.io/react-json-view/badges.svg)](https://uiwjs.github.io/react-json-view/lcov-report/)

@@ -26,3 +27,4 @@ A React component for displaying and editing javascript arrays and JSON objects.

🌒 Support dark/light mode
📦 Zero dependencies
📦 Zero dependencies
♻️ Whether to highlight updates.

@@ -116,2 +118,3 @@ ## Quick Start

'--w-rjv-info-color': '#656565',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#9cdcfe',

@@ -146,3 +149,3 @@ '--w-rjv-copied-success-color': '#28a745',

```tsx mdx:preview:&title=Online Editing Theme
import React, { useState, useRef } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import Colorful from '@uiw/react-color-colorful';

@@ -179,2 +182,3 @@ import JsonView from '@uiw/react-json-view';

'--w-rjv-info-color': '#656565',
'--w-rjv-update-color': '#ebcb8b',
'--w-rjv-copied-color': '#0184a6',

@@ -205,6 +209,19 @@ '--w-rjv-copied-success-color': '#28a745',

};
const [src, setSrc] = useState({ ...object })
useEffect(() => {
const loop = () => {
setSrc(src => ({
...src,
timer: src.timer + 1
}))
}
const id = setInterval(loop, 1000)
return () => clearInterval(id)
}, []);
return (
<React.Fragment>
<div style={{ display: 'flex', gap: '1rem' }}>
<JsonView value={object} keyName="root" style={{ flex: 1, ...theme }} />
<JsonView value={src} keyName="root" style={{ flex: 1, ...theme }} />
<div>

@@ -314,2 +331,46 @@ <Colorful color={hex} onChange={onChange} />

## Highlight Updates
```tsx mdx:preview
import React, { useState, useEffect } from 'react';
import JsonView from '@uiw/react-json-view';
import { TriangleArrow } from '@uiw/react-json-view/triangle-arrow';
import { TriangleSolidArrow } from '@uiw/react-json-view/triangle-solid-arrow';
const object = {
string: 'Lorem ipsum dolor sit amet',
integer: 42,
timer: 0,
object: { 'first-child': true, 'second-child': false, 'last-child': null },
}
export default function Demo() {
const [src, setSrc] = useState({ ...object })
useEffect(() => {
const loop = () => {
setSrc(src => ({
...src,
timer: src.timer + 1
}))
}
const id = setInterval(loop, 1000)
return () => clearInterval(id)
}, []);
return (
<JsonView
value={src}
keyName="root"
style={{
'--w-rjv-background-color': '#ffffff',
'--w-rjv-border-left': '1px dashed #ebebeb',
// ✅ Change default update background color ✅
'--w-rjv-update-color': '#ff6ffd',
}}
/>
)
}
```
This feature can be disabled with `highlightUpdates={false}`, and the default color can be changed with `--w-rjv-update-color`.
## Modify Icon Style

@@ -434,2 +495,4 @@

enableClipboard?: boolean;
/** Whether to highlight updates. @default true */
highlightUpdates?: boolean;
/** Display for quotes in object-key @default " */

@@ -436,0 +499,0 @@ quotes?: "'" | '"' | '';

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc