Trying to access a custom prop in styled components - reactjs

Hi I'm trying to access a custom prop in a styled-component.I know that this is a very basic thing but I can't figure it out. I think that it has something to do with the way how I access my theme.
It does not throw any error but the margin-bottom value is just not showing up in the printed css.
Can you point me in a direction? Thanks!
import StyledWrapper from './productCardStyles';
<StyledWrapper spaceBelow={spaceBelow}>
hello world
</StyledWrapper>
//productCardStyles.js
export default styled('div')(
({ theme }) => `
background: red;
margin-bottom: ${props => (props.spaceBelow ? '25px' : '0')};
`);
Thank you very much for your time.

I assume you are using ThemeProvider in the higher order component. You can access theme by just using props.theme...
Update your productCardStyles.js
import styled from 'styled-components'
const wrapper = styled.div`
background: red;
margin-bottom: ${props => (props.spaceBelow ? '25px' : '0')};
color: ${props => props.theme.primaryColor} // to access theme
`
export default wrapper

Related

styled-components — how to use :not() selector on a prop?

Let's say I have an element with a property "selected":
<Button selected>
Text
</Button>
const Button = styled.div`
&:not(???) {
color: red;
}
`;
How do I select all instances of Button which don't have the "selected" property?
Maybe there is another way to do what I'm trying to achieve?
Сlarification edit:
I actually need to use :not together with :hover, like this:
const Button = styled.div`
&:not(???):hover {
color: red;
}
`;
styled-components uses some template magic to allow you to access passed props like so:
const Button = styled.div`
color: ${props => props.selected ? "color when selected" : "red"};
`;
With styled-components, this tends to be the more idiomatic way of setting things based on props rather than using CSS selectors.
That's how you can do it:
const Button = styled.div`
${props => !props.selected && css`
:hover {
color: red;
}`
}
`;
Don't forget to import css from styled-components;

Using Storybook to show React components in both React & Plain HTML/CSS

so if I have a React Button component that uses styled component like so:
import styled, { css } from "styled-components";
import React from "react";
const Button = ({ theme, children }) => {
const StyledButton = styled.a`
padding: 10px 20px;
border-radius: 20px;
${theme === "primary" &&
css`
color: black;
background: white;
`}
${theme === "secondary" &&
css`
color: white;
background: black;
`}
`;
return <StyledButton>{children}</StyledButton>;
};
export default Button;
Is it possible to display this component, alongside its React code & HTML/CSS code on Storybook? (Without having to hard code the HTML/CSS code in)
I was thinking of using React's renderToString() to convert it into HTML and using the styled component's string for the CSS. Not sure if this is possible?
Yes, it is a storybook addon, not a React API.
See storysource addon.

Emotion.js how to do composition / conditional styling in react-native?

https://github.com/emotion-js/emotion/tree/master/packages/native
gives example
style={css`
border-radius: 10px;
`}
However, I can't figure out how I can do composition as done in https://emotion.sh/docs/composition with react-native
<div css={[danger, base]}>
Nor I can't do conditional styling as done in https://emotion.sh/docs/styled
const Button = styled.button`
color: ${props =>
props.primary ? 'hotpink' : 'turquoise'};
`
Even if I could do, they use two different methods one using css one using styled . How can I get the two at the same time with react-native?
Question 1: How to do composition in emotion/native in React Native?
It's really simple all you need to is use style property like so:
const style1 = css`
font-size: 40px;
`
const color = css`
color: red;
`
// And then in your component you can pass the all your style objects
// in an array to style property
<Text style={[fontSize, color]}>Hello world</Text>
Question 2: Conditional style in emotion/native in React Native?
const Description = styled.Text`
font-size: ${props => props.fontSize !== undefined ? props.fontSize : "40px"};
color: hotpink;
`
<Description fontSize={"60px"}>
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Description>
Here's a working exampe as a snack

Invariant Violation: "borderLeft" is not a valid style property

I'm using styled-components in a React Native project and I'm trying to set a left border in a text component.
import React, { Component } from 'react';
import styled from 'styled-components';
const TitleText = (props) => {
return (
<Text>{props.text}</Text>
);
};
const Text = styled.Text`
font-family: ${props => props.theme.fontFamily};
color: ${props => props.theme.darkBlue};
border-left: 1px solid #000;
`;
The problem is that after adding border-left: 1px solid #000and reload the app, it shows: "Invariant Violation: "borderLeft" is not a valid style property".
How can I add a left border to that component using styled components?
I don't believe it's possible to directly set the border left (or top, right, bottom) style property on components in react native.
This is likely to be the cause of your error, in that there is no mapping from border-left to any equivalent styling property in react native.
Your best best might be to explicitly specify the border property values per side as follows:
const Text = styled.Text`
font-family: ${props => props.theme.fontFamily};
color: ${props => props.theme.darkBlue};
/* Note that react native typically requires the same
border style to be applied to all sides of a component
that supports borders */
border-style: solid;
/* Most components in react native support unique border width and
colors on each side of the component */
border-left-color: #000;
border-left-width: 1px;
`;
Following changes should solve the issue-
import React, { Component } from 'react';
import styled from 'styled-components';
const TitleText = (props) => {
return (
<Text>{props.text}</Text>
);
};
const Text = styled.Text`
font-family: ${props => props.theme.fontFamily};
color: ${props => props.theme.darkBlue};
border-left-width: 1px;
border-left-style : solid;
border-left-color : #fff
`;
Refer following links for available properties -
Layout Props
StyleSheetGuide

How to load a imported component dynamically based on its name inside a styled element?

today i have a question concerning the REACT package styled-components.
What I'm trying to accomplish is to create a styled div-component, which will be used as a parallax-container and has to load a certain image as its background.
Now I could probably just import the image into the file and call it using ${imgComponentName} while being inside the styled.div.
But I'm trying to be able to load the same Parallax-component with multiple images, whose names i want to pass as a prop on calling the Parallax-component like <Parallax bgi="mountain">.
My current code looks as follows:
import PropTypes from 'prop-types'
import styled from 'styled-components'
import hills from '../static/img/home/hills.jpeg'
import mountain from '../static/img/home/mountain.jpeg'
const bgi = props => props.bgi ? props => props.bgi : "mountain"
export const Parallax = styled.div`
display: flex;
align-items: center;
justify-content: center;
min-height: 80vh;
background-image: url(${bgi});
background-attachment: fixed;
background-size: cover;
flex-direction: column;
`
Parallax.propTypes = {
bgi: PropTypes.oneOf(['mountain', 'hills'])
}
Is there a way of calling the imported image by its name with the string, that was passed as the prop bgi?
Best regards,
Patrick
P.S.
I'm aware of the extend-syntax, but i wanted to try to solve the problem trough one styled component.
You can use require like this
const bgi = props => props.bgi ? props => require(props.bgi) : "mountain"
or
background-image: url(${require(bgi))}
I am not 100% sure, but I think you have to pass the props someway different. You have to remember, that you are actually only passing a string, that gets converted to a css class in the DOM and returns a React Component.
For example this docu here: https://www.styled-components.com/docs/basics#attaching-additional-props
maybe something like this:
const Parallax = styled.div.attrs({
url: props => props.bgi ? props => props.bgi : "mountain"
})`
background-image: url(${props => props.url});
`;
Did you try to inline it? Like this:
const Parallax = styled.div`
background-image: url(${props => props.bgi ? props => props.bgi : "mountain"});
`

Resources