A modern React application built with Tailwind CSS v4, featuring a dynamic theme system with 22 color options and dark/light mode support, plus a complete UI component library.
π Deployed : TailwindCss Component Library
To enable dark / light mode switch you havve to get the hook : useTheme.ts & add this line to your css :
@custom-variant dark (&:where(.dark, .dark *));After taht the hook will be able to change mods on the fly.
β¨ Theme System
- 22 color themes (red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose, slate, gray, zinc, neutral, stone)
- Dark/Light/System mode toggle with localStorage persistence
- CSS variable-based theming for runtime color switching
- Floating theme panel for easy customization
π¦ Component Library (32 Total)
Base Components (8)
- Button, Input, Card, Badge, Select, Textarea, Alert, ThemePanel
Form Components (5)
- Checkbox, Radio, Toggle, Slider, FormGroup
Feedback Components (5)
- Toast, Tooltip, ProgressBar, Spinner, Skeleton
Navigation Components (5)
- Tabs, Breadcrumb, Pagination, Navbar, Sidebar
Layout Components (5)
- Modal, Drawer, Divider, Avatar, Stack (HStack/VStack)
Data Components (3)
- Table, List, Dropdown
π¨ Interactive Demo
- Full-page showcase of all components with live examples
- Responsive design with working state management
- Complete dark mode support
- Node.js 18+ and npm
- Modern web browser
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewThe app will be available at http://localhost:5173/
src/
βββ App.tsx # Main app with comprehensive demo
βββ index.css # Global styles & theme CSS variables
βββ main.tsx # React entry point
βββ components/
β βββ ThemePanel.tsx # Floating theme switcher
β βββ Alert.tsx, Badge.tsx, Button.tsx, Card.tsx
β βββ Input.tsx, Select.tsx, Textarea.tsx
β βββ form/ # Form components (5)
β β βββ Checkbox.tsx, Radio.tsx, Toggle.tsx
β β βββ Slider.tsx, FormGroup.tsx
β β βββ index.ts
β βββ feedback/ # Feedback components (5)
β β βββ Toast.tsx, Tooltip.tsx, ProgressBar.tsx
β β βββ Spinner.tsx, Skeleton.tsx
β β βββ index.ts
β βββ navigation/ # Navigation components (5)
β β βββ Tabs.tsx, Breadcrumb.tsx, Pagination.tsx
β β βββ Navbar.tsx, Sidebar.tsx
β β βββ index.ts
β βββ layout/ # Layout components (5)
β β βββ Modal.tsx, Drawer.tsx, Divider.tsx
β β βββ Avatar.tsx, Stack.tsx
β β βββ index.ts
β βββ data/ # Data components (3)
β β βββ Table.tsx, List.tsx, Dropdown.tsx
β β βββ index.ts
β βββ index.ts # Central exports for all components
βββ hooks/
βββ useTheme.ts # Dark/light/system mode management
Click the floating button in the bottom-right corner to open the theme panel:
- Select a color from the 22-color grid to change the primary color
- Toggle the switch to switch between light and dark modes
- Choose from Light, Dark, or System (syncs with OS preference)
import { useTheme } from './hooks/useTheme'
function MyComponent() {
const { theme, setTheme } = useTheme()
return (
<button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
Toggle to {theme === 'dark' ? 'light' : 'dark'} mode
</button>
)
}Base Components:
import {Button, Input, Card, Badge, Alert} from "./components"
export function Example() {
return (
<Card>
<Input label="Name" />
<Button>Submit</Button>
<Badge>New</Badge>
</Card>
)
}Form Components:
import {Checkbox, Radio, Toggle, Slider, FormGroup} from "./components/form"
export function FormExample() {
const [value, setValue] = useState(50)
return (
<FormGroup label="Settings" required>
<Checkbox label="Accept terms" />
<Toggle label="Enable notifications" />
<Slider min={0} max={100} value={value} onChange={setValue} />
</FormGroup>
)
}Feedback Components:
import {Toast, Tooltip, ProgressBar, Spinner} from "./components/feedback"
export function FeedbackExample() {
return (
<>
<Tooltip content="Helpful text">
<Button>Hover</Button>
</Tooltip>
<ProgressBar value={75} max={100} />
<Spinner size="md" />
</>
)
}Navigation Components:
import {Tabs, Navbar, Pagination} from "./components/navigation"
export function NavExample() {
const [page, setPage] = useState(1)
return (
<>
<Navbar title="App" logo="π¨" />
<Tabs
tabs={[
{id: "1", label: "Tab 1", content: "Content 1"},
{id: "2", label: "Tab 2", content: "Content 2"},
]}
/>
<Pagination currentPage={page} totalPages={5} onPageChange={setPage} />
</>
)
}Layout Components:
import {Modal, Avatar, HStack, Divider} from "./components/layout"
export function LayoutExample() {
const [open, setOpen] = useState(false)
return (
<>
<HStack gap="md">
<Avatar initials="JD" />
<p>User Profile</p>
</HStack>
<Divider />
<Modal isOpen={open} onClose={() => setOpen(false)}>
Modal content here...
</Modal>
</>
)
}Data Components:
import {Table, List, Dropdown} from "./components/data"
export function DataExample() {
return (
<>
<Table
columns={[
{key: "name", label: "Name"},
{key: "email", label: "Email"},
]}
data={data}
/>
<List
items={[
{id: 1, label: "Item 1"},
{id: 2, label: "Item 2"},
]}
/>
</>
)
}From main index (recommended):
import {Button, Checkbox, Modal, Table} from "./components"From category folders:
import {Checkbox, Toggle, Slider} from "./components/form"
import {Toast, Tooltip, Spinner} from "./components/feedback"
import {Tabs, Navbar, Sidebar} from "./components/navigation"
import {Modal, Avatar, HStack} from "./components/layout"
import {Table, List, Dropdown} from "./components/data"The primary color is available via CSS variables:
<div className="bg-primary-500 text-white">Uses the selected primary color</div>Or directly in CSS/Tailwind:
.custom-element {
background-color: var(--color-primary-500);
}32 Components across 6 categories:
| Category | Count | Description |
|---|---|---|
| Base | 8 | Foundation UI elements (Button, Input, Card, Badge, Select, Textarea, Alert, ThemePanel) |
| Form | 5 | Form controls with validation support (Checkbox, Radio, Toggle, Slider, FormGroup) |
| Feedback | 5 | User feedback mechanisms (Toast, Tooltip, ProgressBar, Spinner, Skeleton) |
| Navigation | 5 | Navigation patterns (Tabs, Breadcrumb, Pagination, Navbar, Sidebar) |
| Layout | 5 | Structural components (Modal, Drawer, Divider, Avatar, Stack) |
| Data | 3 | Data display (Table, List, Dropdown) |
β All components feature:
- Full TypeScript support with precise prop interfaces
- Complete dark mode support out of the box
- Responsive design ready for mobile/tablet/desktop
- Accessible HTML with ARIA labels and semantic structure
- Customizable props for flexibility
- Tailwind CSS classes with primary color variants
- Consistent styling and animations
Form Components:
- Checkbox - Customizable checkbox with labels and error states
- Radio - Single radio button with RadioGroup wrapper for managing multiple options
- Toggle - Switch component with 3 sizes (sm/md/lg) and smooth animations
- Slider - Range input with visual progress bar and gradient fill
- FormGroup - Wrapper component for consistent form layouts with labels, hints, errors
Feedback Components:
- Toast - Dismissible notifications with 4 variants (success/error/info/warning) and auto-dismiss
- Tooltip - Hover tooltips with 4 directional positions (top/bottom/left/right)
- ProgressBar - Visual progress indicator with 4 variants, labels, and animations
- Spinner - Loading indicator with 3 sizes and customizable colors
- Skeleton - Animated placeholder for loading states with circular option
Navigation Components:
- Tabs - Tabbed interface with pills and underline variants
- Breadcrumb - Navigation path display with icon support
- Pagination - Smart page navigation with ellipsis and arrow controls
- Navbar - Sticky header with logo, title, and responsive mobile menu
- Sidebar - Full-height collapsible navigation with drawer overlay for mobile
Layout Components:
- Modal - Centered dialog with 3 sizes (sm/md/lg), header, body, footer, and close button
- Drawer - Slide-out panel from left or right with overlay backdrop
- Divider - Horizontal or vertical divider with optional text label
- Avatar - User avatar displaying image or initials with online status indicator
- Stack - Layout utilities (HStack, VStack) with gap, alignment, and justify options
Data Components:
- Table - Data table with striped/hover/bordered variants, custom cell rendering
- List - Ordered/unordered lists with compact variant and active state
- Dropdown - Positioned dropdown menu with divider support and disabled items
The theme system operates on two independent tracks:
1. Dark/Light Mode (themeMode in localStorage)
- Managed by
useTheme()hook - Applies
darkclass to root HTML element - Supports three modes:
light,dark,system - System mode syncs with OS preference via
prefers-color-schememedia query - Persisted in localStorage with key:
themeMode
2. Color Theme (themeColor in localStorage)
- Managed by ThemePanel component
- Applies
data-theme="colorname"attribute to root HTML element - 22 color presets available
- Uses CSS variables for dynamic color switching
- Persisted in localStorage with key:
themeColor
An inline script in index.html runs before React renders, applying saved theme settings synchronously:
<script>
const themeMode = localStorage.getItem("themeMode")
const themeColor = localStorage.getItem("themeColor") || "indigo"
if (themeMode === "dark") {
document.documentElement.classList.add("dark")
}
document.documentElement.dataset.theme = themeColor
</script>This ensures the correct theme is visible immediately, with no lightβdark flash.
The index.css file defines:
@themeblock with 22 color palettes mapping to CSS variables- Custom dark variant:
@custom-variant dark (&:where(.dark, .dark *)) - Each color theme mapped via
[data-theme="colorname"]selectors - All components use
dark:variants which activate when.darkclass is present
themeMode- Stores:"light","dark", or"system"themeColor- Stores: Color name like"indigo","red","cyan", etc.
- React 19.2.0 - UI framework
- Tailwind CSS 4.1.18 - Utility-first CSS with variable theming
- TypeScript 5.9.3 - Type-safe JavaScript
- Vite 7.3.1 - Fast build tool and dev server
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Any modern browser supporting CSS variables and ES2020
npm run dev # Start development server
npm run build # Create production bundle
npm run preview # Preview production build locally
npm run lint # Run ESLintimport { useTheme } from './hooks/useTheme'
import type { Theme } from './hooks/useTheme'
export function MyComponent() {
const { theme, setTheme } = useTheme()
// theme is "light" | "dark" | "system"
const handleToggle = () => {
setTheme(theme === 'dark' ? 'light' : 'dark')
// Automatically saves to localStorage and applies dark class
}
return (
<div>
<p>Current mode: {theme}</p>
<button onClick={handleToggle}>Toggle Dark Mode</button>
</div>
)
}To add or modify color themes, edit src/index.css:
- Add color variables in the
@themeblock (if adding new colors):
@theme {
--color-mycustom-50: #f0f0f0;
--color-mycustom-500: #5555ff;
--color-mycustom-900: #001a4d;
/* ... other shades ... */
}- Add a color preset selector:
[data-theme="mycustom"] {
--color-primary-50: var(--color-mycustom-50);
--color-primary-100: var(--color-mycustom-100);
/* ... map all shades ... */
--color-primary-900: var(--color-mycustom-900);
}- Add to THEMES array in
ThemePanel.tsx:
const THEMES = [
// ... existing colors ...
"mycustom",
]MIT - Feel free to use this project for personal or commercial use.
The theme system includes detailed console logging to help track state changes. Open your browser's developer console (F12) to see:
When initializing:
π useTheme initialized:
- Saved in localStorage (themeMode): dark
- Using mode: dark
π applyTheme: Applying dark mode
When toggling dark mode:
π Dark mode toggle clicked:
- Current theme mode: dark
- New theme mode: light
π changeTheme called:
- New mode: light
- Saved to localStorage: themeMode = light
π applyTheme: Applying light mode
When changing color:
π¨ Color theme changed:
- New color: red
- Dark mode state: dark
Remove these console.log calls if they're not needed in production.
Pull requests welcome! For major changes, please open an issue first to discuss what you'd like to change.


