How to use styled component on a React application - reactjs

I have been trying to change the styling from bulma to Styled components on my react application but I am facing some issues while trying to implement it inside my function.
import React, {FC} from 'react';
import styled from 'styled-components';
const theme = styled.div`
text-align: center;
background-color: #535151;
font-style: bold;
`;
const H1 = styled.h1`
font-size: 60pt;
font-style: Verdana;
color: black;
`;
interface HeaderProps {
title: string;
subtitle: string;
}
const Header: FC<HeaderProps> = ({title, subtitle}) =>{
return (
<>
<theme>
<H1 className="title mb-3">{title}</H1>
<h2 className="subtitles mt-0">{subtitle}</h2>
</theme>
</>
);
}
export default Header;

import React from 'react';
import styled from 'styled-components';
const Template = styled.a`
background-color: red;
`;
export const Test = () => {
return(
<>
<Template>Hello</Template>
</>
)
}
Try this.

Related

Component content not imported when importing styled components

I am building a site using React and have decided to use Styled Components. I have a component that is styled with Styled Components and is receiving a prop from my homepage where I am using an instance of this component. I have the styling being pulled into the homepage, but it is not pulling in the content of the component. When if I just pull in the whole component it pulls in the content fine, but it doesn't allow me to pass the prop, but if I import the component styling it doesn't pull in the content of the component, but the prop passes properly. So I need some help with how to pull in the content and styling and get the prop to pass.
I am pretty new to Gatsby and Styled Components so thanks for any help.
My Component Code
import React from 'react'
import styled from "styled-components"
import { useStaticQuery, graphql } from 'gatsby'
export const WhyChooseSection = styled.section`
border-bottom: 1px solid var(--charcoal);
`
export const WhyChooseH2 = styled.h2`
display: ${(props) => props.displayH2};
text-align: center;
`
export const WhyChooseContent = styled.div`
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
width: 100%;
max-width: 1160px;
margin: 0 auto;
padding-top: 40px;
padding-bottom: 40px;
column-gap: 100px;
row-gap: 30px;
#media(min-width: 992px) {
justify-content: space-between;
column-gap: 0;
}
.why-icon {
width: 180px;
height: 145px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
p {
margin-bottom: 0;
font-size: 19px;
font-weight: var(--font-bold);
}
}
`
export function WhyChooseIcons() {
const data = useStaticQuery(graphql`
{
whyChooseIcons: allWp {
nodes {
acfOptionsOfficeSettings {
whyChooseInteriorDetails {
whyChooseIcons {
whyChooseIconGraphic {
altText
id
sourceUrl
}
whyChooseIconTitle
}
}
}
}
}
}
`)
return (
<>
{data.whyChooseIcons.nodes.map((node, index) => (
<WhyChooseSection key={index}>
<WhyChooseH2>Why Choose Interior Details?</WhyChooseH2>
<WhyChooseContent>
{node.acfOptionsOfficeSettings.whyChooseInteriorDetails.whyChooseIcons && node.acfOptionsOfficeSettings.whyChooseInteriorDetails.whyChooseIcons.map((item) => (
<div className='why-icon' key={item.whyChooseIconGraphic.id}>
<img src={item.whyChooseIconGraphic.sourceUrl} alt={item.whyChooseIconGraphic.altText} />
<p>{item.whyChooseIconTitle}</p>
</div>
))}
</WhyChooseContent>
</WhyChooseSection>
))}
</>
)
}
export default WhyChooseIcons
My Homepage Code
import * as React from "react"
// import styled from "styled-components"
import { graphql } from 'gatsby'
import Seo from "../components/seo"
import Hero from '../components/heroComponent'
import { WhyChooseSection } from '../components/whyChooseIcons'
import { WhyChooseH2 } from '../components/whyChooseIcons'
import { WhyChooseContent } from '../components/whyChooseIcons'
import HomeProducts from '../components/homeProducts'
import HomeTestimonials from '../components/testimonials'
import HomeNewHomes from '../components/homeNewHomes'
import HomeFamilyTreatment from '../components/homeFamilyTreatment'
import HomeSolutions from '../components/homeSolutions'
import HomeMotorization from '../components/motorizationComps'
import HomeBrands from '../components/homeBrands'
import CTAOne from '../components/ctaOne'
const IndexPage = (hero) => {
const heroData = hero.data.homeHero
return (
<>
{heroData.edges.map(({ node }, index) => (
<Hero key={index} heroTitle={node.template.homePage.heroH1} heroSubTitle={node.template.homePage.heroParagraph} heroBg={node.template.homePage.heroBackground.gatsbyImage} heroBtnOneText={node.template.homePage.heroButton1Text} heroBtnOneURL={node.template.homePage.heroButton1Url} heroBtnTwoText={node.template.homePage.heroButton2Text} heroBtnTwoURL={node.template.homePage.heroButton2Url} />
))}
<WhyChooseSection>
<WhyChooseH2 displayH2="none"></WhyChooseH2>
<WhyChooseContent></WhyChooseContent>
</WhyChooseSection>
<HomeProducts />
<HomeTestimonials />
<HomeNewHomes />
<HomeFamilyTreatment />
<HomeSolutions />
<HomeMotorization />
<HomeBrands />
<CTAOne />
</>
)
}
export default IndexPage
export const Head = () => <Seo title="Home" />
export const HeroContent = graphql`
{
homeHero: allWpPage(filter: {template: {templateName: {eq: "Home Template"}}}) {
edges {
node {
template {
... on WpHomeTemplate {
homePage {
heroH1
heroParagraph
heroButton1Text
heroButton1Url
heroButton2Text
heroButton2Url
heroBackground {
gatsbyImage(placeholder: BLURRED, width: 1920)
altText
}
}
}
}
}
}
}
}
`
Since you only want to pass a prop into your <WhyChooseIcons> component and that the component itself renders its own content, there is no need to provide any children node to it in the consuming parent.
Simply update your <WhyChooseIcons> component to accept a prop that it will pass to its inner child. Let's name it displayH2 and we can simply pass it into the <WhyChooseH2> component by doing this: <WhyChooseH2 displayH2={displayH2}>. So your component definition now looks like this:
export function WhyChooseIcons({ displayH2 }) {
// Rest of the component logic here
return (
<>
{data.whyChooseIcons.nodes.map((node, index) => (
<WhyChooseSection key={index}>
<WhyChooseH2 displayH2={displayH2}>Why Choose Interior Details?</WhyChooseH2>
{/* Other content here */}
</WhyChooseSection>
))}
</>
)l
};
Then in the file where you consume this component, it is just a matter of passing "none" to the prop:
<WhyChooseSection displayH2="none">
HOWEVER this feel like a XY problem to me, because all you want is to control the conditional rendering of this component. What you can do is to create a prop on your component that determines whether <WhyChosseH2> should be rendered or not.
export const WhyChooseH2 = styled.h2`
text-align: center;
`
export function WhyChooseIcons({ shouldHideH2 }) {
return (
<>
{data.whyChooseIcons.nodes.map((node, index) => (
<WhyChooseSection key={index}>
{!shouldHideH2 && <WhyChooseH2>Why Choose Interior Details?</WhyChooseH2>}
{/* Other content here */}
</WhyChooseSection>
))}
</>
)
}
Then you can just control H2 rendering with a true/false boolean:
{/* To show it, just don't set the prop */}
<WhyChooseIcons />
{/* To hide it, both ways are valid */}
<WhyChooseIcons shouldHideH2 />
<WhyChooseIcons shouldHideH2={true} />

