Styled-Components Text or Paragraphs - javascript

Is it possible to style Text or Paragraphs with styled-components? If yes, how can I pass text into the component?
For example, I had this Footer component:
const Footer = () => (
<footer className="site-footer">
<p className="text"> HELLO</p>
<Copyright
link={'https://hotmail.com'}
text={'HELOO'}></Copyright>
</footer>
);
export default Footer;
I wanted to switch from global classes to css in js, which is why I thought of using styled-components. Now I tried this:
export const StyledText = styled.text`
text: Hellooo
color: white;
text-align: center;
`
But if I comment out the paragraph and use StyledText component, nothing shows up. If I try passing Styled Component text={'HELLO'} my app crashes. How can I convert my footer in such a way that it uses styled-components?

You can update your component to look like this:
import styled from 'styled-components';
const StyledText = styled.p`
color: white;
text-align: center;
`;
export default function Footer({text}){
return <footer className="site-footer">
<StyledText>{text}</StyledText>
<Copyright
link={'https://hotmail.com'}
text={text}/>
</footer>;
}
You will be able to call your Footer component like:
<Footer text="HELLO"/>
Hope this helps,

styled-components just deals with the styles of a component and not the content. All children will be preserved, so you can do something like this:
// JSX
<StyledText>Hello</StyledText>
// StyledText.js
export default styled.p`
color: white;
text-align: center;
`;

Yes, you can style every html element and every custom component as long its passes className.
This example covers pretty much the basic API:
const Text = styled.p`
color: blue;
text-align: center;
`;
const Copyright = ({ className, link, text }) => (
<div className={className}>
<Text>{link}</Text>
<Text>{text}</Text>
</div>
);
const StyledCopyright = styled(Copyright)`
border: 1px black solid;
${Text} {
color: palevioletred;
}
`;
const Footer = () => {
return (
<footer>
<Text>HELLO</Text>
<Copyright link="https://hotmail.com" text="World" />
<StyledCopyright link="https://hotmail.com" text="World" />
</footer>
);
};

Related

Using styled component

I have a button which need to be styled using styled component. As I am new to react I need your help in getting button color change to green on success and blue on failure. Also I have class card-preview which need to have box shadow when I hover on it while using styled component .The below code will give you an idea what I am trying to do.
import styled from "styled-components";
const Button = styled.button`
border: none;
border-radius: 10px;
padding: 7px 10px;
font-size: 1.3rem;
background: ${(props) => (props.success ? "green" : "blue")};
color: white;
`;
const Cardlist = ({ cards, title }) => {
return (
<div className="card-list">
<h2>{title}</h2>
{cards.map((card) => (
<div className="card-preview" key={card.id}>
<h2>{card.name}</h2>
if({card.status}==='success')
<Button success>{card.status}</Button>
else
<Button pending>{card.status}</Button>
</div>
))}
</div>
);
};
export default Cardlist;
For the button and CSS I think what you have should be working, though it could be more DRY. The if-else isn't valid in JSX anyway. I'm also not sure what you do with the pending prop, but it appears to be the antithesis of the success "state".
const Button = styled.button`
border: none;
border-radius: 10px;
padding: 7px 10px;
font-size: 1.3rem;
background: ${(props) => (props.success ? "green" : "blue")};
color: white;
`;
...
{cards.map((card) => (
<div className="card-preview" key={card.id}>
<h2>{card.name}</h2>
<Button
success={card.status === 'success'}
pending={card.status !== 'success'} // <-- may not be necessary
>
{card.status}
</Button>
</div>
))}
To apply some style to the card-preview div you just need to convert that to a styled-component as well.
const CardPreview = styled.div.attrs(() => ({
className: "card-preview",
}))`
:hover { // <-- sometimes you need &:hover to get the parent node
// apply box-shadow and any other CSS rules here
}
`;
Then replace the div with CardPreview component.
{cards.map((card) => (
<CardPreview key={card.id}>
<h2>{card.name}</h2>
<Button success={card.status === 'success'} >
{card.status}
</Button>
</CardPreview>
))}
See Pseudoselectors & Nesting
Update: Reagarding .attrs
This is a chainable method that attaches some props to a styled
component.
It simply allows you to specify prop values when the component is created versus when it's being used. The className prop looks to be a static "card-preview" so may as well set it once and forget it (in this specific case).

Properties background image not working [React]

I'm trying to set the background image of a div depending on the value of a component property, the background doesn't show, however it does show when I harcode the background-image property in the css file.
Here is the component code :
import React, { Component } from "react";
import "./Banner.css";
export default class Banner extends Component {
render() {
const style = {
backgroundImage: `url("${this.props.image}")`,
};
return (
<div className="banner" style={style}>
Chez vous, partout et ailleurs
</div>
);
}
}
Here is the Banner.css file:
.banner {
/* background-image: url("../assets/images/moutains.png"); */
background-size: cover;
height: 170px;
border-radius: 20px;
text-align: center;
vertical-align: middle;
line-height: 170px;
font-size: 2.5rem;
color: #fff;
}
In the parent component:
<Banner image="../assets/images/moutains.png" text="" />
EDIT: Complete code and assets here: https://github.com/musk-coding/kasa
codesandbox: https://codesandbox.io/s/github/musk-coding/kasa
Thanks in advance for your help
Since, you are trying to access the image directly in your Component using the inline CSS. You must move your image to the public folder.
CODESANDBOX LINK: https://codesandbox.io/s/image-relative-path-issue-orbkw?file=/src/components/Home.js
Code Changes:
export default class Home extends Component {
render() {
const imageURL = "./assets/images/island-waves.png";
return (
<div className="container">
<div className="slogan" style={{ backgroundImage: `url(${imageURL})` }}>
Chez vous, partout et ailleurs
</div>
<Gallery />
</div>
);
}
}
NOTE: From React Docs, you can see the ways to add images in Component. create-reac-app-images-docs. But since you want an inline CSS, in that case we have to move our assets folder into the public folder to make sure that the image is properly referenced with our component.

