React
by Pratik Galoria
HTML
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css">
<div id="app"></div>
SCSS
body {
padding: 10px;
font-family: Helvetica;
}
#app {
background: #2d2d3a;
border-radius: 6px;
padding: 20px 0;
}
ul {
margin-left: 20px;
}
li {
color: #fff;
margin: 8px 0;
> i {
color: #57626e;
font-size: 20px;
}
> span {
padding: 0 10px;
}
}
React
class Treeview extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<ul>
{this.props.data.map(node => <TreeNode node={node} />)}
</ul>
)
}
}
class TreeNode extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
isCollapsed: true,
};
}
handleClick(e) {
e.stopPropagation();
this.setState((state, props) => ({
isCollapsed: !state.isCollapsed,
}));
}
render() {
const {isCollapsed} = this.state;
const {node} = this.props;
return (
<li key={node.value} onClick={this.handleClick}>
<i className={isCollapsed ? `fas fa-plus-square` : `fas fa-minus-square`} />
<span>{node.value} {node.items && `(${node.items.length})`}</span>
{node.items && (
<ul style={{display: isCollapsed ? 'none' : 'block'}}>
{node.items.map(item => <TreeNode node={item} />)}
</ul>
)}
</li>
);
}
}
// API response
const data = [
{
value: 'GN0001',
items: [
{
value: 'Channel1',
items: [
{value: 'Sub1'},
{
value: 'Sub2',
items: [
{
value: 'Step'
},
],
},
],
},
{value: 'Channel2'},
]
}
];
ReactDOM.render(<Treeview data={data} />, document.querySelector("#app"))