Material-UI withStyles doesn't apply any kind of styles - reactjs

I used the example in Material-UI for an AppBar and I simply changed it from a function to a class component, after that I looked at how to use withStyles and I did the exact same thing, but no matter what I do, and what kind of changes I make no style is applied.
"react": "^16.8.6",
"#material-ui/core": "^4.1.2",
"#material-ui/icons": "^4.2.1",
import React, {Component} from 'react';
import styleClasses from './SideDrawer.module.css';
import { withStyles } from '#material-ui/styles';
import PropTypes from 'prop-types';
// import UIManager from '../../UIManager/UIManager';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import { fade, makeStyles } from '#material-ui/core/styles';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import Badge from '#material-ui/core/Badge';
import MenuItem from '#material-ui/core/MenuItem';
import Menu from '#material-ui/core/Menu';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import AccountCircle from '#material-ui/icons/AccountCircle';
import MailIcon from '#material-ui/icons/Mail';
import NotificationsIcon from '#material-ui/icons/Notifications';
import MoreIcon from '#material-ui/icons/MoreVert';
const useStyles = makeStyles(theme => ({
grow: {
flexGrow: 1,
zIndex: 1000,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
color: 'red'
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginRight: theme.spacing(2),
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('md')]: {
width: 200,
},
}
}));
class SideDrawer extends Component {
render () {
const { classes } = this.props;
console.log('classes', classes)
return (
<div className={styleClasses.grow}>
<AppBar className={'SideDrawer-inputInput-14'}>
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Test
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="search..."
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ 'aria-label': 'Search' }}
/>
</div>
<div className={classes.grow} />
</Toolbar>
</AppBar>
</div>
)
}
}
SideDrawer.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(useStyles)(SideDrawer);
The console.log('classes', classes) returns :
{grow: "SideDrawer-grow-8", menuButton: "SideDrawer-menuButton-9", title: "SideDrawer-title-10", search: "SideDrawer-search-11", searchIcon: "SideDrawer-searchIcon-12", …}
grow: "SideDrawer-grow-8"
inputInput: "SideDrawer-inputInput-14"
inputRoot: "SideDrawer-inputRoot-13"
menuButton: "SideDrawer-menuButton-9"
search: "SideDrawer-search-11"
searchIcon: "SideDrawer-searchIcon-12"
title: "SideDrawer-title-10"
But none of these styles is applied to the actual items or the AppBar. What am I doing wrong?

You should not be trying to use makeStyles along with withStyles. makeStyles returns a custom hook and passing this custom hook into withStyles will not work correctly.
Instead, you want the following:
const styles = theme => ({
grow: {
flexGrow: 1,
zIndex: 1000,
},
/* and all your other styles ... */
});
// other stuff (e.g. your SideDrawer component) ...
export default withStyles(styles)(SideDrawer);

Related

How to change style (Color ; Icon ; Indicator ; Size etc..) Indicator of Tabs with Material-UI ⚛️ React Web?

