How to use multiple styles in material ui withStyles() React JS? - javascript

I have the following:
const styles = theme => ({root: {backgroundColor: '#000000'})
const styles2 = theme => ({root: {backgroundColor: '#fff'})
on my react component I have
export default compose(
withStyles(styles, {withTheme: true}),
I need to determine what style to use in render() what is the best way to do that ?

After long investigation the best solution I came with is as follows:
I have imported classNames package
Used only one style
const styles = theme => ({
whiteRoot: {
backgroundColor: '#fff',
},
blackRoot: {
backgroundColor: '#000000',
},
})
and on render()
for example
<Grid container className={classNames(classes[`${black}Root`])} justify='center'>
and worked fine

Related

React Native Styled Components how to pass non specific styles as props for re usable components

Given the following simple component example which uses styled components for the Pressable:
const StyledPressable = styled.Pressable = props => props.buttonStyle
const Icon: FC<{buttonStyle: string}> = ({buttonStyle}) => {
return (
<StyledPressable buttonStyle={buttonStyle} >
<SomeIconComponent/>
</StyledPressable>
)
}
I would like to create a reusable component which takes in style props while still using styled components. Normally using the vanilla react native styles, this is really simple one would just pass in the style object as a prop an use it as a value in the necessary component. How would i achieve this behavior using styled components? my initial guess is that the buttonStyle has to be a string in the same format as styled components, but how would i make it so that the style which is declared inside the '' of lets say StyledPressable in this example is equal to the passed buttonStyle prop?
Since i am learning styled components, i am very open to any other way to achieve this behavior while using styled components.
import styled from "styled-components/native"
const Pressable = styled.Pressable(props => (props.buttonStyle))
export default function App() {
return (
<View style={styles.container}>
<Pressable buttonStyle={{ backgroundColor: "pink" }}>
<Text>This is button</Text>
</Pressable>
</View>
);
}
Inder's answer using some Typescript
import styled from "styled-components/native"
interface PressableProps {
buttonStyle?: CSSObject
}
const Pressable = styled.Pressable<PressableProps>({ buttonStyle }) => buttonStyle)
export default function App() {
return (
<View style={styles.container}>
<Pressable buttonStyle={{ backgroundColor: "pink" }}>
<Text>This is button</Text>
</Pressable>
</View>
);
}

What is the alternative of makeStyles for Material UI v.5

I just started using Material UI version 5. Originally to use my custom theme's styles, I would use makestyles, but it seems that does not work in v.5. My themes are on their own component, and to import those, I used {createTheme} instead of the old {createMuiTheme}. I have my theme imported into the Parent component as usual and have it set up as <ThemeProvider theme{theme}></ThemeProvider>.
Now, on my other component, I again was trying to use useStyles, but it was not working because it is not used in version 5. I am having a hard time trying to figure out how to convert it so that it can be used in version 5. Here is some of the unfinished code I was working on:
const useStyles = makeStyles((theme) => ({
logo: {
height: "8em",
marginLeft: "0.2em",
},
tabContainer: {
marginLeft: "auto",
},
tab: {
...theme.typography.tab,
minWidth: 10,
marginRight: "50px",
opacity: 1,
"&hover": {
color: theme.palette.common.purple,
textDecoration:"none",
},
},
}));
export default function Navigation(props) {
const classes = useStyles();
const [value, setValue] = useState(0);
const handleChange = (e, value) => {
setValue(value);
};
const refreshPage = () => {
window.location.reload();
};
useEffect(() => {
switch (window.location.pathname) {
case "/":
if (value !== 0) {
setValue(0);
}
break;
default:
break;
}
}, [value]);
return (
<React.Fragment>
<ElevationScroll>
<AppBar
position="relative"
style={{
borderBottom: "2px solid black",
}}
>
<Toolbar disableGutters>
<img src={logo} alt="nasa logo" className={classes.logo}/>
<Typography variant="h1" style={{ textAlign: "center" }}>
Nasa<br></br>Photos
</Typography>
<Tabs
value={value}
onChange={handleChange}
className={classes.tabContainer}
indicatorColor="primary"
>
<Tab
className={classes.tab}
component={Link}
onClick={refreshPage}
to="/"
label="Home"
/>
</Tabs>
</Toolbar>
</AppBar>
</ElevationScroll>
</React.Fragment>
);
}
I have read about the xs property and I have also heard of the styled() through Material UI's documentation, but I am having a hard time applying it to the code that I have written and would like a push in the right direction.
So to edit what I had earlier, I am going to also add my Theme.js file as well. I thought that this has been done correctly, but again it isn't reading my tab nor my palette.
import {createTheme} from "#mui/material/styles";
const pink = "#FFC0CB";
const lightblue = "#ADD8E6";
const purple = "#800080";
const black = "#000000";
const theme = createTheme({
palette: {
common: {
pink: pink,
lightblue: lightblue,
purple: purple,
black: black
},
primary: {
main: pink,
mainGradient: "linear-gradient(to left, purple, pink)",
},
secondary: {
main: lightblue,
mainGradient: "linear-gradient(to right, lightblue, pink)"
},
},
typography: {
tab: {
fontFamily:"Orbitron",
textTransform: "none",
fontSize: "2.5rem",
color: black,
},
h1: {
fontFamily: "Orbitron",
fontSize: "2.5em"
},
h2: {
fontFamily: "Orbitron",
fontSize: "2.5em"
},
subtitle1: {
fontFamily: "Orbitron"
},
subtitle2: {
fontFamily: "Orbitron",
fontSize: "1.5rem"
},
buttons: {
fontFamily: "Orbitron",
textTransform: "none"
},
},
});
export default theme
I have imported my theme into my App.js file which is my top level file, I will include that here just in case something has been done wrong with that:
import React,{useState} from "react";
import PicOfDay from "./Components/PictureOfDay";
import Navigation from "./Components/Navigation";
import {
Typography,
} from "#mui/material";
import {ThemeProvider} from '#mui/material/styles'
import theme from "../src/ui/Theme";
import {BrowserRouter as Router} from "react-router-dom";
function App(props) {
const [date, setDate] = useState(new Date());
return (
<ThemeProvider theme={theme}>
<Router>
<Navigation date={date} setDate={setDate} />
<Typography
variant="h1"
style={{fontSize: "5rem", textAlign: "center", marginTop:"2rem"}}
>
Astronomy Picture of the Day
</Typography>
{/* <PicOfDay date={date} /> */}
</Router>
</ThemeProvider>
);
}
export default App;
I did look at some documentation a couple of you sent me, and I was looking at the troubleshooting part where it said "[Types] Property "palette", "spacing" does not exist on type 'DefaultTheme'" because makeStyles is exported differently and it does not know about Theme. There seems to be a snipet to put in a typescript project (which I am not running, I am using javascript) and there was a section to add a ts file to my javascript and put the snippet it recommended, which I tried, but am I missing something because it did not do anything and I am not sure if I need to put something in my App.js file in order for it to read that?
You can still use the makeStyles utils as what you're using, but in material v5 if you love to do it you need to install one more package #mui/styles and
import { makeStyles } from '#mui/styles';
https://mui.com/guides/migration-v4/#mui-material-styles
The makeStyles JSS utility is no longer exported from #mui/material/styles. You can use #mui/styles/makeStyles instead.
Also, you need to add tab and purple to createTheme if you need them
const theme = createTheme({
typography: {
tab: {
fontSize: 20,
},
},
palette: {
common: {
purple: 'purple',
},
},
})
Based on documentation:
#mui/styles is the legacy styling solution for MUI. It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the #mui/material anymore.
You can use the-sx-prop or styled
so what i understood from this question is that you want to add custom classes to the material-ui components. and makestyles is giving you error about theme.. you can resolve this by providing default theme to makestyles. you can use ThemeProvider to do that.. all you've to do is create a default theme with createTheme() then use that in ThemeProvider to pass it to all components in tree below ThemeProvider.. just use ThemeProvider to wrap your root component and that will provide default theme to each makeStyles that are currently in use..
import { makeStyles } from '#mui/styles';
import { createTheme, ThemeProvider } from '#mui/material/styles';
const theme = createTheme();
const useStyles = makeStyles((theme) => (
root : {
background: theme.palette.primary.main,
}));
function Component() {
const classes = useStyles();
return <div className={classes.root} />
}
// In the root of your app
function App(props) {
return <ThemeProvider theme={theme}><Component {...props} /></ThemeProvider>;
}
import * as React from 'react';
import { StyledEngineProvider } from '#mui/material/styles';
export default function GlobalCssPriority() {
return (
<StyledEngineProvider injectFirst>
{/* Your component tree. Now you can override MUI's styles. */}
</StyledEngineProvider>
);
}
You need to use provider on main file to get default styles first.
Visit here Material UI injections!

Using variables inside react native stylesheets wont recognize the variable

I import a color as props.color into my functional component and set it as the state 'tagColor'. When I use tagColor as a value in my stylesheet to set the background color i receive the error 'variable tagColor not found'
How can I use variables inside my stylesheet?
const Tag = (props) => {
const [tagColor, setColor] = useState(props.color)
return (
<View style={styles.container}>
<TouchableOpacity style={styles.tag} title='tag'>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
alignItems: "center",
justifyContent: "center",
height: 25,
display: 'flex'
},
tag: {
backgroundColor: tagColor,
}
});
export default Tag;
Well, of course it doesn't recognize tagColor, it's in a different scope. Notice tagColor is in the scope of your function component, while the StyleSheet is a different scope.
One way to solve this is to directly pass the backgroundColor to the style prop, like that:
<TouchableOpacity style={{backgroundColor: tagColor}} title="tag">
Another way is to define the tag class in your StyleSheet as a function that receives the color and returns the style, like:
const styles = StyleSheet.create({
container: {
...
},
tag: tagColor => ({
backgroundColor: tagColor,
})
});
And then use it like that:
<TouchableOpacity style={styles.tag(tagColor)} title="tag">
I'd go with the first way if you don't have any more styles other than backgroundColor. If you need more styles, go with the 2nd method.

MUI Drawer set background color

How to simply set background color of MUI Drawer?
tried this, but doesn't work
<Drawer
style={listStyle3}
open={this.state.menuOpened}
docked={false}
onRequestChange={(menuOpened) => this.setState({menuOpened})}
/>
const listStyle3 = {
background: '#fafa00',
backgroundColor: 'red'
}
Edit: (May-21) - Material UI V4.11.1
This can be done differently in version 4.11.1 and functional components.
There's no need to use an HoC anymore. Here's how it's done:
You should use the makeStyles helper to create the hook with a definitions of the classes and use the hook to pull them out.
const useStyles = makeStyles({
list: {
width: 250
},
fullList: {
width: "auto"
},
paper: {
background: "blue"
}
});
const DrawerWrapper = () => {
const classes = useStyles();
return (
<Drawer
classes={{ paper: classes.paper }}
open={isOpen}
onClose={() => setIsOpen(false)}
>
<div
tabIndex={0}
role="button"
onClick={() => setIsOpen(true)}
classes={{ root: classes.root }}
>
{sideList}
</div>
</Drawer>
)
}
Here's a working sandbox
Edit: (Jan-19) - Material UI V3.8.3
As for the latest version asked, the way to configure the backgroundColor would be by overriding the classes.
Based on material-ui documentation here, and the css api for drawer here - This can be done by creating an object in the form of:
const styles = {
paper: {
background: "blue"
}
}
and passing it to the Drawer component:
<Drawer
classes={{ paper: classes.paper }}
open={this.state.left}
onClose={this.toggleDrawer("left", false)}
>
A working example can be seen in this codesandbox.
Don't forget to wrap your component with material-ui's withStyles HoC as mentioned here
Based on the props you used I have the reason to think that you're using a version which is lower than v1.3.1 (the last stable version) but for the next questions you'll ask, I recommend writing the version you're using.
For version lower than V1, you can change the containerStyle prop like this:
<Drawer open={true} containerStyle={{backgroundColor: 'black'}}/>
In MUI v5, you can use the sx prop to style MUI components:
<Drawer
PaperProps={{
sx: {
backgroundColor: "pink",
color: "red",
}
}}
Or use styleOverrides to define the custom styles in createTheme:
const theme = createTheme({
components: {
MuiDrawer: {
styleOverrides: {
paper: {
backgroundColor: "pink",
color: "red",
}
}
}
}
});
Material UI V4.3.2
As in this version you can change the backgroundColor by making use of makeStyles from '#material-ui/core/styles' as shown below:
import Drawer from '#material-ui/core/Drawer';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
paper: {
background: 'black',
color: 'white'
}
});
const SideDrawer = props => {
const styles = useStyles();
return (
<Drawer
anchor="right"
open={props.drawerOpen}
onClose={() => props.toggleDrawer(false)}
classes={{ paper: styles.paper }}
>
Items
</Drawer>
);
};
export default SideDrawer;
Drawer doesn't accept style props. Use classes instead
See Drawer API
If anyone's looking for how to do this conditionally for dark/light mode, you can make 2 separate classes and use a conditional to use the right one in the component. Here's an example of how to modify #Yirenkyi's answer do achieve this:
import Drawer from '#material-ui/core/Drawer';
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles({
paperLight: {
background: 'white',
color: 'black'
},
paperDark: {
background: 'black',
color: 'white'
}
});
const SideDrawer = props => {
const userPrefersDarkMode = true; //here's your condition
const styles = useStyles();
return (
<Drawer
anchor="right"
open={props.drawerOpen}
onClose={() => props.toggleDrawer(false)}
classes={{ paper: userPrefersDarkMode ? styles.paperDark : styles.paperLight }}
>
Items
</Drawer>
);
};
export default SideDrawer;

