Proposing new components

When and how the agent should extend the library

The Reva design system isn't finished. New patterns emerge from real product work. The reva-design-system-adherence skill encodes a Creative Extension Protocol for exactly this situation.

When to propose

When existing @reva/ui primitives genuinely won't do a great job. Examples:

  • A "quick filter toggle bar" where ToggleGroup feels too rigid and Tabs feels too heavy
  • A "metric card with sparkline" where Card + Chart separately compose awkwardly
  • A "split button" with primary action + secondary dropdown where Button doesn't have the variant

These are welcomed. Reva embraces extending the design system when the gap is real.

When NOT to propose

When an existing primitive would work but you want a slightly different visual treatment. The right move there is to use the primitive's existing variants, not invent a new one or add a custom variant inline.

The protocol

When the agent identifies a gap, it must:

  1. Justify — briefly explain why existing primitives fall short (1-2 sentences). Specific. "ToggleGroup only supports single-select; this needs multi-select with persistent state across page navigation."
  2. Sketch the proposed API — props, variants, anatomy, accessibility roles. Keep it small; this is a sketch not a spec.
  3. Confirm before building. The user decides whether the proposal is right for the prototype.
  4. Implement inline (in the prototype's src/components/), and mark it as a candidate for promotion into @reva/ui with a comment header.
// CANDIDATE for @reva/ui — see prototypes/expense-tracker for context
// Proposed shape:
//   <QuickFilterBar value={…} onValueChange={…}>
//     <QuickFilterChip value="this-month">This month</QuickFilterChip>
//     ...
//   </QuickFilterBar>
export function QuickFilterBar(...) { ... }

What NOT to do

  • Don't silently invent variants on existing primitives. "I added a variant='subtle-pill' to Button" without proposing it = bypass of the protocol.
  • Don't fork primitives. Don't copy the Card source into your prototype and call it MyCard. Use the primitive or propose a new component.
  • Don't decorate primitives with className to defeat their visual identity. Adding className="rounded-full bg-blue-500 shadow-2xl" to <Button> to make it look completely different = fork-by-stealth.

If a candidate component proves itself across multiple prototypes, that's strong signal it should graduate into @reva/ui proper. Open a Linear issue when that pattern emerges.

On this page