Overview

aSaaSin’s UI is built on shadcn/ui. We keep thin wrappers in components/ui/* and compose them into higher-level pieces in components/*. Some wrappers also sit on top of focused libraries:

  • Chart - shadcn/ui’s Chart wrapper (internally uses Recharts).
  • Carousel - shadcn/ui’s carousel (internally Embla).
  • Data Table - our table primitives + TanStack Table.
  • Drawer / Sheet - Vaul.
  • Flow Canvas - XYFlow.
  • Icons - Lucide.
  • Animations - Lottie (where used).
  • Color Picker - react-colorful.

Use our wrappers instead of importing these libraries directly - props, styles, and dark mode are unified.

Component Architecture

  • Primitives (components/ui/*)
    Button, Dialog, Input, Table, Tabs, Toast, Tooltip, Chart, Carousel, etc. These expose consistent props (variant, size, className) and tie into our theme tokens.
  • Composite components (components/*)
    Dashboard cards, forms, dialogs, data tables, marketing sections - built by composing primitives with app logic.
  • Charts
    We use shadcn/ui’s Chart (not bare Recharts). Series are mapped to CSS variables so you don’t hardcode colors.
  • Carousel
    Built on Embla for smooth touch/scroll. You configure slides/spacing, we provide sane defaults.
  • Data Table
    Built on TanStack Table. Our wrappers handle markup, sorting headers, empty states, you define columns/cells.

Variants

Most primitives accept variant and size props (via CVA). Common options you’ll see:

  • variant: default, highlight, outline, destructive, ghost, link, icon
  • size: sm, md, lg, icon

Use className for small local tweaks. Colors and dark mode come from tokens - no hardcoded hex.

Composition pattern

Many primitives support asChild (Radix Slot) so you can keep behavior/styling while rendering a different tag (e.g., render Button as a Next.js Link) without losing focus rings or variants.

Client vs server

Some components are client-only (Chart, Carousel, interactive Data Tables, Drawers). Others render on the server. If a component needs the browser, its file starts with use client. Refer to each component’s page for specifics.