diff --git a/README.md b/README.md
index ddbeb3e..560e475 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,8 @@ npm install @microlink/react-json-view --save
```js
import ReactJsonView from '@microlink/react-json-view'
-
+ }}
+ showComma
+/>
```
### API
@@ -84,6 +87,7 @@ import ReactJsonView from '@microlink/react-json-view'
| `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. |
| `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. |
+| `showComma` | `boolean` | `true` | When set to `true`, commas are displayed between object properties and array elements for better readability. Interactive tools (clipboard, edit, delete icons) appear after the comma when hovering over JSON elements. |
#### Callbacks
diff --git a/dev-server/src/index.js b/dev-server/src/index.js
index 229ae0e..9fee0bc 100644
--- a/dev-server/src/index.js
+++ b/dev-server/src/index.js
@@ -64,6 +64,53 @@ ReactDom.render(
return false
}}
defaultValue=''
+ showComma={true}
+ />
+
+
+
+ {/* Same example without commas for comparison */}
+ {
+ console.log('edit callback', e)
+ if (e.new_value == 'error') {
+ return false
+ }
+ }}
+ onDelete={e => {
+ console.log('delete callback', e)
+ }}
+ onAdd={e => {
+ console.log('add callback', e)
+ if (e.new_value == 'error') {
+ return false
+ }
+ }}
+ onSelect={e => {
+ console.log('select callback', e)
+ console.log(e.namespace)
+ }}
+ displayObjectSize={true}
+ name={'dev-server (no commas)'}
+ enableClipboard={copy => {
+ console.log('you copied to clipboard!', copy)
+ }}
+ shouldCollapse={({ src, namespace, type }) => {
+ if (type === 'array' && src.indexOf('test') > -1) {
+ return true
+ } else if (namespace.indexOf('moment') > -1) {
+ return true
+ }
+ return false
+ }}
+ defaultValue=''
+ showComma={false}
/>
@@ -98,6 +145,7 @@ ReactDom.render(
src.constructor.name === 'Moment'
}
selectOnFocus
+ showComma={true}
/>
diff --git a/src/js/components/ArrayGroup.js b/src/js/components/ArrayGroup.js
index 55d6122..f819c92 100644
--- a/src/js/components/ArrayGroup.js
+++ b/src/js/components/ArrayGroup.js
@@ -109,6 +109,8 @@ export default class extends React.PureComponent {
type='array'
parent_type='array_group'
theme={theme}
+ showComma={this.props.showComma}
+ isLast={i === groups - 1}
{...rest}
/>
)
diff --git a/src/js/components/DataTypes/Object.js b/src/js/components/DataTypes/Object.js
index a7a0605..0334d4e 100644
--- a/src/js/components/DataTypes/Object.js
+++ b/src/js/components/DataTypes/Object.js
@@ -144,7 +144,6 @@ class RjvObject extends React.PureComponent {
{object_type === 'array' ? '[' : '{'}
- {expanded ? this.getObjectMetaData(src) : null}
)
}
@@ -167,7 +166,6 @@ class RjvObject extends React.PureComponent {
{object_type === 'array' ? '[' : '{'}
- {expanded ? this.getObjectMetaData(src) : null}
)
}
@@ -185,6 +183,8 @@ class RjvObject extends React.PureComponent {
theme,
jsvRoot,
iconStyle,
+ showComma,
+ isLast,
...rest
} = this.props
@@ -222,8 +222,13 @@ class RjvObject extends React.PureComponent {
>
{object_type === 'array' ? ']' : '}'}
- {expanded ? null : this.getObjectMetaData(src)}
+ {showComma && !isLast && !jsvRoot && (
+
+ ,
+
+ )}
+ {this.getObjectMetaData(src)}
)
}
@@ -234,7 +239,8 @@ class RjvObject extends React.PureComponent {
parent_type,
index_offset,
groupArraysAfterLength,
- namespace
+ namespace,
+ showComma,
} = this.props
const { object_type } = this.state
const elements = []
@@ -244,8 +250,9 @@ class RjvObject extends React.PureComponent {
keys = keys.sort()
}
- keys.forEach(name => {
+ keys.forEach((name, index) => {
variable = new JsonVariable(name, variables[name], props.bigNumber)
+ const isLast = index === keys.length - 1
if (parent_type === 'array_group' && index_offset) {
variable.name = parseInt(variable.name) + index_offset
@@ -260,6 +267,8 @@ class RjvObject extends React.PureComponent {
src={variable.value}
namespace={namespace.concat(variable.name)}
parent_type={object_type}
+ isLast={isLast}
+ showComma={showComma}
{...props}
/>
)
@@ -282,6 +291,8 @@ class RjvObject extends React.PureComponent {
namespace={namespace.concat(variable.name)}
type='array'
parent_type={object_type}
+ isLast={isLast}
+ showComma={showComma}
{...props}
/>
)
@@ -294,6 +305,8 @@ class RjvObject extends React.PureComponent {
singleIndent={SINGLE_INDENT}
namespace={namespace}
type={this.props.type}
+ isLast={isLast}
+ showComma={showComma}
{...props}
/>
)
diff --git a/src/js/components/VariableEditor.js b/src/js/components/VariableEditor.js
index d0bcb32..2d14b10 100644
--- a/src/js/components/VariableEditor.js
+++ b/src/js/components/VariableEditor.js
@@ -57,7 +57,9 @@ class VariableEditor extends React.PureComponent {
onSelect,
displayArrayKey,
quotesOnKeys,
- keyModifier
+ keyModifier,
+ showComma,
+ isLast
} = this.props
const { editMode } = this.state
return (
@@ -126,6 +128,11 @@ class VariableEditor extends React.PureComponent {
>
{this.getValue(variable, editMode)}
+ {showComma && !isLast && (
+
+ ,
+
+ )}
{enableClipboard
? (
e.metaKey || e.ctrlKey,
- bigNumber: null
+ bigNumber: null,
+ showComma: true
}
// 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 a8b290d..dff05f0 100644
--- a/src/js/themes/getStyle.js
+++ b/src/js/themes/getStyle.js
@@ -386,6 +386,13 @@ const getDefaultThemeStyling = theme => {
color: colors.validationFailure.iconColor,
fontSize: constants.iconFontSize,
transform: 'rotate(45deg)'
+ },
+ comma: {
+ display: 'inline-block',
+ color: constants.commaColor,
+ fontSize: constants.commaFontSize,
+ marginRight: constants.commaMarginRight,
+ cursor: 'default'
}
}
}
diff --git a/src/js/themes/styleConstants.js b/src/js/themes/styleConstants.js
index 98c1ba6..4b921a6 100644
--- a/src/js/themes/styleConstants.js
+++ b/src/js/themes/styleConstants.js
@@ -91,5 +91,9 @@ export default {
addKeyModalWidth: '200px',
addKeyModalMargin: 'auto',
addKeyModalPadding: '10px',
- addKeyModalRadius: '3px'
-}
+ addKeyModalRadius: '3px',
+
+ commaColor: '#666',
+ commaFontSize: '12px',
+ commaMarginRight: '4px'
+};
diff --git a/test/tests/js/Index-test.js b/test/tests/js/Index-test.js
index ed409bb..d8d22c5 100644
--- a/test/tests/js/Index-test.js
+++ b/test/tests/js/Index-test.js
@@ -128,4 +128,48 @@ describe('', function () {
)
expect(wrapper.find('.object-size')).to.have.length(1)
})
+
+ it('should show commas when showComma is true', function () {
+ const wrapper = render(
+
+ )
+ // Check that commas are present in the rendered output
+ expect(wrapper.text()).to.include(',')
+ })
+
+ it('should not show commas when showComma is false', function () {
+ const wrapper = render(
+
+ )
+ // Check that commas are not present in the rendered output
+ expect(wrapper.text()).to.not.include(',')
+ })
+
+ it('should default to showing commas when showComma is not specified', function () {
+ const wrapper = render(
+
+ )
+ // Check that commas are present by default
+ expect(wrapper.text()).to.include(',')
+ })
})
diff --git a/test/tests/js/components/DataTypes/Object-test.js b/test/tests/js/components/DataTypes/Object-test.js
index e85d497..7c01c0b 100644
--- a/test/tests/js/components/DataTypes/Object-test.js
+++ b/test/tests/js/components/DataTypes/Object-test.js
@@ -373,4 +373,97 @@ describe('', function () {
)
expect(wrapper.text()).to.equal('"":{"d":"d""b":"b""a":"a""c":"c"}')
})
+
+ it('Object should show comma when showComma is true and not last element', function () {
+ let src = {
+ prop1: 1,
+ prop2: 2
+ }
+
+ const wrapper = shallow(
+
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true
+ })
+
+ it('Object should not show comma when showComma is false', function () {
+ let src = {
+ prop1: 1,
+ prop2: 2
+ }
+
+ const wrapper = shallow(
+
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false
+ })
+
+ it('Object should not show comma when isLast is true', function () {
+ let src = {
+ prop1: 1,
+ prop2: 2
+ }
+
+ const wrapper = shallow(
+
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false
+ })
+
+ it('Object should not show comma when jsvRoot is true', function () {
+ let src = {
+ prop1: 1,
+ prop2: 2
+ }
+
+ const wrapper = shallow(
+
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false
+ })
})
diff --git a/test/tests/js/components/VariableEditor-test.js b/test/tests/js/components/VariableEditor-test.js
index 9d1f57c..075a998 100644
--- a/test/tests/js/components/VariableEditor-test.js
+++ b/test/tests/js/components/VariableEditor-test.js
@@ -372,4 +372,86 @@ describe('', function () {
'\\\n\t\r\f\\n'
)
})
+
+ it('VariableEditor should show comma when showComma is true and not last element', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ showComma
+ isLast={false}
+ variable={{
+ name: 'test',
+ value: 5,
+ type: 'int'
+ }}
+ />
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true
+ })
+
+ it('VariableEditor should not show comma when showComma is false', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ showComma={false}
+ isLast={false}
+ variable={{
+ name: 'test',
+ value: 5,
+ type: 'int'
+ }}
+ />
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false
+ })
+
+ it('VariableEditor should not show comma when isLast is true', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ showComma
+ isLast
+ variable={{
+ name: 'test',
+ value: 5,
+ type: 'int'
+ }}
+ />
+ )
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false
+ })
+
+ it('VariableEditor should render comma before tools when showComma is true', function () {
+ const wrapper = shallow(
+ { }}
+ rjvId={rjvId}
+ showComma
+ isLast={false}
+ variable={{
+ name: 'test',
+ value: 5,
+ type: 'int'
+ }}
+ />
+ )
+
+ // Check that comma exists
+ expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true
+
+ // Check that tools (edit icon) exist
+ const editIcon = wrapper.find('.click-to-edit-icon')
+ expect(editIcon).to.have.length(1)
+ })
})