I implementing TabsBar in my Appbar for my React Desktop Application.
But I really have a hard time stylizing the Tabs part. If anyone can help me with clear explanations, that would be great. I want to add Icons to the right of the text. Change the color of the tab indicator and put it on top as on the picture example. I'm a beginner. I searched for 4 days but the I ask because I block
We have two colors :(#738889) & (#006F85) for actived Tab.
AppBar with Tabs Designed
Voici Mon code actuel ci-dessous :
import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Tabs from '#material-ui/core/Tabs';
import Tab from '#material-ui/core/Tab';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import SearchIcon from '#material-ui/icons/Search';
import InputBase from '#material-ui/core/InputBase';
import Icon from '#material-ui/core/Icon';
import { fade, makeStyles } from '#material-ui/core/styles';
import { withStyles } from '#material-ui/core/styles';
import { ReactComponent as BrandLogo } from '../Assets//PriceWanted/BrandLogo.svg';
import { ReactComponent as Icon_MicroPhone } from '../Icons/Icon_MicroPhone.svg';
import { ReactComponent as Icon_Separation } from '../Icons/Icon_Separation.svg';
import { ReactComponent as Icon_Global } from '../Icons/Icon_Global.svg';
import { ReactComponent as Icon_Lightning } from '../Icons/Icon_Lightning.svg';
import { ReactComponent as Icon_Shipment_Boat } from '../Icons/Icon_Shipment_Boat.svg';
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
width: '100%',
backgroundColor: theme.palette.background.paper,
},
Tabs: {
marginLeft: 50,
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
transition: theme.transitions.create('backgroundColor'),
marginRight: 10,
width: '100%',
backgroundColor: fade(theme.palette.common.black, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.black, 0.70),
boxShadow: '0 3px 5px 2px rgba(25, 1, 12, .2)',
},
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(3),
width: 'auto',
},
},
inputRoot: {
color: '#2F6164',
'&:hover': {
color: '#b2ebf2',
},
},
inputInput: {
padding: theme.spacing(1),
paddingLeft: `calc(1em + ${theme.spacing(2.5)}px)`,
paddingRight: `calc(1em + ${theme.spacing(2.5)}px)`,
transition: theme.transitions.create('width'),
width: '90%',
flex: 1,
[theme.breakpoints.up('sm')]: {
borderColor: 'grey',
'&:focus': {
borderColor: 'green',
},
width: '35ch',
'&:focus': {
width: '50ch',
},
},
},
searchIcon: {
padding: theme.spacing(0, 1),
color: '#889FA0',
height: '100%',
position: 'absolute',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
iconButton: {
padding:5,
marginRight: 6,
marginLeft: 6,
},
Toolbar: {
alignItems:'center'
},
}));
TabPanel.propTypes = {children: PropTypes.node,index: PropTypes.any.isRequired,value: PropTypes.any.isRequired,};
function TabPanel(props) {const { children, value, index, ...other } = props;}
function a11yProps(index) {return{id: `simple-tab-${index}`,'aria-controls': `simple-tabpanel-${index}`,};}
export default function SimpleTabs() {
const classes = useStyles();
const StyledButton = withStyles({
root : {background: 'linear-gradient(270deg,#00DBFF 0%, #021118 61.57%, #000000 100%)',
'&:hover': {background:'linear-gradient(90deg, #00DBFF 0%, #000000 100%)',},
position: 'relative',
borderRadius: 4,
border: 1,
color: 'White',
height: 35,
padding: '10 5px',
boxShadow: '0 3px 5px 2px rgba(0px 4px 4px #CBCBCB)',
marginLeft: 1,
justifyContent:'center'},
textTransform: 'capitalize',})(Button);
const [value, setValue] = React.useState(0);
const handleChange = (event,newValue) => {setValue(newValue);};
return (
<div className={classes.grow}>
<AppBar position="static">
<AppBar style={{background: '#FFFFFF'}}>
<Toolbar>
<BrandLogo/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase placeholder="Marque,Modèle..."classes={{ root: classes.inputRoot,input: classes.inputInput,}}
inputProps={{ 'aria-label': 'search' }}/>
<IconButton className={classes.iconButton} aria-label="menu">
<Icon_MicroPhone/>
</IconButton>
</div>
<Icon_Separation style={{ flex: 1 }}/>
<Tabs
value={value}
onChange={handleChange}
variant="fullWidth"
indicatorColor="secondary"
textColor="secondary"
aria-label="icon label tabs example">
<Tab label="LIVE DEALS" {...a11yProps(0)} icon={<Icon_Lightning />}/>
<Tab label="GLOBAL STOCK" {...a11yProps(1)} icon={<Icon_Global/>}/>
<Tab label="TRANSPORT" {...a11yProps(2)} icon={<Icon_Shipment_Boat/>}/>
</Tabs>
<StyledButton
variant="contained"
color="primary"
className={classes.StyledButton}
endIcon={<Icon>power_settings_new&style</Icon>}>
CONNEXION
</StyledButton>
</Toolbar>
</AppBar>
</AppBar>
</div>);}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

