Custom button for expand/collapse node in Tree

Summary: When clicking a node in the tree, currently it expands or collapses the subtree under it. This adds a chevron button which only handles the expansion functionality, and clicking on the label with the Section name will show info about that Section in the side panel.

Reviewed By: fabiomassimo

Differential Revision: D17165150

fbshipit-source-id: ac6b6c127b68274f53523b3ea62422ff96116e9b
This commit is contained in:
Mihaela Ogrezeanu
2019-09-04 10:49:05 -07:00
committed by Facebook Github Bot
parent 4f181cc2ea
commit d77b5f0062
2 changed files with 66 additions and 12 deletions

View File

@@ -7,7 +7,15 @@
import type {SectionComponentHierarchy} from './Models'; import type {SectionComponentHierarchy} from './Models';
import {PureComponent, styled, Toolbar, Spacer, colors} from 'flipper'; import {
Button,
Glyph,
PureComponent,
styled,
Toolbar,
Spacer,
colors,
} from 'flipper';
import {Tree} from 'react-d3-tree'; import {Tree} from 'react-d3-tree';
import {Fragment} from 'react'; import {Fragment} from 'react';
@@ -51,6 +59,17 @@ const Container = styled('div')({
'10px 10px,10px 10px,100px 100px,100px 100px,100px 100px,100px 100px,100px 100px,100px 100px', '10px 10px,10px 10px,100px 100px,100px 100px,100px 100px,100px 100px,100px 100px,100px 100px',
}); });
const LabelContainer = styled('div')({
display: 'flex',
});
const IconButton = styled('div')({
position: 'relative',
left: 5,
top: -8,
background: colors.white,
});
type TreeData = Array<{ type TreeData = Array<{
identifier: string, identifier: string,
name: string, name: string,
@@ -80,15 +99,47 @@ type State = {
zoom: number, zoom: number,
}; };
const NodeLabel = (props: { class NodeLabel extends PureComponent<Props, State> {
nodeData: { state = {
name: string, collapsed: false,
},
}) => {
const name = props?.nodeData?.name;
return <Label title={name}>{name}</Label>;
}; };
showNodeData = e => {
e.stopPropagation();
this.props.onLabelClicked(this.props?.nodeData);
};
toggleClicked = () => {
this.setState({
collapsed: !this.state.collapsed,
});
};
render() {
const name = this.props?.nodeData?.name;
const isSection = this.props?.nodeData?.attributes.isSection;
const chevron = this.state.collapsed ? 'chevron-right' : 'chevron-left';
return (
<LabelContainer>
<Label title={name} onClick={this.showNodeData}>
{name}
</Label>
{isSection && (
<IconButton onClick={this.toggleClicked}>
<Glyph
color={colors.blueGreyTint70}
name={chevron}
variant={'filled'}
size={12}
/>
</IconButton>
)}
</LabelContainer>
);
}
}
export default class extends PureComponent<Props, State> { export default class extends PureComponent<Props, State> {
treeFromFlatArray = (data: TreeData) => { treeFromFlatArray = (data: TreeData) => {
const tree = data.map(n => { const tree = data.map(n => {
@@ -214,7 +265,9 @@ export default class extends PureComponent<Props, State> {
zoom={this.state.zoom} zoom={this.state.zoom}
nodeLabelComponent={{ nodeLabelComponent={{
// $FlowFixMe props are passed in by react-d3-tree // $FlowFixMe props are passed in by react-d3-tree
render: <NodeLabel />, render: (
<NodeLabel onLabelClicked={this.props.nodeClickHandler} />
),
}} }}
allowForeignObjects allowForeignObjects
nodeSvgShape={{ nodeSvgShape={{
@@ -230,7 +283,6 @@ export default class extends PureComponent<Props, State> {
}, },
}} }}
nodeSize={{x: 300, y: 100}} nodeSize={{x: 300, y: 100}}
onClick={this.props.nodeClickHandler}
/> />
)} )}
</Container> </Container>

View File

@@ -172,8 +172,10 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
onNodeClicked = (targetNode: any, evt: InputEvent) => { onNodeClicked = (targetNode: any, evt: InputEvent) => {
if (targetNode.attributes.isSection) { if (targetNode.attributes.isSection) {
const sectionData = {};
sectionData['global_key'] = targetNode.attributes.identifier;
this.setState({ this.setState({
selectedTreeNode: null, selectedTreeNode: {sectionData},
}); });
return; return;
} }