Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#186: Add onToggleCollapse callback #276

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions dev-server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
22 changes: 22 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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<string | null>;

}

export type TypeDefaultValue = string | number | boolean | object;

export interface ThemeObject {
Expand Down
9 changes: 7 additions & 2 deletions src/js/components/DataTypes/Object.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
}
});
}

Expand Down
57 changes: 57 additions & 0 deletions test/tests/js/components/DataTypes/Object-test.js
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -325,6 +326,7 @@ describe("<JsonObject />", function() {

expect(wrapper.state("expanded")).to.equal(true)
})

it("sort object keys", () => {
let src = {
d: 'd',
Expand Down Expand Up @@ -365,4 +367,59 @@ describe("<JsonObject />", 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(
<JsonObject
src={src}
theme="rjv-default"
namespace={["root"]}
onToggleCollapse={mockToggleCollapseCallback}
/>
)

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(
<JsonObject
src={src}
theme="rjv-default"
namespace={["root"]}
collapsed={false}
onToggleCollapse={mockToggleCollapseCallback}
/>
)

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)
})
})
})