diff --git a/README.md b/README.md
index 3395da4..ddbeb3e 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,8 @@ import ReactJsonView from '@microlink/react-json-view'
'last-child': null
},
string_number: '1234',
- date: new Date()
+ date: new Date(),
+ bigNumber: new BigNumber('0.0060254656709730629123')
}} />
```
@@ -81,7 +82,8 @@ import ReactJsonView from '@microlink/react-json-view'
| `quotesOnKeys` | `boolean` | `true` | Set to `false` to remove quotes from keys (e.g., `"name":` vs. `name:`). |
| `validationMessage` | `string` | "Validation Error" | Custom message for validation failures to `onEdit`, `onAdd`, or `onDelete` callbacks. |
| `displayArrayKey` | `boolean` | `true` | When set to `true`, the index of the elements prefix values. |
-| `escapeStrings` | `boolean` | `true` | When set to `true`, strings sequences such as \n, \t, \r, \f will be escaped. |
+| `escapeStrings` | `boolean` | `true` | When set to `true`, strings sequences such as \n, \t, \r, \f will be escaped. |
+| `bigNumber` | `Class` | `null` | A custom class for handling large numbers. The class should have a constructor that accepts a numeric string/value and a `name` property for display purposes. You can use existing libraries like `bignumber.js`, `decimal.js`, `big.js`, or provide your own implementation. |
#### Callbacks
diff --git a/dev-server/src/index.js b/dev-server/src/index.js
index 9158e1f..229ae0e 100644
--- a/dev-server/src/index.js
+++ b/dev-server/src/index.js
@@ -9,11 +9,23 @@ import Moment from 'moment'
//import the react-json-view component (installed with npm)
import JsonViewer from './../../src/js/index'
+// custom big number class, You can use existing libraries like `bignumber.js`, `decimal.js`, `big.js` etc.
+class BigNumber {
+ name = 'customName'
+ constructor(value) {
+ this.value = value
+ }
+ toString() {
+ return this.value.toString()
+ }
+}
+
//render 2 different examples of the react-json-view component
ReactDom.render(
{/* just pass in your JSON to the src attribute */}
namespace.indexOf('moment') > -1
}
@@ -220,7 +234,8 @@ function getExampleJson1 () {
string_number: '1234',
date: new Date(),
moment: Moment(),
- regexp: /[0-9]/gi
+ regexp: /[0-9]/gi,
+ bigNumber: new BigNumber('0.0060254656709730629123')
}
}
diff --git a/src/js/components/DataTypes/BigNumber.js b/src/js/components/DataTypes/BigNumber.js
new file mode 100644
index 0000000..289e168
--- /dev/null
+++ b/src/js/components/DataTypes/BigNumber.js
@@ -0,0 +1,18 @@
+import React from 'react'
+import DataTypeLabel from './DataTypeLabel'
+
+// theme
+import Theme from './../../themes/getStyle'
+
+export default class extends React.PureComponent {
+ render () {
+ const type_name = 'bigNumber'
+ const { props } = this
+ return (
+
+
+ {this.props.value.toString()}
+
+ )
+ }
+}
diff --git a/src/js/components/DataTypes/DataTypes.js b/src/js/components/DataTypes/DataTypes.js
index 56223dd..78c8ef3 100644
--- a/src/js/components/DataTypes/DataTypes.js
+++ b/src/js/components/DataTypes/DataTypes.js
@@ -9,3 +9,4 @@ export { default as JsonObject } from './Object'
export { default as JsonRegexp } from './Regexp'
export { default as JsonString } from './String'
export { default as JsonUndefined } from './Undefined'
+export { default as JsonBigNumber } from './BigNumber'
diff --git a/src/js/components/DataTypes/Object.js b/src/js/components/DataTypes/Object.js
index d3c1b90..4d37bff 100644
--- a/src/js/components/DataTypes/Object.js
+++ b/src/js/components/DataTypes/Object.js
@@ -245,12 +245,12 @@ class RjvObject extends React.PureComponent {
}
keys.forEach(name => {
- variable = new JsonVariable(name, variables[name])
+ variable = new JsonVariable(name, variables[name], props.bigNumber)
if (parent_type === 'array_group' && index_offset) {
variable.name = parseInt(variable.name) + index_offset
}
- if (!variables.hasOwnProperty(name)) {
+ if (!Object.prototype.hasOwnProperty.call(variables, name)) {
} else if (variable.type === 'object') {
elements.push(
)
} else {
+ // include bigNumber
elements.push(
{
if (this.props.onEdit !== false) {
- const stringifiedValue = stringifyVariable(variable.value)
- const detected = parseInput(stringifiedValue)
+ const stringifiedValue = stringifyVariable(variable.value, this.props.bigNumber)
+ const detected = parseInput(stringifiedValue, this.props.bigNumber)
this.setState({
editMode: true,
editValue: stringifiedValue,
@@ -236,6 +237,8 @@ class VariableEditor extends React.PureComponent {
return
case 'regexp':
return
+ case 'bigNumber':
+ return
default:
// catch-all for types that weren't anticipated
return {JSON.stringify(variable.value)}
@@ -259,7 +262,7 @@ class VariableEditor extends React.PureComponent {
class='variable-editor'
onChange={event => {
const value = event.target.value
- const detected = parseInput(value)
+ const detected = parseInput(value, this.props.bigNumber)
this.setState({
editValue: value,
parsedInput: {
@@ -320,12 +323,15 @@ class VariableEditor extends React.PureComponent {
}
submitEdit = submit_detected => {
- const { variable, namespace, rjvId } = this.props
+ const { variable, namespace, rjvId, bigNumber: BigNumber } = this.props
const { editValue, parsedInput } = this.state
let new_value = editValue
if (submit_detected && parsedInput.type) {
new_value = parsedInput.value
- }
+ if (BigNumber && parsedInput.type === 'bigNumber') {
+ new_value = new BigNumber(new_value)
+ }
+ }
this.setState({
editMode: false
})
@@ -456,6 +462,8 @@ class VariableEditor extends React.PureComponent {
return
case 'date':
return
+ case 'bignumber':
+ return
}
}
}
diff --git a/src/js/helpers/parseInput.js b/src/js/helpers/parseInput.js
index da0c451..39aaca5 100644
--- a/src/js/helpers/parseInput.js
+++ b/src/js/helpers/parseInput.js
@@ -1,11 +1,11 @@
-export default function parseInput (input) {
+export default function parseInput (input, bigNumber) {
// following code is to make a best guess at
// the type for a variable being submitted.
// we are working with a serialized data representation
input = input.trim()
try {
- input = JSON.stringify(JSON.parse(input))
+ input = structuredClone(input)
if (input[0] === '[') {
// array
return formatResponse('array', JSON.parse(input))
@@ -16,6 +16,10 @@ export default function parseInput (input) {
input.match(/\-?\d+\.\d+/) &&
input.match(/\-?\d+\.\d+/)[0] === input
) {
+ // big number
+ if (bigNumber && parseFloat(input).toString() !== input) {
+ return formatResponse('bigNumber', input)
+ }
// float
return formatResponse('float', parseFloat(input))
} else if (
@@ -25,6 +29,10 @@ export default function parseInput (input) {
// scientific float
return formatResponse('float', Number(input))
} else if (input.match(/\-?\d+/) && input.match(/\-?\d+/)[0] === input) {
+ // big number
+ if (bigNumber && parseInt(input).toString() !== input) {
+ return formatResponse('bigNumber', input)
+ }
// integer
return formatResponse('integer', parseInt(input))
} else if (
diff --git a/src/js/helpers/stringifyVariable.js b/src/js/helpers/stringifyVariable.js
index 4d912b2..ad4275b 100644
--- a/src/js/helpers/stringifyVariable.js
+++ b/src/js/helpers/stringifyVariable.js
@@ -1,7 +1,7 @@
import { toType } from './util'
-export default value => {
- const type = toType(value)
+export default (value, bigNumber) => {
+ const type = toType(value, bigNumber)
let string_value
switch (type) {
case 'undefined': {
@@ -14,6 +14,9 @@ export default value => {
case 'string':
string_value = value
break
+ case 'bigNumber':
+ string_value = value.toString()
+ break
case 'date':
string_value = value.toString()
break
diff --git a/src/js/helpers/util.js b/src/js/helpers/util.js
index 6654f8a..2ec1388 100644
--- a/src/js/helpers/util.js
+++ b/src/js/helpers/util.js
@@ -1,5 +1,12 @@
// returns a string "type" of input object
-export function toType (obj) {
+export function toType (obj, bigNumber) {
+
+ /* Check if the object is an instance of the custom BigNumber class passed in as a prop
+ * If it matches, return 'bigNumber' type so it can be displayed appropriately
+ */
+ if (bigNumber && obj?.constructor?.name === bigNumber?.name) {
+ return 'bigNumber'
+ }
let type = getType(obj)
// some extra disambiguation for numbers
if (type === 'number') {
diff --git a/src/js/index.js b/src/js/index.js
index 0819e00..0e48d17 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -59,7 +59,8 @@ class ReactJsonView extends React.PureComponent {
defaultValue: null,
displayArrayKey: true,
selectOnFocus: false,
- keyModifier: e => e.metaKey || e.ctrlKey
+ keyModifier: e => e.metaKey || e.ctrlKey,
+ bigNumber: null
}
// will trigger whenever setState() is called, or parent passes in new props.
diff --git a/src/js/themes/getStyle.js b/src/js/themes/getStyle.js
index b05affd..a8b290d 100644
--- a/src/js/themes/getStyle.js
+++ b/src/js/themes/getStyle.js
@@ -25,7 +25,8 @@ const colorMap = theme => ({
null: theme.base0A,
undefined: theme.base05,
regexp: theme.base0A,
- background: theme.base02
+ background: theme.base02,
+ bigNumber: theme.base09
},
editVariable: {
editIcon: theme.base0E,
@@ -182,6 +183,10 @@ const getDefaultThemeStyling = theme => {
display: 'inline-block',
color: colors.dataTypes.integer
},
+ bigNumber: {
+ display: 'inline-block',
+ color: colors.dataTypes.bigNumber
+ },
string: {
display: 'inline-block',
color: colors.dataTypes.string