borderRadius not working when use Material UI

I using ReactJS and Material-UI in my web application. When I define props search for search bar, it's working except borderRadius. I checked Style tab in the Developer Tools (F12), border-radius property was overwritten but search bar not change. Please help me.
My code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './../actions/index';
import AppBar from '#material-ui/core/AppBar';
import Badge from '#material-ui/core/Badge';
import IconButton from '#material-ui/core/IconButton';
import Tooltip from '#material-ui/core/Tooltip';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import { withStyles } from '#material-ui/core/styles';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import MenuIcon from '#material-ui/icons/Menu';
import MailIcon from '#material-ui/icons/Mail';
import HomeIcon from '#material-ui/icons/Home';
import QuestionIcon from '#material-ui/icons/QuestionAnswer';
import CartIcon from '#material-ui/icons/ShoppingCart';
import PersonIcon from '#material-ui/icons/Person';
import SearchIcon from '#material-ui/icons/Search';
const styles = theme => ({
root: {
width: '100%',
},
grow: {
flexGrow: 1,
},
appBar: {
zIndex: 1300,
},
//search props for search bar
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginRight: theme.spacing.unit * 2,
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing.unit * 3,
width: 'auto',
},
},
searchIcon: {
width: theme.spacing.unit * 9,
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
width: '100%',
backgroundColor: '#EAE9E8'
},
inputInput: {
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('md')]: {
width: 200,
},
},
})
class Header extends Component {
onToggleNav = () => {
this.props.onToggleNav()
}
render() {
const { classes } = this.props;
return (
<header className={classes.root}>
<AppBar color="inherit" className={classes.appBar}>
<Toolbar>
<IconButton color="inherit" className={"remove_outline"} onClick={this.onToggleNav}>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
Watch Shop
</Typography>
{/* search bar */}
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
</div>
<div className={classes.grow} />
<div>
<Tooltip title="Trang chủ">
<IconButton className="remove_outline">
<HomeIcon />
</IconButton>
</Tooltip>
<Tooltip title="Hỗ trợ">
<IconButton className="remove_outline">
<QuestionIcon />
</IconButton>
</Tooltip>
<Tooltip title="Phản hồi">
<IconButton className="remove_outline">
<MailIcon />
</IconButton>
</Tooltip>
<Tooltip title="Tài khoản">
<IconButton className="remove_outline">
<PersonIcon />
</IconButton>
</Tooltip>
<Tooltip title="Giỏ đồ">
<IconButton className="remove_outline">
<Badge badgeContent={4} color="secondary">
<CartIcon />
</Badge>
</IconButton>
</Tooltip>
</div>
</Toolbar>
</AppBar>
</header>
);
}
}
const mapDispatchToProps = (dispatch, props) => {
return {
onToggleNav: () => {
dispatch(actions.isShowNav())
}
}
}
export default connect(null, mapDispatchToProps)(withStyles(styles)(Header));
Style tab in the Developer Tools
Style tab in the Developer Tools
Search bar:
Search bar

How to connect Algolia and #material-ui

