Files

13 KiB

Stack Research

Domain: Personal finance dashboard UI overhaul — React SPA Researched: 2026-03-16 Confidence: HIGH


Context: What Already Exists

This is a subsequent-milestone research document. The stack is locked. The project uses:

Package Installed Version Status
React 19.2.4 Locked
Vite 8.0.0 Locked
TypeScript ~5.9.3 Locked
Tailwind CSS 4.2.1 Locked
Recharts 3.8.0 Locked — already on latest
Radix UI (via radix-ui) 1.4.3 Locked
Lucide React 0.577.0 Locked
next-themes 0.4.6 Locked
TanStack Query 5.90.21 Locked

The index.css already defines a complete OKLCH @theme inline color system with category-specific colors (--color-income, --color-bill, etc.) and chart colors (--color-chart-1 through --color-chart-5). The project uses the radix-ui unified package (post-June 2025 migration).

No new frameworks or backend dependencies. This research covers only what to add or lean into for the UI overhaul.


shadcn/ui Components to Add

The project has shadcn/ui components already (card, button, input, etc.) but is missing two critical primitives for the redesign.

Component Install Command Purpose Why
chart npx shadcn@latest add chart ChartContainer + ChartTooltipContent wrappers Provides theme-aware chart wrappers that read from CSS variables. Eliminates boilerplate for consistent chart theming across all chart types. Copy-paste into src/components/ui/chart.tsx.
accordion npx shadcn@latest add accordion Collapsible category sections on dashboard Built on Radix UI Accordion primitive. WAI-ARIA compliant, keyboard navigable, supports type="multiple" to keep multiple groups open.
collapsible npx shadcn@latest add collapsible Single collapsible toggle pattern Alternative to Accordion when only one independent section needs to expand/collapse (simpler than full Accordion).