React Navigation switching background colors and styling StackNavigator

I'm fairly new to React Native, but I have a simple working app with three scenes. I was previously using Navigator but it felt laggy and was excited to try out React Navigation (as in https://reactnavigation.org/). After implementing React Navigation, my background color switched from white to grey, and what was grey to white. This is a strange and shouldn't be related. However I didn't change my styles. I only implemented the new navigation and the colors changed. When I revert back to Navigator my colors return. I'm using StackNavigator. Has anyone else encountered this strange phenomenon?
Or maybe a better question is : how do I style my header and background color in React Navigation's StackNavigator?
To style the header in React Navigation use a header object inside the navigationOptions object:
static navigationOptions = {
header: {
titleStyle: {
/* this only styles the title/text (font, color etc.) */
},
style: {
/* this will style the header, but does NOT change the text */
},
tintColor: {
/* this will color your back and forward arrows or left and right icons */
}
}
}
For styling the backgroundColor, you just need to set the backgroundColor in your app otherwise you'll get the default color.
UPDATE!! As of May 2017 beta9 the navigationOptions are now flat
You can read about the breaking change here
You need to remove the object keys from the header object. Also, notice they have been renamed.
static navigationOptions = {
title: 'some string title',
headerTitleStyle: {
/* */
},
headerStyle: {
/* */
},
headerTintColor: {
/* */
},
}
Here is an example of what I am using to change the card background color and Header background and font color.
/*
1. Change React Navigation background color.
- change the style backgroundColor property in the StackNavigator component
- also add a cardStyle object to the Visual options config specifying a background color
*/
//your new background color
let myNewBackgroundColor = 'teal';
const AppNavigator = StackNavigator({
SomeLoginScreen: {
screen: SomeLoginScreen
}
}, {
headerMode: 'screen',
cardStyle: {backgroundColor: myNewBackgroundColor
}
});
//add the new color to the style property
class App extends React.Component {
render() {
return (
<AppNavigator style = {{backgroundColor: myNewBackgroundColor}} ref={nav => {this.navigator = nav;}}/>
);
}
}
/*
2. Change React Navigation Header background color and text color.
- change the StackNavigator navigationOptions
*/
/*
its not clear in the docs but the tintColor
changes the color of the text title in the
header while a new style object changes the
background color.
*/
//your new text color
let myNewTextColor = 'forestgreen';
//your new header background color
let myNewHeaderBackgroundColor = 'pink';
const AppNavigator = StackNavigator({
SomeLoginScreen: {
screen: SomeLoginScreen,
navigationOptions: {
title: 'Register',
header: {
tintColor: myNewTextColor,
style: {
backgroundColor: myNewHeaderBackgroundColor
}
},
}
}
}, {
headerMode: 'screen',
cardStyle:{backgroundColor:'red'
}
});
Use below code to create custom navigation header
static navigationOptions = {
title: 'Home',
headerTintColor: '#ffffff',
headerStyle: {
backgroundColor: '#2F95D6',
borderBottomColor: '#ffffff',
borderBottomWidth: 3,
},
headerTitleStyle: {
fontSize: 18,
},
};
Try this code.
static navigationOptions = {
title: 'KindleJoy - Kids Learning Center',
headerTintColor: '#ffffff',
/*headerBackground: (
<Image
style={StyleSheet.absoluteFill}
source={require('./imgs/yr_logo.png')}
/>
),*/
headerStyle: {
backgroundColor: '#1d7110',
borderBottomColor: 'black',
borderBottomWidth: 0,
},
headerTitleStyle: {
fontSize: 18,
}
};
I think none of the above answers worked for me in react-navigation 5 so, I made it mine own solution and share it with you
Just changed background of your theme in react-navigation 5 and you are good to go.
import React from 'react';
import { NavigationContainer, DefaultTheme } from '#react-navigation/native';
const MainNavigator = () => {
const MyTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: '#FFF',
},
};
return (
<NavigationContainer theme={MyTheme}>
...
</NavigationContainer>
);
};
export default MainNavigator;
https://reactnavigation.org/docs/themes/
Ok nothing worked for me, so I managed to figure out my own solution
static navigationOptions = ({ navigation, screenProps }) => ({
headerLeft: (
<NavBackButton onPress={() => { navigation.goBack(); }} />
),headerStyle: {
backgroundColor: CLColors.MAIN_BLUE
},
headerTitle: <Text style={[CLStyles.H6MEDIUM_WHITE, {marginLeft:8}]}>Profile</Text>
, footer: null,
});
headerTitle will do the magic to place a custom Text element here.
headerStyle will do the magic to change the background color of your navbar.
headerLeft will help you to customize your back button.
In stack navigator you can change it with contentStyle.backgroundColor like below syntax
<Stack.Navigator screenOptions={{ contentStyle: {backgroundColor: '#f6f6f6f'}}}>
note: #f6f6f6f is colour code of red colour you can change it as per your requirement, below is extra code snippets in case
const Stack = createNativeStackNavigator();
export default function App() {
return (
<>
<StatusBar style='auto' />
<NavigationContainer>
<Stack.Navigator screenOptions={{ contentStyle: {backgroundColor: '#f6f6f6f'}}}>
<Stack.Screen name="List Page" component={ListPage} />
<Stack.Screen name="List Page 2" component={ListPage} />
</Stack.Navigator>
</NavigationContainer>
</>
);
}

Categories

Resources