Theme-ui: Creating Multiple Variants

Created on 6 Oct 2019  ·  15Comments  ·  Source: system-ui/theme-ui

I am looking for a way to create multiple variants for buttons. For example, let's say I want to have the following three variants:

  1. Size (small, medium, large, etc).
  2. Look (primary, secondary, disabled, etc).
  3. Kind (default, outline, text, etc).

So that I could style a button like this:

<button
 sx={{
    size="buttons.size.large"
    kind="buttons.kind.outline"
    look="buttons.look.secondary"
 }}
/>

This IS possible with style system -- here is an example:

But I can't figure out how to do with with Theme-UI.

Is this possible with Theme-UI? If so, can how can I do it?

Thanks.

Most helpful comment

We've discussed adding support for a variants key which would deep merge multiple variants, but haven't introduced that yet

All 15 comments

Seems like an array could work, where it would just merge the variants.

sx={{
  variant: [
    'buttons.size.large',
    'buttons.kind.outline',
    'buttons.look.secondary'
  ]
}}

Currently the variant property only accepts a single argument, but it's something I've considered. @timkindberg the array syntax would allow you to use different variants at different breakpoints

Okay, thanks for letting me know.

@jxnblk Any solution to this? I have the same need. Could you consider to re-open this issue?

I get it working doing this. However, it would be cooler to support this internally.

import { useResponsiveValue, useBreakpointIndex } from "@theme-ui/match-media";
import get from "lodash.get";
import theme from "../theme";

function variants(...variantBlocks) {
  const variants = useResponsiveValue(variantBlocks);
  let styles = {};
  variants.map(variant => {
    styles = { ...styles, ...get(theme, variant) };
  });
  return styles;
}

function Example() {
  const index = useBreakpointIndex();
  return (
    <Button
      sx={{
        ...variants(
          ["buttons.colors.secondary", "buttons.sizes.xs"],
          ["buttons.colors.primary", "buttons.sizes.lg"]
        )
      }}
    >
      Breakpoint index: {index}
    </Button>
  );
}

How about comma separated strings? @jxnblk

Merry Christmas to y'all 🎅 🎉

Seems like an array could work, where it would just merge the variants.

sx={{
  variant: [
    'buttons.size.large',
    'buttons.kind.outline',
    'buttons.look.secondary'
  ]
}}

This approach breaks on breakpoints with e.g. breakpoints: ['40em', '52em', '64em'], buttons.size.large is applied at min 40em, buttons.kind.outline at min 52em etc. and only at min 64em are applied all 3 variants 😔.

I feel like this isn't quite right, but there is the (obvious?) solution of adding a variants prop that accepts an array of variant values (strings, or I guess arrays if you want the behavior described above with breakpoints).

I like the variants prop 👍 last array item wins I guess?

Lachlan Campbell notifications@github.com schrieb am Mi., 15. Jan. 2020,
17:38:

I feel like this isn't quite right, but there is the (obvious?) solution
of adding a variants prop that accepts an array of variant values
(strings, or I guess arrays if you want the behavior described above with
breakpoints).


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/system-ui/theme-ui/issues/403?email_source=notifications&email_token=ABHUZK3WEKFPA4BL6LW66Q3Q56F75A5CNFSM4I54YBD2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJCCCNI#issuecomment-574890293,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABHUZK4R2656YWXDL7A2QVDQ56F75ANCNFSM4I54YBDQ
.

Yeah, if they conflict, treat it like CSS declarations, the later declarations override the earlier.

We've discussed adding support for a variants key which would deep merge multiple variants, but haven't introduced that yet

I've made a PR (#586) adding support for this to v0.3! I need a bit of technical help finishing the css support but it's 90% ready to go.

Are there still plans to finish this PR @lachlanjc? Would be awesome. Thanks to everyone for the great work on theme ui!

@nandorojo I’d love to, unfortunately the surrounding code has changed a bunch while there was discussion & I’ve had a new job/lot going on recently. Not sure if the specific timeline but I’d love to get back to that soon, it’s functionality I’d use every day 🙂

I would too @lachlanjc ! :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

8eecf0d2 picture 8eecf0d2  ·  3Comments

blummis picture blummis  ·  4Comments

LeunensMichiel picture LeunensMichiel  ·  3Comments

tesseralis picture tesseralis  ·  3Comments

K-Kit picture K-Kit  ·  4Comments