I am beginner to ReactJS, Currently I am using styled-component for style some module. Actually I created 2 files in one folder. One is style.js where I am making 2,3 object and now I want to export these 3 object to my another file which name is 2nd.js but it not working for me Could you please help me How I can import style.js object to my file .
Style.js Code
import styled from 'styled-components';
export const SubText = styled.div`
font-size: 20px;
text-align: center;
padding-bottom: 30px;
width: 330px;
color: #012653;
margin: 0 auto;
font-weight: 440;
`;
export const GeneralText = styled.div`
color: red;
font-size: 26px;
font-weight: 600;
text-align: center;
min-width: 266px;
padding-bottom: 30px;
font-family: Lato, sans-serif;
margin-top: 50px;
color: #012653;
`;
export const ButtonWrapper = styled.div`
text-align: center;
margin-top: 26px;
`;
2nd.js Code
import Style from './Style';
<GeneralText>This is dummy text </GeneralText>
You can do this by:-
import {SubText, GeneralText, ButtonWrapper} from './style'
Actually,there are many ways to solve this:
import * as Style from './style'
Or the above answers says:
import {SubText, GeneralText, ButtonWrapper} from './style'
Related
So this could honestly be as simple as just over looking it and staring for so long and being new to react but on my section component I'm loading in my backgroundImg prop wont load the image and I cant figure it out. My pictures are in the public folder and my code is in the src components folder
Also, I can get images to load in the file just not when I'm calling them through prop
Home.js This is where I am calling my component and trying to load the file in through the prop type
import React from 'react'
import styled from 'styled-components'
import Section from './Section'
function Home() {
return (
<Container>
<Section
title="Model S"
description="Order Online for Touchless Delivery"
backgroundImg='/public/pictures/model-s.jpg'
leftBtnText="Custom Order"
rightBtnText="Existing Inventory"
/>
<Section
title="Model E"
description="Order Online for Touchless Delivery"
backgroundImg=".\Pictures\model-e.jpg"
leftBtnText="Custom Order"
rightBtnText="Existing Inventory"
/>
<Section />
<Section />
</Container>
)
}
export default Home
//Home and styled help you stlye the component without using css
const Container = styled.div`
height: 100vh;
`
Section.js The component for the Screen
import React from 'react'
import styled from 'styled-components'
//props are just parameters you can set when calling the component
function Section(props) {
return (
<Wrap bgImg={props.backgroundImg}>
<ItemText>
<h1>{props.title}</h1>
<p>{props.description}</p>
</ItemText>
<Buttons>
<ButtonGroup>
<LeftButton>
{props.leftBtnText}
</LeftButton>
<RightButton>
{props.rightBtnText}
</RightButton>
</ButtonGroup>
<DownArrow src='/Pictures/down-arrow.svg' />
</Buttons>
</Wrap>
)
}
export default Section
const Wrap = styled.div`
width: 100vw;
height: 100vh;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
`
const ItemText = styled.div`
padding-top: 15vh;
text-align: center;
`
const ButtonGroup = styled.div`
display: flex;
margin-bottom: 30px;
#media (max-width: 786px){
flex-direction: column;
}
`
const LeftButton = styled.div`
background-color: rgba(23, 26, 32, 0.8);
height: 40px;
width: 256px;
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 100px;
opacity: 0.85;
text-transform: uppercase;
font-size: 12px;
cursor: pointer;
margin: 8px;
`
const RightButton = styled(LeftButton)`
background: white;
opacity: 0.65;
color: black;
`
const DownArrow = styled.img`
margin-top: 20px;
height: 40px;
overflow-x: hidden;
animation: animateDown infinite 1.5s;
`
const Buttons = styled.div`
`
Thanks for the help.
I haven't tested this, but it looks like you didn't use the Wrap bgImg prop in the styled component. There is background-size, background-position, background-repeat, but not background-image using the prop.
Example:
background-image: ${props => props.bgImg || ''};
https://styled-components.com/docs/basics#passed-props
Error:
./src/card.js
Attempted import error: 'Bottom' is not exported from './styles/cards.style'.
card.js
import React from 'react'
import {
Bottom,
Color,
Text,
Image
} from "./styles/cards.style";
function Card(props) {
return (
<div>
<Bottom>
<Color />
<Text>{props.text}</Text>
<Text>{props.text}</Text>
</Bottom>
<Image
alt=""
src={props.image}
/>
</div>
);
}
export default Card;
cards.style
import styled from "styled-components";
export default {
colors: {
black: "rgba(0,0,0,1)",
brandPrimary: "rgba(238,120,36,1)",
brandPrimaryLight: "rgba(255,184,8,1)",
brandTertiary: "rgba(0,65,125,1)",
darkSlateGray: "rgba(51,51,51,1)",
white: "rgba(255,255,255,1)"
},
fonts: {
uiMainContent: {
family: "Poppins",
size: "15px",
weight: "300",
lineHeight: "21px"
},
uiSubContent: {
family: "Poppins",
size: "13px",
weight: "300",
lineHeight: "20px"
}
}
};
export const Bottom = styled.div`
width: 100%;
height: calc(100% - 20px);
background-color: ${props => props.theme.colors.white};
border-radius: 4px;
padding: 0 0 20px;
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
`;
export const Color = styled.div`
height: 120px;
background-color: ${props =>
props.theme.colors.brandPrimary};
margin-bottom: 16px;
border-radius: 4px 4px 0px 0px;
align-self: stretch;
`;
export const Text = styled.p`
color: ${props => props.theme.colors.black};
margin-left: 16px;
letter-spacing: 0.1px;
font-family: ${props =>
props.theme.fonts.uiSubContent.family};
font-size: ${props =>
props.theme.fonts.uiSubContent.size};
font-weight: ${props =>
props.theme.fonts.uiSubContent.weight};
line-height: ${props =>
props.theme.fonts.uiSubContent.lineHeight};
&:not(:last-of-type) {
margin-bottom: 4px;
}
`;
export const Image = styled.img`
width: 150px;
height: 92px;
position: absolute;
left: 29px;
top: 14px;
`;
I am trying to build cards in reactjs. I usually stick to scss however cannot use props with scss which I will have to use later to dynamically generate components. Not sure what is wrong here as I did export Button. Please can someone shed some insight you see what is so blatantly wrong it is causing this error.
in that case you have an export default as the first thing of you code, if you are exporting more than one thing from the same file, you should stick to exporting each const/function by itself and not having any export default
If you are using ReactJS/NextJS I would really recommend creating a global theme that you normally write and import with the application, so you could have things like
// global.js
const GlobalStyle = createGlobalStyle`
* {
box-sizing: border-box;
}
:root {
--black: rgba(0,0,0,1);
--brandPrimary: rgba(238,120,36,1);
...
...
`
}
Take a look here, it should help you a lot.
What I did:
I'm passing some props to functional component Stat.jsx.
What I expected:
I need to pass some background gradient color codes as a string type prop to the Stat.jsx component to make custom color elements.
What happened:
Props aren't passing to the Stat.jsx, also props object is empty.
Stat.jsx
import React from 'react';
import styled from 'styled-components';
const Stat = styled.div`
display: flex;
align-items: center;
justify-content: center;
padding: 0 2.5em;
width: auto;
height: 2.5em;
border-radius: 0.5em;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
background: linear-gradient(160deg, ${(props) => console.log(props) });
font-size: 1.8em;
font-family: Rubik-Medium;
color: #fff;
`;
// console.log(props) is returning object: { children: "1000", theme: {} }
export default ({ value }) => <Stat>{value}</Stat>;
Stats.jsx
import React from 'react';
import Stat from './Stat';
import styled from 'styled-components';
const Stats = styled.div`
display: flex;
`;
export default () => (
<div>
<Stats>
<Stat value="1000" background="#F4D03F, #16A085" />
</Stats>
</div>
);
Quick Fix
Because you don't pass the background prop to the actual Stat component:
export default (props) => <Stat {...props}>{props.value}</Stat>;
Explanation
A better way to illustrate the issue is by renaming your components:
import React from 'react';
import styled from 'styled-components';
const StyledStat = styled.div`
display: flex;
align-items: center;
justify-content: center;
padding: 0 2.5em;
width: auto;
height: 2.5em;
border-radius: 0.5em;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
background: linear-gradient(160deg, ${(props) => console.log(props) });
font-size: 1.8em;
font-family: Rubik-Medium;
color: #fff;
`;
export default function Stat(props){
const { value } = props;
return (
<StyledStat {...props}>
{value}
</StyledStat>;
};
Styled components props comes from the ThemeProvider usually, this is why you see a theme props while console.logging inside your styled.div
Usually in App.js you have something like that:
// src/App.jsx
import React from 'react'
import { ThemeProvider } from 'styled-components';
const theme: {
colors: {
primary: blue,
}
}
const App = () => (
<ThemeProvider theme={theme}>
<Stat />
</ThemeProvider>
)
export default App;
you can access these attributes with
${(props) => props.theme.colors.primary }
because styled-components provides its theme props to every StyledComponents (there is a Context Provider/consumer thing behind)
import React from 'react';
import styled from 'styled-components';
const Stat = styled.div`
display: flex;
align-items: center;
justify-content: center;
padding: 0 2.5em;
width: auto;
height: 2.5em;
border-radius: 0.5em;
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.2);
background: linear-gradient(160deg, ${(props) => props.theme.colors.primary} });
font-size: 1.8em;
font-family: Rubik-Medium;
color: #fff;
`;
I tried using vue-styled-compoenents to style a simple button with some text inside but the styles dont work and I get a scopedSlots issue in the parent component.
This is the code for the button and the text components in component.js
import styled from 'vue-styled-components';
export const sLabel = styled.label`
color: #000;
`;
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
${sLabel} {
color: #fff;
}
`;
This is my code in my page.
<template>
<sButton>
<sLabel>Button</sLabel>
</sButton>
</template>
<script>
import { sButton, sLabel } from './component.js'
export default {
components: {
sButton,
sLabel
}
}
</script>
This is the result I get under the sButton styles and nothing under sLabel
), scopedSlots: this.$scopedSlots
But Instead if I just use this code it works.
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
label {
color: #fff;
}
`;
The styles are applied to the parent component if I declare the parent component before the child even if the styles are under the child.
export const sButton = styled.div`
height: 1rem;
width: 2rem;
background-color: #000;
${sLabel} {
color: #fff;
}
`;
export const sLabel = styled.label`
color: #000;
`;
Can someone tell me where my code is incorrect and what is causing these issues ?
I've been trying to find the solution to my problem.
I have several Heading Tags (H1, H2 etc) each in their own file.
I would like to add some css when calling them based on a prop. Some headings have a small border-bottom and some don't. So, in order to refractor my code, I want to add some css based on a prop. I can't seem to find a way.
Here's an example of Heading H2:
import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';
const HeadingH2 = styled.h2`
color: ${colors.text};
font-family: ${fonts.montSerrat};
font-size: 1.6em;
font-weight: ${fontWeights.light};
letter-spacing: 0.2em;
padding-bottom: 0.7em;
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`;
export default HeadingH2
Example of calling Heading H2:
import React from 'react';
import HeadingH2 from '../../common/headings/heading_h2';
import HeadingBaseline from '../../common/headings_baseline';
// Features
import {SectionContainer, FeaturesContainer} from './features.style';
import Feature from './feature';
import feature1 from '../../../img/features/feature1.png';
import feature2 from '../../../img/features/feature2.png';
import feature3 from '../../../img/features/feature3.png';
// Text
import Text from '../../../content';
const Features = () => {
return(
<SectionContainer id={"what"}>
<HeadingH2>
What We Do
</HeadingH2>
<HeadingBaseline>
{Text.headingBaseline}
</HeadingBaseline>
<FeaturesContainer>
<Feature
src={feature1}
headingText={Text.feature1.heading}
paragraph={Text.feature1.paragraph}
/>
<Feature
src={feature2}
headingText={Text.feature2.heading}
paragraph={Text.feature2.paragraph}
/>
<Feature
src={feature3}
headingText={Text.feature3.heading}
paragraph={Text.feature3.paragraph}
/>
</FeaturesContainer>
</SectionContainer>
)
};
export default Features;
I want to extract the following CSS properties
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
So, assuming I have the above CSS rule in a separate file, how do I add/import them using props on my styled component HeadingH2.
Thanks for the help :)
You can also use css helper from styled-components to create a SharedStyles.js file.
In the demo you can see it in action.
Just using it in a style of an inherited component is not working as expected. If I'm adding it to StyledBase then the variables are not correctly added afterwards (hover style override stops working).
That's why I copied ${borderBottom} to each styled component Heading1 / Heading2 instead of adding it to StyledBase.
I think having a level prop for the heading is a good idea but I would handle it differently by creating a HeadingBase component and add your styles to a StyledBase component (also see code in the demo).
The HeadingBase code looks like this:
const HeadingBase = ({ className, children, level = 1 }) =>
React.createElement(`h${level}`, { className }, children);
It's a component that renders h1,h2,... tags based on the prop level passed (defaults to h1). The h-tag receives className as props (needed for styled-components) and contains the children passed to the component.
SharedStyles.js
import { css } from "styled-components";
export const borderBottom = css`
&:after{
content: "";
display: block;
height: 3px;
width: 200px;
background-color: ${props => props.color || "black"};
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
`;
Then you can import it with import { borderBottom } from "./SharedStyles"; and add it to your styled-component like following:
const Heading1= styled.h1`
${borderBottom}
`;
Something like this works:
const HeadingH2 = styled.h2`
position: ${props => props.relative && 'relative'};
padding: ${props => props.paddingBottom ? '0 0 20px 0' : '0'};
}
`;
Then use like this:
<HeadingH2 relative paddingBottom />
Possible answer:
I add the following CSS rules in a separate file like so.
I create a function which returns a string of text. I can import this function and add those rules to any component I wish.
export const borderBottom = () => {
return `
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`
}
And use it like so on any heading or component that I wish:
import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';
import {borderBottom} from '../../../../css';
const HeadingH5 = styled.h5`
color: ${colors.black};
font-family: ${fonts.montSerrat};
font-size: 1em;
font-weight: ${fontWeights.light};
letter-spacing: 0.1em;
padding-bottom: 0.45em;
margin-bottom: 25px;
${borderBottom}
`
;
export default HeadingH5;
This works for me. Any other suggestions are welcome.
You should definely check this: typestyle
the best way you can write dynamic css (for me). Works perfectly with react, even with ssr if you need it...
Why not just have a headingLevel prop? and then pass it into the styled component? And just have one StyledHeader styled component as I'm guessing the code is the mostly the same in all the heading styles files? Which is a big no no, you want to always try not to repeat your code.
const Features = () => {
return(
<SectionContainer id={"what"}>
<StyledHeader
headingLevel={headingLevel}
>
What We Do
</StyledHeader>
<HeadingBaseline>
{Text.headingBaseline}
</HeadingBaseline>
<FeaturesContainer>
<Feature
src={feature1}
headingText={Text.feature1.heading}
paragraph={Text.feature1.paragraph}
/>
<Feature
src={feature2}
headingText={Text.feature2.heading}
paragraph={Text.feature2.paragraph}
/>
<Feature
src={feature3}
headingText={Text.feature3.heading}
paragraph={Text.feature3.paragraph}
/>
</FeaturesContainer>
</SectionContainer>
)
};
export default Features;
And in your StyledHeader file
The below function will take your passed in heading level of h1, h2, h3 and will apply a border, if not the above 3 heading level it will be 0 value. I'd do some checks to ensure the value is lower case e.g. toLowerCase()
const getBorder = ({ headingLevel } ) => {
const headingLevelMap = {
h1: 0.7,
h2: 0.6,
h3: 0.6,
};
return headingLevelMap[headingLevel] || 0;
}
const HeadingH2 = styled.headingLevel`
color: ${colors.text};
font-family: ${fonts.montSerrat};
font-size: 1.6em;
font-weight: ${fontWeights.light};
letter-spacing: 0.2em;
padding-bottom: 0.7em;
border-bottom: ${getCorrectBorderBottom}em solid black
position: relative;
text-transform: uppercase;
text-align: center;
&:after{
content: "";
display: block;
height: 3px;
width: 45px;
background-color: currentColor;
/* position */
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
`;
I'd also check that if the value of the passed in headingLevel is not any of the 6 heading levels it should have a default value of whatever you want.
The above was just quick pseudo code, but hopefully get the general idea here? Let me know it comments if not.
I'd also recommend that you split your Title component out into a separate component.