From d053cb56aa9b25178b6b14b6183d81a66d1b8a57 Mon Sep 17 00:00:00 2001 From: Herman Chow Date: Fri, 17 Jan 2020 18:26:39 +1100 Subject: [PATCH 1/2] #186: Add onToggleCollapse callback that returns new expanded state, name, namespace and rjvId. --- dev-server/src/index.js | 3 + src/js/components/DataTypes/Object.js | 9 ++- .../js/components/DataTypes/Object-test.js | 57 +++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/dev-server/src/index.js b/dev-server/src/index.js index 168bb3a2..a87f8d1d 100644 --- a/dev-server/src/index.js +++ b/dev-server/src/index.js @@ -37,6 +37,9 @@ ReactDom.render( console.log("select callback", e) console.log(e.namespace) }} + onToggleCollapse={e => { + console.log("toggle collapse callback", e) + }} displayObjectSize={true} name={"dev-server"} enableClipboard={copy => { diff --git a/src/js/components/DataTypes/Object.js b/src/js/components/DataTypes/Object.js index c14a3ff5..5cb6a38f 100644 --- a/src/js/components/DataTypes/Object.js +++ b/src/js/components/DataTypes/Object.js @@ -80,15 +80,20 @@ class RjvObject extends React.PureComponent { } toggleCollapsed = () => { + const { onToggleCollapse, name, namespace, rjvId } = this.props; + this.setState({ expanded: !this.state.expanded }, () => { AttributeStore.set( - this.props.rjvId, - this.props.namespace, + rjvId, + namespace, 'expanded', this.state.expanded ); + if (typeof onToggleCollapse === 'function') { + onToggleCollapse({ expanded: this.state.expanded, name, namespace, rjvId }); + } }); } diff --git a/test/tests/js/components/DataTypes/Object-test.js b/test/tests/js/components/DataTypes/Object-test.js index 02ce4b18..ff8a7ef0 100644 --- a/test/tests/js/components/DataTypes/Object-test.js +++ b/test/tests/js/components/DataTypes/Object-test.js @@ -1,5 +1,6 @@ import React from "react" import { shallow, render, mount } from "enzyme" +import sinon from "sinon" import { expect } from "chai" import JsonObject from "./../../../../../src/js/components/DataTypes/Object" @@ -325,6 +326,7 @@ describe("", function() { expect(wrapper.state("expanded")).to.equal(true) }) + it("sort object keys", () => { let src = { d: 'd', @@ -365,4 +367,59 @@ describe("", function() { ) expect(wrapper.text()).to.equal('"":{"d":"d""b":"b""a":"a""c":"c"}'); }) + + describe("callbacks", function() { + let sandbox; + + beforeEach(function() { + sandbox = sinon.sandbox.create() + }) + + afterEach(function() { + sandbox.restore() + }) + + it("should call onToggleCollapse callback when collapsing", function() { + let src = { prop1: 1, prop2: 2, prop3: 3 } + const mockToggleCollapseCallback = sandbox.spy(); + + const wrapper = mount( + + ) + + expect(wrapper.state("expanded"), "should start collapsed").to.equal(false) + expect(wrapper.find("CollapsedIcon").length, "should have one collapsed icon").to.equal(1) + + wrapper.find("CollapsedIcon").simulate("click"); + expect(mockToggleCollapseCallback.calledWithMatch({ expanded: true }), + "should call callback with object with property expanded as true").to.equal(true) + }) + + it("should call onToggleCollapse callback when expanding", function() { + let src = { prop1: 1, prop2: 2, prop3: 3 } + const mockToggleCollapseCallback = sandbox.spy(); + + const wrapper = mount( + + ) + + expect(wrapper.state("expanded"), "should start expanded").to.equal(true) + expect(wrapper.find("ExpandedIcon").length, "should have one expanded icon").to.equal(1) + + wrapper.find("ExpandedIcon").simulate("click"); + expect(mockToggleCollapseCallback.calledWithMatch({ expanded: false }), + "should call callback with object with property expanded as false").to.equal(true) + }) + }) }) From 1710bd9e517e649b3e2390be48f90123649759de Mon Sep 17 00:00:00 2001 From: Herman Chow Date: Mon, 20 Jan 2020 12:56:55 +1100 Subject: [PATCH 2/2] #186: Update types and README for the onToggleCollapse callback. Removed rjvId as it appears to be more of an internal id that isn't exposed to consumers. --- README.md | 1 + index.d.ts | 22 ++++++++++++++++++++++ src/js/components/DataTypes/Object.js | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fed04f2f..d6ac3744 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Name|Type|Default|Description `collapsed`|`boolean` or `integer`|`false`|When set to `true`, all nodes will be collapsed by default. Use an integer value to collapse at a particular depth. `collapseStringsAfterLength`|`integer`|`false`|When an integer value is assigned, strings will be cut off at that length. Collapsed strings are followed by an ellipsis. String content can be expanded and collapsed by clicking on the string value. `shouldCollapse`|`(field)=>{}`|`false`|Callback function to provide control over what objects and arrays should be collapsed by default. An object is passed to the callback containing `name`, `src`, `type` ("array" or "object") and `namespace`. +`onToggleCollapse`|`(collapse)=>{}`|`false`|Callback function to hook into when an object or array has been expanded or collapsed. An object is passed to the callback containing `expanded`, `name`, and `namespace`. `groupArraysAfterLength`|`integer`|`100`|When an integer value is assigned, arrays will be displayed in groups by count of the value. Groups are displayed with brakcet notation and can be expanded and collapsed by clickong on the brackets. `enableClipboard`|`boolean` or `(copy)=>{}`|`true`|When prop is not `false`, the user can copy objects and arrays to clipboard by clicking on the clipboard icon. Copy callbacks are supported. `displayObjectSize`|`boolean`|`true`|When set to `true`, objects and arrays are labeled with size diff --git a/index.d.ts b/index.d.ts index 4a91dc29..d927a085 100644 --- a/index.d.ts +++ b/index.d.ts @@ -117,6 +117,12 @@ export interface ReactJsonViewProps { * Default: false */ onSelect?: ((select: OnSelectProps) => void) | false; + /** + * When a function is passed in, toggling an expand/collapse object triggers the onToggleCollapse method to be called. + * + * Default: false + */ + onToggleCollapse?: ((collapse: onToggleCollapseProps) => void) | false; /** * Custom message for validation failures to onEdit, onAdd, or onDelete callbacks. * @@ -219,6 +225,22 @@ export interface OnSelectProps { } +export interface onToggleCollapseProps { + /** + * The name of the currently selected entry. + */ + name: string | null; + /** + * The new expanded state of the expandable/collapsable object. + */ + expanded: boolean; + /** + * List of keys representing the scopes above the selected entry. + */ + namespace: Array; + +} + export type TypeDefaultValue = string | number | boolean | object; export interface ThemeObject { diff --git a/src/js/components/DataTypes/Object.js b/src/js/components/DataTypes/Object.js index 5cb6a38f..1842f57d 100644 --- a/src/js/components/DataTypes/Object.js +++ b/src/js/components/DataTypes/Object.js @@ -92,7 +92,7 @@ class RjvObject extends React.PureComponent { this.state.expanded ); if (typeof onToggleCollapse === 'function') { - onToggleCollapse({ expanded: this.state.expanded, name, namespace, rjvId }); + onToggleCollapse({ expanded: this.state.expanded, name, namespace }); } }); }