Material UI - tooltip displays unexpectedly - javascript

I use material-ui with react in my project. What I want to do is to simply change the tooltip (each tooltip contains an Icon) when certain condition is met.
ToolTipWrapper.js
import React from "react";
import { Tooltip } from "#material-ui/core";
import { CheckCircle, Error } from "#material-ui/icons";
import { green, deepOrange } from "#material-ui/core/colors";
class TooltipWrapper extends React.Component {
render() {
return this.props.error.length === 0 ? (
<Tooltip title="meet all requirements" placement="bottom-start">
<CheckCircle style={{ color: green[400] }} />
</Tooltip>
) : (
<Tooltip title="Not meet all requirements" placement="bottom-start">
<Error style={{ color: deepOrange[400] }} />
</Tooltip>
);
}
}
export default TooltipWrapper;
index.js
import React from "react";
import { render } from "react-dom";
import TooltipWrapper from "./TooltipWrapper.js";
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
error: []
};
}
handleClick = () => {
this.setState({
error: [123]
});
};
render() {
return (
<div style={styles}>
<TooltipWrapper error={this.state.error} />
<button onClick={this.handleClick}>change</button>
</div>
);
}
}
render(<App />, document.getElementById("root"));
Please check this demo in codesandbox:demo link
Now the problem is that the second tooltip will not show as expected after changing from the first tooltip by clicking the button. The position of the second tooltip magically moved to the top left, which is quite strange.
Thanks for your help.

try this.
import React from "react";
import { Tooltip } from "#material-ui/core";
import { CheckCircle, Error } from "#material-ui/icons";
import { green, deepOrange } from "#material-ui/core/colors";
class TooltipWrapper extends React.Component {
render() {
return (
<Tooltip
title={
this.props.error.length === 0
? "meet all requirements"
: "Not meet all requirements"
}
placement="bottom-start"
id="test"
>
<span>
{this.props.error.length === 0 ? (
<CheckCircle style={{ color: green[400] }} aria-label="test" />
) : (
<Error style={{ color: deepOrange[400] }} aria-label="test" />
)}
</span>
</Tooltip>
);
}
}
export default TooltipWrapper;
working sandbox version.
https://codesandbox.io/s/w2zkn847m5

Related

ERROR: Touchable child must either be native or forward setNativeProps to a native component

