Skip to content

Commit ea120fe

Browse files
committed
feat(storybook): add stories for both tree implementations
1 parent 6f817a0 commit ea120fe

File tree

4 files changed

+321
-140
lines changed

4 files changed

+321
-140
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import {number, withKnobs} from '@storybook/addon-knobs';
2+
import {storiesOf} from '@storybook/react';
3+
import * as React from 'react';
4+
import AutoSizer from 'react-virtualized-auto-sizer';
5+
import Tree from '../src/FixedSizeTree';
6+
import {CommonNodeComponentProps, CommonNodeMetadata} from '../src/utils';
7+
8+
document.body.style.margin = '0';
9+
document.body.style.display = 'flex';
10+
11+
const root = document.getElementById('root')!;
12+
root.style.margin = '10px 0 0 10px';
13+
root.style.flex = '1';
14+
15+
interface DataNode {
16+
children: DataNode[];
17+
id: number;
18+
name: string;
19+
}
20+
21+
interface StackElement {
22+
nestingLevel: number;
23+
node: DataNode;
24+
}
25+
26+
let nodeId = 0;
27+
28+
const createNode = (depth: number = 0) => {
29+
const node: DataNode = {
30+
children: [],
31+
id: nodeId,
32+
name: `test-${nodeId}`,
33+
};
34+
35+
nodeId += 1;
36+
37+
if (depth === 5) {
38+
return node;
39+
}
40+
41+
// tslint:disable-next-line:increment-decrement
42+
for (let i = 0; i < 5; i++) {
43+
node.children.push(createNode(depth + 1));
44+
}
45+
46+
return node;
47+
};
48+
49+
const rootNode = createNode();
50+
const defaultTextStyle = {marginLeft: 10};
51+
const defaultButtonStyle = {fontFamily: 'Courier New'};
52+
53+
function* treeWalker(
54+
refresh: boolean,
55+
): IterableIterator<CommonNodeMetadata | string | symbol | null> {
56+
const stack: StackElement[] = [];
57+
58+
stack.push({
59+
nestingLevel: 0,
60+
node: rootNode,
61+
});
62+
63+
while (stack.length !== 0) {
64+
const {node, nestingLevel} = stack.pop()!;
65+
const id = node.id.toString();
66+
67+
const isOpened = yield refresh
68+
? {
69+
childrenCount: node.children.length,
70+
data: node.name,
71+
id,
72+
isOpenByDefault: true,
73+
nestingLevel,
74+
}
75+
: id;
76+
77+
if (node.children.length !== 0 && isOpened) {
78+
// tslint:disable-next-line:increment-decrement
79+
for (let i = node.children.length - 1; i >= 0; i--) {
80+
stack.push({
81+
nestingLevel: nestingLevel + 1,
82+
node: node.children[i],
83+
});
84+
}
85+
}
86+
}
87+
}
88+
89+
const Node: React.FunctionComponent<CommonNodeComponentProps> = ({
90+
metadata: {childrenCount, data, nestingLevel},
91+
isOpen,
92+
style,
93+
toggle,
94+
}) => {
95+
const isLeaf = childrenCount === 0;
96+
97+
return (
98+
<div
99+
style={{
100+
...style,
101+
alignItems: 'center',
102+
display: 'flex',
103+
marginLeft: nestingLevel * 30 + (isLeaf ? 48 : 0),
104+
}}
105+
>
106+
{!isLeaf && (
107+
<div>
108+
<button type="button" onClick={toggle} style={defaultButtonStyle}>
109+
{isOpen ? '-' : '+'}
110+
</button>
111+
</div>
112+
)}
113+
<div style={defaultTextStyle}>{data}</div>
114+
</div>
115+
);
116+
};
117+
118+
interface TreePresenterProps {
119+
readonly itemSize: number;
120+
}
121+
122+
const TreePresenter: React.FunctionComponent<TreePresenterProps> = ({
123+
itemSize,
124+
}) => (
125+
<AutoSizer disableWidth>
126+
{({height}) => (
127+
<Tree
128+
treeWalker={treeWalker}
129+
itemSize={itemSize}
130+
height={height}
131+
width="100%"
132+
>
133+
{Node}
134+
</Tree>
135+
)}
136+
</AutoSizer>
137+
);
138+
139+
storiesOf('Tree', module)
140+
.addDecorator(withKnobs)
141+
.add('FixedSizeTree', () => (
142+
<TreePresenter itemSize={number('Row height', 30)} />
143+
));

__stories__/Tree.tsx

Lines changed: 0 additions & 140 deletions
This file was deleted.

0 commit comments

Comments
 (0)