-
Notifications
You must be signed in to change notification settings - Fork 32
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
Added postProcessCssNamespace to define different strategy to wrap cl… #15
Added postProcessCssNamespace to define different strategy to wrap cl… #15
Conversation
This sounds great. Thanks very much for your contribution and thorough explanation. At first glance, your proposal sounds like a good way to enhance this. I will try to take a closer look tomorrow at the changes you are proposing. I’ve very much wanted to get back to improving this tool, but have been short on bandwidth. |
Hi all, I have noticed that I will need to update the docs if this proposal gets accepted. So, let me know and I will update it. Also, if you guys want to simply remove the previous behaviour that would be a breaking change release. I would not mind doing it. 😉 |
Thanks again for your contribution. I didn't get to this until late at night and started taking a look. I need a bit more time with it and hope to do that tomorrow. Regarding the docs: It definitely makes sense to hold off until we are sure about that changes. We can add that at the end or do a fast-follow PR. |
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.
This is excellent. It took me a bit to get my head wrapped around what was happening because the solution is a bit different than the one I was mulling over in my head. I think I like your approach better!
I left a few minor comments. Honestly, they are fairly optional. Feel free to disagree.
If you'd like, please add the new doc to this PR. Otherwise, we can add it in a follow up PR.
Thanks again for the contribution!
src/visitors/cssNamespace.js
Outdated
@@ -1,21 +1,49 @@ | |||
import * as t from 'babel-types'; | |||
import { isStyled } from 'babel-plugin-styled-components/lib/utils/detectors'; | |||
|
|||
const containsInitialSelfReference = css => | |||
/^(([^\{]([\w-_,:+\s]+))*\&\s*([^\{]([\w-_,:+\s]+))*)+[\{]/g.test(css.trim()); |
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.
Regex is always tough to read and this bit is somewhat essential to how this works, can you please add some comments here that helps explain this regex a bit?
Something like: This regex checks to see if the css contains a self reference (&) at the beginning which is not proceeded by other valid css. For example, {someString}
would return true but {someOtherString}
would return false.
As we don't have tests for this particular function in isolation, I think those comments will help us remember what is going on when we look back on this.
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.
I don't mind adding tests for the particular function. I believe it will improve coverage around the behaviour adopted. Btw, shall I add the new behaviour as it is in this PR (non-breaking change)? Or should we replace the current behaviour by this bew one and release as a breaking change?
src/visitors/cssNamespace.js
Outdated
const { cssNamespace } = state.opts; | ||
if (!cssNamespace) { | ||
return '&&'; | ||
const { cssNamespace, postProcessCssNamespace } = state.opts; |
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.
I agree with your approach here. Let's leave this as a new option for now to avoid the breaking change. Once we have it in the wild for a bit and continue to confirm this works in more complex codebases, let's update to only have this option.
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.
Haaa, I think you just answered my previous question. 😉
src/visitors/cssNamespace.js
Outdated
if (Array.isArray(cssNamespace)) { | ||
return `.${cssNamespace.join(' .')} &`; | ||
if (cssNamespace) { | ||
const wrapperClass = `.${[].concat(cssNamespace).join(' .')} &`; |
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.
Nice trick here! I'll have to remember this one. The .concat works with a string or array.
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.
Concat can add a new element or each item of given array. 😁 Not really good trick for production if it is all the time running on client and creates new instances which can potentially invoke the garbage collector often and the degrade performance. But, here we do it on compile time which is ok. 😉
export default MyStyledComponent; | ||
" | ||
`; | ||
|
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.
Excellent. I like how you've used examples right from the issue for the tests.
Can we add one additional test that explicitly checks for & + &
as that was one other case noted in the issue?
src/visitors/cssNamespace.js
Outdated
} | ||
|
||
return `.${cssNamespace} &`; | ||
if (postProcessCssNamespace) { | ||
const wrapperClass = `${[].concat(postProcessCssNamespace).join(', ')}`; |
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.
It looks like line 22 is the only difference between the cssNamespace
and postProcessCssNamespace
. Can/should we further reduce code duplication by only having this single line of code inside of the condition, then the rest of the lines below the conditional?
: `${cssNamespace} {&{${css}${shouldLeaveScopeOpen ? '' : '}}'}`; | ||
|
||
const NO_STRIP = false; | ||
const STRIP_END_CURLY_BRACKETS = true; |
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.
I'm a fan of this pattern to make booleans as arguments a bit more readable. Very nice!
Thanks so much for reviewing this. I will put the changes as soon as possible. 👍🎉 |
@nvanselow I have added the changes as agreed. Every change is in a different commit to help the review. I added documentation, but, I did not add the version bump. I believe it is a minor change according to I will leave up to you to decide it and release it, if you don't mind. Thanks again! |
51dd691
to
4198707
Compare
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.
Awesome work! These changes are right on. I like the new name as well.
I agree that this would be a minor version change at this point until we remove the original approach. I can get that published after we merge this PR.
So, I have added the version bump as minor. Whenever suits you, could you merge and release it? Thank you |
Will do! I will likely get this released first thing tomorrow. Thanks again! |
I think my last commit dismissed your approval 😆 |
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.
No worries! I appreciate the separate commits. Makes it easy to see what changed very quickly and re-approve.
Updating the package on NPM failed a few times. It looks like the api keys on NPM have changed. I am working on fixing this and hope to have this deployed soon to NPM. |
Just to let you know, a few weeks ago the all NPM tokens have been revoked due to a malicious code in 2 eslint plugins. It might be that the reason. 😉 |
Thanks for the heads up @daniloster. That was my line of thinking as well. I'm waiting on the owners of the npm org that hosts this package to provide me with an updated key. Hopefully won't be too much longer. |
We got the new API key and this is live on NPM! |
Hi guys, I had look at this issue #12 and added a new possibility with this PR. Added a feature to set multiple wrappers which create nested
& {/* ... */}
when required only. This new strategy should sort the problem mentioned in the issue, besides it conserves whatever the developer has added there as class definition by only wrapping the end result, almost like a post css processor.I have seen that currently the array is treated as a single wrapper in the cssNamespace creating nested specificity. But, what if we use the concept of array as multiple wrappers and add the wrapper basically as a post css processor? It would be a matter of decorating the function that writes down the css classes and attributes.
I am sorry if this suggestion sounds stupid somehow.
The main reason for that is that the cssNamespace should be something that developer can set as e.g.
cssNamespace: ['#root-div .wrapperClass', 'body.theme-whatever']
and this should generate wrappers like e.g.#root-div .wrapperClass, body.theme-whatever { /* whatever rules applied there */ }
At the moment the developer is setting this configuration, he knows exactly what are the wrapper required and there is no need to build this internally reducing the flexibility of this tools.
So, I have added an extra property to the configuration
postProcessCssNamespace
, then, the current behaviour is maintained (being not a breaking change) and developers can migrate or be ready to a future release where the proppostProcessCssNamespace
takes place ofcssNamespace
being the main strategy.I hope this change helps this library and any recommendations/critics are more than welcome.
Thank you