Extending styles with styled-components not working
As stated in documentation:
The styled method works perfectly on all of your own or any
third-party components, as long as they attach the passed className
prop to a DOM element.
Example
// This could be react-router-dom's Link for example, or any custom component
const Link = ({ className, children }) => (
<a className={className}>
{children}
</a>
);
const StyledLink = styled(Link)`
color: palevioletred;
font-weight: bold;
`;
render(
<div>
<Link>Unstyled, boring Link</Link>
<br />
<StyledLink>Styled, exciting Link</StyledLink>
</div>
);
Ref: https://www.styled-components.com/docs/basics#styling-any-component
Styled-components: Styles are not applied when trying to style already styled component
First, move the styled component outside of function scope or your style will reset on every render and you will get heavy performance issues.
Secondly, in order to apply styles, you need to pass className
property.
See Styling normal React components
If you use the styled(MyComponent) notation and MyComponent does not render the passed-in className prop, then no styles will be applied.
const Container = styled.div`
display: flex;
align-items: center;
height: 36px;
& > div:not(:last-child) {
margin-right: 5px;
}
`;
const LanguageChooser = ({ className }) => {
return (
<Container className={className}>
<Flag {...languages.pl} />
<Flag {...languages.en} />
</Container>
);
};
const Button = styled.div`
cursor: pointer;
font-size: 24px;
transition: 0.2s all;
&:hover {
font-size: 36px;
}
`;
const Flag = ({ flag, language }) => {
const { i18n } = useTranslation();
return <Button onClick={() => i18n.changeLanguage(language)}>{flag}</Button>;
};
styled-components not applying style to custom functional react component
From the docs:
The styled method works perfectly on all of your own or any
third-party components as well, as long as they pass the className
prop to their rendered sub-components, which should pass it too, and
so on. Ultimately, the className must be passed down the line to an
actual DOM node for the styling to take any effect.
For example, your component would become:
const Div = ({ className }) => (<div className={className}>test</div>)
const StyledDiv = styled(Div)`
color: green;
`;
Modified example:
const styled = styled.default
const Div = ({ className }) => (<div className={className}>test</div>)
const StyledDiv = styled(Div)`
color: green;
font-size: larger;
`;
const App = () => {
return(<StyledDiv>Test</StyledDiv>)
}
ReactDOM.render(<App />, document.querySelector('.app'))
<script src="//unpkg.com/react@16.5.2/umd/react.development.js"></script>
<script src="//unpkg.com/react-dom@16.5.2/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/styled-components/3.4.9/styled-components.min.js"></script>
<div class="app"></div>
styled-components: Extend existing component with additional prop for styling
This is exactly what transient props are for.
All you need to do is prefix the prop with a $
and styled-components
won't pass the prop to the underlying DOM element.
// Note the $ prefix in the prop name br>const StyledToggleButton = styled(ToggleButton)<{ $hasMargin?: boolean }>`
&& {
color: red;
// Just use the prop as normal
${(props) =>
props.$hasMargin &&
css`
margin: 10px;
`}
}
`;
<StyledToggleButton
value={""}
size={"small"}
{/* Assign the prop as normal */}
$hasMargin={true}
>
click
</StyledToggleButton>;
Here's your updated Codesandbox link with that error gone.
Extending regular React components with styled-components
I don't really know where the confusion lies, you can pass any React component to the styled
Higher Order Component.
The issue you have is that you aren't trying to style the BoxFunctional
or BoxClass
components, but rather you are trying to style the JSX they render. You just need to proxy the className
prop through to what each renders.
Styling any Component
The
styled
method works perfectly on all of your own or any
third-party component, as long as they attach the passedclassName
prop to a DOM element.
const BoxFunctional = (props) => (
<div className={props.className}>{props.children}</div>
);
class BoxClass extends Component {
render() {
return <div className={this.props.className}>{this.props.children}</div>;
}
}
Demo
How to extend component style in styled-components
Since ElipseDetails is not a styled component, but calls to a styled one, you can do something like:
function ElipseDetail({ text, children }: Props): ReactElement {
return (
<Container>
<Text>{text}</Text>
{children}
</Container>
);
}
ElipseDetail.Styled = Container;
export default ElipseDetail
And then, in a different component, you can change it like so:
const StyledElipseDetail = styled(ElipseDetail.Styled)`
${Text} {
//
}
`;
...
return <StyledElipseDetailed>...</StyledElipseDetail>
PS - I have taken this approach from an older question of mine which I found quite useful.
Related Topics
Animate the CSS Transition Property Within :After/:Before Pseudo-Classes
Svg Height Incorrectly Calculated in Webkit Browsers
Vertical Align Center Image in Fixed Size Div
Using Mixins in Bootstrap 3 to Avoid Unsemantic Markup for Layout Structure
What Does the Scalez() CSS Transform Function Do
Semantic Grid with Bootstrap + Less Mixins ¿ How
CSS Selector for Disabled Input Type="Submit"
Understanding the Difference Between the Flex and Flex-Grow Properties
CSS Width and Max-Width Combined
How to Limit a Table Cell to One Line of Text Using CSS
Grayscale Image with CSS on Safari 5.X
Clicking Safari 5.1 Select Menu Refreshes Page
Internet Explorer Button:Active Inner-Padding