I am currently doing ReactNative course from coursera and the course is 4 years old and i am facing this error: Touchable child must either be native or forward setNativeProps to a native component.
I've no idea what this is. It will be greatly helpful if someone will help me.Adding files details as well:
App.js
import React from 'react';
import Main from './components/MainComponent';
export default class App extends React.Component {
render() {
return (
<Main />
);
}
}
MainComponent.js
import React, { Component } from 'react';
import Menu from './MenuComponent';
import { DISHES } from '../shared/dishes';
import Dishdetail from './DishdetailComponent';
import { View } from 'react-native';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
dishes: DISHES,
selectedDish: null,
};
}
onDishSelect(dishId) {
this.setState({selectedDish: dishId})
}
render() {
return (
<View style={{flex:1}}>
<Menu dishes={this.state.dishes} onPress={(dishId) => this.onDishSelect(dishId)} />
<Dishdetail dish={this.state.dishes.filter((dish) => dish.id === this.state.selectedDish)[0]} />
</View>
);
}
}
export default Main;
MenuComponent.js
import React from 'react';
import { View, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
function Menu(props) {
const renderMenuItem = ({item, index}) => {
return (
<View>
<ListItem
key={index}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
</View>
);
};
return (
<View>
<FlatList
data={props.dishes}
renderItem={renderMenuItem}
keyExtractor={item => item.id.toString()}
/>
</View>
);
}
export default Menu;
Dishdetailcomponent.js
import React from 'react';
import { Text, View } from 'react-native';
import { Card } from 'react-native-elements';
function Dishdetail(props) {
return(
<View >
<RenderDish dish={props.dish} />
</View>
);
}
function RenderDish(props) {
const dish = props.dish;
if (dish != null) {
return(
<View>
<Card
featuredTitle={dish.name}
image={require('./images/uthappizza.png')}>
<Text style={{margin: 10}}>
{dish.description}
</Text>
</Card>
</View>
);
}
else {
return(<View></View>);
}
}
export default Dishdetail;
Help will be appreciated!!
Thanks
I had same issue some days before. Quickfix for this issue.
import TouchableOpacity form 'react-native';
Add following in the MenuComponent.js
<ListItem
Component={TouchableOpacity}
key={item.id}
title={item.name}
subtitle={item.description}
hideChevron={true}
onPress={() => props.onPress(item.id)}
leftAvatar={{ source: require('./images/uthappizza.png')}}
/>
and run the program again. This will fix your problem.

React: ProgressiveMobileStepper handleNext function does not work (Material UI)

Dear community I am currently writing a website and its user onboarding using the ProrgressiveMobileStepper using Material UI. You can find my website here:
https://konekto-eeioq6hwh.now.sh/first_use
Apart from the formatting being screwed up (for which I would also appreciate your help), I am mainly concerned that the next button does not work. I have structured that the several screens are conditionally rendered in index.js depending on the state and the handleNext function should be called from ProgressiveMobileStepper when the button is clicked. However, the screen does not update then.
index.js file:
import React from 'react';
import { Grid, Container } from '#material-ui/core';
import { Header } from '../Layout';
import logo from './android-icon-192x192.png';
import { withStyles } from '#material-ui/core/styles';
import ExplanationAboutProcess0 from './Explanation0';
import ExplanationAboutProcess1 from './ExplanationProcess1';
import ExplanationAboutProcess2 from './ExplanationProcess2';
import ExplanationAboutProcess3 from './ExplanationProcess3';
import ProgressiveMobileStepper from './ProgressiveMobileStepper';
const styles = theme => ({
container: {
alignItems: 'center',
border: 'black',
'border-width': 'medium',
'margin-top': '80px',
background: 'rgba(255, 255, 255, 0.8)',
'border-radius': '20px'
},
picture: { display: 'block', margin: '0 auto' },
box: { width: '230px' }
});
class FirstUse extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {
componentType: 'explanationaboutprocess0'
};
this.handleNext = this.handleNext.bind(this);
this.handleBack = this.handleBack.bind(this);
}
fun() {
//this.props.history.push('/settings');
}
handleNext(e) {
console.log(e);
console.log(this.componentType);
if (this.componentType == 'explanationaboutprocess0')
this.setState({ componentType: 'explanationaboutprocess1' });
}
handleBack(e) {
console.log(e);
if (this.componentType == 'explanationaboutprocess1')
this.setState({ componentType: 'explanationaboutprocess0' });
}
render() {
let component;
if (this.state.componentType == 'explanationaboutprocess0') {
component = (
<ExplanationAboutProcess0
handleNext={this.handleNext}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess1') {
component = (
<ExplanationAboutProcess1
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess2') {
component = (
<ExplanationAboutProcess2
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
} else if (this.state.componentType == 'explanationaboutprocess3') {
component = (
<ExplanationAboutProcess3
handleComponentType={this.handleComponentType}
handleBack={this.handleBack}
/>
);
}
return (
<React.Fragment>
<Header title="Learn how to send SOS" />
<Grid
container
className={this.classes.container}
direction="column"
spacing={2}
>
<Grid item sm={12} className={this.classes.item}>
<img src={logo} alt="Logo" />
</Grid>
<Grid item sm={12} className={this.classes.item} />
<Container component="main" maxWidth="sm">
{component}
</Container>
</Grid>
<Grid item sm={12} className={this.classes.item}>
<ProgressiveMobileStepper />
</Grid>
</React.Fragment>
);
}
}
export default withStyles(styles)(FirstUse);
ProgressiveMobileStepper.js file:
import React from 'react';
import { makeStyles, useTheme } from '#material-ui/core/styles';
import MobileStepper from '#material-ui/core/MobileStepper';
import Button from '#material-ui/core/Button';
import KeyboardArrowLeft from '#material-ui/icons/KeyboardArrowLeft';
import KeyboardArrowRight from '#material-ui/icons/KeyboardArrowRight';
const useStyles = makeStyles({
root: {
maxWidth: 400,
flexGrow: 1
}
});
export default function ProgressMobileStepper(props) {
const classes = useStyles();
const theme = useTheme();
const [activeStep, setActiveStep] = React.useState(0);
return (
<MobileStepper
variant="progress"
steps={6}
position="static"
className={classes.root}
nextButton={
<Button
size="small"
onClick={props.handleNext}
disabled={activeStep === 5}
>
Next
{theme.direction === 'rtl' ? (
<KeyboardArrowLeft />
) : (
<KeyboardArrowRight />
)}
</Button>
}
backButton={
<Button
size="small"
onClick={props.handleBack}
disabled={activeStep === 0}
>
{theme.direction === 'rtl' ? (
<KeyboardArrowRight />
) : (
<KeyboardArrowLeft />
)}
Back }
</Button>
}
/>
);
}
Just as an example, you can see two of the screens, which should be conditionally rendered below:
Explanation0.js file:
import React from 'react';
import { Typography } from '#material-ui/core';
export default class ExplanationAboutProcess1 extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {};
}
render() {
return (
<React.Fragment>
<Typography>
Konnekto allows you to send an emergency request from you phone
without requiring a celluar connection. Please enter your personal
information.
</Typography>
</React.Fragment>
);
}
}
ExplanationProcess1.js file:
import React from 'react';
export default class ExplanationAboutProcess1 extends React.Component {
constructor(props) {
super(props);
this.classes = props.classes;
this.state = {};
}
render() {
return (
<React.Fragment>
<p>
To explain you how you would use the app in case of emergency, we
guide you through which questions we ask you:
<br />
0.1 Are you affected yourself?
<br />
0.2 How do you want to contact?
</p>
</React.Fragment>
);
}
}
I would really appreciate your help!