This is the documentation of how to create a basic SearchBox element from just an input field in Algolia. The problem is, Algolia's ends up looking pretty ugly
That's where material-ui comes in. I have used AppBar before which contains a search element, so my thinking was to instantiate SearchBox within my AppBar.js component, but with material-ui's proprietary InputBase (instead of boring html input).
I'll paste the code I have so far below but it's refusing to compile with InputBase (and more specifically it's associated props) being used to create a custom SearchBox element.
If anyone has any experience with meshing different API's like this or think you might know what's going on, don't hesitate to let me know!
import React from 'react';
import PropTypes from 'prop-types';
import AppBar from '#material-ui/core/Appbar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import {fade} from '#material-ui/core/styles/colorManipulator';
import {withStyles} from "#material-ui/core/styles";
import SearchIcon from '#material-ui/icons/Search';
import { connectSearchBox } from 'react-instantsearch-dom';
const styles = theme => ({
root:{
width: '100%',
},
grow:{
flexGrow: 1,
},
menuButton:{
marginLeft: -12,
marginRight: 20,
},
title:{
display: 'none',
[theme.breakpoints.up('sm')]:{
display: 'block',
},
},
search:{
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover':{
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]:{
marginLeft: theme.spacing.unit,
width: 'auto',
},
},
searchIcon:{
width: theme.spacing.unit * 9,
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot:{
color: 'inherit',
width: '100%',
},
inputInput:{
paddingTop: theme.spacing.unit,
paddingRight: theme.spacing.unit,
paddingBottom: theme.spacing.unit,
paddingLeft: theme.spacing.unit * 10,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]:{
width: 120,
'&:focus':{
width: 200,
},
},
},
});
function SearchBox({currentRefinement, refine}, props){
const {classes} = props;
return(
<InputBase
type='search'
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search for Destination by Name, State, and keywords..."
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
);
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar(props){
const {classes} = props;
return(
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<Typography className={classes.title} variant="h6" color='inherit' noWrap>
title
</Typography>
<div className={classes.grow}/>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon/>
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
SearchAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SearchAppBar);
(as you can probably tell, I have gone very by the book with respect to documentation - I haven't tried anything special)
If you want to use the material ui search box component instead of Algolia's, you can use connectSearchBox(); to sync the material ui search box and Algolia search box API.
import { InstantSearch, connectSearchBox } from "react-instantsearch-dom";
const CustomSearchBox = connectSearchBox(MaterialUISearchBox);
Inside MaterialUISearchBox component, you will use the props Algolia provides: currentRefinement and refine().
<InputBase
placeholder="Search…"
inputProps={{ "aria-label": "search" }}
value={this.props.currentRefinement}
onChange={(e) => this.props.refine(this.currentTarget.value)}
searchAsYouType={false}
/>
Please check the url for further details about Algolia's custom components.
https://www.algolia.com/doc/api-reference/widgets/search-box/react/

React - Material UI Drawer and Header Bar

This is my first post, so let me know if I have done anything wrong. I have searched for an answer, and have not been able to find anything on this site or anywhere else. I have started playing around with React to make an intranet application at work. My previous knowledge is mostly .Net and I was only an amateur at that.
For my application I am leveraging the NPM Material UI modules. I am trying to get the Drawer to always be below the header bar and the header bar to move all the way across the screen. Currently, the position of the drawer blocks out part of the header part. My current App.js is as follows
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withStyles } from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import Badge from '#material-ui/core/Badge';
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft';
import ChevronRightIcon from '#material-ui/icons/ChevronRight';
import NotificationsIcon from '#material-ui/icons/Notifications';
import { mainListItems, secondaryListItems } from './Components/Sidebar.js';
const drawerWidth = 240;
const styles = theme => ({
root: {
display: 'flex',
},
toolbar: {
paddingRight: 24, // keep right padding when drawer closed
},
chevronLeft: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
},
chevronRight: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
chevronRightButton: {
marginLeft: 12,
marginRight: 36,
},
chevronRightButtonHidden: {
display: 'none',
},
chevronLeftButton: {
marginLeft: 12,
marginRight: 36,
},
chevronLeftButtonHidden: {
display: 'none',
},
title: {
flexGrow: 1,
},
drawerPaper: {
position: 'relative',
whiteSpace: 'nowrap',
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerPaperClose: {
overflowX: 'hidden',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
width: theme.spacing.unit * 7,
[theme.breakpoints.up('sm')]: {
width: theme.spacing.unit * 9,
},
},
appBarSpacer: theme.mixins.toolbar,
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3,
height: '100vh',
overflow: 'auto',
},
chartContainer: {
marginLeft: -22,
},
tableContainer: {
height: 320,
},
});
class Dashboard extends React.Component {
state = {
open: true,
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
render() {
const { classes } = this.props;
return (
<React.Fragment>
<CssBaseline />
<div className={classes.root}>
<AppBar
position="absolute"
className={classNames(classes.appBar, this.state.open && classes.appBarShift)}
>
<Toolbar disableGutters={!this.state.open} className={classes.toolbar}>
<Typography variant="title" color="inherit" noWrap className={classes.title}>
Dashboard
</Typography>
<IconButton color="inherit">
<Badge badgeContent={4} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
classes={{
paper: classNames(classes.drawerPaper, !this.state.open && classes.drawerPaperClose),}}
open={this.state.open}
>
<Divider />
<List>{mainListItems}</List>
<Divider />
<List>{secondaryListItems}</List>
<div className={classes.chevronLeft}>
<IconButton
color="inherit"
aria-label="Close drawer"
onClick={this.handleDrawerClose}
// className={classNames(
// classes.chevronLeftButton,
// this.state.open && classes.chevronLeftButtonHidden,)}
>
<ChevronLeftIcon />
</IconButton>
</div>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerOpen}
className={classNames(
classes.chevronRightButton,
this.state.open && classes.chevronRightButtonHidden,)}
>
<ChevronRightIcon />
</IconButton>
</Drawer>
</div>
</React.Fragment>
);
}
}
Dashboard.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Dashboard);
You will no doubt notice the Chevrons don't work correctly. Only one is supposed to be visible at a time, but I am still working on that.
Any advice you can give me to correct the appearance would be greatly appreciated.
Thanks in advance.
Regards,
Mitch

