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

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

Related

custom props doesn't work in material-ui components

i want to add ( background & color ) custom props, to the mui button, like this:
<ButtonCustom bg="#6415ff" color="#f7fafc">Sign Up</ButtonCustom>
<ButtonCustom bg="#e2e8f0" color="#4a5568">Search</ButtonCustom>
file: ButtonCustom.js
import Button from "#mui/material/Button";
import { styled } from "#mui/system";
const ButtonStyled = styled(Button)`
background-color: ${({ bg }) => bg};
color: ${({ color }) => color};
padding: 16px 0;
&:hover {
background-color: #5011cc;
}
font-size: 16px;
width: 12rem;
`;
export default ButtonStyled;
But it will give me this error:
TypeError
Cannot read properties of undefined (reading 'main')
so my question is : how can i add more than one custom props??
Thank you very much for giving me time and answering this question.

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.

Extend a Styled Component from a different file

What I'm trying to achieve is to be able to add extra styling to my Button.tsx(essentially extending the styles) when using this component in different files. As you can see in my Button.tsx I have defined some default styles I would like the button to have, but as I use more buttons across my app, I might want to change the background or color, etc.
One thing I could do is this:
Example of not what I want to do:
import React from 'react'
import styled from 'styled-components'
interface IButton = {
children: string
}
export default function Button({ children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
const RedButton = styled(Button)`
// Inherits all of the styles from Button.
background: red;
`
return (
<Button>{children}</Button
)
}
This example will inherit my Button styles and then allows me to extend. The problem with this solution is, if I decide to add more buttons, I will always have to come back to this file and then add the different variants, which could start to make this file get pretty chunky and messy.
Ideally I would like to extend my <Button> from the App.tsx file, or which ever file I'm using my <Button> in.
How could I adjust the code below to achieve this?
Button.tsx
import React from 'react'
import styled from 'styled-components'
interface IButton = {
children: string
}
export default function Button({ children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
return (
<Button>{children}</Button
)
}
App.tsx
import React from 'react'
import styled from 'styled-components'
export default function App() {
return (
{/* This button would render with the default styles from Button.tsx */}
<Button>Button One</Button>
{/* This button would render with extended styles, a blue background for example */}
<Button>Button Two</Button>
)
}
In your App.tsx you can do the same:
const BlueButton = styled(Button)`
background: blue;
`
what styled-components does is it creates a class with background blue and pass it to your Button. so in your Button.tsx you need to accept the css class
export default function Button({ className, children }: IButton) {
const Button = styled.button`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
return (
<Button className={className}>{children}</Button
)
}
Edit
another way to do is to export the style like this
const BaseStyles = css`
padding: 1em;
background: #ccc;
border-radius: 5px;
`
const BaseButton = styled.button`
${BaseStyles}
`
Then later override the styles
const BlueButton = styled.button`
${BaseStyles}
background: blue;
`

Passing a custom class/style to a styled-component in Gatsby (React)

I've created the following styled-component for my gatsby project.
import React from "react"
import styled, { css } from 'styled-components'
const Button = styled.div`
background-color: #4E58F5;
width: 200px;
padding: 20px;
margin-right: 30px;
margin-top: 30px;
border-radius: 30px;
color: #FFFFFF;
transition: background-color 0.25s ease;
${props => props.primary && css`
background-color: #FFF;
color: red;
`}
`;
export default props => (
<Button>{props.buttonText}</Button>
)
I've not found the examples in the documentation to be clear or consistent enough to understand how I should be passing in the "primary" option to my components.
I'm trying to do the following, on my index.js page. The Button renders, but the primary word has no effect. What am I missing here?
<Button primary buttonText="Submit" />
The component you're exporting, does not recognize the primary property, and thus cannot pass it on to the Button element. You can fix this either by exporting the styled component itself, or by passing unrecognized props to the Button.
const Button = styled.div`
[...]
`;
export default Button;
OR
export default ({buttonText, ...props})=>(
<Button {...props}>{buttonText}</Button>
);

styled-components causing unexpected behaviour when rendering props

I have a WhiteBox react component which simply renders a white box with some styles.
I have a SmallBox react component which simply uses WhiteBox to render a more specific box.
I have a Content react component which renders three SmallBox boxes which does what it's supposed to do (renders three white boxes).
However when I tried to add a text as a props from the parent, the white box is aligned with some unexpected margin from top.
NOTE: when I simply put "This is a text" the css is okay, but when I send "this is a text" as props.text, the whitebox is rendered with extra margin from top.
I Use styled-components and react as I said.
I've tried to console.log the text, and everything seems to be okay. I also tried to switch the props.children or props.text and it does not work
-----------------White Box Component ----------------------
import styled from "styled-components";
const StyledBox = styled.div`
display: inline-block;
width: ${props => props.width}px;
height: ${props => props.height}px;
margin-right: ${props => props.marginRight}px;
margin-left: 100px;
background-color: white;
border-radius: 5px;
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: #646777;
padding: 10px;
`;
const WhiteBox = props => {
return (
<StyledBox
width={props.width}
height={props.height}
marginRight={props.marginRight}
>
{props.text} // if I change this to simply "this is a text" it works well. somehow the props.text is causing problems.
</StyledBox>
);
};
export default WhiteBox;```
-----------------Small Box Component ----------------------
import React from "react";
import styled from "styled-components";
import WhiteBox from "../whitebox/white-box";
const SmallBox = props => {
return (
<WhiteBox width={320} height={130} marginRight={70} marginLeft={70} text={props.text}>
</WhiteBox>
);
};
export default SmallBox;
-----------------Content Component ----------------------
import React, { Component } from "react";
import SmallBox from "./smallbox/small-box";
import styled from "styled-components";
const StyledContent = styled.div`
position: absolute;
left: 320px;
top: 80px;
width: 100%;
height: 100%;
background-color: #f1f3f7;
`;
class Content extends Component {
render() {
return (
<>
<StyledContent>
<SmallBox text="this text is great" /> // causing problem
<SmallBox />
<SmallBox />
</StyledContent>
</>
);
}
}
export default Content;
The issue has to do with how many lines are rendered. The longer the text in the props, the more the lines rendered.
One solution would be to change the display property for WhiteBox:
const StyledBox = styled.div`
display: inline-flex;
....
`;
Another solution would be to override the default style vertical-align: baseline, simply add vertical-align: top;
const StyledBox = styled.div`
display: inline-block;
....
vertical-align: top;
`;

Resources