CRITICAL: Recharts v3 + shadcn chart.tsx compatibility. The project is on Recharts 3.8.0. The official shadcn/ui chart PR (#8486) for Recharts v3 support is not yet merged (as of March 2026). After running npx shadcn@latest add chart, the generated chart.tsx may need manual fixes:

  1. The ChartContainer may log "width(-1) and height(-1) of chart should be greater than 0" warnings — fix by adding initialDimension={{ width: 320, height: 200 }} to the ResponsiveContainer inside chart.tsx.
  2. If TypeScript errors appear on TooltipProps, update the import to use TooltipProps from recharts directly.
  3. Community-verified workaround exists in shadcn-ui/ui issue #9892.

Confidence: HIGH — PR #8486 and issue #9892 are the authoritative sources; the fix is a small patch to one file.


Core Charting Patterns (Recharts 3.8.0)

No new charting libraries are needed. Recharts 3.8.0 is the current stable release and supports all required chart types natively. Three chart types are needed for the dashboard redesign:

1. Donut Chart (expense category breakdown)

// Already in use. Enrich by:
// - Increasing innerRadius to ~60, outerRadius to ~100 for visual weight
// - Adding paddingAngle={3} for visible segment separation
// - Using stroke="none" (replaces removed blendStroke in v3)
// - Rendering a center label via custom activeShape or absolute-positioned div
<PieChart>
  <Pie
    data={pieData}
    dataKey="value"
    cx="50%"
    cy="50%"
    innerRadius={60}
    outerRadius={100}
    paddingAngle={3}
    stroke="none"
  >
    {pieData.map((entry) => (
      <Cell key={entry.type} fill={categoryColors[entry.type]} />
    ))}
  </Pie>
  <Tooltip content={<ChartTooltipContent />} />
</PieChart>

Note: In Recharts v3, Cell is deprecated in favor of the shape prop and activeShape/inactiveShape are deprecated in favor of shape. Existing Cell usage still works; migration is not required for this milestone.

2. Vertical Bar Chart (income budget vs actual)

<BarChart data={incomeData}>
  <CartesianGrid vertical={false} strokeDasharray="3 3" />
  <XAxis dataKey="name" />
  <YAxis />
  <Bar dataKey="budgeted" radius={[4, 4, 0, 0]} fill="var(--color-muted)" />
  <Bar dataKey="actual" radius={[4, 4, 0, 0]} fill="var(--color-income)" />
  <Tooltip content={<ChartTooltipContent />} />
</BarChart>

3. Horizontal Bar Chart (spend by category type)

// layout="vertical" turns BarChart into a horizontal bar chart
<BarChart data={categoryData} layout="vertical">
  <XAxis type="number" hide />
  <YAxis type="category" dataKey="name" width={130} />
  <Bar dataKey="budgeted" radius={[0, 4, 4, 0]} fill="var(--color-muted)" />
  <Bar dataKey="actual" radius={[0, 4, 4, 0]} fill="var(--color-primary)" />
  <Tooltip content={<ChartTooltipContent />} />
</BarChart>

Confidence: HIGH — All three patterns verified against Recharts official examples and docs.


Tailwind CSS 4 Color System Patterns

The existing index.css is already correctly structured with @theme inline. The overhaul needs to extend it with:

1. Richer category colors (more vibrant for charts)

The current category colors are defined but conservative. For the rich visual style target, increase chroma:

/* Recommended: bump chroma from ~0.14 to ~0.18+ for visual richness */
--color-income:           oklch(0.68 0.19 145);   /* vivid green */
--color-bill:             oklch(0.65 0.19 25);    /* vivid orange-red */
--color-variable-expense: oklch(0.70 0.18 55);    /* vivid amber */
--color-debt:             oklch(0.62 0.20 355);   /* vivid rose */
--color-saving:           oklch(0.68 0.18 220);   /* vivid blue */
--color-investment:       oklch(0.65 0.18 285);   /* vivid purple */

2. Semantic status tokens for budget comparison

--color-over-budget:   oklch(0.62 0.20 25);    /* red-orange for overspend */
--color-on-budget:     oklch(0.68 0.19 145);   /* green for on-track */
--color-budget-bar-bg: oklch(0.92 0.01 260);   /* neutral track for progress bars */

3. Dark theme token set

The current CSS has no dark mode overrides. With next-themes v0.4.6 already installed, dark mode works by toggling .dark on <html>. Add a dark block:

.dark {
  @theme inline {
    --color-background: oklch(0.13 0.02 260);
    --color-foreground: oklch(0.95 0.005 260);
    --color-card:       oklch(0.18 0.02 260);
    /* ...etc — mirror the light tokens with dark values */
  }
}

This is optional for the current milestone (desktop-first, dark mode not listed as a goal), but the token structure is already set up for it.

Confidence: HIGH — Tailwind CSS 4 @theme inline pattern verified against official Tailwind v4 docs.


Typography Patterns

Already uses Inter via --font-sans. No new font installations needed. Apply these patterns consistently:

Pattern CSS / Tailwind Where to Use
Tabular numbers tabular-nums (already used in DashboardPage) All currency amounts, percentages
Monospace amounts font-mono Dense data tables where column alignment matters
Numeric font features font-feature-settings: "tnum" 1 When tabular-nums alone is insufficient
Large metric emphasis text-3xl font-bold tracking-tight Summary card primary values
Muted labels text-sm text-muted-foreground Section headers, stat labels

The codebase already uses tabular-nums on currency values — this is correct and should be applied everywhere financial numbers appear.

Confidence: HIGH — Pattern matches current codebase and Shopify Polaris / Datawrapper typography standards.


Layout Patterns

Summary card grid:

// 4 cards on desktop, 2x2 on tablet, stacked on mobile
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">

Chart row:

// Charts side-by-side on desktop, stacked on mobile
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">

Collapsible category section:

// Using shadcn Accordion — one group per CategoryType
<Accordion type="multiple" defaultValue={["income", "bill"]}>
  <AccordionItem value="income">
    <AccordionTrigger>
      {/* Summary row: label + budgeted + actual + delta */}
    </AccordionTrigger>
    <AccordionContent>
      {/* Line item rows */}
    </AccordionContent>
  </AccordionItem>
</Accordion>

Use type="multiple" so users can expand multiple sections simultaneously. Default expand income and variable_expense as the most-checked categories.

Confidence: HIGH — Standard shadcn/ui pattern, verified against official docs.


What NOT to Use

Avoid Why Use Instead
Nivo Adds a large bundle, different component API, requires adapting all existing chart code Recharts 3.8.0 — already installed, sufficient
ApexCharts / ECharts New library dependency, no benefit over Recharts for this scope Recharts 3.8.0
react-financial-charts Designed for candlestick / OHLC trading charts, not budget dashboards Recharts 3.8.0
Recharts 2.x Project is already on v3.8.0 — never downgrade Stay on 3.8.0
shadcn npx shadcn@latest add for chart without reading the output The generated chart.tsx requires a manual Recharts v3 patch Run the add command, then apply the initialDimension fix to ChartContainer
CSS-in-JS for theming Tailwind v4 @theme inline already handles all theming via CSS variables Extend index.css @theme inline block
Custom progress bar libraries Raw Tailwind divs with style={{ width: X% }} are already used and are sufficient Keep existing progress bar pattern, improve styling only
Framer Motion Adds bundle weight; CSS transitions via transition-all duration-200 cover needed animations Tailwind transition utilities
React Grid Layout Drag/resize dashboards are out of scope for this milestone Standard CSS Grid

Alternatives Considered

Recommended Alternative When to Use Alternative
Recharts 3.8.0 (stay) Nivo If you needed animated, visually opinionated charts with server-side rendering — not applicable here
shadcn Accordion KendoReact PanelBar If the project used KendoReact's broader component suite — it doesn't
Tailwind tabular-nums Geist Mono font Use Geist Mono only if building a dense trading-style table where column alignment is a core feature, not a budget dashboard
shadcn chart.tsx (copy-paste) Direct Recharts usage Acceptable — the project's existing dashboard already uses Recharts directly. shadcn wrappers add theme-aware tooltips and config-based colors but are not mandatory

Version Compatibility

Package Version Compatible With Notes
Recharts 3.8.0 React 19 Requires react-is peer dependency override for React 19
shadcn chart.tsx CLI generated Recharts 3.8.0 Apply initialDimension fix to ChartContainer after generation
Tailwind CSS 4.2.1 @theme inline Use @theme inline (not bare @theme) when referencing other CSS vars
next-themes 0.4.6 React 19 Compatible; dark mode toggled via .dark class on <html>
radix-ui 1.4.3 Post-June 2025 migration shadcn CLI add commands now generate imports from radix-ui, not @radix-ui/react-*

Installation

# Add shadcn chart primitives (then apply Recharts v3 fix to chart.tsx)
npx shadcn@latest add chart

# Add Accordion for collapsible dashboard sections
npx shadcn@latest add accordion

# Add Collapsible if single-section toggles are needed
npx shadcn@latest add collapsible

No npm/bun package installs needed — Recharts 3.8.0 is already installed and sufficient.


Sources


Stack research for: SimpleFinanceDash UI Overhaul Researched: 2026-03-16