MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-12

1.0.5.2 Primitive components — Button, Input, Textarea, Card, Modal, Pill, Tooltip, Toast, Spinner

Done
Description

Estimate: 35m · Depends on: 1.0.5.1

Build the React primitive components that every screen will compose from. Nine primitives cover almost everything Motir's UI needs: Button (4 variants), Input, Textarea, Card, Modal, Pill / Tag, Tooltip, Toast, Spinner. Each must use only the tokens from 1.0.5.1 — never hardcoded values — so a future theme tweak propagates through one source.

Why this is the biggest Subtask in Story 1.0.5: primitives are the foundation of every later UI Subtask in the entire project. Getting them right (accessible, consistent, composable) saves work in every Subtask that touches the UI; getting them wrong propagates problems for months. This Subtask deserves the most attention in the story.

What you'll do: For each primitive, create a file under /components/ui/<Name>.tsx with a typed props interface, all variants implemented, and full keyboard / aria support. Use class-variance-authority for variant management and tailwind-merge for class composition (the modern React + Tailwind primitive pattern). Render every variant + state of every primitive on the /app/_tokens/page.tsx route from 1.0.5.1 as a living style guide.

Acceptance criteria

  • Button: variants primary | secondary | ghost | danger × sizes sm | md | lg × states default | hover | active | focus | disabled | loading. Loading state shows the Spinner inline.
  • Input, Textarea: with label, error message, helper text, disabled state, prefix/suffix slots.
  • Card: with optional header / footer slots, hover state, optional clickable mode (wraps in <a> or button).
  • Modal: accessible (focus trap, ESC closes, click-outside closes, returns focus on close), supports a header / body / footer slot pattern.
  • Pill / Tag: variants for status (planned / in-progress / done) and severity (info / warn / danger / success).
  • Tooltip: appears on hover + focus, sensible positioning, accessible name on the trigger.
  • Toast: stackable, auto-dismiss with hover-to-pause, variants (info / success / warn / error).
  • Spinner: 3 sizes; works inside Button and as standalone.
  • Every primitive uses ONLY tokens from globals.css — zero hardcoded hex / px values.
  • /app/_tokens/page.tsx renders all primitives × all variants × key states as a single specimen page.
  • Each primitive has a brief JSDoc @example comment with a minimal usage sample.

Context refs

  • /app/globals.css (from 1.0.5.1) — the token source
  • tailwind.config.ts (from 1.0.5.1) — the Tailwind theme
  • awesome-design-md — open-source component-pattern corpus, fetched at prompt-gen time
  • Radix UI primitives docs (URL) — for the unstyled accessibility primitives we can wrap (Modal, Tooltip, Toast)
  • cva + tailwind-merge docs
Status
Done
Type
Sub-task