How to Default export react withRouter while using material UI makeStyles - javascript

I am using Material UI makeStyles with class components and adding use style as props while default exporting it in an arrow function.
export default () => {
const classes = useStyles();
return (
<LoginClass classes={classes} />
)
}
In react documentation it states that you need to use hooks while using makestyles which currently until now I have been doing correctly.
The issue I am facing now is I want to use react withRouter to use:
this.props.history.push
which I dont have access to in my class.
Below is my code that works perfectly but I cant direct users to other pages.
const useStyles = makeStyles((theme) => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: '#009688',
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
backgroundColor: '#33ab9f',
'&:hover': {
backgroundColor: '#009688',
},
},
}));
class LoginClass extends React.Component {
handleSubmit(event) {
this.props.history.push('/home') //dont have access to history unless I use withRouter
}
render() {
const classes = this.props.classes;
const { input } = this.state
return (
<React.Fragment>
<CssBaseline />
<MenuBarClass classes={classes} isLogin={this.state.isLogin} />
</React.Fragment>
)
}
}
After alot of research I have found a way to direct users to other pages by using:
export default withRouter(withStyles(useStyles)(LoginClass))
but using the above export distorts my whole page design.
any solution with using classes and makeStyles would be greatly appreciated.
Thank you.
so I can direct the users to other pages.

Try this way:
const styles = theme => ({
paper: {
marginTop: theme.spacing(8),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: '#009688',
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
backgroundColor: '#33ab9f',
'&:hover': {
backgroundColor: '#009688',
},
},
});
...
export default withRouter(withStyles(styles)(LoginClass))

Related

When importing page to App.js it shows up blank

I am fairly new to React Native and am struggling to get this page to show up when importing it to App.js. It was working by itself, but once I tried to clean things up and put the code into its own file and just call upon it, things went south.
To break things down;
Welcome.js contains the code of a "welcome page" I am trying to create
App.js is the default file created that basically just calls Welcome
and GetStartedButton is just the code of a button that is imported into Welcome but I dont think its necessary to provide.
When running App.js I am not receiving any errors, my screen is just white!
Thank you for any help, I appreciate it more than you know. I apologize for my ignorance!
It wouldnt surprise me if it was just another typo.
I am sure my code is horrible btw! Assuming my styles were an interesting way to do things! Learning...
Welcome.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button} from 'react-native';
import GetStarted from './src/components/GetStartedButton';
export default class Welcome extends Component {
render() {
return (
<View style={styles.containerMain}>
<View style={styles.containerClub}>
<Text style={styles.title}>Word</Text>
</View>
<View style={styles.containerCaption}>
<Text style={styles.caption}> Words Words Words </Text>
</View>
<View style={styles.containerBottom}>
<GetStarted text='Get Started' color='#E50061' />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
containerMain: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
containerClub: {
position: 'absolute',
bottom: 288
},
containerCaption: {
position: 'absolute',
bottom: 250
},
/* To style the button and positioning*/
containerBottom: {
position: 'absolute',
bottom: 100
},
/* To style "Word"*/
title: {
fontSize: 35,
fontWeight: "bold",
},
/* To style "Words Words Words"*/
caption:
{
fontSize: 16
}
}
)
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, Button} from 'react-native';
import Welcome from './src/pages/Welcome';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Welcome/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
}
);
GetStartedButton.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
const GetStarted = props => {
const content = (
<View style={[styles.button, {backgroundColor: props.color}]}>
<Text style={styles.text}>{props.text}</Text>
</View>
)
return <TouchableOpacity onPress={props.onPress}>{content}</TouchableOpacity>
}
const styles = StyleSheet.create({
button: {
padding: 20,
width: 340,
borderRadius: 8,
alignItems: 'center',
},
text: {
color: 'white',
fontSize: 20,
justifyContent: 'center',
alignItems: 'center',
}
});
export default GetStarted;
The problem is in your Welcome component styles. You colored your texts white, so... it is all white.
const styles = StyleSheet.create({
// (...)
/* To style "word"*/
title: {
color: 'white', // remove it!
fontSize: 35,
fontWeight: "bold",
},
/* To style "words words words"*/
caption:
{
color: 'white', // remove it!
fontSize: 16
}
#edit
Also you did not apply your styles in your App component. It should look like this:
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Welcome/>
</View>
)
}
}
Try changing backgroundColor to something else other than white like
containerMain: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black'
},

How can I use CSS #media for responsive with makeStyles on Reactjs Material UI?

