Interactive react component for displaying javascript arrays and JSON objects.
npx @tessl/cli install tessl/npm-react-json-view@1.21.0React JSON View is an interactive React component for displaying and editing JavaScript arrays and JSON objects with a responsive, customizable interface. It provides extensive theming options, in-place editing capabilities, and comprehensive data type support.
npm install react-json-viewimport ReactJson from "react-json-view";CommonJS:
const ReactJson = require("react-json-view");import ReactJson from "react-json-view";
// Basic JSON display
const myJsonObject = {
users: [
{ id: 1, name: "Alice", active: true },
{ id: 2, name: "Bob", active: false }
],
metadata: {
total: 2,
lastUpdated: "2023-01-01"
}
};
function App() {
return <ReactJson src={myJsonObject} />;
}The main ReactJsonView component with comprehensive display and interaction options.
interface ReactJsonViewProps {
/** The input JSON object or array to display (required) */
src: object;
/** Name of the root node. Use null or false for no name (default: "root") */
name?: string | null | false;
/** Base-16 theme name or custom theme object (default: "rjv-default") */
theme?: ThemeKeys | ThemeObject;
/** Custom CSS styles for container (default: {}) */
style?: React.CSSProperties;
/** Style of expand/collapse icons (default: "triangle") */
iconStyle?: 'circle' | 'triangle' | 'square';
/** Indent width for nested objects (default: 4) */
indentWidth?: number;
/** Collapse all nodes (true) or at specific depth (number) (default: false) */
collapsed?: boolean | number;
/** Truncate strings after specified length (default: false) */
collapseStringsAfterLength?: number | false;
/** Custom collapse logic callback (default: false) */
shouldCollapse?: false | ((field: CollapsedFieldProps) => boolean);
/** Group arrays after specified length (default: 100) */
groupArraysAfterLength?: number;
/** Enable copy functionality or provide custom copy callback (default: true) */
enableClipboard?: boolean | ((copy: OnCopyProps) => void);
/** Show object/array sizes (default: true) */
displayObjectSize?: boolean;
/** Show data type labels (default: true) */
displayDataTypes?: boolean;
/** Show array indices as prefixes for array elements (default: true) */
displayArrayKey?: boolean;
/** Show quotes on object keys (default: true) */
quotesOnKeys?: boolean;
/** Sort object keys alphabetically (default: false) */
sortKeys?: boolean;
/** Show array indices as prefixes for array elements (default: true) */
displayArrayKey?: boolean;
/** Edit callback - enables edit functionality when provided (default: false) */
onEdit?: ((edit: InteractionProps) => false | any) | false;
/** Add callback - enables add functionality when provided (default: false) */
onAdd?: ((add: InteractionProps) => false | any) | false;
/** Delete callback - enables delete functionality when provided (default: false) */
onDelete?: ((del: InteractionProps) => false | any) | false;
/** Select callback - triggered when clicking values (default: false) */
onSelect?: ((select: OnSelectProps) => void) | false;
/** Default value for new keys when adding (default: null) */
defaultValue?: TypeDefaultValue | TypeDefaultValue[] | null;
/** Custom validation error message (default: "Validation Error") */
validationMessage?: string;
}
declare const ReactJson: React.ComponentType<ReactJsonViewProps>;
export default ReactJson;Usage Examples:
import ReactJson from "react-json-view";
// Themed display with editing
function JsonEditor() {
const [data, setData] = useState({
name: "John",
age: 30,
hobbies: ["reading", "coding"]
});
return (
<ReactJson
src={data}
theme="monokai"
collapsed={1}
displayDataTypes={false}
onEdit={(edit) => {
setData(edit.updated_src);
}}
onAdd={(add) => {
setData(add.updated_src);
}}
onDelete={(del) => {
setData(del.updated_src);
}}
/>
);
}
// Read-only display with custom styling
function JsonDisplay() {
return (
<ReactJson
src={complexData}
name="API Response"
theme="solarized"
collapsed={2}
collapseStringsAfterLength={50}
groupArraysAfterLength={10}
style={{
backgroundColor: "#f5f5f5",
borderRadius: "4px",
padding: "10px"
}}
/>
);
}React JSON View supports extensive theming through built-in base-16 themes or custom theme objects.
/** Built-in theme names */
type ThemeKeys =
| 'apathy' | 'apathy:inverted'
| 'ashes' | 'bespin' | 'brewer'
| 'bright' | 'bright:inverted'
| 'chalk' | 'codeschool' | 'colors'
| 'eighties' | 'embers' | 'flat'
| 'google' | 'grayscale' | 'grayscale:inverted'
| 'greenscreen' | 'harmonic' | 'hopscotch'
| 'isotope' | 'marrakesh' | 'mocha'
| 'monokai' | 'ocean' | 'paraiso'
| 'pop' | 'railscasts' | 'rjv-default'
| 'shapeshifter' | 'shapeshifter:inverted'
| 'solarized' | 'summerfruit' | 'summerfruit:inverted'
| 'threezerotwofour' | 'tomorrow' | 'tube' | 'twilight';
/** Custom theme object following base-16 specification */
interface ThemeObject {
base00: string; // Default Background
base01: string; // Lighter Background
base02: string; // Selection Background
base03: string; // Comments, Invisibles
base04: string; // Dark Foreground
base05: string; // Default Foreground
base06: string; // Light Foreground
base07: string; // Light Background
base08: string; // Variables, Tags, Delimiters
base09: string; // Integers, Boolean, Constants
base0A: string; // Classes, Markup Bold
base0B: string; // Strings, Inherited Class
base0C: string; // Support, Regular Expressions
base0D: string; // Functions, Methods, Headings
base0E: string; // Keywords, Storage, Selector
base0F: string; // Deprecated, Opening/Closing Tags
}Usage Examples:
// Using built-in themes
<ReactJson src={data} theme="monokai" />
<ReactJson src={data} theme="solarized" />
<ReactJson src={data} theme="grayscale:inverted" />
// Custom theme
const customTheme: ThemeObject = {
base00: "#ffffff",
base01: "#f5f5f5",
base02: "#e0e0e0",
base03: "#888888",
base04: "#666666",
base05: "#333333",
base06: "#111111",
base07: "#000000",
base08: "#d32f2f",
base09: "#f57c00",
base0A: "#fbc02d",
base0B: "#388e3c",
base0C: "#0097a7",
base0D: "#1976d2",
base0E: "#7b1fa2",
base0F: "#5d4037"
};
<ReactJson src={data} theme={customTheme} />Enable editing, adding, and deleting functionality through callback props.
/** Interaction event data passed to callbacks */
interface InteractionProps {
/** Updated JSON tree after the interaction */
updated_src: object;
/** Original JSON tree before the interaction */
existing_src: object;
/** Key name of the interacted element */
name: string | null;
/** Array of keys representing the path to the element */
namespace: Array<string | null>;
/** Original value before interaction */
existing_value: object | string | number | boolean | null;
/** New value after interaction */
new_value?: object | string | number | boolean | null;
}
/** Selection event data */
interface OnSelectProps {
/** Name of the selected element */
name: string | null;
/** Value of the selected element */
value: object | string | number | boolean | null;
/** Type of the value (refined for numbers: 'float', 'integer', 'nan') */
type: string;
/** Array of keys representing the path to the selected element */
namespace: Array<string | null>;
}
/** Copy event data */
interface OnCopyProps {
/** The JSON tree source object */
src: object;
/** Array of keys representing the path to copied element */
namespace: Array<string | null>;
/** Name of the copied element */
name: string | null;
}Usage Examples:
function EditableJson() {
const [jsonData, setJsonData] = useState({
users: [{ name: "Alice" }],
settings: { theme: "light" }
});
const handleEdit = (edit: InteractionProps) => {
console.log("Editing:", edit.name, "from", edit.existing_value, "to", edit.new_value);
// Validate the change
if (edit.name === "theme" && !["light", "dark"].includes(edit.new_value as string)) {
return false; // Prevent invalid theme
}
// Accept the change
setJsonData(edit.updated_src);
};
const handleAdd = (add: InteractionProps) => {
console.log("Adding:", add.name, "=", add.new_value);
setJsonData(add.updated_src);
};
const handleDelete = (del: InteractionProps) => {
console.log("Deleting:", del.name);
// Prevent deletion of required fields
if (del.name === "users") {
return false;
}
setJsonData(del.updated_src);
};
const handleSelect = (selection: OnSelectProps) => {
console.log("Selected:", selection.name, "=", selection.value);
console.log("Path:", selection.namespace.join("."));
};
return (
<ReactJson
src={jsonData}
onEdit={handleEdit}
onAdd={handleAdd}
onDelete={handleDelete}
onSelect={handleSelect}
defaultValue="New Value"
validationMessage="Invalid input - please check your data"
/>
);
}Fine-tune the appearance and behavior of the JSON display.
/** Collapse behavior configuration */
interface CollapsedFieldProps {
/** Name of the field being evaluated for collapse */
name: string | null;
/** The corresponding JSON subtree */
src: object;
/** Type of the source ('array' or 'object') */
type: 'array' | 'object';
/** Array representing the scope path */
namespace: Array<string | null>;
}
/** Valid types for default values when adding new elements */
type TypeDefaultValue = string | number | boolean | object;Usage Examples:
// Advanced display configuration
<ReactJson
src={largeDataset}
name="Dataset"
collapsed={(field) => {
// Collapse arrays with more than 5 items
if (field.type === "array" && field.src.length > 5) {
return true;
}
// Collapse nested objects deeper than 2 levels
return field.namespace.length > 2;
}}
collapseStringsAfterLength={100}
groupArraysAfterLength={20}
displayObjectSize={true}
displayDataTypes={true}
displayArrayKey={true}
quotesOnKeys={false}
sortKeys={true}
indentWidth={2}
iconStyle="square"
/>
// Minimal clean display
<ReactJson
src={data}
name={false}
displayObjectSize={false}
displayDataTypes={false}
displayArrayKey={false}
quotesOnKeys={false}
enableClipboard={false}
style={{
fontFamily: "Monaco, monospace",
fontSize: "14px"
}}
/>Configure copy-to-clipboard functionality with optional custom handling.
Usage Examples:
// Enable clipboard with custom handler
<ReactJson
src={data}
enableClipboard={(copy: OnCopyProps) => {
const value = copy.namespace.reduce(
(obj, key) => key ? obj[key] : obj,
copy.src
);
// Custom copy logic
navigator.clipboard.writeText(JSON.stringify(value, null, 2));
console.log("Copied to clipboard:", copy.name);
}}
/>
// Simple clipboard enable/disable
<ReactJson src={data} enableClipboard={true} />
<ReactJson src={data} enableClipboard={false} />React JSON View includes built-in validation and error handling:
src is not an object or arrayfalse from onEdit, onAdd, or onDelete prevents the change and shows validation message// Validation example
const handleEdit = (edit: InteractionProps) => {
try {
// Validate new value
if (typeof edit.new_value === 'string' && edit.new_value.length > 100) {
return false; // Shows validationMessage
}
setData(edit.updated_src);
} catch (error) {
console.error("Edit failed:", error);
return false;
}
};
<ReactJson
src={data}
onEdit={handleEdit}
validationMessage="Value too long (max 100 characters)"
/>