-
-
Notifications
You must be signed in to change notification settings - Fork 106
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
override shouldForwardProp #231
override shouldForwardProp #231
Conversation
Deploy request for xstyled rejected. Rejected with commit cbdacd6 https://docs.netlify.com/configure-builds/environment-variables/#sensitive-variable-policy |
how? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dependencies are not at the good place, they should be added in the concerned package. Also no package-lock, we use yarn here. And define dependencies with ^
.
I think you might run into trouble with this approach if you wrap another component instead of an HTML element. In that case you want to filter out the system props, but you must pass through other props which aren't necessarily HTML attributes. For example: const Component = ({foo}) => <div>{foo}</div>
const StyledComponent = styled(Component)`
color: pink;
`
<StyledComponent foo="Hello!" /> You can't apply The problem gets trickier if you use And most unfortunately, solving this might require a change in emotion upstream. The problem is that Emotion doesn't pass the dynamic element to be created to Here you can see it... For its internal determination, Emotion uses I recently confronted this in styled-components and was able to make the change upstream, see styled-components/styled-components#3436 (for v6 in development) and styled-components/styled-components#3451 (for v5, merged but not released yet) I'm not an expert on Emotion so I'd suggest you check everything I claim here, but this PR caught my eye because of my recent related work on styled-components. |
@agriffis nice catch, so you think it is not possible to do it. But a great question is, why would you pass unallowed props? |
@maxmedina05 I am sorry but I can't merge it, it would break all |
@gregberge I don't fully understand your question. When you use a styled component, the props are a mixture of three things:
With this mix of props, you can reliably apply If the wrapped component is already an HTML element, then you can also strip any non-HTML attrs. However this depends on being able to detect The only full solution I can think of is to declare /**
* Factory for shouldForwardProp that takes into account the component's
* propTypes (which should always be stripped, even if they are valid HTML attrs)
* and also strips non-HTML attrs, if the wrapped component is an HTML element.
*/
const makeShouldForwardProp = propTypes => (prop, validAttr, el) =>
!propTypes.hasOwnProperty(prop) && (typeof el !== 'string' || validAttr(prop))
const propTypes = {disabled: PropTypes.bool, ...getSystemPropTypes(system)}
const StyledComponent = styled.div.withConfig({shouldForwardProp: makeShouldForwardProp(propTypes)})(
({disabled}) => css`
${disabled && css`color: red;`}
${system}
`)
StyledComponent.propTypes = propTypes So we have a component that will:
I have been pondering how to make this more automatic in xstyled, as the OP of this issue desires, but I haven't solved it yet. |
I suppose I'm thinking something like this:
Oh, is diff --git a/packages/styled-components/src/createX.ts b/packages/styled-components/src/createX.ts
index 4d3b72f..ef0939a 100644
--- a/packages/styled-components/src/createX.ts
+++ b/packages/styled-components/src/createX.ts
@@ -32,10 +32,10 @@ export const createX = <TProps extends object>(generator: StyleGenerator) => {
tags.forEach((tag) => {
// @ts-ignore
x[tag] = styled(tag).withConfig({
- shouldForwardProp: (prop, defaultValidatorFn) => {
+ shouldForwardProp: (prop, defaultValidatorFn, elementToBeCreated) => {
if (typeof prop === 'string' && generator.meta.props.includes(prop))
return false
- return defaultValidatorFn(prop)
+ return elementToBeCreated !== 'string' || defaultValidatorFn(prop)
},
})<TProps>(() => [`&&{`, generator, `}`])
}) This is kind of a bug in styled-components that the |
So there is nothing to do in xstyled, everything's good. |
@gregberge You described this approach here: #191 (comment) but it will drop any non-HTML props, for example see https://codesandbox.io/s/cool-poincare-rzyyt?file=/src/App.js I've created a PR #236 to fix this. |
This is from discussion at styled-components#231 (comment) This is arguably a bug in styled-components, because what it passes as `defaultValidatorFn` isn't really the default validator function, because it doesn't include the test of `elementToBeCreated`.
This is from discussion at styled-components#231 (comment)
@maxmedina05 You created this PR, I raised a problem with it, and now I'm sure it feels like it ran away from you. 😬 You said at the beginning:
In theory you shouldn't be passing props to If you are still seeing a problem, perhaps you could open an issue with an example. |
This is from discussion at styled-components#231 (comment)
This is from discussion at #231 (comment)
I've been trying to upgrade to v2 an internal library that was built using xstyled v1. After I upgraded, I get the following error for some box components that are using props for doing conditional styling. So far, this error is only happening for styled components using styled.box. For example: const StyledContainer = styled.box(
{
backgroundColor: "yellow",
padding: "1rem"
},
({ dark }) =>
dark
? {
backgroundColor: "black",
color: "white"
}
: {}
); I made this example, in Stackblitz: https://stackblitz.com/edit/react-lcxvdr?file=src/Example.js |
@maxmedina05 For now you'll need to use your own |
This is from discussion at #231 (comment)
This is from discussion at #231 (comment)
This is from discussion at #231 (comment)
Summary
Currently, some props are being passed and written to the DOM. Emotion is handling this by using is-prop-valid which checks if the prop is a valid html attribute before writing. Here
Test plan