Parsing error in react with style-components - reactjs

I'm creating a light/dark mode switch in React with this tutorial - Tutorial Link
After adding GlobalStyles from styled-components even that I was doing all according to tutorial I receive this error:
./src/Components/Global.js
Line 13:40: Parsing error: Unterminated template
11 | align-items: center;
12 | background: ${({ theme }) => theme.body};
> 13 | color: ${({ theme }) => theme.text};
| ^
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: center;
Here is code from Global.js
import { createGlobalStyle } from 'styled-components';
export const GlobalStyles = createGlobalStyle`
*,
*::after,
*::before {
box-sizing: border-box;
}
body {
align-items: center;
background: ${({ theme }) => theme.body};
color: ${({ theme }) => theme.text};
display: flex;
flex-direction: column;
justify-content: center;
height: 100vh;
margin: 0;
padding: 0;
font-family: BlinkMacSystemFont, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
transition: all 0.25s linear;
}
And here is my App.js
import React from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { GlobalStyles } from './Components/Global';
import { ThemeProvider} from 'styled-components';
import { lightTheme, darkTheme} from './Components/Theme'
function App() {
return (
<ThemeProvider theme={lightTheme}>
<>
<GlobalStyles />
<button>Toggle theme</button>
<h1>It's a light theme!</h1>
<footer>
</footer>
</>
</ThemeProvider>
);
}
export default App;
Question: How I can fix that error and did I miss something in syntax which leads to this error?

Related

Set Background Image using props in Styled Components

This is the Home Component. I am passing the Details as props to Main component
import React from 'react'
import Main from '../components/Main'
import Navbar from '../components/Navbar'
const Home = () => {
return (
<div>
<Navbar/>
<Main
title = "Model Y"
text = "Schedule a Demo Drive"
bgImg = "../assets/model-x.jpg"
leftBtnText = "Custom Order"
rightBtnText = "View Inventory"
/>
</div>
)
}
export default Home
This is the main components
import React from 'react';
import styled from 'styled-components';
import KeyboardArrowDownOutlinedIcon from '#mui/icons-material/KeyboardArrowDownOutlined';
const Container = styled.div`
height: 100vh;
width: 100%;
/* background-image: url('../assets/model-y.jpg'); */
background-image: ${props => `url(${props.bgImage})`};
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
gap:15rem;
`;
const Heading = styled.div`
flex:3;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
`;
const Title = styled.h1`
font-size: 2.7rem;
font-weight: 700;
color:#202328;
`;
const Text = styled.p`
font-weight:500;
font-size: 1rem;
letter-spacing: 0.4px;
cursor: pointer;
color:#202328;
`;
const Line = styled.span`
height: 1.1px;
background-color: black;
width: 100%;
`;
const Buttons = styled.div`
display: flex;
align-items: center;
gap: 2rem;
`;
const Bottom = styled.div`
flex:1;
display:flex;
flex-direction: column;
align-items: center;
gap:2rem;
`;
const ButtonLeft = styled.button`
padding: 0.6rem 6rem;
border-radius: 0.5rem;
border: none;
font-size: 1rem;
font-weight: 900;
background-color: rgba(23,26,32,0.8);
color: white;
opacity:0.80;
cursor: pointer;
`;
const ButtonRight = styled(ButtonLeft)`
background-color: white;
color: #202328;
opacity:0.70;
`;
const DownArrow = styled.div`
animation:bounce infinite 1s;
color:white;
cursor:pointer;
`;
const Main = (props) => {
return (
<Container bgImage={props.bgImg}>
<Heading>
<Title>{props.title}</Title>
<Text>
{props.text}
</Text>
<Line/>
</Heading>
<Bottom>
<Buttons>
<ButtonLeft>{props.leftBtnText}</ButtonLeft>
<ButtonRight>{props.rightBtnText}</ButtonRight>
</Buttons>
<DownArrow>
<KeyboardArrowDownOutlinedIcon fontSize='large'/>
</DownArrow>
</Bottom>
</Container>
)
}
export default Main
The file structure (for Images path)
enter image description here
I want the background Image I am passing as props to be visible.
After using the above code it looks like this
enter image description here
As you can see the Image is not visible behind but in inspect you can clearly see the correct url for image is there.
Please Help.
You should import the background image.
import bg from '../assets/model-x.jpg';
and pass the imported bg to the bgImg props.
like this:
import React from 'react'
import Main from '../components/Main'
import Navbar from '../components/Navbar'
import bg from '../assets/model-x.jpg';
const Home = () => {
return (
<div>
<Navbar/>
<Main
title="Model Y"
text="Schedule a Demo Drive"
bgImg={bg}
leftBtnText = "Custom Order"
rightBtnText = "View Inventory"
/>
</div>
)
}
export default Home

React Component not loading in localhost

i am currently following a tutorial to build a react website, however, i am unable to load NavBar (code is below) on my localhost. the web pack is being complied successfully and i am able to load a normal header, just not NavBar. i have attached the codes below. appreciate all the helps and inputs. tia
video that i am following: https://www.youtube.com/watch?v=Nl54MJDR2p8&t=375s
App.js
import './App.css';
import Navbar from './components/NavBar';
import { BrowserRouter as Router } from 'react-router-dom';
function App() {
return (
<Router>
<Navbar />
</Router>
);
};
export default App;
index.js for NavBar
import React from 'react';
import { FaBars } from 'react-icons/fa';
import { Nav, NavbarContainer, NavLogo, MobileIcon, NavMenu, NavItem, NavLinks } from './NavBarElements';
const Navbar = () => {
return (
<>
<Nav>
<NavbarContainer>
<NavLogo to='/'>Blockchain Voting System</NavLogo>
<MobileIcon>
<FaBars />
</MobileIcon>
<NavMenu>
<NavItem>
<NavLinks to="about">About</NavLinks>
</NavItem>
</NavMenu>
</NavbarContainer>
</Nav>
</>
);
};
export default Navbar;
NavBarElements.js
import styled from 'styled-components'
import { Link as LinkR } from 'react-router-dom'
import { Link as LinkS } from 'react-scroll'
export const Nav = styled.nav`
background: #000;
height: 80px;
// margin-top: -80px;
display: flex;
justify-content: center;
align-items: center;
font-size: 1rem;
position: sticky;
top: 0;
z-index: 10;
#media screen and (max-width: 960px){
transition: 0.8s all ease;
}
`;
export const NavbarContainer = styled.div`
display: flex;
justify-content: space-between;
height: 80px;
z-index: 1;
width: 100%;
padding: 0 24px;
max-width: 1100px;
`;
export const NavLogo = styled(LinkR)`
color: red;
justify-self: flex-start;
cursor: pointer;
font-size: 1.5rem;
display: flex;
align-items: center;
margin-left: 24px;
font-weight: bold;
text-decoration: none;
`;
export const MobileIcon = styled.div`
display: none;
#media screen and (max-width: 768px) {
display: block;
position: absolute;
top: 0;
right: 0;
transform: translate(-100%, 60%);
font-size: 1.8rem;
cursor: pointer;
}
`;
export const NavMenu = styled.ul`
display: flex;
align-items: center;
list-style: none;
text-align: center;
margin-right: -22px;
#media screen and (max-width: 768px) {
display: none;
}
`;
export const NavItem = styled.li`
height: 80px;
`;
export const NavLinks = styled(LinkS)`
color: #fff;
display: flex;
align-items: center;
text-decoration: none;
padding: 0 1 rem;
height: 100%;
cursor: pointer;
&.active {
border-bottom: 3px solid #01bf71;
}
`;

Passing custom props to styled-component in typescript [duplicate]

This question already has answers here:
Using styled-components with props and TypeScript
(8 answers)
Closed 1 year ago.
I'm new to React with Typescript and Styled-Component and I came across this issue. I created a 'Header' component and I was trying to pass the state whenever the button is clicked into the HeaderStyled as a probs to change the CSS style depends on the state but I got error.
import React, {useState} from 'react'
import HeaderStyled from './Header_styled';
const Header = () => {
const [open,setOpen] = useState(false);
return (
<HeaderStyled open={open}>
<img src="/images/logo.svg" alt="sunnyside_logo" />
<ul>
<li>About</li>
<li>Services</li>
<li>Projects</li>
<li><button>CONTACT</button> </li>
</ul>
<div onClick={() => setOpen(!open)}>
<div></div>
<div></div>
<div></div>
</div>
</HeaderStyled>
)
}
export default Header;
Here is my HeaderStyled component
const HeaderStyled = styled.div `
background-color: ${theme.primaryBlue};
display: flex;
justify-content: flex-end;
padding: 20px 20px;
align-items: center;
ul {
position: absolute;
background-color: white;
top: 6%;
width: 80%;
height: 25%;
right: 10%;
display: flex;
flex-direction: column;
padding: 0px;
align-items: center;
justify-content: space-around;
transform: ${({open}) => open ? 'translateX(0)': 'translateX(120%)'};
li {
padding: 0px;
a {
color: #0000002e;
}
}
button {
background-color: yellow;
color: black;
}
}
The error I got from HeaderStyled
Have a look in the Styled Components docs for Typescript - Using custom props
import React, { useState } from "react";
import styled from "styled-components";
interface Props {
open: boolean;
}
const HeaderStyled = styled.div<Props>``;
const Header = () => {
const [open, setOpen] = useState(false);
return <HeaderStyled open={open}></HeaderStyled>;
};
export default Header;
The way to do it in TS is to define a type or an interface and add that to the styled component:
type HeaderStyledProps = {
open: boolean;
}
const HeaderStyled = styled.div<HeaderStyledProps>`
background-color: ${theme.primaryBlue};
display: flex;
justify-content: flex-end;
padding: 20px 20px;
align-items: center;
ul {
position: absolute;
background-color: white;
top: 6%;
width: 80%;
height: 25%;
right: 10%;
display: flex;
flex-direction: column;
padding: 0px;
align-items: center;
justify-content: space-around;
transform: ${({open}) => open ? 'translateX(0)': 'translateX(120%)'};
li {
padding: 0px;
a {
color: #0000002e;
}
}
button {
background-color: yellow;
color: black;
}
}
`

