-
Notifications
You must be signed in to change notification settings - Fork 671
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: Add merging array of variants #1226
Conversation
Okay, the code is correct, but I think we have some prior work to unpack. This is sort of a duplicate of #1017, which was already a duplicate itself.
Also connected to Pull Request #823. I have a feeling this will be harder to merge, than we might expect looking at the code. I think we should try to understand the previous work first, and discover the concerns which blocked its finalization. |
Do you want to add in the documentation I wrote on #586? Feel free to edit it of course but that could be a starting point. |
thanks @lachlanjc - I added your documentation now. Sorry I didnt see your PR when submitting this one, but we are getting there :) |
Oh you’re good! I made that awhile ago, before TS & all, so we needed a new implementation. |
Co-authored-by: Piotr Monwid-Olechnowicz <[email protected]>
packages/components/src/Box.js
Outdated
const variant = ({ theme, variant, __themeKey = 'variants' }) => { | ||
if (Array.isArray(variant)) { | ||
return css( | ||
deepmerge.all( |
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.
shouldn't we also support
sx={{
variant: ['a', 'b']
}}
?
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.
We could move this logic up to css
package.
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.
shouldn't we also support
sx={{ variant: ['a', 'b'] }}
?
This is the responsive variants syntax, right?
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 the responsive variants syntax, right?
Well, now it is.
from V1 roadmap #832
- Variant composition, e.g. variant: ['large', 'primary'] (or plural variants). This would potentially be a breaking change, meaning that the variant property itself would no longer support responsive arrays, but the values within the variant could. Add support for combining multiple variants #586, Add variant composition feature #1017
sx={{
variant: ['a', 'b'] // new combined variant
variant: [['a', 'b']] // new responsive tuple variant
}}
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 think we should create a new issue with that feature.
@atanasster I've invaded your branch to add a test again. We need to talk about it. Why does |
I feel we now have duplicate code for this in
|
Just want to check on this PR, as lost track of the discussion. Is this finally going to add |
@atanasster Any progress on this issue? This feature will be a blessing. @joernroeder I think this PR is supposed to close #1208 (using |
@joernroeder - no, this PR does not handle responsive arrays of arrays of variants (thats a mouthful ). Can expand on the "finally" part - was this discussed previously? @a-y-u-s-h I think we are waiting on a "stable" 0.6.0 release before merging other PRs. |
@atanasster @a-y-u-s-h maybe that's just me, but when I see arrays in theme-ui I immediately "think in breakpoints". As far as I know this change is the only place where that pattern breaks and an array means something else – merging in this case – which might be confusing. There were several issues and discussions which mentioned responsive variants before and several people worked on it, "finally" was my enthusiasm that this might be now landing and I can reorg and clean my theme soon :) |
Good point. I think this needs more discussion (I'm not sure whether conclusions have already been made about it) Both interpretations of array in variants: merge, and treating it as breakpoint differences are actually kind of good valid feature ideas now that I think about it. There can be multiple solutions for this (at the top of my head, these are the ones I can think about right now):
If If this means breakpoint variants: box:
variant: [a, b, c, d] Then this could mean merging variants: box:
extend: [a, b, c, d]
If this means breakpoint variants: box:
variant: [a, b, c, d] Then this could mean merging variants: box:
variant: [[ a, b, c, d ]] Then this (an array of arrays) could mean breakpoint and merged variants (but this can also be confusing, We'll have to remember that merging stops after innermost array level): box:
variant: [[ a, b, c, d ], [e, f], [g, h]] |
@joernroeder - I see what you mean by thinking first in breakpoints, I myself came a bit late to this 'variants arrays' party and this PR is specifically for multiple variants that need to be merged, not for responsive arrays of variants. @a-y-u-s-h - very good points, can you please start a new thread for responsive arrays of variants. I would personally support a notation such as |
Agreed. Responsive variants would be cool down the road, but I think we should prioritize merging, since there's currently no approachable way in Theme UI's API to accomplish that, whereas you can make variants responsive with media queries/responsive values without too much monkeypatching. |
thanks @a-y-u-s-h for the write up
|
As of v0.3.5, code
works in a way that it constructs a variant You can see it in action here https://codesandbox.io/s/theme-ui-starter-forked-gsfjq Considering this feature, is this going to break in future versions, since the brackets syntax for variants now seems to be used for merging instead? |
Hi, I was wondering if there are still plans to implement this? The use case for me would be to support different variants of a button, ie combining color, size and style. Regarding this PR and some conversations beforehand, some people have raised issues with nested arrays - and the changing API. This would not be a breaking change, given that
EDIT: I could actaually live without the responsive array API on the |
@hasparus Thought about this a bit, & I think the pure array implementation is rather confusing since it overlaps with responsive syntax in an invisible way. I think I’d prefer making this a separate |
I'm down with the At the object level, it would be fine, but I'm thinking about other libs that could also use this prop. For instance, Framer Motion has a |
This is great if you're just typing a few, but I can imagine variant merging to be super useful depending on other UI state, & having to do With Framer Motion—not sure how to solve that problem. |
Agreed, variant={`primary, ${active ? 'active' : ''}, ${colour ? colour : ''}`} |
I feel like if we're going to use a string type, using a different operator to make it clearer we're merging might be better: |
Yeah, totally agreed. It's also a fair explanation of why this issue is open for 2 years.
is a total monstrosity compared to the following :D
|
After thinking a bit more it, I have a new (extended) proposal for the API. @hasparus : if I still like the string approach to adhere to the excellent usage of arrays for breakpoints across the entire package.
variant={{ primary: true, outline, small: isSmall }} where outline and small would be conditional on Now it would be easy to do this variant={[{ primary: true, outline, small: true }], [{ primary: true, outline }]} Primary button which might be outlined depending on logic, small on mobile and "normal" sized on other devices As a side note, a comma separated string seems more natural to me, rather than using the plus sign, but could live with either or. |
@balintpeak Really appreciate the detailed proposal! I’m still leaning toward @hasparus’s suggestion because I prefer that it centers on combining variants while elegantly supporting conditionals, whereas the object syntax centers on conditionals & less elegantly supports unconditional combinations. I can also see the object syntax being easy to add down the road. Closing this PR since we need a new implementation, but still very much want to add this! |
issues #1209 #1208
allows to specify array of variants, merged right to left
<Box variant={['boxes.beep', 'boxes.bop']} />