Override styled-components in React - reactjs

I'm trying to find a way to override a styled component with styled-components like this:
Let's say I have a reusable component Wrapper:
class Wrapper extends Component {
...
render() {
const Wrap = styled.div`
padding: 5px;
background-color: green;
`;
return (
<Wrap>
{children}
</Wrap>
)
}
}
export default Wrapper
And then I have Component B that imports Wrapper but should extend the styles like this: myNewWrap uses Wrapper
import Wrapper from './Wrapper'
class B extends Component {
...
render() {
const myNewWrap = styled(Wrapper)`
background-color: red;
`;
return (
<myNewWrap>
Some awesome text
</myNewWrap>
)
}
}
Result should be that Some awesome text has padding from Wrapper but background-color from own component. But what I get is only the styles from Wrapper.

Have you considered using extend from Styled-Components? Styled generates new component styles with a new class whereas extend is meant to use base styling from another Styled component, but then tweak or add additional styles.
Additionally, their docs explain when you should you use styled() (see section "When should I use styled()?")
when to use styled

you override the styled component simply by passing a className to the styled component and do styling with reference to that class
<myNewWrap className="my-wrap">

Related

Styled components vs props.children

I have been working with react using css modules till now. I wanted to switch to styled components and there is one thing that confuses me. When working with css modules i have been creating many UI components as wrappers, passing props.children in between and then styling the wrapper in specific ".module.css" file. Now when i saw how styled components work, its like creating a component and styling that one element or even styling nested jsx tags. So styled components have wrapper behaviour. Does it kinda replace usage of props.children?
No, Styled Components do not force you not to use props.children.
You can use a Styled Component as a wrapper and style children inside of it as you would do with a Component styled with a css.module:
I guess you are composing your React components like this:
// css.module
// styles.module.css
.container {
background-color: red;
}
.container > h2 {
color: green;
}
// Your React Component Wrapper:
const Wrapper = ({children}) => <div className={styles.container}>{children}</div>
// And you use it like this:
<Wrapper><h2>This text is green on a red background</h2></Wrapper>
You can do the same thing with Styled Components:
const Wrapper = ({ children }) => <StyledWrapper>{children}</StyledWrapper>;
const StyledWrapper = styled.div`
background-color: red;
& > h2 {
color: green;
}
`;
// And you use it like this:
<Wrapper><h2>This text is green on a red background</h2></Wrapper>
The result is the same and even the usage is the same, styled-components do not force you to use a certain React Composition Pattern, it's up to you whether to style container and then select children inside of it, or if to individually style all the children.
They just give you some super-powers, for example you can target a Styled Component Child inside a Styled Component Parent, by simply calling the Component name, or you have the chance to use JS variables more easily into your css code, since all props passed to a Styled Component can be retrieved by the css.
DEMO

Locate a component in React project

I wrote a Logout button component in my React app for which I wish to locate at the top right corner of the screen.
render() {
<LogoutButtonComponent height: , backgroudColor: />
}
It wouldn't let me assign any values for height and etc.
This is the Logout component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return <button type="button" onClick={this.handleClick}>Logout</button>;
}
}
Should I locate it by < col /> ?
To add inline styles, you should defined a style object as prop, and pass it values, like doniyor2109 mentioned. There are a few caveats to using this, however.
style={{ height: 100, height: '100px', height: '100%', minHeight: '100px'}}.
Not every value should be passed as integer, some need to be passed as a string
Not every css attribute gets passed as you would expect them to, the css min-height actually gets passed as minHeight, so replace all hyphens with lower camel case style
Inline styles get insanely difficult to manage. I suggest you at the very least create an object outside the component, and pass it in like:
const DivStyle = { minHeight: '100px' }
and then:
<LogoutButtonComponent style={DivStyle} />
You can prefix that DivStyle with an export if you want to import {DivStyle} from './somefile' in other places
I suggest you check out a library like styled-components as it makes styling much easier!
I suggest you check out this article which outlines your options
You don't really add styles to your component like that. It's better to add those styles in the source for the actual component. So how exactly do you want it displayed? I will provide a template kind of and you can change it to what you want.
Go to your source for your Logout Button Component. In the return of your render method try adding a div call it container. Then add styling in a css file to that div or if you are using react-bootstrap or reactstrap or #material/ui/core you can adjust the style according to their documentation.
You can add your css for the className .container to make it appear the way you would like.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return (
<div className="container">
{* notice the className here *}
<button type="button" onClick={this.handleClick}>Logout</button>
</div>
)
}
}
Hope this helps.

