utility classes in styled component react - reactjs

hi I am using styled componant in react
const H4 = styled.h4`
font-size: 15px;
letter-spacing: 0.38px;
line-height: 1.33;
color: red;
padding: 20px;
`;
<H4>Small header</H4>
it will give exsact style in H4 tag. but how can I override this padding with utility classes like m-b-10 it will give margin-bottom:10px
something like this <H4 m-b-10>small header</H4>
same time I need to use this utility class whereever I want. in css I can simply write
m-b-10{margin-bottom:10px !important};
how can achieve this things on styled componenet?

One of the best solutions is to use https://styled-system.com/, it plays well with Styled Components and other libraries like Emotion and it offers what you need, to use utility-classes in the component definition.
Example:
import styled from 'styled-components'
import { color, space, fontSize } from 'styled-system'
// Set default styles and add styled-system functions to your component
const Box = styled.div`
/*defaut styles */
color: white;
font-size: 25px;
padding: 20px;
/* configurable properties */;
${color};
${space};
${fontSize};
`;
And to use it:
<Box bg="black" >
Lorem Ipsum
</Box>
<Box bg="black" color="green" fontSize="12px" p="10px">
Lorem Ipsum
</Box>
That code, will render this:
It also supports Media-Querys, Themes etc..
You can play with this CodeAndSandbox where it is been used with Styled Components https://codesandbox.io/s/styled-components-with-styled-system-njr17

You can use variables like
const m-b-10 = '20px';
const H4 = styled.h4`
padding: ${m-b-10};
`;
You can define such variables in a separate file and import them to styles components

You can define utility classes in the top component of your React tree. The example uses Gatsby.js, but you can easily adapt it for other React framework.
// src/components/layout.js
const GlobalStyles = createGlobalStyles`
html {
/* Put your CSS variables here*/
}
.m-b-10 {
margin-bottom: 10px;
}
`
Then make whatever defined in createGlobalStyles available for access in child components.
// src/components/layout.js
export default function Layout({ children }) {
return (
<React.Fragment>
<GlobalStyle />
{children}
</React.Fragment>
)
}
// src/pages.index.js
import Layout from "../components/layout"
const H4 = styled.h4`
font-size: 15px;
letter-spacing: 0.38px;
line-height: 1.33;
color: red;
padding: 20px;
`;
const IndexPage = () => {
return (
<Layout>
<H4 className="m-b-10" />
</Layout>
)
}

Related

error:styled_components__WEBPACK_IMPORTED_MODULE_0__.default.FaChevronRight is not a function

**import styled from 'styled-components';
import { FaChevronRight } from 'react-icons/fa';
const ButtonSty = styled.button`
width:128px;
height:32px;
border:2px solid #074EE8;
box-sizing:border-box;
border-radius:4px;
`
const Ancor = styled.a`
font-style:normal;
font-weight:normal;
font-size:16px;
line-height:18px;
color:#074EE8;
text-decoration:none;
`
const Icon = styled.FaChevronRight`
width:4px;
height:9px;
border:2px solid #074EE8;
`
function Button() {
return (
<div>
<ButtonSty> <Ancor href="#">Saznaj vise **<Icon />**</Ancor> </ButtonSty>
</div>
)
}
export default Button**
Guestion: how to style a react-icon with styled-component
When i create Icon and put in ancor the error above show
I do not know how to style component with react-icon
The dot notation is for styling HTML elements, i.e. button, a, div, etc. The correct syntax for styling another React component is:
const Icon = styled(FaChevronRight)`
width: 4px;
height: 9px;
border: 2px solid #074EE8;
`
See: Extending Styles
This is a custom component, so you have to wrap it with parentheses:
const Icon = styled(FaChevronRight)`
width:4px;
height:9px;
border:2px solid #074EE8;
`

How Do you reset the CSS in React if you're doing styled components?

So I'm creating a footer with styled components and we don't use classes like in normal css.
If I want to replicate the same CSS trick where we do this code below
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
How would I replicate this in a styled component? Is that even the correct way to do it?
Or would I need to create an App.css file and simply add it to my project?
Here's the typical code for a styled component in react
import styled from 'styled-components/macro';
export const Container = styled.div`
padding: 80px 60px;
background: black;
font-family: 'Nunito Sans', sans-serif;
#media (max-width: 1000px) {
padding: 70px 30px;
}
`;
Is it possible to add that * { box-sizing} code into my styled component or what is the proper way to implement that into my project?
import { createGlobalStyle } from 'styled-components'
const GlobalStyle = createGlobalStyle`
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
`
// in your app root
<React.Fragment>
<GlobalStyle />
<Navigation /> {/* example of other top-level stuff */}
</React.Fragment>

Extend a Styled Component from a different file