Render one of the component that has inside another component according to state

I'm facing an issue of rendering components following a condition. Both of the components have inside the exact component that should be rendered but not displayed.
Both of them are styled with Styled Components.
In my example, I want to display one component when clicking on the other component (footer).
Currently, I have this working:
<footer className={cx(styles.footer, { [styles.hideFooter]: hide })}>
<StyledAboutContainer>
<About />
</StyledAboutContainer>
</footer>
And I want to transform it into a Styled component way and I struggle.
I've tried to do this:
<StyledFooterContainer hide={false}>
{hide ? StyledHideFooter : StyledFooter}
<StyledAboutContainer>
<About />
</StyledAboutContainer>
</footer>
The CSS of them are:
export const StyledFooterContainer = styled.div`
max-height: 0;
`;
export const StyledFooter = styled.footer`
background: #EFF0F4;
color: #6782A4;
display: flex;
flex-flow: column nowrap;
flex-grow: 1;
max-height: 150px;
font-size: 10pt;
transition: .7s ease;
`;
export const StyledHideFooter = styled.div`
max-height: 0;
`;
Thanks.
You want to determine which footer component to use before the return statement:
const MyComponent = () => {
// Determine the footer component to use
const FooterComponent = hide ? StyledHideFooter : StyledFooter;
// Render FooterComponent
return (
<StyledFooterContainer>
<FooterComponent>
<StyledAboutContainer>
<About />
</StyledAboutContainer>
</FooterComponent>
</StyledFooterContainer>
);
};
Components are just variables, so you can store them as such.

Styling a nested styled-component from an outer one

Using styled-components, I am trying to style a nested <Input /> component that I have created, which is being used within a different component that has a dropdown appear when typing. I need to add padding-left: 3rem to this nested input but I cannot access it from the component <Dropdown />.
<Dropdown
options={options}
/>
The above is imported where I need it. I need to access the below input from the above <Dropdown />.
<div>
<Input {...props}/> // I need to edit the padding in this component
// rendered input unique to this new component would go here
</div>
The above <Input /> is imported from another component which is used in all instances where I require an input.
export const Dropdown = styled(DropDown)`
padding-left: 3rem !important;
`;
The component works fine but this fails to affect the inner padding of the Input that I need to target.
What do I do?
From what you've said, I'd suggest that the dependency of padding the Input component is with your Dropdown (which you seem to realise already).
Therefore you'd be better off having that "unqiue" styling coupled with your Dropdown component via a wrapping styled component within it.
The following example is crude (and by no means complete or working), but hopefully it illustrates how the ownership of the padding-left should be within the Dropdown and not a sporadic styled component floating some where else in your code base.
./Input/Input.jsx
const Input = ({ value }) => (
<input value={value} />
);
./Dropdown/styled.js
const InputWrapper = styled.div`
position: relative;
padding-left: 3rem !important; /* Your padding */
`;
const Icon = styled.div`
position: absolute;
top: 0;
left: 0;
width: 3rem;
height: 3rem;
background: blue;
`;
const Menu = styled.ul`/* whatever */`;
./Dropdown/Dropdown.jsx
import Input from '...';
import { InputWrapper, Icon, Menu } from './styled';
const Dropdown = ({ options }) => (
<div>
<InputWrapper>
<Icon />
<Input value={'bleh'} />
</InputWrapper>
<Menu>{options}</Menu>
</div>
);
This setup will promote reusable self-contained components.
Figured out the solution below:
export const StyledInput = styled.div`
&& #id-for-input { // specifically on the <Input />
padding-left: 3rem !important;
}
`;
<StyledInput>
<Dropdown />
</StyledInput>

Styled-components doesn't output style tag

I've set up a new project in React using Webpack, and wanted to give a try to Styled Components.
My index.js looks like this:
import React from "react"
import ReactDOM from "react-dom"
import Page from "./site/Page"
import styled from 'styled-components'
// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// Create a Wrapper component that'll render a <section> tag with some styles
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Index = props => {
return (
<Page>
<Wrapper>
<Title>Test</Title>
</Wrapper>
</Page>);
};
ReactDOM.render(<Index/>, document.getElementById("app"))
The code outputted by styled-components on the HTML page looks fine but the <style> the on the head doesn't get added, resulting in no css style at all.
<section class="sc-bwzfXH gzMTbA">
<h1 class="sc-bdVaJa bzmvhR">Test</h1>
</section>
Does somebody have any suggestions?
Take a look at this API: CSSStyleSheet.insertRule().
Styled Components inserts empty style tags for hosting these dynamically injected styles.

Categories