Styling multiple React apps with styled-components / styled-theming

I have a bunch of content-similar React apps to style, and I'm trying to shape a system, based on Styled-Components/Styled-Theming, to rule and modify their global styles just by changing the <ThemeProvider /> theme prop.
I've been trying different options, and this is what seems to work best :
an external themes.js file with all styles wrapped in a global object
import theme from "styled-theming";
const backG = theme.variants("observatory", "backG", {
positiveDark: {
_OBS1: 'hsl(73, 65%, 50%)',
_OBS2: 'hsl(210, 100%, 60%)',
},
negativeDark: {
_OBS1: 'hsl(8, 70%, 63%)',
_OBS2: 'hsl(0, 100%, 90%)',
},
actionDark: {
_OBS1: 'hsl(53, 82%, 62%)',
_OBS2: 'hsl(48, 100%, 50%)',
},
});
const cursor = theme.variants("observatory", "cursor", {
normal: {
_OBS1: 'initial',
_OBS2: 'initial',
},
pointer: {
_OBS1: 'pointer',
_OBS2: 'pointer',
},
});
const fontS = theme.variants("observatory", "fontS", {
h1: {
_OBS1: "2.4rem",
_OBS2: "2.25rem",
},
h2: {
_OBS1: "2.2rem",
_OBS2: "2rem",
},
h3: {
_OBS1: "2rem",
_OBS2: "1.75rem",
},
});
const flexL = theme.variants("observatory", "flexL", {
layout1: {
_OBS1: "; display: flex; justify-content: center;",
_OBS2: "; display: flex; justify-content: center;",
},
layout2: {
_OBS1: "; display: flex; justify-content: space-around; align-items: flex-start;",
_OBS2: "; display: flex; flex-direction: column; align-items: flex-start;",
},
layout3: {
_OBS1: "; display: flex; flex-direction: column; align-items: flex-start;",
_OBS2: "; display: flex; justify-content: space-around; align-items: flex-start;",
}
});
const themes = {
backG: backG,
cursor: cursor,
flexL: flexL,
fontS: fontS,
}
export {themes};
a CRA representing my app, with
an index.js file with 2 <ThemeProvider />, the first one referencing the external file, the second one dealing with themes inside of that external file
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
// styles
import {themes} from "./themes";
import {ThemeProvider} from "styled-components";
ReactDOM.render(
<ThemeProvider theme={themes}>
<ThemeProvider theme={{ observatory: "_OBS2" }}>
<App />
</ThemeProvider>
</ThemeProvider>,
document.getElementById('root')
);
an App.js file and other children components
import React from 'react';
// styles
import styled, { injectGlobal } from "styled-components";
// components
import ThreeButtons from "./ThreeButtons";
injectGlobal`
#import url('https://fonts.googleapis.com/css?family=Quicksand:400,500');
html {
font: 400 10px Roboto, sans-serif;
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
font: 500 1.8rem Quicksand;
}
`
const Wrapper1 = styled.div`
display: ${props => props.theme.flexL};
align-items: ${props => props.theme.flexL};
`
const App = () => (
<Wrapper1 flexL="layout1">
<ThreeButtons alignSelf1="center" flexL="layout2" />
<ThreeButtons alignSelf2="flex-end" flexL="layout3" />
</Wrapper1>
);
export default App;
import React from "react";
// styles
import styled from "styled-components";
// components
import Button from "./Button";
const Wrapper1 = styled.div`
flex: 1;
display: ${props => props.theme.flexL};
flex-direction: ${props => props.theme.flexL};
align-items: ${props => props.theme.flexL};
`
const ThreeButtons = (props) => (
<React.Fragment>
<Wrapper1
flexL={props.flexL}
>
<Button
backG="positiveDark"
cursor="pointer"
fontS="h1"
label="lg-pos-button-pointer"
/>
<Button
alignSelf={props.alignSelf1}
backG="negativeDark"
cursor="pointer"
fontS="h2"
label="md-neg-button-pointer"
/>
<Button
alignSelf={props.alignSelf2}
backG="actionDark"
cursor="normal"
fontS="h3"
label="sm-act-button-nopointer"
/>
</Wrapper1>
</React.Fragment>
)
export default ThreeButtons;
import React from "react";
// styles
import styled from "styled-components";
const StyledButton = styled.button`
align-self: ${props => props.alignSelf};
background: ${props => props.theme.backG};
font-size: ${props => props.theme.fontS};
cursor: ${props => props.theme.cursor};
padding: 1.2rem 1.8rem;
border: none;
border-radius: .3rem;
margin: 1rem;
filter: saturate(50%);
transition: filter ease-in-out .15s;
&:hover {
filter: saturate(100%);
}
`
const Button = (props) => (
<StyledButton
backG={props.backG}
cursor={props.cursor}
alignSelf={props.alignSelf}
fontS={props.fontS}
>
{props.label}
</StyledButton>
)
export default Button;
Like I said before, it looks like it works, but still there're 2 things I'm not really comfortable with because I don't get it :
in the themes.js external file, I've been trying to create some kind of Flexbox mixins : to make it work, I must add an initial semicolon in the string value, or the first property is not considered and its value is not applied. Can someone explain me why ?
in the index.js file, I must nest a <ThemeProvider /> inside another one to make it work correctly : again, can someone explain me how Styled-Components and Styled-Theming are working together ?
generally speaking, have you got any tips or advice to make my solution a better solution or to solve my initial problem, which was to globally style a bunch of content-similar React apps ?
If you need, you can find the entire code on GitHub : https://github.com/paillenapple/styles_sandbox
Thanks for your help.
Silvère