What I'm trying to achieve is to be able to add extra styling to my Button.tsx(essentially extending the styles) when using this component in different files. As you can see in my Button.tsx I have defined some default styles I would like the button to have, but as I use more buttons across my app, I might want to change the background or color, etc.
One thing I could do is this:
Example of not what I want to do:
import React from 'react'
import styled from 'styled-components'
interface IButton = {
children: string
}
export default function Button({ children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
const RedButton = styled(Button)`
// Inherits all of the styles from Button.
background: red;
`
return (
<Button>{children}</Button
)
}
This example will inherit my Button styles and then allows me to extend. The problem with this solution is, if I decide to add more buttons, I will always have to come back to this file and then add the different variants, which could start to make this file get pretty chunky and messy.
Ideally I would like to extend my <Button> from the App.tsx file, or which ever file I'm using my <Button> in.
How could I adjust the code below to achieve this?
Button.tsx
import React from 'react'
import styled from 'styled-components'
interface IButton = {
children: string
}
export default function Button({ children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
return (
<Button>{children}</Button
)
}
App.tsx
import React from 'react'
import styled from 'styled-components'
export default function App() {
return (
{/* This button would render with the default styles from Button.tsx */}
<Button>Button One</Button>
{/* This button would render with extended styles, a blue background for example */}
<Button>Button Two</Button>
)
}
In your App.tsx you can do the same:
const BlueButton = styled(Button)`
background: blue;
`
what styled-components does is it creates a class with background blue and pass it to your Button. so in your Button.tsx you need to accept the css class
export default function Button({ className, children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
return (
<Button className={className}>{children}</Button
)
}
Edit
another way to do is to export the style like this
const BaseStyles = css`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
const BaseButton = styled.button`
${BaseStyles}
`
Then later override the styles
const BlueButton = styled.button`
${BaseStyles}
background: blue;
`

Styled component ReactJs

export const RedHeader = styled.div`
color: red;
border: 1px solid blue;
background-color: gray;
`;
function Header(className) {
return (
<RedHeader className={className}>
this is styled component example
<p>test</p>
</RedHeader>
)
}
export default Header;
I have red the cdocumentation but i can't figure out, why should we use className as a props and after that in className={className}?
When using styled components, there should be no need to use className (which renders as class attribute in HTML) anymore. In your example, you pass className to the styled component, but the styled component does not use it in any way.
You can pass properties to your styled components if you want dynamic styling like you would do with class names in classic CSS.
Example with style that depends on a class name:
const RedHeader = styled.div`
color: red;
&.active {
color: blue;
}
`
Example with props:
const RedHeader = styled.div`
color: ${props => props.active ? 'blue' : 'red'}
`
function Header({ active }) {
return (
<RedHeader active={active}>
example
</RedHeader>
)
}

styled-components causing unexpected behaviour when rendering props

I have a WhiteBox react component which simply renders a white box with some styles.
I have a SmallBox react component which simply uses WhiteBox to render a more specific box.
I have a Content react component which renders three SmallBox boxes which does what it's supposed to do (renders three white boxes).
However when I tried to add a text as a props from the parent, the white box is aligned with some unexpected margin from top.
NOTE: when I simply put "This is a text" the css is okay, but when I send "this is a text" as props.text, the whitebox is rendered with extra margin from top.
I Use styled-components and react as I said.
I've tried to console.log the text, and everything seems to be okay. I also tried to switch the props.children or props.text and it does not work
-----------------White Box Component ----------------------
import styled from "styled-components";
const StyledBox = styled.div`
display: inline-block;
width: ${props => props.width}px;
height: ${props => props.height}px;
margin-right: ${props => props.marginRight}px;
margin-left: 100px;
background-color: white;
border-radius: 5px;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: #646777;
padding: 10px;
`;
const WhiteBox = props => {
return (
<StyledBox
width={props.width}
height={props.height}
marginRight={props.marginRight}
>
{props.text} // if I change this to simply "this is a text" it works well. somehow the props.text is causing problems.
</StyledBox>
);
};
export default WhiteBox;```
-----------------Small Box Component ----------------------
import React from "react";
import styled from "styled-components";
import WhiteBox from "../whitebox/white-box";
const SmallBox = props => {
return (
<WhiteBox width={320} height={130} marginRight={70} marginLeft={70} text={props.text}>
</WhiteBox>
);
};
export default SmallBox;
-----------------Content Component ----------------------
import React, { Component } from "react";
import SmallBox from "./smallbox/small-box";
import styled from "styled-components";
const StyledContent = styled.div`
position: absolute;
left: 320px;
top: 80px;
width: 100%;
height: 100%;
background-color: #f1f3f7;
`;
class Content extends Component {
render() {
return (
<>
<StyledContent>
<SmallBox text="this text is great" /> // causing problem
<SmallBox />
<SmallBox />
</StyledContent>
</>
);
}
}
export default Content;
The issue has to do with how many lines are rendered. The longer the text in the props, the more the lines rendered.
One solution would be to change the display property for WhiteBox:
const StyledBox = styled.div`
display: inline-flex;
....
`;
Another solution would be to override the default style vertical-align: baseline, simply add vertical-align: top;
const StyledBox = styled.div`
display: inline-block;
....
vertical-align: top;
`;

Resources