New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Styled Decorator #537
Comments
In my opinion there is no need to support a HOC or a decorator because that's a pattern we don't recommend to use with styled-components. What speaks against this version for you? const Text = style.div`
padding: 10px;
background: blue;
font-size: 12px;
`
export class SomeThingComponent extends React.Component {
render() {
return <Text>Hello World</Text>;
}
} This way you don't need to pass a classname down to a component which is a cleaner way to use styled-components. |
Sometimes one might not want to create an entirely separate component class if it will only be used in that one place. Also imagine if the styled component takes say 10 different arguments which would determine the style. In that case: which would be easier: const Text = styled.div`
height: ${{height} => height}px;
width: ${{width} => width}px;
color: ${{color} => color};
position: absolute;
top: ${{offset} => offset * 2}px;
left: ${{offset} => offset * 4 + 3}px;
`
class SomeThingComponent extends React.Component {
render() {
return <Text height={this.props.height} width={this.props.width} color={this.props.color} offset={this.props.offset}>Hello World</Text>;
}
} Or this: @styled.decorator`
height: ${{height} => height}px;
width: ${{width} => width}px;
color: ${{color} => color};
position: absolute;
top: ${{offset} => offset * 2}px;
left: ${{offset} => offset * 4 + 3}px;
`
class SomeThingComponent extends React.Component {
render() {
return <div className={this.props.className}>Hello World</div>;
}
} |
You can also spread the props into the class SomeThingComponent extends React.Component {
render() {
return <Text {...props}>Hello World</Text>;
}
} Which makes the first example of you not much longer or complicated then the example with the decorator. |
That may be so, but that doesn't solve the problem of needing to create an entirely separate component class. Someone might not want to do that. |
Your solution also creates another problem. What if within those props, there is a @styled.decorator`
...
`
class SomeThing extends React.Component {
render() {
return <div className={this.props.className}><button onClick={this.props.onClick}>Hello World</button></div>
}
} but with your solution: class SomeThing extends React.Component {
render() {
return <Text {...props}><button onClick={this.props.onClick}>Hello World</button></Text>;
}
} this would have unintended consequences. |
This would be the solution: class SomeThing extends React.Component {
render() {
const { onClick, ...props } = this.props
return <Text {...props}><button onClick={onClick}>Hello World</button></Text>;
}
} I don't think we will support decorators because there was already a discussions about HoC. @mxstbr said at #316 (comment) that we will not support them with the explanation
Because decorators are basically HoCs I think we will not support them as well. On the other hand the HoC / decorator is a single line of code so if you really want to use it you should write your own little helper function. |
If the decorator would only be one line, why not support that one line? It shouldn't be too big of an increase to maintain. I can maintain it if nobody else wants to. If the answer to that question is the philosophy for styled-components dictated by @mxstbr above, then why are you supporting this? styled(SomeThing)`
color: black;
margin-left: ${props => props.leftMargin}px;
` This is basically creating a higher-order component. |
Why is creating a separate component a problem that needs to be solved? Performance issue? Code aesthetics? Just trying to understand the motivation 😄 |
Code aesthetics and readability. |
I can create the PR. |
I don't think we're going to support this officially I'm afraid, for the reasons stated above. I'm not convinced this adds any value to the library, in fact I think it takes away from the value of using it. |
I really like the idea as well 👍 it would make the code cleaner (less components to declare). |
I also like the idea. It can be a sepparate package on NPM that adds more sugar to styled-components. |
FWIW, I just do this: // with_styles.js
import styled from 'styled-components';
export default function (strings, ...items) {
return function (WrappedComponent) {
return styled(WrappedComponent)(strings, ...items);
};
} import with_styles from './with_styles';
@with_styles`
border: 2px dotted lime;
`
class MyComponent extends React.PureComponent {
// ...
} |
It's simply not possible and not supported, because it would allow users to easily go against or enforced best practices and methodologies. By default we do offer passing in any component into the styled factory function, and that can be used as an escalation e hatch or even to make this possible with a helper, but it's mainly for complex stacks of components and third party components. It's not recommended to use this frequently, as building up your component structures from bottom to top leads to cleaner architectures that scales. At the bottom you'll find pure presentational components, above them structural ones, and at the top container/smart components. This can of course be nested and combined in different ways. But by allowing this pattern by default, we'd be recommending to put the presentational components, like a stylesheet, at any position of this component stack, which is less desirable. So if you really want to do this, we're not stopping you. But try to keep this in mind, and we believe you'll likely find more scalable styling code as a result. |
Could you add in the following code where appropriate:
So that we can begin using styled-components in the following way:
It would look much cleaner than writing:
The text was updated successfully, but these errors were encountered: