Open randallmlough opened 1 year ago
I've thought about something similar. Essentially introducing Stitches.js
variant serialization. It would be make your "abuse" much simpler, but I will consider this too. I like the callback idea :)
I have an advanced button component if you're looking for something similar here: https://github.com/sannajammeh/opendash/blob/main/packages/ui/src/Button.tsx
This uses plenty of compound variants. I wouldn't classify it as abuse as Stitches.js
recommends the same thing. Keep in mind the template literal class names require tailwind-merge
or a custom merger in classed.config.ts
, otherwise the DOM will look very ugly.
Cool. I looked at your example and yeah, very similar. The current process works for a couple of items, but the cracks begin to show when have a much larger variant object like the real one I have below.
const outlineCompoundVariants = [
{
outline: true,
color: "primary",
className: outlineVariants["primary"],
},
{
outline: true,
color: "primary-light",
className: outlineVariants["primary-light"],
},
{
outline: true,
color: "primary-dark",
className: outlineVariants["primary-dark"],
},
{
outline: true,
color: "secondary",
className: outlineVariants["secondary"],
},
{
outline: true,
color: "secondary-light",
className: outlineVariants["secondary-light"],
},
{
outline: true,
color: "secondary-dark",
className: outlineVariants["secondary-dark"],
},
{
outline: true,
color: "light",
className: outlineVariants["light"],
},
{
outline: true,
color: "dark",
className: outlineVariants["dark"],
},
{
outline: true,
color: "success",
className: outlineVariants["success"],
},
{
outline: true,
color: "danger",
className: outlineVariants["danger"],
},
];
This is just for outline styling. I have the same object size for solid colors and focus too. That said, I wouldn't recommend what I'm doing for a one-off project, but this is part of a UI package that I use across all my projects and with other people, so the need to have uniformity (along with leveraging stories) outweighs the decrease in readability.
Regardless, I acknowledge it is a monster of my own creation
Going to start the work on this feature! Thanks for the request
Hey @sannajammeh, any progress on this feature? I have some time in the next couple of weeks if I can be of any help.
Hey @randallmlough. Apologies for the long wait time on this issue, I've been pretty swamped with work. Still going to be a bit swamped the coming weeks I'm afraid. Feel free to fork and submit a PR.
@randallmlough couldn't you do something like:
const outlineCompoundVariants = Object.keys(outlineVariants).map((color) => ({
outline: true,
color,
className: outlineVariants[color],
}));
?
Feature Request
I'm looking for more functionality around compound variants. I would love a way to use a keyed value from a component as the key for a variant in compound variants.
If the above doesn't make a lot of sense, here's an example of a workaround that I have that achieves what I am after. Hopefully, this will illustrate the problem better.
Below is a button that can have multiple states: plain text, a solid color, or outlined
To have the above functionality my button component needs to look like this
As you can see, I'm abusing the compound variant array and the boolean variant attribute. In a perfect world, condensing the "solid" and "outline" variants into one would be awesome.
An idea that could solve this is to have class/className accept either a string or a function that passes a variants object and returns a string.
Example: