Components overview

All reusable UI components themed via CSS variables. No hardcoded colors — swap the palette in globals.css without touching a single component.

Design system

Every component in NextForge follows these rules:

  • Colors only via CSS variables (var(--color-*)) — never hardcoded hex values
  • Mobile-first Tailwind classes — base styles, then sm:, md:, lg: overrides
  • Accessible by default — proper aria attributes, focus-visible rings, role attributes
  • TypeScript props — all components have fully typed prop interfaces
  • No external UI library — components are self-contained and fully owned by you

Theming via CSS variables

The entire color palette is defined in app/globals.css in the @theme block. To change the primary color across every component, change one variable:

app/globals.css
@theme {
  --color-primary: #2563eb;          /* change this */
  --color-primary-hover: #1d4ed8;    /* and this */
  --color-primary-foreground: #ffffff;
}

Every Button, Input focus ring, active nav link, and toast accent updates automatically.

Component list

ComponentLocationTypeDescription
Buttoncomponents/ui/Button.tsxClient5 variants, isLoading, auto-disabled
Inputcomponents/ui/Input.tsxClientLabel, error, hint, icon slots
Loadercomponents/ui/Loader.tsxClientSpinner, dots, skeleton variants
Toastcomponents/ui/Toast.tsxClient4 types, auto-dismiss, slide-up animation
Modalcomponents/ui/Modal.tsxClientPortal, focus trap, ESC close
Navbarcomponents/nav/Navbar.tsxClientAuth-aware, mobile hamburger, dark mode
Footercomponents/footer/Footer.tsxServerDynamic link groups

Loading states convention

All form submissions in NextForge use React's useTransition:

const [isPending, startTransition] = useTransition()

function handleSubmit(formData: FormData) {
  startTransition(async () => {
    const result = await someServerAction(formData)
    // handle result
  })
}

// Button is disabled + shows spinner for the full duration:
<Button isLoading={isPending} disabled={isPending}>
  Submit
</Button>

This prevents double-submission, gives immediate visual feedback, and keeps the UI responsive during server round-trips.