How to use styling from another called component?

I'm currently using the material-ui react library and have copied the responsive drawer component example.
Is there a possible way to separate the sidebar and header into a separate component and call the sidebar function and my own main content in the main section using the classes.content styling set in the sidebar component
<main className={classes.content}>
<Typography noWrap>{'You think water moves fast? You should see ice.'}
</Typography>
</main>
e.g my home function wants to use the side
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import List from 'material-ui/List';
import Typography from 'material-ui/Typography';
import IconButton from 'material-ui/IconButton';
import Hidden from 'material-ui/Hidden';
import Divider from 'material-ui/Divider';
import MenuIcon from 'material-ui-icons/Menu';
import { mailFolderListItems, otherMailFolderListItems } from './tileData';
const drawerWidth = 240;
const styles = theme => ({
root: {
width: '100%',
height: 430,
marginTop: theme.spacing.unit * 3,
zIndex: 1,
overflow: 'hidden',
},
appFrame: {
position: 'relative',
display: 'flex',
width: '100%',
height: '100%',
},
appBar: {
position: 'absolute',
marginLeft: drawerWidth,
[theme.breakpoints.up('md')]: {
width: `calc(100% - ${drawerWidth}px)`,
},
},
navIconHide: {
[theme.breakpoints.up('md')]: {
display: 'none',
},
},
drawerHeader: theme.mixins.toolbar,
drawerPaper: {
width: 250,
[theme.breakpoints.up('md')]: {
width: drawerWidth,
position: 'relative',
height: '100%',
},
},
content: {
backgroundColor: theme.palette.background.default,
width: '100%',
padding: theme.spacing.unit * 3,
height: 'calc(100% - 56px)',
marginTop: 56,
[theme.breakpoints.up('sm')]: {
height: 'calc(100% - 64px)',
marginTop: 64,
},
},
});
class ResponsiveDrawer extends React.Component {
state = {
mobileOpen: false,
};
handleDrawerToggle = () => {
this.setState({ mobileOpen: !this.state.mobileOpen });
};
render() {
const { classes, theme } = this.props;
const drawer = (
<div>
<div className={classes.drawerHeader} />
<Divider />
<List>{mailFolderListItems}</List>
<Divider />
<List>{otherMailFolderListItems}</List>
</div>
);
return (
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar className={classes.appBar}>
<Toolbar>
<IconButton
color="contrast"
aria-label="open drawer"
onClick={this.handleDrawerToggle}
className={classes.navIconHide}
>
<MenuIcon />
</IconButton>
<Typography type="title" color="inherit" noWrap>
Responsive drawer
</Typography>
</Toolbar>
</AppBar>
<Hidden mdUp>
<Drawer
type="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={this.state.mobileOpen}
classes={{
paper: classes.drawerPaper,
}}
onRequestClose={this.handleDrawerToggle}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden mdDown implementation="css">
<Drawer
type="permanent"
open
classes={{
paper: classes.drawerPaper,
}}
>
{drawer}
</Drawer>
</Hidden>
<main className={classes.content}>
<Typography noWrap>{'You think water moves fast? You should see ice.'}</Typography>
</main>
</div>
</div>
);
}
}
ResponsiveDrawer.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
export default withStyles(styles, { withTheme: true })(ResponsiveDrawer);
You can move separate styling into separate components by just moving the styling into the new React component. I've done your case as an example.
The main component:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Typography from 'material-ui/Typography';
const styles = theme => ({
content: {
backgroundColor: theme.palette.background.default,
width: '100%',
padding: theme.spacing.unit * 3,
height: 'calc(100% - 56px)',
marginTop: 56,
[theme.breakpoints.up('sm')]: {
height: 'calc(100% - 64px)',
marginTop: 64,
},
},
});
const Main = (props) => {
const { classes } = props;
return (
<main className={classes.content}>
<Typography noWrap>You think water moves fast? You should see ice.</Typography>
</main>
);
};
Main.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles, { withTheme: true })(Main);
The rest, using the extracted main component:
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Drawer from 'material-ui/Drawer';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import List from 'material-ui/List';
import Typography from 'material-ui/Typography';
import IconButton from 'material-ui/IconButton';
import Hidden from 'material-ui/Hidden';
import Divider from 'material-ui/Divider';
import MenuIcon from 'material-ui-icons/Menu';
import { mailFolderListItems, otherMailFolderListItems } from './tileData';
const drawerWidth = 240;
const styles = theme => ({
root: {
width: '100%',
height: 430,
marginTop: theme.spacing.unit * 3,
zIndex: 1,
overflow: 'hidden',
},
appFrame: {
position: 'relative',
display: 'flex',
width: '100%',
height: '100%',
},
appBar: {
position: 'absolute',
marginLeft: drawerWidth,
[theme.breakpoints.up('md')]: {
width: `calc(100% - ${drawerWidth}px)`,
},
},
navIconHide: {
[theme.breakpoints.up('md')]: {
display: 'none',
},
},
drawerHeader: theme.mixins.toolbar,
drawerPaper: {
width: 250,
[theme.breakpoints.up('md')]: {
width: drawerWidth,
position: 'relative',
height: '100%',
},
},
});
class ResponsiveDrawer extends React.Component {
state = {
mobileOpen: false,
};
handleDrawerToggle = () => {
this.setState({ mobileOpen: !this.state.mobileOpen });
};
render() {
const { classes, theme } = this.props;
const drawer = (
<div>
<div className={classes.drawerHeader} />
<Divider />
<List>{mailFolderListItems}</List>
<Divider />
<List>{otherMailFolderListItems}</List>
</div>
);
return (
<div className={classes.root}>
<div className={classes.appFrame}>
<AppBar className={classes.appBar}>
<Toolbar>
<IconButton
color="contrast"
aria-label="open drawer"
onClick={this.handleDrawerToggle}
className={classes.navIconHide}
>
<MenuIcon />
</IconButton>
<Typography type="title" color="inherit" noWrap>
Responsive drawer
</Typography>
</Toolbar>
</AppBar>
<Hidden mdUp>
<Drawer
type="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={this.state.mobileOpen}
classes={{
paper: classes.drawerPaper,
}}
onRequestClose={this.handleDrawerToggle}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden mdDown implementation="css">
<Drawer
type="permanent"
open
classes={{
paper: classes.drawerPaper,
}}
>
{drawer}
</Drawer>
</Hidden>
<Main />
</div>
</div>
);
}
}
ResponsiveDrawer.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
export default withStyles(styles, { withTheme: true })(ResponsiveDrawer);
So, you can just pull the styling out with the React component that you're extracting. The docs give some more details about material-ui's styling system.

Resources