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
feat(atomic): add support for atomic using styled API #966
Conversation
Hi @juanferreras!
|
Hi @juanferreras , thanks so much for working on this! This is really exciting to see, I'm glad it's been useful! My thoughts on your questions:
I think this shouldn't change anything other than the class order for non-atomic From my limited testing, it seems like it works if you swap these lines and remove the gating in getTemplateType Questions 3 and 4: It sounds like if we go with the suggestion in 1 (atomize even dynamic styles) that this class would always be empty, but it'd probably be easiest with the existing infrastructure to have this class be generated and applied to elements. If people don't want that, they can always just use atomic Thanks for your work on this and sorry for the delayed review! I'm very enthusiastic on the idea, if I can provide any assistance on getting tests or functionality to work, let me know! 🙏 |
Hey @juanferreras, thank you for your pull request 🤗. |
thanks so much to both on the feedback! Updated the PR and the tests with the feedback so far.
- .atm_f4_c17gu1mi {background-color: var(--f4_c17gu1mi);}
+ .atm_f4_c17gu1mi {background-color: var(--cccybe9-1);} Not sure how feasible would it be to create an atom based on the exact interpolation text (eg.
it works pretty much seamlessly with the extra change you've sent @jpnelson! There's one test case that changed its behaviour Interop between styled react/atomic seems to work great too, but there's one caveat. Given how property priorities are implemented (eg. const TitleAtomic = atomicStyled.h1`background-color: blue`;
const TitleReactOverAtomic = styled(TitleAtomic)`background: red`; // shows red
const TitleAtomicOverAtomic = atomicStyled(TitleAtomic)`background: red`; // would show blue I've pushed an update to increase P/S: it looks like CI might be caching dependencies incorrectly – as without changes it's now passing OK in 1 of the checks (not on node v10 still from the same error as before) P/S 2: @jpnelson as per your comment, more than happy to update this PR once you land #973 and apply the changes on my end – many thanks for the work there too! super useful 🙏 |
|
@Anber sounds like a great idea! I'll update this PR with the latest and see if I can generate any I'll start experimenting with something like const Component1 = styled.div`
/* compiles to `.atm_aa_xx` */
color: ${props => props.color};
`;
const Component2 = styled.div`
/* compiles to the same `.atm_aa_xx` */
color: ${props => props.color};
/* same `var(--hash)` but different property, different atom class `.atm_bb_xx` */
border-color: ${props => props.color};
/* different `var(--hash)` and different property, different atom class `.atm_cc_yy` */
background-color: ${props => props.color || 'white'};
`; |
@Anber / @jpnelson moving this to ready for review! many thanks for the support thus far. I'm sadly still struggling with tests on CI (they don't like the re-export of For a small recap of updates,
Thanks! |
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.
Great work!
excellent! thanks for approving and merging @Anber! I'll keep an eye out when it gets released as a |
+1 Great work! Very exciting progress on this!
This sounds preferable to me, better to not have people worry about that. We'll just need to keep in mind that
This makes sense to me – a declaration is the property + the value, if we're providing the value though via a css variable, we can just hash the property – any collisions there would be intentional. It might be interesting to write a test for the collision case just to see the output (a dynamic property component overriding another dynamic property of the same type) As for the CI, I was running the tests locally too, and I was able to actually reproduce the error a couple of times. The error seemed flaky though – rerunning locally fixed the issue, and I wasn't able to consistently reproduce it circleci has a local execution option that I was trying to get it to work. To use that, I first had to modify the config locally as it doesn't support multiple parallel workflows:
With this, the problem is actually reproducible locally – just a bit slow to run (I think it wouldn't have any of the caching as it does in CI) (I also needed to follow this workaround for the M1 mac to get circleci local to work) |
name: \\"StyledComponent2\\", | ||
class: \\"sccybe9\\" | ||
}); | ||
const AtomicComponent = /*#__PURE__*/reactStyled(\\"div\\")({ |
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 error. Should it be atomicStyled
instead of reactStyled
?
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.
If so, I've already fixed 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.
@Anber good catch! sorry for missing it!
I understand this should have been replaced to use either localName?.atomicStyled
or localName?.styled
depending on whether styled.type === 'atomic-styled'
or not.
LMK if you'd like me to open a follow up PR with the fix – many thanks!
thanks for all the details @jpnelson! I've misunderstood on my end that with This is pretty much the only downside I can see towards making all interpolations just
To be fair, we could just document that P/S: I hope I didn't break CI now that's merged 😬 – I wonder if there's any place I've missed adding the new dependency on |
Motivation
This continues upon the excellent work by @jpnelson on adding first class (opt-in) Atomic CSS support onto Linaria. The motivation (and community support) can be seen on the original issue #225
Summary
This PR attempts to use the same patterns in #867 :
styled
export on@linaria/atomic
which simply re-exports the one in@linaria/react
, but can be used to makeatomic-styled
opt-inimport { styled } from '@linaria/atomic'
, all the CSS rules within are extracted as atomic classes and re-used across different componentsconst Component = styled(AnotherComponent)
should still work as expected (and it should be compatible with@linaria/react
too). There might be certain edge cases with property priorities (wrapping components currently boosts atomic property priorities by 1, which should be enough in most cases to override AnotherComponent original atom classes).import { styled as atomicStyled } from '@linaria/atomic'
and it should still work as expected.Examples
Input
Output
Test plan
Several tests were added with the behaviour described above, and all existing tests were also passing correctly locally (EDIT: not sure why CI v10 can't resolve the internal dependency, locally seems to work fine and the other CI started passing too). Please check the snapshot generated to confirm the functionality works as you'd expect.
I've also applied this changes on the
/website
and it looks like there's no visual difference when replacingSee the following video
https://user-images.githubusercontent.com/8507996/163470135-77dccb6d-82c2-49fc-b161-ae9de9435326.mp4