Overriding react components styles with styled component

I tried to override style of component created by standard way of styled-components(styled.) and both the ways(styled() and style.extends) worked for me.
But when I am trying to override style of simple react component with styled() approach, its rendering the component but not overriding it's style.
Below is snippet of code
import React, { Component } from "react";
import styled from "styled-components";
export default class MyLabel extends Component {
render() {
return <label>{this.props.children}</label>;
}
}
const StyledMyLabel = styled(MyLabel)`
color: green;
`;
And for display purpose I am using following syntax
<StyledMyLabel>My Styled Label</StyledMyLabel>
Please refer the link on codesandbox which might be useful
You have to pass className to desirable styling element manually to make it works.
import React, { Component } from "react";
import styled from "styled-components";
export default class MyLabel extends Component {
render() {
return <label className={this.props.className}>{this.props.children}</label>;
}
}
const StyledMyLabel = styled(MyLabel)`
color: green;
`;
NOTE:
Consider carefully whether to wrap your own components in a styled component, when it isn't necessary. You will disable the automatic whitelisting of props, and reverse the recommended order of styled components and structural components.
See more info here.
<label style={{color: "green"}}>{this.props.children}</label>
or
const style = {color : "green"};
<label style={style}>{this.props.children}</label>

Material-UI #next Does not support props-based styling?

With the arrival of Material-UI#next comes the replacement of LESS-based styling with CSS-to-JS-based styling. However, the component demos on Material-UI's website appear to ignore the creation of props-based-styling. I'm trying to create divs containing various Material-UI components at specific absolute heights on my page, however, the requirement of the stylesheet being predefined outside of the class means that the properties within the stylesheet can't be based on props passed to the component. Am I missing something?
For example:
import React, {Component} from 'react';
import {withStyles, createStyleSheet} from 'material-ui/styles';
import Button from 'material-ui/Button';
const styleSheet = createStyleSheet({
container: {
position: "absolute",
top: /*How can this be dependent upon the props passed to the component?*/,
height: /*How can this be dependent upon the props passed to the component?*/,
}
});
class Foo extends Component {
render() {
let classes = this.props.classes;
return (
<div className={classes.container}>
<Button raised/>
</div>
);
}
}
export default withStyles(styleSheet)(Foo);
The example component displayed above can't have props-dependent styles, because props is not defined when the stylesheet is created. So how do I solve this problem? IS there a solution?
I would strongly advise you check out Styled Compoments. They make styling very simple and even allow you to pass third party components (in your case Material UI components). They also allow you to pass in props like the following:
const Stylesheet = styled.div`
color: ${props => props.primary ? 'white' :
`
<Stylesheet primary>My Div</Stylesheet>
Check out the docs for more details, that was a very simple example, but they are super easy to work with and you can accomplish exactly what you need with them.

Target specific CSS classes with Styled Components

How would I go about styling something like the react-datepicker with styled-components? The datepicker library looks like it uses some type of BEM style (screenshot below) which I would normally just use their provided class names and style those using Sass. But, how would I target those class names with styled-components? Is that even possible?
Since styled-components is just CSS™ you'd do it like with any other style sheet, by using the class names react-datepicker provided.
The only difference is that you'll have to wrap the datepicker in one wrapper styled component which applies all of these classes:
const Wrapper = styled.div`
&.react-datepicker {
color: blue;
}
`
<Wrapper>
<Datepicker />
</Wrapper>
Searching for hours, I found that the best solution is to add a stylized parent component (it can be a div) overlying the component that needs a className and add the definition of the className directly into the stylized parent component.
VERY IMPORTANT:
A space is needed between the ampersand & and the class for this to take effect!
const StyledParent = styled.div`
& .your-class-name {
border-color: red;
}
`;
<StyledParent>
<Datepicker yourClassName="your-class-name" />
</StyledParent>
If you ever need to access and style another component you can do this if they are not in the same file:
Export whatever you need to access:
export { Wrapper as CircledButtonWrapper };
Import it where you need it:
import { CircledButtonWrapper } from "/Bla/CircledButton";
Use it where you need to style it:
const Wrapper = styled.div`
/* Some other styles */
&:hover {
${CircledButtonWrapper} {
opacity: 1;
}
} `;
Edit:
I see now that the question was refering to accessing className...

Resources