Skip to content

Commit aa90b29

Browse files
committed
Add family tree example to storybook
1 parent cccc049 commit aa90b29

File tree

5 files changed

+312
-0
lines changed

5 files changed

+312
-0
lines changed

storybook/FamilyTree/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Family Tree
2+
3+
This entire example is inspired on [this blog post](https://jwcooney.com/2016/08/21/example-pure-css-family-tree-markup/) by Justin Cooney. The entire credit on the tree markup, styles and even the family data goes to him.

storybook/FamilyTree/data.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
export const familyTree = [
2+
{
3+
id: '1',
4+
he: {
5+
name: 'Joe Mighty',
6+
born: 1601,
7+
died: 1681,
8+
},
9+
},
10+
{
11+
id: '2',
12+
she: {
13+
name: 'Sue Mighty',
14+
born: 1607,
15+
died: 1685,
16+
},
17+
he: {
18+
name: 'Jim Snow',
19+
born: 1633,
20+
died: 1697,
21+
},
22+
children: [
23+
{
24+
id: '3',
25+
she: {
26+
name: 'Lily Sight',
27+
born: 1633,
28+
died: 1697,
29+
},
30+
he: {
31+
name: 'Sam Snow',
32+
born: 1631,
33+
died: 1695,
34+
},
35+
children: [
36+
{
37+
id: '4',
38+
he: {
39+
name: 'Ralf Snow',
40+
born: 1651,
41+
},
42+
},
43+
{
44+
id: '5',
45+
she: {
46+
name: 'Brie Snow',
47+
born: 1653,
48+
},
49+
},
50+
],
51+
},
52+
{
53+
id: '6',
54+
she: {
55+
name: 'Zoe Blue',
56+
born: 1633,
57+
died: 1697,
58+
},
59+
he: {
60+
name: 'Jim Snow',
61+
born: 1633,
62+
died: 1697,
63+
},
64+
children: [
65+
{
66+
id: '7',
67+
she: {
68+
name: 'Sally Bern',
69+
born: 1653,
70+
},
71+
he: {
72+
name: 'Ralf Snow',
73+
born: 1651,
74+
},
75+
children: [
76+
{
77+
id: '8',
78+
she: {
79+
name: 'Magna Snow',
80+
born: 1697,
81+
},
82+
},
83+
],
84+
},
85+
{
86+
id: '9',
87+
she: {
88+
name: 'Brie Snow',
89+
born: 1653,
90+
},
91+
},
92+
],
93+
},
94+
{
95+
id: '10',
96+
he: {
97+
name: 'John Snow',
98+
born: 1635,
99+
died: 1699,
100+
},
101+
},
102+
],
103+
},
104+
];

storybook/FamilyTree/index.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import Treefold from '../../src';
3+
import './styles.css';
4+
import { familyTree } from './data';
5+
6+
const renderPerson = ({ name, born, died }, gender) => (
7+
<span className={gender}>
8+
{name}
9+
<br />
10+
{born} - {died}
11+
</span>
12+
);
13+
14+
const FamilyTree = () => (
15+
<div className="tree">
16+
<ul>
17+
<Treefold
18+
nodes={familyTree}
19+
renderNode={({
20+
node,
21+
isFolder,
22+
isExpanded,
23+
getToggleProps,
24+
renderChildNodes,
25+
}) => (
26+
<li>
27+
<div
28+
className={isFolder ? 'non-leaf' : 'leaf'}
29+
{...(isFolder ? getToggleProps() : {})}
30+
>
31+
{node.he && renderPerson(node.he, 'male')}
32+
{node.he && node.she && <span className="spacer" />}
33+
{node.she && renderPerson(node.she, 'female')}
34+
</div>
35+
{isExpanded && <ul>{renderChildNodes()}</ul>}
36+
</li>
37+
)}
38+
/>
39+
</ul>
40+
</div>
41+
);
42+
43+
export default FamilyTree;

storybook/FamilyTree/styles.css

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
* {
2+
margin: 0;
3+
padding: 0;
4+
font-family: sans-serif, Arial;
5+
font-size: 10pt;
6+
}
7+
8+
.tree {
9+
white-space: nowrap;
10+
min-width: 800px;
11+
min-height: 500px;
12+
}
13+
14+
.tree ul {
15+
padding-top: 20px;
16+
position: relative;
17+
transition: all 0.5s;
18+
-webkit-transition: all 0.5s;
19+
-moz-transition: all 0.5s;
20+
}
21+
22+
.tree li {
23+
float: left;
24+
text-align: center;
25+
list-style-type: none;
26+
position: relative;
27+
padding: 20px 5px 0 5px;
28+
transition: all 0.5s;
29+
-webkit-transition: all 0.5s;
30+
-moz-transition: all 0.5s;
31+
}
32+
33+
/*We will use ::before and ::after to draw the connectors*/
34+
.tree li::before,
35+
.tree li::after {
36+
content: '';
37+
position: absolute;
38+
top: 0;
39+
right: 50%;
40+
border-top: 1px solid #ccc;
41+
width: 50%;
42+
height: 20px;
43+
}
44+
45+
.tree li::after {
46+
right: auto;
47+
left: 50%;
48+
border-left: 1px solid #ccc;
49+
}
50+
51+
/*We need to remove left-right connectors from elements without any siblings*/
52+
.tree li:only-child::after,
53+
.tree li:only-child::before {
54+
display: none;
55+
}
56+
57+
/*Remove space from the top of single children*/
58+
.tree li:only-child {
59+
padding-top: 0;
60+
}
61+
62+
/*Remove left connector from first child and right connector from last child*/
63+
.tree li:first-child::before,
64+
.tree li:last-child::after {
65+
border: 0 none;
66+
}
67+
68+
/*Adding back the vertical connector to the last nodes*/
69+
.tree li:last-child::before {
70+
border-right: 1px solid #ccc;
71+
border-radius: 0 5px 0 0;
72+
-webkit-border-radius: 0 5px 0 0;
73+
-moz-border-radius: 0 5px 0 0;
74+
}
75+
76+
.tree li:first-child::after {
77+
border-radius: 5px 0 0 0;
78+
-webkit-border-radius: 5px 0 0 0;
79+
-moz-border-radius: 5px 0 0 0;
80+
}
81+
82+
/*Time to add downward connectors from parents*/
83+
.tree ul ul::before {
84+
content: '';
85+
position: absolute;
86+
top: 0;
87+
left: 50%;
88+
border-left: 1px solid #ccc;
89+
width: 0;
90+
height: 20px;
91+
}
92+
93+
.tree li div {
94+
border: 1px solid #ccc;
95+
padding: 5px 10px;
96+
text-decoration: none;
97+
color: #666;
98+
font-family: arial, verdana, tahoma;
99+
font-size: 11px;
100+
display: inline-block;
101+
min-width: 80px;
102+
min-height: 30px;
103+
border-radius: 5px;
104+
-webkit-border-radius: 5px;
105+
-moz-border-radius: 5px;
106+
transition: all 0.5s;
107+
-webkit-transition: all 0.5s;
108+
-moz-transition: all 0.5s;
109+
}
110+
111+
.tree li div .male {
112+
background-color: lightblue;
113+
display: inline-block;
114+
width: 90px;
115+
padding: 10px;
116+
border-radius: 5px;
117+
-webkit-border-radius: 5px;
118+
-moz-border-radius: 5px;
119+
}
120+
121+
.tree li div .female {
122+
background-color: lightpink;
123+
display: inline-block;
124+
width: 90px;
125+
padding: 10px;
126+
border-radius: 5px;
127+
-webkit-border-radius: 5px;
128+
-moz-border-radius: 5px;
129+
}
130+
131+
.tree li div .spacer {
132+
background-color: lightblue;
133+
display: inline-block;
134+
width: 10px;
135+
}
136+
137+
.tree li div.leaf {
138+
cursor: default;
139+
}
140+
141+
.tree li div.non-leaf {
142+
cursor: pointer;
143+
}
144+
145+
/*Time for some hover effects*/
146+
/*We will apply the hover effect to the lineage of the element also*/
147+
.tree li div.non-leaf:hover,
148+
.tree li div.non-leaf:hover + ul li div {
149+
background: #c8e4f8;
150+
color: #000;
151+
border: 1px solid #94a0b4;
152+
}
153+
154+
/*Connector styles on hover*/
155+
.tree li div.non-leaf:hover + ul li::after,
156+
.tree li div.non-leaf:hover + ul li::before,
157+
.tree li div.non-leaf:hover + ul::before,
158+
.tree li div.non-leaf:hover + ul ul::before {
159+
border-color: #94a0b4;
160+
}

storybook/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import { SingleSelection } from './utils';
77
import Table from './Table';
88
import UnorderedList from './UnorderedList';
99
import Selector from './Selector';
10+
import FamilyTree from './FamilyTree';
1011

1112
storiesOf('Treefold', module)
13+
.add('family tree', () => <FamilyTree />)
1214
.add('controlled', () => (
1315
<ToggleController>
1416
{({ isOn, onToggle }) => (

0 commit comments

Comments
 (0)