const useStyles = makeStyles(theme => ({
wrapper: {
width: "300px"
},
text: {
width: "100%"
},
button: {
width: "100%",
marginTop: theme.spacing(1)
},
select: {
width: "100%",
marginTop: theme.spacing(1)
}
}));
Is there a way to use CSS #media at the above variable?
if impossible, how can I make my custom css for responsive?
Below is an example showing two ways of specifying media queries within makeStyles (further down is a v5 example using styled). You can use up, down, only, and between functions in theme.breakpoints (which generate the media query strings for you based on the breakpoints specified in the theme), or you can use media queries directly.
import React from "react";
import Button from "#material-ui/core/Button";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
button: {
color: "white",
[theme.breakpoints.down("xs")]: {
marginTop: theme.spacing(1),
backgroundColor: "purple"
},
[theme.breakpoints.between("sm", "md")]: {
marginTop: theme.spacing(3),
backgroundColor: "blue"
},
"#media (min-width: 1280px)": {
marginTop: theme.spacing(5),
backgroundColor: "red"
}
}
}));
export default function App() {
const classes = useStyles();
return (
<Button className={classes.button} variant="contained">
Hello World!
</Button>
);
}
Related documentation:
https://material-ui.com/customization/breakpoints/
https://cssinjs.org/jss-plugin-nested/?v=v10.1.1#nest-at-rules
Below is a similar example using v5 of Material-UI. This has been adjusted to use styled instead of makeStyles and the usage of theme.breakpoints.down and theme.breakpoints.between has been adjusted based on the changes in behavior for those functions (down is now exclusive of the specified breakpoint rather than inclusive and the end breakpoint for between is also now exclusive, so for both of those the breakpoint specified needs to be one up from what would have been used in v4). Also, the min-width of the media-query that is specified directly has been adjusted from 1280px to 1200px to match the new value of the lg breakpoint in v5.
import React from "react";
import Button from "#material-ui/core/Button";
import { styled } from "#material-ui/core/styles";
const StyledButton = styled(Button)(({ theme }) => ({
color: "white",
[theme.breakpoints.down("sm")]: {
marginTop: theme.spacing(1),
backgroundColor: "purple"
},
[theme.breakpoints.between("sm", "lg")]: {
marginTop: theme.spacing(3),
backgroundColor: "blue"
},
"#media (min-width: 1200px)": {
marginTop: theme.spacing(5),
backgroundColor: "red"
}
}));
export default function App() {
return <StyledButton variant="contained">Hello World!</StyledButton>;
}
Documentation on changes to breakpoints from v4 to v5: https://next.material-ui.com/guides/migration-v4/#theme

How to implement Material-UI ThemeProvider and WithStyles using Typescript