React Styled Components Extend

i'm trying to re-use and extend a styled-component with no luck. I suspect i haven't quite grasped how to properly use styled-components
I have a component that renders a chevron icon, based on what icon prop is passed to it. What i want to be able to do is export this component, then import it and extend its styles. ie - in this example remove its padding in Header.jsx:
Chevron.jsx
import React from 'react'
import styled from 'styled-components'
const StyledChevron = styled.i`
display: flex;
align-items: center;
justify-content: center;
padding: 14px;
cursor: pointer;
border-left: 1px solid #efefef;
transition: all .1s linear;
transform: rotate(0deg);
${props=>props.closed && ``};
&:hover {
background: #f7f4f4;
}
`
const Chevron = (props) => {
return (
<StyledChevron closed={props.item.closed} onClick={()=>{props.openSubMenu(props.item.id)}} className={props.icon}/>
)
}
export default Chevron
Header.jsx
import React from 'react'
import styled from 'styled-components'
import cssvars from '../../js/style/vars'
import Chevron from './Chevron'
const StyledHeader = styled.div`
display: flex;
align-items: center;
padding: 11px;
justify-content: space-between;
background: ${cssvars.primaryColor};
h2 {
font-size: 19px;
color: #fff;
display: flex;
align-items: center;
}
`
const BackChevron = Chevron.extend`
padding: 0
`
const Header = (props) => {
return (
<StyledHeader>
<h2>{props.item.title}</h2>
<BackChevron {...props} icon="icon-arrow-left"/>
</StyledHeader>
)
}
export default Header
With the above code, im getting console error: Uncaught TypeError: _Chevron2.default.extend is not a function
styled-components has some kind of inheritance
Chevron.jsx
import React from 'react'
import styled from 'styled-components'
const StyledChevron = styled.i`
display: flex;
align-items: center;
justify-content: center;
padding: 14px;
cursor: pointer;
border-left: 1px solid #efefef;
transition: all .1s linear;
transform: rotate(0deg);
${props => props.closed && ``};
&:hover {
background: #f7f4f4;
}
`
const Chevron = (props) => (
<StyledChevron
closed={props.item.closed}
onClick={() => props.openSubMenu(props.item.id)}
className={props.icon}
/>
)
export default Chevron
Header.jsx
import React from 'react'
import styled from 'styled-components'
import cssvars from '../../js/style/vars'
import Chevron from './Chevron'
const StyledHeader = styled.div`
display: flex;
align-items: center;
padding: 11px;
justify-content: space-between;
background: ${cssvars.primaryColor};
h2 {
font-size: 19px;
color: #fff;
display: flex;
align-items: center;
}
`
const BackChevron = styled(Chevron)`
padding: 0
`
const Header = (props) => (
<StyledHeader>
<h2>{props.item.title}</h2>
<BackChevron {...props} icon="icon-arrow-left"/>
</StyledHeader>
)
export default Header
as said in #yury-tarabanko comment

Resources