I'm developing a React project using the material-ui library. I'm currently trying to add a drawer which is working fine for me. However, I'm trying to change the background color of this drawer. I've heard that the way to do this is by changing the color of the drawer's paper. I've tried adding the following tag to my CSS object:
const styles = theme => ({
background:"BLUE"
Then I reference this object in my render function using the classNames library:
render(){
const { classes } = this.props;
return(
<div className={styles.root}>
<CssBaseline />
<Drawer
variant="permanent"
className={classNames(classes.drawer, {
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})}
classes = {{
paper: classNames({
background:classes.background,
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})
}}
However, when I run this on localhost, the paper is still a plain old white. Am I missing something about the classNames library or is a special case of the paper tag? Thanks in advance and let me know if I should supply more info than this.
You have a couple issues in the code shown in your question.
For your styles, you need something more like the following:
const styles = theme => ({
drawerPaper: { background: "blue" }
});
In this case, "drawerPaper" is the key for my class name and then the object to the right contains the CSS properties for that class. When passed into withStyles, this will generate CSS like the following:
<style>
.classname-generated-for-drawerPaper-key: {
background: blue;
}
</style>
You had a class name key of "background" with the string "BLUE" as the CSS properties which will end up with CSS like the following:
<style>
.classname-generated-for-background-key: {
0: B;
1: L;
2: U;
3: E;
}
</style>
which of course is not valid CSS and will have no effect on the paper.
The second issue is in how you specify the classes:
classes = {{
paper: classNames({
background:classes.background,
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})
}}
When you pass an object to classNames, the keys of the object are the class names and the associated value controls (based on whether it is falsey or truthy) whether the class name should be included. With the syntax you used, classes.background will always be truthy which means that the class "background" (rather than the generated class name in classes.background) will be included which will have no effect since a "background" class hasn't been defined.
Instead you should have:
classes = {{
paper: classNames(classes.drawerPaper, {
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})
}}
which will unconditionally include classes.drawerPaper.
Here is a modified version of one of the Drawer demos, but with the background color of the drawer changed to blue: https://codesandbox.io/s/wqlwyk7p4l
If you're using global theme = createTheme( the color of a background paper can be set as following
const theme = createTheme({
palette: {
{
primary: colors.blue,
background: {
default: colors.grey[50],
paper: colors.common.white,
},
// ...
Related
I have a custom component for Buttons using NativeBase, and it seems work great initially; once I restart the project, the default style for the button I have set no longer works. To fix this, I have to manually set a variation, and then remove it, like so :
<Button variation="random" /> // Sets the variation to something random
<Button /> // delete the variation section of button, and now the default loads
I have it set up like so:
export const style = extendTheme({
components:{
Button: {
baseStyle: {
rounded: 'lg',
},
defaultProps: {
size: 'sm',
colorScheme: 'green',
_text: {
color: 'white',
fontSize: '30px',
...fonts.h1, //custom font
margin: -2,
}
},
}
}
Then, within App.js:
const style = style // from import
return (
<NativeBaseProvider theme={style}>
<NavigationContainer>
<StackNavigator>
...etc.
)
And finally, in another file:
<Button />
Why is this occurring? I assume it has something to do with NativeBaseProvider wrapping everything in App.js, instead of just wrapping each individual file using the custom components with it.
Thanks!
What is the best way to achieve this behavior along with React + TypeScript?
import { Button, Card } from 'src/components';
const Page = () => (
<div>
<Card mx3 p3 flex justifyContentEnd>
/* Card content */
</Card>
<Button my2 mx3>
Login
</Button>
</div>
);
For instance, mx3 will add 16px margin horizontally, my2 will add 8px margin vertically, etc., similar to how the Bootstrap framework uses classes to apply utility styles easily.
I have looked through a few component libraries with this sort of behavior in order to find a suitable solution; however, I find most do not have strong typing support. Examples are RNUILib, NativeBase, Magnus UI, etc.
You can declare your props like that:
const styles = ['mx3', 'p3', 'flex'] as const
type Styles = Record<typeof styles[number], boolean>;
Then use them like this:
type CardProps = Styles & {
other: 'props here'
}
Now, this should work:
<Card mx3 p3 flex />
You can get applied props like this:
const values = Object.entries(props).map(([key, value]) => value ? key : null).filter(Boolean)
If you see the source code of react-bootstrap, they have mapped the boolean to some CSS class using a util function of classnames package. You can do the same:
...
...
<Component
{...buttonProps}
{...props}
ref={ref}
className={classNames(
className,
prefix,
active && 'active',
variant && `${prefix}-${variant}`,
size && `${prefix}-${size}`,
props.href && props.disabled && 'disabled',
)}
/>
...
...
For some reason setting className is not styling my property:
export default class MyComponent extends Component {
render() {
return(
<div className={styles.example}>
</div>
)
}
}
const styles = StyleSheet.create({
example: {
background: 'black',
width: '100px',
height: '100px'
}
})
It just renders something like
<div class="175">
</div>
With no styling information (there is no CSS rule for the ""class"" 175)
Why is it not (as I expect) ending up with a name like styles__example___2w27N with CSS rules specified in the browser
.styles__example___2w27N {
background-color: 'black';
height: 100px;
width: 100px;
}
How do I get my CSS to be applied?
If I use style={styles.example} (instead of className) I actually get this error:
The style prop expects a mapping from style properties to values, not a string.
I would prefer to use className though because
I have specified hover and active styles, does style work with those?
I want to manually add and override some styles inline
You should be using the <View> component instead of the <div> component, as that will map the <View> component to the native view UI components for each specific platform that you're using (ie: <div> for web, android.view for android, etc.) and not the <div> element directly.
With that, the <View> element and other react-native core components are designed to work with StyleSheet. You should be applying your style to the style prop which all core components have, and not the className prop:
<View style={styles.example}>
</View>
When the above is viewed on the web, you'll see a <div> being used in the source, but on other platforms you'll see other native view UI types being used.
Stylesheet refers to React Native... are you doing react-js or react native?
Assuming you are doing react-js (because of the div), there is no such thing as stylesheet in react-js...
export default class MyComponent extends Component {
render() {
return(
<div className={styles.example}>
</div>
)
}
}
const styles = {
example: {
background: 'black',
width: '100px',
height: '100px'
}
}
I think you copied the code from a react-native document instead of the react-js...
I'm using Material-UI with my React application. I'm also using styled components and I'm viewing the app in a Chrome browser. The issue I'm having doesn't occur when using a Firefox browser.
When applying the overflow attribute in my styled component, I'm seeing this blue line towards the bottom of the modal. This only appears when I'm playing with the size of my browser window. As I gradually bring my browser window closer to normal size, the line goes away. I'm not sure why this is or what I can do to fix it.
Here is a snippet of my code:
export const ScrollableModal = styled(MUIModal)(() => ({
overflow: 'scroll',
}));
const Modal = ({ title, children, actionsLeft, actionsRight, ...rest }) => {
const wrappedTitle =
typeof title === 'string' ? <Typography>{title}</Typography> : title;
return (
<ScrollableModal {...rest}>
<Container>
I've left the rest out because it's not relevant to my question.
Here is a screenshot of what I'm describing:
I guess that's the outline property what they mentioned in the documentation for simple modal:
Notice that you can disable the outline (often blue or gold) with the outline: 0 CSS property.
First needs to be added to the current style:
const useStyles = makeStyles({
modal: {
textAlign: 'center',
width: '35vw',
backgroundColor: 'white',
opacity: 0.8,
outline: 0, // add / remove
}
});
Then it can be applied on the Container just like the following in the render:
const styles = useStyles();
return <>
<Modal open={true}>
<Container className={styles.modal}>
<p>Simple Modal</p>
</Container>
</Modal>
</>
Result by adding and removing outline property with value 0:
I guess with styled components just create a styled Container with opacity: 0 if you don't want to use makeStlyes for this purpose.
That resolved the issue for me.
I hope that helps!
Beginner here. As of now I can use Box like so:
<Box
p={5}
fontSize={4}
width={[ 1, 1, 1/2 ]}
color='white'
bg='magenta'>
Box
</Box>
and give it certain specified props, as it says on the site:
All margin and padding props
width: responsive width
fontSize: responsive font size
color: text color
bg: background color
flex: CSS flex shorthand property
order: CSS order property
alignSelf: CSS align-self property
Question: What if I need more props?
I know that I can extend rebass components, however, this seems to hard-code certain CSS properties into the component. E.g. If my Box is always purple I can create PurpleBox and save the color there. Or on their website there is this example:
const Container = props =>
<Box
{...props}
mx='auto'
css={{
maxWidth: '1024px'
}}
/>
Fair enough!
What what of I need to create a component, say, PositionedBox which gets an additional position prop for relative or absolute positioning?
I would like to use it like so:
<Box
p={5}
fontSize={4}
width={[ 1, 1, 1/2 ]}
color='white'
bg='magenta'
position='abs'>
Box
</Box>
Is this possible? Not sure how I could accomplish this.
You could make use of styled-components and styled-system
import styled from "styled-components";
import { position } from "styled-system";
// through interpolation
const StyledBox = styled(Box)`
// some properties
${position}
`;
// passing as a single property
const StyledBox = styled(Box)(position);
passing multiple properties
import { compose, property1, property2, ... } from "styled-system";
import StyledBox = styled(Box)(compose(property1, property2, ....));
this would extend all the position properties supported by the styled system.
list of all the out-of-the-box properties supported by styled-system here