Component is not being styled according to className - javascript

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...

Related

Trying to add style on react toastify

I am trying to add custom style on react toastify, firstly I have import these
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
than call the react toast:
const handleToast = () => {
toast("sent mail")
}
Here i adding css in toast container :
<div>
<ToastContainer toastStyle={{
marginTop: "4rem",
borderRadius: "20px",
backgroundColor: "red"
}} />
<button onClick={handleToast} className='btn btn-info'>Click here</button>
</div >
But in ToastContainer component css not working.
Thanks in advance
You can try adding the styles to a root/global CSS file.
The classNames you'd use would mainly be:
.Toastify
.Toastify__toast-container
.Toastify__progress-bar
.Toastify__toast
.Toastify__toast-body
Your problem is not clear to me.
I believe you want to style the toast itself. If so, you can easily do it by adding classes like this,
toast("Sent mail",{
className: 'black-background',
bodyClassName: "grow-font-size",
progressClassName: 'fancy-progress-bar'
});
You can add your preferred classnames on global css file, and apply your desired styles there. Here,
className: applied on the toast wrapper (this override toastClassName is set by the container )
bodyClassName: applied on the toast body (this override bodyClassName is set by the container )
progressClassName: applied on the progress bar (this override progressClassName is set by the container )
style: inline style applied to the toast
Also if you want to style the ToastContainer, you can do it the same way.
<ToastContainer toastClassName="foo" style={{ width: "2000px" }} />
toastClassName: applied on the toast wrapper
<ToastContainer className="foo" style={{ width: "2000px" }} />
To know more about how to style it in a different way, you can check out there documentation on styling from here
How to style

Adding sx prop to custom component

I'm using MUI v5, together with Gatsby Image. I'm hoping to keep my styling syntax consistency across the application so I tried to add the sx prop to GatsbyImage.
This is what I've tried:
<Box
component={GatsbyImage}
sx={/* my sx styles */}
/>
This does what I want. Yet, I noticed the sx prop somehow gets passed to the img. This ends up getting a <img sx=[object Object]/> in my HTML.
Although this doesn't really affect my application in anyways, I'm wondering are there better ways to achieve this?
You can use the styled function to add the sx prop to your custom component like this:
import { styled } from "#mui/material/styles";
const ComponentWithSx = styled(YourCustomComponent)();
<ComponentWithSx
sx={{
width: 30,
height: 30,
backgroundColor: "primary.dark"
}}
/>
When you pass the GatsbyImage to the component prop of Box, GatsbyImage is used as the root component inside Box, and the sx object is passed to the DOM element:
function Box(props) {
const { component, ...other /* other includes sx prop */ } = props;
return <component {...other} />;
});
If you want to use Box you need to create a wrapper component to filter the sx prop:
function MyGatsbyImage({ sx, ...props }) {
return <GatsbyImage {...props} />;
}
For anyone trying to style a custom component, I did it this way:
Use the materialUI styled function, like so:
import { styled } from '#mui/material/styles';
import Star from '../components/Star'; //my custom component
[...]
const StarStyled = styled(Star)({ position: 'absolute', right: 5, bottom: 5 });
Then, in your render function, call your newly-styled component:
<StarStyled />
Now, your custom component (in this case, the component "Star") will receive a className prop, so you can use the prop like so:
const Star = ({className}) => {
return (
<span className={className}>
...whatever else you want your component to do
</span>
);
};
export default Star;

Extending Components in rebass.js?

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

Change paper color Material-UI

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,
},
// ...

Extend JSS style class instead of overwriting it

In my React app, I use React JSS for styling. Suppose I have these two files (skipping imports and another non interesting stuff).
This is App.js:
const styles = {
root: {
backgroundColor: '#ffffff',
},
header: {
backgroundColor: '#ff0000',
}
};
class App extends Component {
render() {
const { classes } = this.props;
return (
<div className={classes.root}>
<Header classes={{ root: classes.header }}/>
</div>
);
}
}
export default withStyles(styles)(App);
and this is Header.js:
const styles = theme => ({
root: {
backgroundColor: '#0000ff',
padding: '1em',
},
});
class Header extends Component {
render() {
const { classes } = this.props;
return (
<header className={classes.root}>
Hello header
</header>
);
}
}
export default withStyles(styles)(Header);
What I would like to have is "overriding" the style of the root component of Header without overwriting it completely. I can do either of two things:
use <Header className={classes.header}/>, which results in the header element having the class App-root-0-1-2, which means the background is blue with the padding;
use <Header classes={{ root: classes.header }}/> (as above), which results in the header element having the class App-header-0-1-2, which means the background is read without padding.
It seems I can only have either the style defined by the component OR the one that the parent defines to override it. However, I would like to extend the internal style with the one passed by the parent - of course, with the parent taking precedence in conflicts. In this case, I wish to have the red background with the padding.
How can I achieve that? Is it impossible - do I need to pass the editable style as a property?
You can provide an external class name and use classnames (https://github.com/JedWatson/classnames) (or just inline them) to conditionally render this class name if present:
import classNames from "classnames";
const styles = theme => ({
root: {
backgroundColor: '#0000ff',
padding: '1em',
},
});
class Header extends Component {
render() {
const { classes, className } = this.props;
return (
<header
className={classNames({
[classes.root]: true,
[className]: className
})}>
Hello header
</header>
);
}
}
export default withStyles(styles)(Header);
Then use it:
<Header className={classes.myParentClass} />
This will result in a class names, e.g. Header-root-0-1-2 App-myParentClass-0-4-3

Categories

Resources