how to style a nested react component - reactjs

I have a component that has another nested component inside it. On a particular page I want that component to have a different background color, but it doesn't work. I'm using LESS and importing styles from styles.module.less. What am I doing wrong?
<ParentComponent className={styles.parent}>
<ChildComponent className={styles.child} />
</ParentComponent>
.parent {
.child {
background-color: black;
}
}

Did you try to set style like this?
.parent .child {
background-color: black;
}
Hope it helps.

By the way, you can set style in line like this:
<ChildComponent style={{backgroundColor: 'black'}} className={styles.child} />

Related

ReactJs using styles css module on react-burger-menu component

I am working with react-burger-menu and I am having trouble setting the styles={styles} tag on the menu component, from a CSS module.
Given :
./App.js
import Page from './components/Page/Page';
import SideMenu from './components/sideMenu/SideMenu.js';
import styles from './components/sideMenu/SideMenu.module.css';
function App() {
return (
<div className="app" id="app">
<SideMenu styles={ styles } pageWrapId={ "page-wrap" } outerContainerId={ "app" }/>
<div id="page-wrap">
<Page />
</div>
</div>
);
}
export default App;
./sideMenu/SideMenu.js
import React from "react";
import { scaleRotate as Menu } from "react-burger-menu";
export default props => {
return (
<Menu {...props} >
<a className="menu-item" href="/">
Home
</a>
</Menu>
);
};
./sideMenu/SideMenu.module.css
.bm-burger-button {
position: fixed;
width: 36px;
height: 30px;
right: 36px;
top: 36px;
}
.bm-burger-bars {
background: #373a47;
}
I am unable to pass the prop styles to SideMenu menu bar. The stylesheet is just not read. I have also tried style={styles} instead. If I omit the styles={styles} tag and just put the CSS styling in ./index.css then the styling is rendered correctly but I want to separate the menu styling as a module.
I have also tried to write the
import styles from '../../components/sideMenu/SideMenu.module.css'
inside the sideMenu/SideMenu.js file instead, and return (<Menu {...props} styles={styles}> (...) but still with no success.
Finally, I have also tried to set
<div className="app" id="app" styles={styles}> (...) </div>
in ./App.js as it was suggested in this post but that doesn't work either.
Does anyone know what I am doing wrong?
First, it’s recommend to use camelCase for classes with more than one word. The reason for this is that you’ll access these classes later as properties of a JS object, hyphens are not syntactically allowed. So you must first of all change your SideMenu.module.css for example like this:
.bm_burger_button {
position: fixed;
width: 36px;
height: 30px;
right: 36px;
top: 36px;
}
.bm_burger_bars {
background: #373a47;
}
Import the module you’ve just created from within your component, like you did:
import styles from './components/sideMenu/SideMenu.module.css';
To use a class defined in your module, just refer to it as a normal property from the styles object, like:
<div className={styles.bm_burger_button}> (...) </div>

Styled-Components Pass Props For Condition

I am trying to make a conditional icon with styled-components. But I need to pass props like function params. Because I need to change the icon with the condition.
export const RadioCheck = ({checked}) => styled(checked ? FaCheckCircle : FaRegCircle)`
display: flex;
align-self: center;
margin: 0 2em;
font-size: 1em;
color: ${props => props.checked ? primary : `transparent`}
`
Is there any way for this or I need to create two different components and use them?
Seems to me like you should use the condition where you return the icon to decide which component to use.
Something like
return(
<div>
{checked ?
<FaCheckCircle
//... your props
/>
:
<FaRegCircle
//... props
/>
}
</div>
)
If it's helpful to you, it is possible to style a styled component, such as
const FirstComponent = styled.div`
//some styling
`
const SecondComponent = styled(FirstComponent)`
//some more styling
`

Add styling to child element using Styled Components?

Say I want to create a styled component called <NoPrint /> that adds the following CSS to any element passed as child:
#media print
{
display: none !important;
}
How can I do that?
I want to be able to write a styled component like this:
<NoPrint><p>Some paragraph</p></NoPrint>
<NoPrint><Some>Some React component</Some></NoPrint>
I know that I can write:
const NoPrint = styled.div`
#media print
{
display: none !important;
}
`
render(
<NoPrint>
<Something />
</NoPrint>
)
But this component creates a wrapping div, which I do not want.
This is because you have to pass in the component you want to style, IE:
Style a component without wrapper
const NoPrint = styled(myComponent)`
#media print
{
display: none !important;
}
`
this will apply a custom style directly to an element without a wrapper.
Polymorphic prop
Another way is to use a "as" polymorphic prop
const Component = styled.div`
#media print
{
display: none !important;
}
`;
render(
<Component
as="button"
onClick={() => alert('It works!')}
>
Hello World!
</Component>
)
The only way I can see to figure something without having a div would be to have your media query in a css stylesheet with a classname, and pass that classname to your elements.
something like
#media print
.noPrint{
display: none !important;
}
<p class="noPrint" >Some paragraph</p>
To make an element without a div, there is React.Fragment available, but you can't style those...
I don't know if
Realistically you cant escape the wrapping div. You will have to either wrap it somewhere or, create a static styled component that can be included inside other styled components by referencing it.
Example
You can put this in like a style helper file
export const NoPrint = styled.div`
#media print
{
display: none !important;
}
then you can include it in other styled components. But it will not be wrappable around other components without an associated element like a span or div.

Modify css react component with styled-component

I am consuming some component from library which are not in my project repo. Since I am using styled-component to develop my own component. I want to do little modification on component which I am consuming from other library without touching there code base. Here is little example of what I am trying to achieve but none of following style is getting applied to CustomCom
UI Library
const CustomCom = ()=>{
return (
<div>Child</div>
);
}
My Repo
export default styled(CustomCom)`
height: 20px;
background: green;
`;
This is only possible if the component passes className to the DOM element, per the styled-components documentation
The styled method works perfectly on all of your own or any
third-party components, as long as they attach the passed className
prop to a DOM element.
https://www.styled-components.com/docs/basics#styling-any-components
Here's some sample code, which of course modifies the Library code, which I understand you can't do, but you could fork the library and do it if you want.
const CustomCom = ({className})=>{
return (
<div className={className}>Child</div>
);
}
class App extends Component {
render() {
const MyElem = styled(CustomCom)`
height: 20px;
background: green;
`
return (
<MyElem />
);
}
}
Try below
export const newCustom = styled(CustomCom)`
height: 20px;
background: green;
`;
Now use this custom component
<newCustom />
If you want to extend existing HTML tags you can do this:
export const newCustom = styled.div`
height: 20px;
background: green;
`;

Styled Components & React: Click event

I am trying to create an onClick for a Styled Components Component, but it is not working. It is not logging hello in the console.
<Component onClick={this.handleClick} />
The handleClick:
handleClick(e) {
console.log("hello");
}
This is also in the constructor:
this.handleClick = this.handleClick.bind(this);
The component:
const Component = styled.span`
/* Regular CSS */
${css};
`;
Thanks in advance!
EDIT:
The component is nested in a Button component. When I add the onClick to the Button Component hello is shown in the console. However I want the child to have this function not the parent.
EDIT 2:
Ok so when I change the CSS it works. I have no idea why. This is my css:
top: 0;
left: 0;
width: 10px;
height: 10px;
display: block;
z-index: 0;
position: absolute;
overflow: hidden;
border-radius: inherit;
We probably need more code. Anyway the cleanest way to bind is by arrow functions:
handleClick = () => console.log('click')
If your Button is INSIDE you have to use another props as onClick is binded to onClick event.
Try
// In Parent
<Parent action={this.handleClick} />
// In Child
<Child onClick={this.props.action} />
Your span is rendered with a css value of display: inline. If there is no actual content in it to expand, it will be 0 pixels in width, and therefore you are not actually clicking on it.
I ran into the same issues and in Styled Components I couldn't make it work with a forced display: block. You should use a clickable item, like styled.button...
You might want to try this:
handleClick = e => {
console.log('hello');
}
...
<Component onClick={(e) => this.handleClick(e)} />
or
<Component onClick={this.handleClick.bind(e)}/>

Resources