Can't style #mui Avatar icon with styled-components

I'm playing around with styled-components and having troubles working with material-ui. So thats the code:
import React from "react";
import styled from "styled-components";
import ChatIcon from "#mui/icons-material/Chat";
import MoreVertIcon from "#mui/icons-material/MoreVert";
import { Avatar} from "#mui/material";
function Sidebar() {
return (
<Container>
<Header>
<UserAvatar className={"override"} />
<IconsContainer>
<IconButton>
<ChatIcon />
</IconButton>
<IconButton>
<MoreVertIcon />
</IconButton>
</IconsContainer>
</Header>
</Container>
);
}
export default Sidebar;
const Container = styled.div``;
const Header = styled.div`
display: flex;
position: sticky;
top: 0;
background-color: white;
z-index: 1;
justify-content: space-between;
align-items: center;
padding: 15px;
height: 80px;
border-bottom: 1px solid whitesmoke;
`;
const UserAvatar = styled(Avatar)`
height: 60px;
`;
const IconsContainer = styled.div`;
The styled div is working completely fine, but when I import 'Avatar' from #mui and try to add some styling named UserAvatar, it is completely ignoring what I'm writing down.
I think that with mui they have their own version of styled for styled components. https://mui.com/system/styled/
It appears they want you to use it rather than styled-components
import Button from '#mui/material/Button';
import { styled } from '#mui/material/styles';
const CustomButton = styled(Button)({
// your custom styles go here
}) as typeof Button;
see the import from import { styled } from '#mui/material/styles';;

Override them with styled components

I want to creare a template theme in React for my software suite and allow developers to customize the theme for each software they develop.
The theme will be shipped in a library using styled components
Here is an example of the code:
import styled from 'styled-components'
const ButtonStyled = styled.button`
font-size: 1.5em;
text-align: center;
color: green;
`;
const TomatoButton = styled(ButtonStyled)`
color: tomato;
`;
//This is the default template
const DefaultTemplate = () => {
return <div>
<ButtonStyled className='button'>Button</ButtonStyled>
<TomatoButton className='tomato-button'>Button II</TomatoButton>
</div>
}
//This is the template styled by developers
const DefaultTemplateStyled = styled(DefaultTemplate)`
color: white;
&.button{
color: violet
}
&.tomato-button{
color: black;
}
`;
function App() {
return (<DefaultTemplateStyled />);
}
export default App;
In this app I cannot see the override of the styles, am I missing something?
In styled-components what you should do is pass the className propm like this:
//This is the default template
const DefaultTemplate = ({ className }) => {
return (
<div>
<ButtonStyled className={`button ${className}`}>Button</ButtonStyled>
<TomatoButton className={`tomato-button ${className}`}>
Button II
</TomatoButton>
</div>
);
};
All the other code is fine

How to add style to a component with styled component react?

I'm trying to add style to a component.
It works fine with a component imported from the material-ui library, but it doesn't work when it comes to my original component(that is not used in any library).
Here is the code for style with styled-component
import styled from "styled-components";
import List from "./List";
import AcUnitIcon from "#mui/icons-material/AcUnit";
export const ListCotainer = styled(List)` // doesn't apply style
margin: 100px;
color: pink;
`;
export const Container = styled.div` // applies style
font-family: sans-serif;
text-align: center;
background-color: red;
`;
export const Icon = styled(AcUnitIcon)` // applies style
background-color: blue;
margin: 100px;
padding: 20px;
${Container}:hover & {
background-color: green;
}
`;
App.js
import { ListCotainer, Container, Icon } from "./styles";
export default function App() {
return (
<Container>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<ListCotainer />
<Icon />
</Container>
);
}
List.js (regular component with no library)
import React from "react";
const List = () => {
return (
<div>
<h1>Hello styled component</h1>
</div>
);
};
export default List;
Is there any way I can add style to the List component?
you need to create styled CSS same as you have created for Container in your App.js. i have update your code it should work for you.
styles.js
import styled from "styled-components";
import AcUnitIcon from "#mui/icons-material/AcUnit";
export const ListCotainer = styled.div`
margin: 100px;
width: 200px;
color: pink;
`;
export const Container = styled.div`
font-family: sans-serif;
text-align: center;
background-color: red;
`;
export const Icon = styled(AcUnitIcon)`
background-color: blue;
margin: 100px;
padding: 20px;
${Container}:hover & {
background-color: green;
}
`;
List.js
import React from "react";
import { ListCotainer } from "./styles";
const List = () => {
return (
<ListCotainer>
<h1>Hello styled component</h1>
</ListCotainer>
);
};
export default List;
App.js
import { Container, Icon } from "./styles";
import List from "./List";
export default function App() {
return (
<Container>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<List />
<Icon />
</Container>
);
You may not be able to style like this component and what you are applying to the style material component is a svg/icon that you can apply to icons and img with style components.
style.js
import styled from "styled-components";
import AcUnitIcon from "#mui/icons-material/AcUnit";
export const ListCotainer = styled.div`
margin: 100px;
width: 200px;
color: pink;
`;
export const Container = styled.div`
font-family: sans-serif;
text-align: center;
background-color: red;
`;
export const Icon = styled(AcUnitIcon)`
background-color: blue;
margin: 100px;
padding: 20px;
${Container}:hover & {
background-color: green;
}
`;
App.js
import { Container, Icon } from "./styles";
import List from "./List";
export default function App() {
return (
<Container>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<List />
<Icon />
</Container>
);
}
List.js
import React from "react";
import { ListCotainer } from "./styles";
const List = () => {
return (
<ListCotainer>
<h1>Hello styled component</h1>
</ListCotainer>
);
};
export default List;

Why my styled component not work with text-decoration?

I'm trying to remove underline for my Link in react by using styled-components
if I use style={{textDecoration: "none"}} it will work but when I use text-decoration: none; in my styled components it won't work:
here is my js code:
import React from "react";
import styled from "styled-components";
import { Link } from "#reach/router";
import { CSSTransition, TransitionGroup } from "react-transition-group";
const StyleNavbarContainer = styled.nav`
background-color: #333333;
width: 100%;
color: #d6d6d6;
position: fixed;
text-align: center;
top: 0;
`;
const AppleLogo = styled.div`
font-size: 20px;
display: inline-block;
`;
const StyleLinkList = styled.ul`
display: inline-block;
`;
const StyledLink = styled(Link)`
padding: 12px 10px;
color: #d6d6d6;
text-decoration: none;
`;
const Navbar = (props) => {
return (
<>
<StyleNavbarContainer>
<AppleLogo>
<i class="fab fa-apple"></i>
</AppleLogo>
<StyleLinkList>
<StyledLink to="/">Mac</StyledLink>
</StyleLinkList>
</StyleNavbarContainer>
</>
);
};
export default Navbar;
add my App.jsx file here is the code:
import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "./components/Navbar";
function App() {
return (
<div className="App">
<Navbar />
</div>
);
}
export default App;
Need to remove import "bootstrap/dist/css/bootstrap.min.css"; from App.jsx

Resources