github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/dashboard/assets/components/SideBar.jsx (about)

     1  // @flow
     2  
     3  // Copyright 2017 The Spectrum Authors
     4  // This file is part of the Spectrum library.
     5  //
     6  // The Spectrum library is free software: you can redistribute it and/or modify
     7  // it under the terms of the GNU Lesser General Public License as published by
     8  // the Free Software Foundation, either version 3 of the License, or
     9  // (at your option) any later version.
    10  //
    11  // The Spectrum library is distributed in the hope that it will be useful,
    12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    14  // GNU Lesser General Public License for more details.
    15  //
    16  // You should have received a copy of the GNU Lesser General Public License
    17  // along with the Spectrum library. If not, see <http://www.gnu.org/licenses/>.
    18  
    19  import React, {Component} from 'react';
    20  
    21  import withStyles from 'material-ui/styles/withStyles';
    22  import List, {ListItem, ListItemIcon, ListItemText} from 'material-ui/List';
    23  import Icon from 'material-ui/Icon';
    24  import Transition from 'react-transition-group/Transition';
    25  import {Icon as FontAwesome} from 'react-fa';
    26  
    27  import {MENU, DURATION} from './Common';
    28  
    29  // menuDefault is the default style of the menu.
    30  const menuDefault = {
    31  	transition: `margin-left ${DURATION}ms`,
    32  };
    33  // menuTransition is the additional style of the menu corresponding to the transition's state.
    34  const menuTransition = {
    35  	entered: {marginLeft: -200},
    36  };
    37  // Styles for the SideBar component.
    38  const styles = theme => ({
    39  	list: {
    40  		background: theme.palette.background.appBar,
    41  	},
    42  	listItem: {
    43  		minWidth: theme.spacing.unit * 3,
    44  	},
    45  	icon: {
    46  		fontSize: theme.spacing.unit * 3,
    47  	},
    48  });
    49  export type Props = {
    50  	classes: Object,
    51  	opened: boolean,
    52  	changeContent: () => {},
    53  };
    54  // SideBar renders the sidebar of the dashboard.
    55  class SideBar extends Component<Props> {
    56  	constructor(props) {
    57  		super(props);
    58  
    59  		// clickOn contains onClick event functions for the menu items.
    60  		// Instantiate only once, and reuse the existing functions to prevent the creation of
    61  		// new function instances every time the render method is triggered.
    62  		this.clickOn = {};
    63  		MENU.forEach((menu) => {
    64  			this.clickOn[menu.id] = (event) => {
    65  				event.preventDefault();
    66  				props.changeContent(menu.id);
    67  			};
    68  		});
    69  	}
    70  
    71  	shouldComponentUpdate(nextProps) {
    72  		return nextProps.opened !== this.props.opened;
    73  	}
    74  
    75  	menuItems = (transitionState) => {
    76  		const {classes} = this.props;
    77  		const children = [];
    78  		MENU.forEach((menu) => {
    79  			children.push(
    80  				<ListItem button key={menu.id} onClick={this.clickOn[menu.id]} className={classes.listItem}>
    81  					<ListItemIcon>
    82  						<Icon className={classes.icon}>
    83  							<FontAwesome name={menu.icon} />
    84  						</Icon>
    85  					</ListItemIcon>
    86  					<ListItemText
    87  						primary={menu.title}
    88  						style={{
    89  							...menuDefault,
    90  							...menuTransition[transitionState],
    91  							padding: 0,
    92  						}}
    93  					/>
    94  				</ListItem>,
    95  			);
    96  		});
    97  		return children;
    98  	};
    99  
   100  	// menu renders the list of the menu items.
   101  	menu = (transitionState) => {
   102  		const {classes} = this.props; // The classes property is injected by withStyles().
   103  
   104  		return (
   105  			<div className={classes.list}>
   106  				<List>
   107  					{this.menuItems(transitionState)}
   108  				</List>
   109  			</div>
   110  		);
   111  	};
   112  
   113  	render() {
   114  		return (
   115  			<Transition mountOnEnter in={this.props.opened} timeout={{enter: DURATION}}>
   116  				{this.menu}
   117  			</Transition>
   118  		);
   119  	}
   120  }
   121  
   122  export default withStyles(styles)(SideBar);