Overview
The @budgetbee/ui package provides a comprehensive library of reusable React components built with shadcn/ui , Radix UI , and Tailwind CSS .
Installation
pnpm add @budgetbee/ui --filter your-package
Or in your package.json:
{
"dependencies" : {
"@budgetbee/ui" : "workspace:*"
}
}
{
"name" : "@budgetbee/ui" ,
"description" : "Core ui package" ,
"type" : "module"
}
Exports
Components
Hooks
Utilities
Styles
// UI components from shadcn/ui
import { Button } from "@budgetbee/ui/core/button" ;
import { Dialog } from "@budgetbee/ui/core/dialog" ;
import { Card } from "@budgetbee/ui/core/card" ;
import { Input } from "@budgetbee/ui/core/input" ;
import { Select } from "@budgetbee/ui/core/select" ;
Available Components
BudgetBee UI includes 30+ production-ready components:
Accordion Collapsible content sections
Alert Dialog Modal dialog for important actions
Avatar User profile images with fallback
Badge Small labels and tags
Breadcrumb Navigation breadcrumbs
Button Interactive buttons with variants
Calendar Date picker calendar
Carousel Image and content carousel
Chart Data visualization with Recharts
Checkbox Checkboxes with tree support
Collapsible Expandable content areas
Command Command palette / search
Context Menu Right-click context menu
Dropdown Menu Dropdown menus
Empty State Empty state placeholders
And many more: menubar, navigation-menu, popover, progress, radio-group, resizable, select, separator, sheet, skeleton, slider, sonner, switch, table, tabs, textarea, toast, toggle, tooltip
Component Usage
import { Button } from "@budgetbee/ui/core/button" ;
function MyComponent () {
return (
< div className = "space-x-2" >
< Button > Default </ Button >
< Button variant = "destructive" > Delete </ Button >
< Button variant = "outline" > Outline </ Button >
< Button variant = "ghost" > Ghost </ Button >
< Button variant = "link" > Link </ Button >
< Button size = "sm" > Small </ Button >
< Button size = "lg" > Large </ Button >
< Button disabled > Disabled </ Button >
</ div >
);
}
Dialog
import {
Dialog ,
DialogContent ,
DialogDescription ,
DialogHeader ,
DialogTitle ,
DialogTrigger ,
} from "@budgetbee/ui/core/dialog" ;
import { Button } from "@budgetbee/ui/core/button" ;
function MyComponent () {
return (
< Dialog >
< DialogTrigger asChild >
< Button > Open Dialog </ Button >
</ DialogTrigger >
< DialogContent >
< DialogHeader >
< DialogTitle > Are you sure? </ DialogTitle >
< DialogDescription >
This action cannot be undone.
</ DialogDescription >
</ DialogHeader >
< div className = "flex justify-end gap-2" >
< Button variant = "outline" > Cancel </ Button >
< Button variant = "destructive" > Delete </ Button >
</ div >
</ DialogContent >
</ Dialog >
);
}
Card
import {
Card ,
CardContent ,
CardDescription ,
CardFooter ,
CardHeader ,
CardTitle ,
} from "@budgetbee/ui/core/card" ;
import { Button } from "@budgetbee/ui/core/button" ;
function MyComponent () {
return (
< Card >
< CardHeader >
< CardTitle > Budget Overview </ CardTitle >
< CardDescription > Your spending this month </ CardDescription >
</ CardHeader >
< CardContent >
< p className = "text-3xl font-bold" > $2,450.00 </ p >
</ CardContent >
< CardFooter >
< Button > View Details </ Button >
</ CardFooter >
</ Card >
);
}
import { Input } from "@budgetbee/ui/core/input" ;
import { Label } from "@budgetbee/ui/core/label" ;
import { Button } from "@budgetbee/ui/core/button" ;
function MyComponent () {
return (
< form className = "space-y-4" >
< div >
< Label htmlFor = "email" > Email </ Label >
< Input
id = "email"
type = "email"
placeholder = "[email protected] "
/>
</ div >
< div >
< Label htmlFor = "password" > Password </ Label >
< Input
id = "password"
type = "password"
/>
</ div >
< Button type = "submit" > Sign In </ Button >
</ form >
);
}
Select
import {
Select ,
SelectContent ,
SelectItem ,
SelectTrigger ,
SelectValue ,
} from "@budgetbee/ui/core/select" ;
function MyComponent () {
return (
< Select >
< SelectTrigger className = "w-[180px]" >
< SelectValue placeholder = "Select a category" />
</ SelectTrigger >
< SelectContent >
< SelectItem value = "groceries" > Groceries </ SelectItem >
< SelectItem value = "transport" > Transport </ SelectItem >
< SelectItem value = "entertainment" > Entertainment </ SelectItem >
</ SelectContent >
</ Select >
);
}
Calendar
import { Calendar } from "@budgetbee/ui/core/calendar" ;
import { useState } from "react" ;
function MyComponent () {
const [ date , setDate ] = useState < Date | undefined >( new Date ());
return (
< Calendar
mode = "single"
selected = { date }
onSelect = { setDate }
className = "rounded-md border"
/>
);
}
Toast Notifications
import { Toaster } from "@budgetbee/ui/core/sonner" ;
import { toast } from "sonner" ;
import { Button } from "@budgetbee/ui/core/button" ;
function MyComponent () {
return (
<>
< Button onClick = { () => toast . success ( 'Transaction added!' ) } >
Add Transaction
</ Button >
< Toaster />
</>
);
}
Charts
BudgetBee UI includes chart components powered by Recharts :
import { AreaChart } from "@budgetbee/ui/core/chart" ;
function MyComponent () {
const data = [
{ month: 'Jan' , amount: 1200 },
{ month: 'Feb' , amount: 1500 },
{ month: 'Mar' , amount: 1800 },
];
return (
< AreaChart
data = { data }
categories = { [ 'amount' ] }
index = "month"
className = "h-72"
/>
);
}
Theming
BudgetBee UI supports dark mode via next-themes:
import { ThemeProvider } from "next-themes" ;
function App ({ children } : { children : React . ReactNode }) {
return (
< ThemeProvider
attribute = "class"
defaultTheme = "system"
enableSystem
disableTransitionOnChange
>
{ children }
</ ThemeProvider >
);
}
Theme Toggle
import { useTheme } from "next-themes" ;
import { Button } from "@budgetbee/ui/core/button" ;
function ThemeToggle () {
const { theme , setTheme } = useTheme ();
return (
< Button
variant = "ghost"
onClick = { () => setTheme ( theme === "dark" ? "light" : "dark" ) }
>
Toggle Theme
</ Button >
);
}
Utility Functions
cn() - Class Name Merger
Combine and merge Tailwind classes:
import { cn } from "@budgetbee/ui/lib/utils" ;
const className = cn (
"text-lg font-bold" ,
isActive && "text-blue-500" ,
isDisabled && "opacity-50 cursor-not-allowed"
);
Styling with Tailwind
BudgetBee UI uses Tailwind CSS v4. Import the global styles in your app:
import "@budgetbee/ui/globals.css" ;
PostCSS Configuration
Use the shared PostCSS config:
import config from "@budgetbee/ui/postcss.config" ;
export default config ;
Adding New Components
To add a new shadcn/ui component:
cd packages/ui
pnpm shadcn:add < component-nam e >
Example:
pnpm shadcn:add dropdown-menu
This will:
Download the component from shadcn/ui
Add it to packages/ui/core/
Install any required dependencies
Components are added to packages/ui/core/ directory as specified in components.json
Dependencies
Key dependencies used by @budgetbee/ui:
{
"dependencies" : {
"class-variance-authority" : "^0.7.1" ,
"clsx" : "^2.1.1" ,
"cmdk" : "^1.1.1" ,
"date-fns" : "^4.1.0" ,
"embla-carousel-react" : "^8.6.0" ,
"lucide-react" : "^0.475.0" ,
"next-themes" : "^0.4.6" ,
"radix-ui" : "^1.4.3" ,
"react-day-picker" : "^9.11.1" ,
"recharts" : "2.15.4" ,
"sonner" : "^2.0.7" ,
"tailwind-merge" : "^3.3.1"
}
}
Component Customization
All components accept className prop for customization:
import { Button } from "@budgetbee/ui/core/button" ;
// Add custom classes
< Button className = "bg-gradient-to-r from-blue-500 to-purple-500" >
Gradient Button
</ Button >
// Override default styles
< Button className = "rounded-full px-8" >
Custom Shape
</ Button >
Accessibility
All components follow accessibility best practices:
Keyboard navigation - Full keyboard support
ARIA attributes - Proper ARIA labels and roles
Focus management - Clear focus indicators
Screen reader support - Semantic HTML and labels
Components are built on Radix UI primitives which handle most accessibility concerns automatically.
Best Practices
Use cn() utility Always use cn() to merge Tailwind classes safely
Import only what you need Import specific components to keep bundle size small
Consistent spacing Use Tailwind spacing scale consistently across components
Responsive design Use responsive Tailwind classes for mobile-friendly UIs
Responsive Design
Use Tailwind’s responsive prefixes:
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" >
< Card > ... </ Card >
< Card > ... </ Card >
< Card > ... </ Card >
</ div >
Animation
Components include built-in animations via tw-animate-css:
import { Dialog } from "@budgetbee/ui/core/dialog" ;
// Animations are automatic
< Dialog >
{ /* Content animates in/out */ }
</ Dialog >
Documentation
For detailed component documentation, visit:
Troubleshooting
Styles not applying
Ensure you’ve imported the global CSS:
import "@budgetbee/ui/globals.css" ;
TypeScript errors
Make sure you have the correct React types installed:
pnpm add -D @types/react @types/react-dom
Dark mode not working
Wrap your app with ThemeProvider:
import { ThemeProvider } from "next-themes" ;
function App ({ children }) {
return (
< ThemeProvider attribute = "class" >
{ children }
</ ThemeProvider >
);
}
Next Steps
Core Package Explore authentication and database utilities
Billing Package Learn about subscription management