I am getting increasingly frustrated as I have spent the past couple of days trying to migrate my react application from javascript to tsx. So far I love the type checking of tsx but I am not convinced that the material-ui library, great as it is explains how to utilise its styling with typescript.
I have followed the guide on here https://material-ui.com/guides/typescript/ to the letter and created a theme:
import { createMuiTheme } from "#material-ui/core/styles";
export default function theme() {
return createMuiTheme({
palette: {
primary: {
main: "#607D8B",
light: "#CFD8DC",
dark: "#455A64",
contrastText: "#FFFFFF"
},
secondary: {
main: "#7C4DFF",
contrastText: "#212121"
}
}
})};
and I have created a style:
import { green, red } from "#material-ui/core/colors";
import { createStyles, withStyles } from "#material-ui/core/styles";
import { Theme } from '#material-ui/core';
const useStyles = (theme: Theme) => createStyles({
root: {
height: "100vh"
},
success: {
backgroundColor: green[600]
},
error: {
backgroundColor: red[800]
},
icon: {
fontSize: 20
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing(1)
},
message: {
display: "flex",
alignItems: "center"
},
image: {
backgroundImage: "url(https://source.unsplash.com/8WFnEehJWso)",
backgroundRepeat: "no-repeat",
backgroundColor: theme.palette.primary.light,
backgroundSize: "cover",
backgroundPosition: "center"
},
paper: {
height: "30vh",
margin: theme.spacing(1.5, 3),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
mui_form: {
width: "100%",
marginTop: theme.spacing(1)
},
submit: {
margin: theme.spacing(3, 0, 2)
},
card: {
maxWidth: 600
},
media: {
height: 500
},
circle: {
display: "flex",
"& > * + *": {
marginLeft: theme.spacing(2)
},
align: "center"
},
menuButton: {
marginRight: theme.spacing(2)
},
title: {
flexGrow: 1,
alignContent: "center"
},
pie: {
height: 250,
marginBottom: theme.spacing(2)
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.secondary.main
},
muiform: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing(1),
"&:focus": {
borderColor: "primary.dark"
}
},
muisubmit: {
margin: theme.spacing(3, 0, 2),
padding: theme.spacing(3, 2),
background: "primary.main",
"&:hover": {
backgroundColor: "primary.dark"
}
},
login: {
padding: "0 30px",
height: 200,
display: "flex",
flexDirection: "column",
justifyContent: "center"
},
loginImage: {
backgroundImage: "url(https://source.unsplash.com/rCbdp8VCYhQ)",
backgroundRepeat: "no-repeat",
backgroundSize: "cover",
backgroundPosition: "center",
height: "100vh"
},
loginSurface: {
height: "40vh",
padding: "20px 10px",
display: "flex",
flexDirection: "column",
alignItems: "center",
background: "black"
},
table: {
minWidth: 650
}
});
export default withStyles(useStyles);
I have then tried to implement this on a component:
import DialogContent from "#material-ui/core/DialogContent";
import DialogContentText from "#material-ui/core/DialogContentText";
import DialogTitle from "#material-ui/core/DialogTitle";
import Slide from "#material-ui/core/Slide";
import Table from "#material-ui/core/Table";
import TableBody from "#material-ui/core/TableBody";
import TableCell from "#material-ui/core/TableCell";
import TableContainer from "#material-ui/core/TableContainer";
import TableHead from "#material-ui/core/TableHead";
import TableRow from "#material-ui/core/TableRow";
import Paper from "#material-ui/core/Paper";
import useStyles from "./useStyles";
import { TransitionProps } from "#material-ui/core/transitions";
import { useTheme } from '#material-ui/core/styles';
import { Theme } from '#material-ui/core';
const Transition = React.forwardRef<unknown, TransitionProps>(
function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
}
);
export default function GuidanceDialogue(){
const theme = useTheme<Theme>();
const [open, setOpen] = React.useState(false);
const classes = useStyles(theme);
The theme is accessed using useTheme and is passed down using the ThemeProvider in the root App.js.
The error I am getting is that:
const classes = useStyles(theme);
Argument of type 'Theme' is not assignable to parameter of type 'ComponentType; }>>'.
Type 'Theme' is not assignable to type 'FunctionComponent; }>>'.
Type 'Theme' provides no match for the signature '(props: PropsWithChildren; }>>, context?: any): ReactElement<...> | null'.ts(2345)
If I cast the type to be as follows:
const classes = useStyles<any>(theme);
So I can see if the type error is really the issue or there is other stuff going on then it mentions that the className property I am referring to e.g. classes.table, table doesn't exist.
I'm very confused by the whole thing, can some please help!
The solution was to write the following the styles file:
const useStyles = makeStyles((theme: Theme) => createStyles({
root: {
Documentation of createStyles, makeStyles
By running the code below, I failed to reproduce your type error.
import { Theme, useTheme, makeStyles } from "#material-ui/core";
const useStyles = makeStyles((theme: Theme) => ({
root: {}
}));
export default function App() {
const theme = useTheme<Theme>();
const classes = useStyles(theme);
return (
<div className="App">
<h1 className={classes.root}>Theme</h1>
</div>
);
}
Try it online:

Adding styles to a custom component through App.js in React Native

Ok guys, I've been trying to figure this out for the past 3 days and I can't find a solution, please keep in mind that I am self-taught and I've been studying react native for like 3 months now.
Anyways, I have a custom button with a defined style and everytime that I render my button it loads with the style presented in its file:
Botaozudo.js:
import React from 'react';
import { Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class Botaozudo extends React.Component {
render() {
const { titulo, evento } = this.props;
return (
<TouchableOpacity
style={styles.button}
onPress={() => evento()}>
<Text style={styles.txtButton}>{titulo}</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
btnAlinhar: {
alignItems: 'flex-end',
marginRight: 20,
paddingTop: 7
},
button: {
backgroundColor: '#a082c9',
width: 100,
height: 40,
borderRadius: 10
},
button2: {
backgroundColor: '#a082c9',
width: 300,
height: 90,
borderRadius: 10
},
txtButton: {
color: '#fff',
fontSize: 20,
textAlign: 'center',
paddingVertical: 5
}
});
Lets say that I want two different buttons on my App.js, one that looks like exactly as above and another one with different size and background color. In my mind I just have to do something like this (for the different one):
<Botaozudo
style={styles.newBtn}
titulo='I am a button'
event={() =>
console.log('yup I am a button')}/>
const styles = StyleSheet.create({
newBtn: {
backgroundColor: '#7c7070',
width: 200,
height: 100
}
});
But the thing is that my Botaozudo doesn't know what that style={} prop means. And what I can't figure out is HOW to make my custom component understand it.
Thanks in advance,
Install https://www.npmjs.com/package/prop-types
Then in Botaozudo.js:
import React from 'react';
import { Text, TouchableOpacity, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
export default class Botaozudo extends React.Component {
static propTypes = {
// Custom style for Botaozudo. Requires object
componentStyle: PropTypes.object,
};
static defaultProps = {
componentStyle: styles,
};
render() {
const { titulo, event, componentStyle } = this.props;
return (
<TouchableOpacity style={componentStyle.newBtn} onPress={() => event()}>
<Text style={styles.txtButton}>{titulo}</Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
btnAlinhar: {
alignItems: 'flex-end',
marginRight: 20,
paddingTop: 7,
},
button: {
backgroundColor: '#a082c9',
width: 100,
height: 40,
borderRadius: 10,
},
button2: {
backgroundColor: '#a082c9',
width: 300,
height: 90,
borderRadius: 10,
},
txtButton: {
color: '#fff',
fontSize: 20,
textAlign: 'center',
paddingVertical: 5,
},
});
and in App.js:
<Botaozudo
componentStyle={styles}
titulo='I am a button'
event={() =>
console.log('yup I am a button')}/>
const styles = StyleSheet.create({
newBtn: {
backgroundColor: '#7c7070',
width: 200,
height: 100
}
});

color change for the loading bar component of material ui

I am trying to learn material ui.
I am trying to change the css of the loading bar.
I referred to the documentation and used colorPrimary classes
but its not changing.
can you tell me how to fix it so taht in future I will fix it myself
providing my code snippet below.
all my code is in ReceipeReviewCardList.js
https://codesandbox.io/s/2zonj08v5r
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
color: "green"
}
};
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<LinearProgress
className={classes.colorPrimary}
variant="determinate"
value={this.state.completed}
you can use example as was in the reply of the issue in material ui github project: https://github.com/mui-org/material-ui/issues/12858#issuecomment-421150158
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import { LinearProgress } from '#material-ui/core';
class ColoredLinearProgress extends Component {
render() {
const { classes } = this.props;
return <LinearProgress {...this.props} classes={{colorPrimary: classes.colorPrimary, barColorPrimary: classes.barColorPrimary}}/>;
}
}
const styles = props => ({
colorPrimary: {
backgroundColor: '#00695C',
},
barColorPrimary: {
backgroundColor: '#B2DFDB',
}
});
export default withStyles(styles)(ColoredLinearProgress);
It works perfect.
You can override the background colors with makeStyles.
On makeStyles file:
export const useStyles = makeStyles(() => ({
root: {
"& .MuiLinearProgress-colorPrimary": {
backgroundColor: "red",
},
"& .MuiLinearProgress-barColorPrimary": {
backgroundColor: "green",
},
},
})
Import and use:
import { useStyles } from "./myFile.style";
...
const classes = useStyles();
...
<div className={classes.root}>
<LinearProgress />
</div>
It is because you set the CSS is not correctly,
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
background: 'green'
}
};
not:
const styles = {
root: {
flexGrow: 1
},
colorPrimary: {
color: "green",
}
};
Hope it help!
If you want to overwrite with sx:
sx={{
'& .MuiLinearProgress-bar1Determinate': {
backgroundColor: 'red',
}
}}
the color of the main bar is set as the BACKGROUNDCOLOR, NOT the COLOR
For Material UI v5 (#mui)
<LinearProgress sx={{
backgroundColor: 'white',
'& .MuiLinearProgress-bar': {
backgroundColor: 'green'
}
}}
variant="determinate"
value={10}/>
I did do it by this way, creating your own theme
import {createMuiTheme, MuiThemeProvider } from '#material-ui/core/styles';
const theme = createMuiTheme({
palette: {
secondary: {
main: '#42baf5'
}
}
})
<MuiThemeProvider theme={theme}>
<LinearProgress color="secondary"/>
</MuiThemeProvider>
An easy workaround i stumbled upon which doesn't seem too much of a hack:
<LinearProgress
className="VolumeBar"
variant="determinate"
value={volume}
/>
.VolumeBar > * { background-color:green; }
.VolumeBar{background-color:gray ;}
The first rule makes the progress appear green(completed part).
The second rule takes care of the uncompleted part .
const BorderLinearProgress = withStyles((theme: Theme) =>
createStyles({
root: {
width: '95%',
height: 10,
borderRadius: 5,
marginTop: 8,
marginBottom: 20
},
colorPrimary: {
backgroundColor: Liquidity.colors.main.pink,
},
bar: {
borderRadius: 5,
backgroundColor: Liquidity.colors.main.yellow,
},
}),
)(LinearProgress);
This worked for me (Material ui version 4):
progressbar: {
background: 'yellow',
'& .MuiLinearProgress-bar': {
backgroundColor: theme.palette.success.main,
},
},
And then
<LinearProgress
className={classes.progressbar}
variant="determinate"
value={30}
/>
That have worked for me !
First set a className to the LinearProgress component
<LinearProgress
className="custom-class"
variant="determinate"
value={MyValue}
/>
then style it from your attached css file as shown in the following :
.custom-class > * { background-color:green !important; }
.custom-class{background-color:gray !important;}
using the !important tag is premordial to override the original color.
style: progress: { color: 'red' },
Component:
<LinearProgress color="inherit" className={classes.progress} />

Categories

Resources