Skip to content
This repository was archived by the owner on May 14, 2020. It is now read-only.

Commit 0f65000

Browse files
committed
recursive collapsing for huge collections
1 parent f98e568 commit 0f65000

File tree

11 files changed

+346
-275
lines changed

11 files changed

+346
-275
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"dependencies": {
5454
"babel-plugin-transform-runtime": "^6.5.0",
5555
"babel-runtime": "^6.3.13",
56-
"react-mixin": "^1.7.0"
56+
"react-mixin": "^1.7.0",
57+
"react-pure-render": "^1.0.2"
5758
}
5859
}

src/ItemRange.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React, { Component } from 'react';
2+
import shouldPureComponentUpdate from 'react-pure-render/function';
3+
import JSONArrow from './JSONArrow';
4+
5+
const STYLES = {
6+
itemRange: {
7+
margin: '8px 0 8px 14px',
8+
cursor: 'pointer'
9+
}
10+
};
11+
12+
13+
export default class ItemRange extends Component {
14+
constructor(props) {
15+
super(props);
16+
this.state = { expanded: false };
17+
18+
this.handleClick = this.handleClick.bind(this);
19+
}
20+
21+
static propTypes = {
22+
}
23+
24+
shouldComponentUpdate = shouldPureComponentUpdate;
25+
26+
render() {
27+
const { theme, styles, from, to, getChildNodes } = this.props;
28+
29+
return (this.state.expanded ?
30+
<div style={{ color: theme.base0D, ...styles.label }}>
31+
{getChildNodes(this.props, from, to)}
32+
</div> :
33+
<div style={{ color: theme.base0D, ...STYLES.itemRange, ...styles.label }}
34+
onClick={this.handleClick}>
35+
<JSONArrow
36+
theme={theme}
37+
open={false}
38+
onClick={this.handleClick}
39+
style={styles.getArrowStyle(false)}
40+
double />
41+
{`${from} ... ${to}`}
42+
</div>
43+
);
44+
}
45+
46+
handleClick() {
47+
this.setState({ expanded: !this.state.expanded });
48+
}
49+
}

src/JSONArrayNode.js

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,19 @@
11
import React from 'react';
22
import JSONNestedNode from './JSONNestedNode';
3-
import grabNode from './grab-node';
43

54
// Returns the "n Items" string for this node, generating and caching it if it hasn't been created yet.
6-
function renderItemString({
7-
data,
8-
getItemString,
9-
itemString,
10-
itemType
11-
}) {
12-
if (!itemString) {
13-
itemString = data.length + ' item' + (data.length !== 1 ? 's' : '');
14-
}
15-
return getItemString('Array', data, itemType, itemString);
16-
}
17-
18-
// Returns the child nodes for each entry in iterable.
19-
// If we have generated them previously we return from cache; otherwise we create them.
20-
function getChildNodes({
21-
data,
22-
getItemString,
23-
labelRenderer,
24-
previousData,
25-
styles,
26-
theme,
27-
valueRenderer,
28-
allExpanded,
29-
keyPath
30-
}) {
31-
const childNodes = [];
32-
data.forEach((value, key) => {
33-
let previousDataValue;
34-
if (typeof previousData !== 'undefined' && previousData !== null) {
35-
previousDataValue = previousData[key];
36-
}
37-
38-
const node = grabNode({
39-
getItemString,
40-
keyPath: [key, ...keyPath],
41-
labelRenderer,
42-
previousData: previousDataValue,
43-
renderItemString,
44-
styles,
45-
theme,
46-
value,
47-
valueRenderer,
48-
allExpanded
49-
});
50-
51-
if (node !== false) {
52-
childNodes.push(node);
53-
}
54-
});
55-
56-
return childNodes;
5+
function createItemString(data) {
6+
return `${data.length} ${data.length !== 1 ? 'items' : 'item'}`;
577
}
588

599
// Configures <JSONNestedNode> to render an Array
6010
export default function JSONArrayNode({ ...props }) {
6111
return (
6212
<JSONNestedNode
6313
{...props}
64-
getChildNodes={getChildNodes}
6514
nodeType='Array'
6615
nodeTypeIndicator='[]'
67-
renderItemString={renderItemString}
16+
createItemString={createItemString}
6817
/>
6918
);
7019
}

src/JSONArrow.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,39 @@ const styles = {
1010
transition: '150ms',
1111
WebkitTransition: '150ms',
1212
MozTransition: '150ms',
13+
WebkitTransform: 'rotateZ(-90deg)',
14+
MozTransform: 'rotateZ(-90deg)',
15+
transform: 'rotateZ(-90deg)',
16+
position: 'relative'
17+
},
18+
baseDouble: {
19+
marginRight: 10
20+
},
21+
arrow: {
1322
borderLeft: '5px solid transparent',
1423
borderRight: '5px solid transparent',
1524
borderTopWidth: 5,
16-
borderTopStyle: 'solid',
17-
WebkitTransform: 'rotateZ(-90deg)',
18-
MozTransform: 'rotateZ(-90deg)',
19-
transform: 'rotateZ(-90deg)'
25+
borderTopStyle: 'solid'
2026
},
2127
open: {
2228
WebkitTransform: 'rotateZ(0deg)',
2329
MozTransform: 'rotateZ(0deg)',
2430
transform: 'rotateZ(0deg)'
31+
},
32+
inner: {
33+
position: 'absolute',
34+
top: 0,
35+
left: -5
2536
}
2637
};
2738

