Ask
52
@lowell_frame ·

cva or plain props for 60 shared components, 5 devs and nobody who owns design Components

We have about 60 components in a shared package. Currently every variant is a ternary in a template literal and some of them are four levels deep and genuinely unreadable.

The obvious move is cva. The thing stopping me is that five people have to learn it and none of us is a designer, so I suspect the mess is a symptom rather than the disease. Anyone regretted going one way or the other at roughly this size?

8 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @notetaking_ivo · 4w ago · 2 replies

    cva earns its keep precisely when variants combine - size times tone times state - and you are tired of a ternary that has to know about all three. That is real and your four-deep template literal is the symptom.

    Out of 60 components, maybe 12 will actually have combinatorial variants. Do those. Leave a Divider as a div with props. Reaching for one API for all 60 is how you end up with a variant config for components that have exactly one appearance.

    The failure mode at 5 people with no design owner is not the API though. It is that everyone adds a variant and nobody ever deletes one, so in a year Button has 9 tones, 4 of which appear once. Put variant names in code review explicitly. It is a social fix for a social problem.

    74
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @burr_bennet · 4w ago

      Add tailwind-merge at the same time or your escape hatch will not work. A consumer passing className="p-8" on a component whose variant emits p-4 gets whichever one the compiler happened to put last in the stylesheet, which is not the one they wrote, and it will look correct in one place and wrong in another.

      25
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @burr_and_edge · 4w ago

    Plain props, and stop there until it genuinely hurts. Every abstraction is a thing a new person has to learn before they can change a button, and at five people that cost is proportionally much higher than it looks. Unreadable ternaries can also be fixed by writing them less cleverly.

    41
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @rest_day_rita · 4w ago · 2 replies

    The question under the question is whether you have tokens. Without them, cva just relocates the hardcoded values into a tidier file, and you will still have four greys and three border radii that are almost the same.

    29
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @pattern_tracer · 4w ago

      Yes. @theme first, variants second. Otherwise you build a genuinely elegant variant API on top of fourteen slightly different shades of grey and now they are elegantly inconsistent.

      16
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @pumptest_pat · 4w ago · 2 replies

    cva is dead weight. Tailwind has data-[state=open]: variants natively, so drive everything off data attributes and delete the whole layer.

    16
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @notetaking_ivo · 4w ago

      Those solve different problems. Data attribute variants are for runtime state coming from something like a headless component library - open, checked, disabled. cva is a compile-time API surface for the props your team types. You will end up wanting both, and using data attributes for size="lg" means putting your design API in the DOM for no benefit.

      13
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @late_stage_phd · 4w ago

    Whichever you pick, write down the decision and the reason in the repo, even three sentences. In eight months a new person will ask why, and the honest answer will otherwise be that someone had a preference on a Tuesday.

    7
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report