How to use HOC to assign a value to a component in react?

I'm trying to make an HOC that assign values to the parameter "color" in an icon component in React js.
I have 3 different colors. They come as follow :
pimary is #f7a014
secondary is #dd8b08
ternary is #56t00
So I can do :
<MyComponent color='primary' />
Here is my withColor HOC :
import React from 'react';
import propTypes from 'prop-types';
function mapColors(color) {
if (color === 'primary') {
return '#f8af39';
}
if (color === 'secondary') {
return '#fff';
}
if (color === 'ternary') {
return '#004c64';
}}
export const withColor = WrappedComponent => {
const NewComponent = ({ color, ...props }) => (
<WrappedComponent color={mapColors(color)} {...props} />
);
NewComponent.propTypes = {
color: propTypes.oneOf(['primary', 'secondary', 'ternary']),
};
return NewComponent;
};
export default withColor;
Here is my component with the icon in it :
import React from 'react';
import { RequestCloseModal } from 'HOC/connectModals';
import { compose } from 'redux';
import {
Collapse,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
} from 'reactstrap';
import { ChevronDown, ChevronUp } from 'react-feather';
import PropTypes from 'prop-types';
import Industrie from 'components/Icons/Industrie';
import FinancerContainer from 'backoffice/containers/Financer/FinancerContainer';
import withContainer from 'HOC/withContainer';
import withColor from 'HOC/WithColor';
class FinancerMatchingDetails extends RequestCloseModal {
static propTypes = {
isOpen: PropTypes.bool,
};
constructor(props) {
super(props);
this.state = {
collapse: false,
};
}
toggle = () => {
this.setState({ collapse: !this.state.collapse });
};
render() {
const { isOpen } = this.props;
return (
<Modal size="xxl" isOpen={isOpen} toggle={this.close}>
<ModalHeader toggle={this.close}>
<div className="col-md-3">
<h4>Some text</h4>
<p>Some text</p>
</div>
</div>
</div>
<div>
<h4>Some text</h4>
{this.state.collapse ? (
<ChevronUp height={20} onClick={this.toggle} />
) : (
<ChevronDown height={20} onClick={this.toggle} />
)}
</div>
</ModalBody>
<ModalFooter>
<div className="container">
<Collapse isOpen={this.state.collapse}>
<div className="row">
<div className="col">
<MyIcon color="primary" />
</div>
</Collapse>
</div>
</ModalFooter>
</Modal>
);
}
}
export default compose(withContainer(FinancerContainer), withColor)(
FinancerMatchingDetails,
);
I'm new to HOC and can't make it to assign the color primary. Thanks for your help.
You defined HOC but never pass any components through it.
E.g.
import withColor from 'HOC/WithColor'; // your HOC
import SomeComponent from 'SomeComponent'; // component that you would like to use with HOC
then you need to define a component that is the result of HOC applied to your component:
const ColoredComponent = withColor(SomeComponent);
and then you can use it as you expected:
<ColoredComponent color="primary" />

