https://github.com/relex/json-diff-react
A React.js component that renders a structural diff of two JSON values
https://github.com/relex/json-diff-react
diff javascript-library json reactjs typescript
Last synced: about 1 year ago
JSON representation
A React.js component that renders a structural diff of two JSON values
- Host: GitHub
- URL: https://github.com/relex/json-diff-react
- Owner: relex
- License: mit
- Created: 2023-03-13T11:45:53.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2023-03-20T10:37:36.000Z (about 3 years ago)
- Last Synced: 2024-04-26T14:03:39.924Z (about 2 years ago)
- Topics: diff, javascript-library, json, reactjs, typescript
- Language: TypeScript
- Homepage: https://relex.github.io/json-diff-react/
- Size: 1.73 MB
- Stars: 5
- Watchers: 5
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE-MIT
Awesome Lists containing this project
README
# json-diff-react
A [React.js] component that renders a structural diff of two JSON values. Written in TypeScript
except for the JavaScript code inherited from the original [json-diff] library.
Types are declared for all user facing functionality.
This is a fork of [json-diff] with all of the dependencies towards Node.js core modules removed.
Code from [json-diff] can be found under `src/JsonDiff/Internal` and it’s mostly unchanged — expect
for the `colorize` module which now returns a JSX element instead of a string.
See the [interactive live demo](https://relex.github.io/json-diff-react/examples/example-07.html).
Also see the [source of that demo](examples/example-07.html).

Also see https://relex.github.io/json-diff-react/ for other examples.
## Simple example
Here is a simple example ([see the full demo of this example](examples/example-02.html)):
``` typescript
function DiffOfJsons({ a, b }: { a: string, b: string }): JSX.Element {
try {
// JSON.parse() can throw an exception if parsing fails.
// It’s for you to handle them before calling .
const parsedA = JSON.parse(a)
const parsedB = JSON.parse(b);
return ;
} catch (e: any) {
return
Error: {e?.message ?? JSON.stringify(e)}
;
}
}
```
Look into the [examples](examples) directory to find more examples on how to use this component.
## Usage
The `` requires 4 input properties:
1. `jsonA` **(required)**: a JSON value
- The caller is responsible for providing a valid, parsed JSON value (e.g. via `JSON.parse`)
2. `jsonB` **(required)**: a JSON value that is compared to `jsonA`
- The caller is responsible for providing a valid, parsed JSON value
3. `styleCustomization` *(optional)*: CSS customization of the markup
4. `jsonDiffOptions` *(optional)*: options that are fed directly to original [json-diff] code
N.B. The type of the input JSON values is described in TypeScript like this (you can import this
type from the library in case you need to use it for the values passed to the
``):
``` typescript
export type JsonValue =
| { [x: string]: JsonValue }
| Array
| string
| number
| boolean
| null;
```
### Style customization
There are two ways to customize the look of the component:
1. via CSS styles
2. via `styleCustomization` property of ``
#### CSS
Add these CSS styles for the component and customize them:
``` css
.deletion {
/* customization for deleted lines (
) */
color: red;
}
.addition {
/* customization for added lines (
) */
color: green;
}
.unchanged {
/* customization for unchanged lines (
) */
color: gray;
}
.diff {
/* customization for the top-level
wrapper that contains the diff */
font-family: monospace;
white-space: pre;
}
```
The names of the classes can be customized via `styleCustomization` React property.
#### styleCustomization
You can also use the `styleCustomization` property to customize how the
component looks and rename the CSS classes.
``` typescript
export type StyleCustomization = {
additionLineStyle: CSS.Properties | null;
additionClassName: string | null | undefined;
deletionLineStyle: CSS.Properties | null;
deletionClassName: string | null | undefined;
unchangedLineStyle: CSS.Properties | null;
unchangedClassName: string | null | undefined;
frameStyle: CSS.Properties | null;
frameClassName: string | null | undefined;
};
```
Explanation of each customization option:
* `additionLineStyle`: `style` attribute of the HTML `
` element that is
used to render added lines in the diff
* Defaults to `null` if not specified (means there will be no `style` added)
* `additionClassName`: `className` attribute of the HTML `` element that
is used to render added lines in the diff
* Defaults to `addition` if not specified
* Set to `null` to remove the `class` attribute
* `deletionLineStyle`: `style` attribute of the HTML `` element that is
used to render deleted lines in the diff
* Defaults to `null` if not specified (means there will be no `style` added)
* `deletionClassName`: `className` attribute of the HTML `` element that
is used to render deleted lines in the diff
* Defaults to `deletion` if not specified
* Set to `null` to remove the `class` attribute
* `unchangedLineStyle`: `style` attribute of the HTML `` element that is
used to render unchanged lines in the diff
* Defaults to `null` if not specified (means there will be no `style` added)
* `unchangedClassName`: `className` attribute of the HTML `` element that
is used to render unchanged lines in the diff
* Defaults to `unchanged` if not specified
* Set to `null` to remove the `class` attribute
* `frameStyle`: `style` attribute of the HTML `` element that contains the
whole rendered diff, i.e. the top level ``
* Can be used to customize background, etc.
* Defaults to `null` if not specified (means there will be no `style` added)
* `frameClassName`: `className` attribute of the HTML `` element that
contains the whole rendered diff, i.e. the top level ``
* Defaults to `diff`
* Set to `null` to remove the `class` attribute
### Options fed to json-diff
You can pass options to the underlying [json-diff] functions via
`jsonDiffOptions` which has the following type:
``` typescript
export interface DiffOptions {
verbose?: boolean;
raw?: boolean;
keysOnly?: boolean;
full?: boolean;
sort?: boolean;
outputKeys?: string[];
keepUnchangedValues?: boolean;
outputNewOnly?: boolean;
maxElisions?: number;
precision?: number;
excludeKeys?: string[];
showElisionsForObjects?: boolean;
renderElision?: (elisionCount: number, maxElisions: number) => string | string[];
}
```
All of the fields are optional. Consult the original [json-diff] library to
learn more about how the options impact the output.
Most of the `DiffOptions` type came from
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/json-diff/index.d.ts.
N.B. I added the `excludeKeys` attribute to the `DiffOptions` imported from
`DefinitelyTyped`. It appears like the type definitions in `DefinitelyTyped`
are outdated.
N.B. `showElisionsForObjects` option was not part of the original [json-diff] library.
It was added only for this library. It’s turned on by default.
It renders elisions like `...` for objects in the similar way it’s done for arrays.
N.B. `renderElision` option was added only to this library.
It wasn’t a part of original [json-diff] library.
It allows you to customize “...”/“... (N entries)” template.
Can also be useful to support localizations other than English.
## Authors
Thanks to Andrey Tarantsov for the work he did on the original [json-diff] package.
This package is just a thin wrapper on top of it.
Thanks to Viacheslav Lotsmanov for providing code review and change suggestions.
This package was built at [RELEX](https://www.relexsolutions.com/).
Main developer: [Joonas Laukka](https://github.com/skyvier).
## License
This software is distributed under the MIT license.
For details, have a look at [LICENSE-MIT](LICENSE-MIT).
[json-diff]: https://github.com/andreyvit/json-diff
[React.js]: https://reactjs.org