2839
export default class JSONArrow extends React.Component {
2940
render() {
3041
let style = {
3142
...styles.base,
43+
...styles.arrow
44+
};
45+
const color = {
3246
borderTopColor: this.props.theme.base0D
3347
};
3448
if (this.props.open) {
@@ -37,10 +51,22 @@ export default class JSONArrow extends React.Component {
3751
...styles.open
3852
};
3953
}
54+
if (this.props.double) {
55+
style = {
56+
...style,
57+
...styles.baseDouble
58+
};
59+
}
4060
style = {
4161
...style,
4262
...this.props.style
4363
};
44-
return <div style={style} onClick={this.props.onClick}/>;
64+
return (
65+
<div style={{ ...color, ...style }} onClick={this.props.onClick}>
66+
{this.props.double &&
67+
<div style={{ ...color, ...styles.inner, ...styles.arrow }} />
68+
}
69+
</div>
70+
);
4571
}
4672
}

src/JSONIterableNode.js

Lines changed: 13 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,32 @@
11
import React from 'react';
22
import JSONNestedNode from './JSONNestedNode';
3-
import grabNode from './grab-node';
43

54
// Returns the "n Items" string for this node, generating and caching it if it hasn't been created yet.
6-
function renderItemString({
7-
data,
8-
getItemString,
9-
itemString,
10-
itemType
11-
}) {
12-
if (!itemString) {
13-
let count = 0;
14-
if (Number.isSafeInteger(data.size)) {
15-
count = data.size;
16-
} else {
17-
for (const entry of data) { // eslint-disable-line no-unused-vars
18-
count += 1;
5+
function createItemString(data, limit) {
6+
let count = 0;
7+
let hasMore = false;
8+
if (Number.isSafeInteger(data.size)) {
9+
count = data.size;
10+
} else {
11+
for (const entry of data) { // eslint-disable-line no-unused-vars
12+
if (limit && count + 1 > limit) {
13+
hasMore = true;
14+
break;
1915
}
16+
count += 1;
2017
}
21-
itemString = count + ' entr' + (count !== 1 ? 'ies' : 'y');
2218
}
23-
return getItemString('Iterable', data, itemType, itemString);
24-
}
25-
26-
// Returns the child nodes for each entry in iterable.
27-
// If we have generated them previously we return from cache; otherwise we create them.
28-
function getChildNodes({
29-
data,
30-
getItemString,
31-
labelRenderer,
32-
previousData,
33-
styles,
34-
theme,
35-
valueRenderer,
36-
allExpanded,
37-
keyPath
38-
}) {
39-
const childNodes = [];
40-
for (const entry of data) {
41-
let key = null;
42-
let value = null;
43-
if (Array.isArray(entry)) {
44-
[key, value] = entry;
45-
} else {
46-
key = childNodes.length;
47-
value = entry;
48-
}
49-
50-
let previousDataValue;
51-
if (typeof previousData !== 'undefined' && previousData !== null) {
52-
previousDataValue = previousData[key];
53-
}
54-
55-
const node = grabNode({
56-
getItemString,
57-
keyPath: [key, ...keyPath],
58-
labelRenderer,
59-
previousData: previousDataValue,
60-
styles,
61-
theme,
62-
value,
63-
valueRenderer,
64-
allExpanded
65-
});
66-
67-
if (node !== false) {
68-
childNodes.push(node);
69-
}
70-
}
71-
72-
return childNodes;
19+
return `${hasMore ? '>' : ''}${count} ${count !== 1 ? 'entries' : 'entry'}`;
7320
}
7421

7522
// Configures <JSONNestedNode> to render an iterable
7623
export default function({ ...props }) {
7724
return (
7825
<JSONNestedNode
7926
{...props}
80-
getChildNodes={getChildNodes}
8127
nodeType='Iterable'
8228
nodeTypeIndicator='()'
83-
renderItemString={renderItemString}
29+
createItemString={createItemString}
8430
/>
8531
);
8632
}

0 commit comments

Comments
 (0)