Changing the url in React/Redux

I'm trying to build an app with React and Redux (DVA). It's using Ant.Design as the main framework. I'm trying to change the URL when the user clicks on a button, and obviously 'bind' that url change to an action, so that if the user goes directly to that URL, he gets what he wants.
At the moment here's what I have, in a function in my component.
const { dispatch, match } = this.props;
dispatch(routerRedux.push('/f/' + record.id));
This is the only thing that I was able to produce. It correctly changes the url, but doesn't bind the url with a specific behaviour, making it completely useless.
How do I link the URL with an action?
If you wish to trigger an action based on a URL, you'll need to use react-router to route a component that then performs the desired action. In such a case it is also a good idea to then visit a different URL, erasing the action-URL from the browser's history.
A typical router definition might look something like this (taken from react-router-redux's docs):
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/success" component={Success}/>
</div>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
)
So you wish to add a path /f/<record-id>. You can do this by adding a line like this:
<Route path="/f/:recordId" component={MyActionComponent}/>
Now you need to define a component, MyActionComponent, that will perform your action.
import { connect } from 'react-redux';
import { replace } from 'react-router-redux';
const mapDispatchToProps = (dispatch: Dispatch) => ({
visitNextLocation: () => dispatch(replace('/success')),
myAction: (recordId) => dispatch(myAction(recordId)),
});
const withDispatch = connect(null, mapDispatchToProps);
class MyActionComponent extends Component {
props: {
match: {
params: {
recordId: string,
}
},
redirectToLogin: () => void,
myAction: string => void,
};
componentWillMount() {
const recordId = this.props.match.params.recordId;
if (recordId) {
this.props.myAction(token);
this.props.visitNextLocation();
}
}
render() {
return null;
}
}
Note the use of replace instead of push. This means, when a user visits this URL their action will get performed and they'll end up on /success. But if they click the Back button, they won't then revisit this URL and run the action again.
I can't put the code on Codepen for privacy reasons. But here's an extract:
router.js
...
},
'/users': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
'/f/:userID': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
...
users.js (the main component that contains LeftPanel and RightPanel)
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Card, List, Divider, Badge, Select, Radio, Input, Popover, Button, Table, Spin } from 'antd';
import RightPanel from './RightPanel';
import LeftPanel from './LeftPanel';
import { routerRedux, Route, Switch } from 'dva/router';
import 'font-awesome/css/font-awesome.min.css';
import FadeIn from 'react-fade-in';
#connect(({ rule, loading }) => ({rule, loading: loading.models.rule }))
export default class Users extends React.Component {
constructor(props) {
super(props)
this.state = {
selected_user: [],
defaultView: true,
isLoadingNow: false,
selectedRowKeys: [],
makeEmpty: false,
searchRes: []
}
}
selectRow = (record) => {
const { dispatch, match } = this.props;
dispatch(routerRedux.replace({ pathname: '/f/' + record.id }));
this.setState({isLoadingNow: true, selectedRowKeys: record.key})
setTimeout(() => {
this.setState({
isLoadingNow: false,
defaultView: false,
selected_user: record
})
}, 75)
}
componentDidMount() {
const { dispatch, match } = this.props;
dispatch({
type: 'rule/fetch'
});
if (match.params.userID == undefined) {
// do nothing
} else if (match.params.userID) {
var result = this.props.rule.data.list.filter(function( obj ) {
return obj.id == match.params.userID;
});
this.selectRow.bind(this, result[0])
}
}
render() {
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
type:"radio"
};
const { rule: { data }, loading } = this.props;
return (<div>
<LeftPanel
rowSelection={rowSelection}
dataSource={this.state.makeEmpty ? this.state.searchRes : this.props.rule.data.list}
selectRow={this.selectRow}
loadingStatus={loading}
/>
<RightPanel
selected_user={this.state.selected_user}
is_default={this.state.defaultView}
loading={this.state.isLoadingNow}
/>
</div>);
}
}
leftPanel.js (responsible for displaying the list of links, on which the user will click on one, which will do 2 things:
- change the url accordingly
- display specific data on RightPanel.js)
import React from 'react';
import { Table, Card } from 'antd';
import styles from './index.less';
// import 'font-awesome/css/font-awesome.min.css';
import { Row, Col, List, Divider, Badge, Select, Radio, Input, Popover, Button } from 'antd';
var moment = require('moment');
class LeftPanel extends React.Component {
constructor(props) {
super(props)
this.state = {
selected_row_index: undefined
}
}
handleChangeStyleOnSelectRow(index) {
this.setState({
selected_row_index: index
}, console.log(this.state.selected_row_index))
}
prettifyForTable(raw_data) {
var prettyRows = [];
raw_data.map((item,index) =>
prettyRows.push(
<div style={{"width": "100%"}}>
<Row style={{ "align-items": "center"}} type="flex" justify="space-between">
<Col span={10}>
<div style={{"font-size": "15px", "text-align": "center"}}>
{item.user_name} <i style={{"color": "rgba(0, 0, 0, 0.25)", "margin": "0 10px", "transform": "rotate(45deg)"}} className="fa fa-plane"> </i> {item.user_age}
<div style={{"font-size": "12px", "color": "grey"}}> {moment(item.user_color).format('HH:MM')} · {moment(item.user_order).format('HH:MM')} </div>
</div>
</Col>
<Col span={3}>
<div style={{"text-align": "right", "text-align": "center"}}>
{item.user_family}
</div>
</Col>
<Col span={6}>
<div style={{"text-align": "right", "text-align": "center"}}>
{moment(item.user_height).format('MMMM D')}
</div>
</Col>
<Col span={3}>
<div style={{"text-align": "center"}}>
{(item.status == "in_progress") ? <div> <Badge style={{"padding-right": "25px"}} status="processing"/></div> : <div style={{"text-align": "center"}}> <Badge style={{"padding-right": "25px"}} status="default"/></div>}
</div>
</Col>
</Row>
</div>
)
);
return prettyRows;
}
render() {
const stylesSelectedRow = { "background": "rgba(155,155,155,0.05)", "box-shadow": "0 0 5px 0 #4A90E2", "transform": "scale(1.01)"};
const { dataSource } = this.props;
return(
<div>
{dataSource &&
<Card bordered={false} loading={this.props.loadingStatus} className={styles.userRows} bodyStyle={{"padding": "0 15px"}}>
<List
size="small"
bordered={false}
dataSource={this.prettifyForTable(dataSource)}
renderItem={(item, index) => (<List.Item onClick={() => {this.state.selected_row_index == index ? null : this.props.selectRow(this.props.dataSource[index]); this.handleChangeStyleOnSelectRow(index)}} style={this.state.selected_row_index == index ? stylesSelectedRow : null} className={styles.userRows}>{item}</List.Item>)}
/>
</Card>
}
</div>
)
}
}
export default LeftPanel;
and finally RightPanel.js, that is reponsible for listening to the URL or a click on LeftPanel, and display data accordingly.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import infopng from '../../../assets/info.svg';
import TabInformations from './TabInformations.js';
import TabFamily from './TabFamily.js';
import TabProblems from './TabProblems.js';
import { Tabs, Button, Spin, Icon, Table, Pagination, Card, Col, Row, Spinner, Badge } from 'antd';
const TabPane = Tabs.TabPane;
import 'font-awesome/css/font-awesome.min.css';
import WindowSizeListener from 'react-window-size-listener'
import FadeIn from 'react-fade-in';
export default class RightPanel extends Component {
render() {
if (this.props.loading) {
return(
<div>
<Spin
indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />}
src="http://web.gndu.ac.in/DepartmentProfile/images/spinner.gif"
/>
</div>
);
} else if (this.props.is_default) {
return(
<div style={{"margin-top": "64px", "margin-right": "10px", "text-align": "center", "height": "90vh", "display": "flex", "align-items": "center", "justify-content": "center"}}>
<div>
<img src={infopng} style={{"height": "155px"}} />
<p style={{"color": "#8e8e8e"}}> select a user on the <br/> left-hand side... </p>
</div>
</div>
);
} else {
return (
<FadeIn>
<Card bodyStyle={{"padding": "0"}} style={{"background-color": "white", "height":"90vh", "padding": "20px", "box-shadow": "rgba(0, 21, 41, 0.1) 0px 0px 6px", "opacity": "1", "transition": "background 0.6s", "border-radius": "2px", "margin": "10px 10px 0 0px", "margin-top": "64px"}}>
<Tabs defaultActiveKey="1" style={{"text-align": "center", "padding": "0 15px"}}>
<TabPane tab="General" key="1">
<TabInformations
selected_user={this.props.selected_user}
/>
</TabPane>
<TabPane tab="Servicing" key="2">
<TabFamily
selected_user={this.props.selected_user}
/>
</TabPane>
<TabPane tab={<div>Defect(s)<Badge showZero count={0} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset', "margin-left": "10px" }} /></div>} key="3">
<TabProblems />
</TabPane>
</Tabs>
</Card>
</FadeIn>
);
}
}
}
This code does the initial job pretty well: when the user clicks on a link on leftPanel.js, leftPanel.js calls the method selectRow in users.js, which in turn selects a row and display it on RightPanel.js.
My question: how to add to this the fact that it changes the URL whenever the user clicks? And obviously, if the user clicks on "go back" in Chrome, the data in RightPanel.js has to change accordingly.. ?

Calling a method from a different component (File) in React JS

I have an App Bar component, I'm using Material UI v1.0.0-beta.33
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "material-ui/styles";
import AppBar from "material-ui/AppBar";
import Toolbar from "material-ui/Toolbar";
import Typography from "material-ui/Typography";
import Button from "material-ui/Button";
import IconButton from "material-ui/IconButton";
import MenuIcon from "material-ui-icons/Menu";
import TemporaryDrawer from "./Drawer";
const styles = {
root: {
width: "100%"
},
flex: {
flex: 1
},
menuButton: {
marginLeft: -12,
marginRight: 20
},
};
function ButtonAppBar(props) {
const { classes } = props;
return (
<div className={classes.root}>
<TemporaryDrawer/>
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" className={classes.flex}>
Title
</Typography>
<Button onClick={} color="inherit">User Name</Button>
</Toolbar>
</AppBar>
</div>
);
}
ButtonAppBar.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(ButtonAppBar);
As you can see I'm importing another component called TemporaryDrawer, in the code of that component there's a method called "toggleDrawer" that triggers the Drawer.
My questions is how can I use the toggleDrawer method from TemporaryDrawer in the above code, I have a button with the onClick method empty.
For reference, I put the code from TemporaryDrawer below:
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "material-ui/styles";
import Drawer from "material-ui/Drawer";
import List from "material-ui/List";
import Divider from "material-ui/Divider";
const styles = {
list: {
width: 250
},
listFull: {
width: "auto"
}
};
class TemporaryDrawer extends React.Component {
state = {
left: false
};
toggleDrawer = (side, open) => () => {
this.setState({
[side]: open
});
};
render() {
const { classes } = this.props;
const sideList = (
<div className={classes.list}>
<List>AA</List>
<List>BB</List>
<List>CC</List>
<Divider />
<List>AA1</List>
<List>BB1</List>
<List>CB1</List>
</div>
);
return (
<div>
<Drawer open={this.state.left} onClose={this.toggleDrawer("left", false)}>
<div
tabIndex={0}
role="button"
onClick={this.toggleDrawer("left", false)}
onKeyDown={this.toggleDrawer("left", false)}
>
{sideList}
</div>
</Drawer>
</div>
);
}
}
TemporaryDrawer.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(TemporaryDrawer);
Thanks in advance.
Looking at the toggleDrawer method in TemporaryDrawer component
the method can simply be "litfed" into the parent component ButtonAppBar
updated ButtonAppBar turned in the class component:
class ButtonAppBar extends Component {
constructor(props) {
super(props);
this.state {
isDrawerOpen: false
}
this.closeDrawer = this.closeDrawer.bind(this);
}
closeDrawer() {
this.setState({ isDrawerOpen: false });
}
render() {
const { classes } = props;
return (
<div className={classes.root}>
<TemporaryDrawer open={this.state.isDrawerOpen} onDrawerClose={this.closeDrawer} />
<AppBar position="static">
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" className={classes.flex}></Typography>
<Button onClick={} color="inherit">User Name</Button>
</Toolbar>
</AppBar>
</div>
);
}
}
And then TemporaryDrawer component can be:
class TemporaryDrawer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Drawer open={this.props.isDrawerOpen} onClose={this.props.onDrawerClose}>
...
</Drawer>
)
}
}

Categories