UNPKG

aurcare-ui

Version:

Aurcare UI component library for healthcare applications with dynamic sidebar, navbar, and stats cards

820 lines (705 loc) 20.4 kB
# aurcare-ui A modern, flexible UI component library for healthcare applications built with React, Next.js, and HeroUI. ## Features - **Dynamic Sidebar**: Collapsible sidebar with nested navigation, RTL support, and badges - **Dynamic Navbar**: User profile, notifications, theme switcher, and language switcher - **TypeScript**: Full type safety with comprehensive TypeScript definitions - **Dark Mode**: Built-in dark mode support with next-themes - **RTL Support**: Full right-to-left language support - **Customizable**: Extensive props for customization including background control and per-item styling - **Accessible**: Built with accessibility in mind ## Installation ```bash npm install aurcare-ui ``` ### Peer Dependencies Make sure you have the following peer dependencies installed: ```bash npm install react react-dom next next-themes @heroui/button @heroui/badge @heroui/dropdown @heroui/avatar @heroui/divider @heroui/theme lucide-react ``` ## Sidebar Component ### Basic Usage ```tsx import { Sidebar } from 'aurcare-ui'; import { Home, Users, Calendar, Settings } from 'lucide-react'; function App() { return ( <Sidebar sections={[ { id: 'main', title: 'Main', items: [ { id: 'home', label: 'Home', href: '/', icon: Home, }, { id: 'users', label: 'Users', href: '/users', icon: Users, badge: 5, badgeColor: 'danger', }, ], }, { id: 'settings', title: 'Settings', items: [ { id: 'settings', label: 'Settings', href: '/settings', icon: Settings, }, ], }, ]} appName="My App" appSubtitle="Dashboard" /> ); } ``` ### Nested Navigation ```tsx <Sidebar sections={[ { id: 'main', items: [ { id: 'patients', label: 'Patients', icon: Users, subItems: [ { id: 'patient-list', label: 'Patient List', href: '/patients', icon: List, }, { id: 'patient-add', label: 'Add Patient', href: '/patients/add', icon: UserPlus, }, ], }, ], }, ]} /> ``` ### Controlled Collapse ```tsx const [isCollapsed, setIsCollapsed] = useState(false); <Sidebar sections={sections} isCollapsed={isCollapsed} onCollapse={setIsCollapsed} /> ``` ### RTL Support ```tsx <Sidebar sections={sections} locale="ar" appName="تطبيقي" appSubtitle="لوحة التحكم" /> ``` ### Custom Header and Footer ```tsx <Sidebar sections={sections} customHeader={ <div className="p-4"> <h1>Custom Header</h1> </div> } customFooter={ <div className="p-4 border-t"> <p>Version 1.0.0</p> </div> } /> ``` ### Background Control (v1.2.0) Control the entire background of the Sidebar for custom light/dark themes: ```tsx // Custom dark theme with slate background <Sidebar sections={navigationSections} backgroundClassName="bg-slate-50 dark:bg-slate-950" /> // Custom gradient background <Sidebar sections={navigationSections} backgroundClassName="bg-gradient-to-b from-blue-50 to-white dark:from-slate-900 dark:to-slate-800" /> // Different border style <Sidebar sections={navigationSections} backgroundClassName="bg-gray-100 dark:bg-gray-900 border-r-4 border-primary" /> ``` ### Per-Item Styling (v1.2.0) Add custom styles to individual navigation items: ```tsx import { NavSection } from 'aurcare-ui'; import { Home, Users, Settings, AlertTriangle, Brain, Star } from 'lucide-react'; const navigationSections: NavSection[] = [ { id: 'main', items: [ { id: 'dashboard', label: 'Dashboard', href: '/dashboard', icon: Home, // Custom styling for this item className: 'bg-blue-50 dark:bg-blue-950 border-l-4 border-blue-500' }, { id: 'users', label: 'Users', href: '/users', icon: Users, // Different style for this item className: 'bg-green-50 dark:bg-green-950' }, { id: 'emergency', label: 'Emergency', href: '/emergency', icon: AlertTriangle, // Special highlight for important item className: 'bg-red-100 dark:bg-red-950 text-red-700 dark:text-red-400 font-bold ring-2 ring-red-500' }, { id: 'new-feature', label: 'AI Analytics', href: '/analytics', icon: Brain, badge: 'BETA', badgeColor: 'warning', // Beta feature badge styling className: 'bg-purple-50 dark:bg-purple-950 border-l-4 border-purple-500' }, { id: 'premium', label: 'Premium Reports', href: '/reports/premium', icon: Star, // Premium feature styling className: 'bg-gradient-to-r from-yellow-50 to-orange-50 dark:from-yellow-950 dark:to-orange-950 border-l-4 border-yellow-500' } ] } ]; ``` ### Dynamic Per-Item Styling ```tsx import { useTranslations } from 'next-intl'; import { NavSection } from 'aurcare-ui'; import { Mail, Activity } from 'lucide-react'; function useNavigationSections() { const t = useTranslations(); const hasUnreadMessages = true; // From your state const isSystemHealthCritical = false; // From your state const navigationSections: NavSection[] = [ { id: 'main', items: [ { id: 'messages', label: t('messages'), href: '/messages', icon: Mail, badge: hasUnreadMessages ? '5' : undefined, badgeColor: 'danger', // Dynamic styling based on unread messages className: hasUnreadMessages ? 'bg-red-50 dark:bg-red-950/50 border-l-4 border-red-500' : '' }, { id: 'system', label: t('systemHealth'), href: '/system', icon: Activity, // Dynamic styling based on system status className: isSystemHealthCritical ? 'bg-red-100 dark:bg-red-950 text-red-700 dark:text-red-400 animate-pulse' : 'bg-green-50 dark:bg-green-950' } ] } ]; return navigationSections; } ``` ### Sidebar Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `sections` | `NavSection[]` | **Required** | Navigation sections with items | | `isCollapsed` | `boolean` | `undefined` | Controlled collapse state | | `onCollapse` | `(collapsed: boolean) => void` | `undefined` | Collapse state change callback | | `currentPath` | `string` | `undefined` | Current active path | | `locale` | `string` | `'en'` | Locale for RTL support | | `appName` | `string` | `'Aurcare'` | App name in header | | `appSubtitle` | `string` | `'Healthcare System'` | App subtitle in header | | `appLogo` | `React.ElementType` | `LayoutDashboard` | App logo icon | | `className` | `string` | `undefined` | Additional CSS classes | | `expandedWidth` | `string` | `'w-72'` | Width when expanded | | `collapsedWidth` | `string` | `'w-20'` | Width when collapsed | | `hideCollapseButton` | `boolean` | `false` | Hide collapse button | | `customHeader` | `ReactNode` | `undefined` | Custom header component | | `customFooter` | `ReactNode` | `undefined` | Custom footer component | | `onNavigate` | `(item: NavItem) => void` | `undefined` | Navigation callback | | `logoClassName` | `string` | `undefined` | Logo section wrapper classes (v1.1.0) | | `logoContainerClassName` | `string` | `undefined` | Logo container box classes (v1.1.0) | | `logoIconClassName` | `string` | `undefined` | Logo icon classes (v1.1.0) | | `navItemClassName` | `string` | `undefined` | All navigation items classes (v1.1.0) | | `navSectionClassName` | `string` | `undefined` | Section title wrapper classes (v1.1.0) | | `backgroundClassName` | `string` | `undefined` | Control entire sidebar background (v1.2.0) | ## Navbar Component ### Basic Usage ```tsx import { Navbar } from 'aurcare-ui'; function App() { return ( <Navbar user={{ name: 'John Doe', email: 'john@example.com', role: 'Administrator', }} onLogout={() => console.log('Logout')} /> ); } ``` ### With Notifications ```tsx <Navbar user={{ name: 'John Doe' }} notifications={[ { id: '1', type: 'info', title: 'New Message', message: 'You have a new message from Jane', time: '5 minutes ago', read: false, }, { id: '2', type: 'success', title: 'Task Completed', message: 'Your task has been completed successfully', time: '1 hour ago', read: true, }, ]} onNotificationClick={(notification) => console.log(notification)} onMarkAllAsRead={() => console.log('Mark all as read')} /> ``` ### With Theme and Language Switcher ```tsx <Navbar user={{ name: 'John Doe' }} showThemeToggle={true} showLanguageSwitcher={true} languages={[ { code: 'en', label: 'English' }, { code: 'ar', label: 'العربية' }, { code: 'es', label: 'Español' }, ]} currentLanguage="en" onLanguageChange={(code) => console.log('Language:', code)} /> ``` ### With Custom Content ```tsx <Navbar user={{ name: 'John Doe' }} leftContent={ <div className="flex items-center gap-2"> <Search className="w-5 h-5" /> <input type="text" placeholder="Search..." /> </div> } rightContent={ <Button variant="flat" color="primary"> New Task </Button> } /> ``` ### Background Control (v1.2.0) Control the entire background of the Navbar for custom themes: ```tsx // Custom background with shadow <Navbar user={user} backgroundClassName="bg-slate-50 dark:bg-slate-950 shadow-lg" /> // Transparent navbar with blur <Navbar user={user} backgroundClassName="bg-white/80 dark:bg-slate-900/80 backdrop-blur-md" /> // Colored navbar <Navbar user={user} backgroundClassName="bg-blue-600 dark:bg-blue-900 text-white" /> ``` ### With Translation Function ```tsx import { useTranslations } from 'next-intl'; function App() { const t = useTranslations(); return ( <Navbar user={{ name: 'John Doe' }} t={t} /> ); } ``` ### Navbar Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `user` | `UserProfile` | `{ name: 'Admin', role: 'Administrator' }` | User profile information | | `notifications` | `Notification[]` | `[]` | Notifications array | | `onNotificationClick` | `(notification: Notification) => void` | `undefined` | Notification click callback | | `onMarkAllAsRead` | `() => void` | `undefined` | Mark all as read callback | | `onLogout` | `() => void` | `undefined` | Logout callback | | `onProfileClick` | `() => void` | `undefined` | Profile click callback | | `onSettingsClick` | `() => void` | `undefined` | Settings click callback | | `languages` | `LanguageOption[]` | `[{ code: 'en', label: 'English' }, { code: 'ar', label: 'العربية' }]` | Available languages | | `currentLanguage` | `string` | `'en'` | Current language code | | `onLanguageChange` | `(code: string) => void` | `undefined` | Language change callback | | `showThemeToggle` | `boolean` | `true` | Show theme toggle | | `showNotifications` | `boolean` | `true` | Show notifications | | `showLanguageSwitcher` | `boolean` | `true` | Show language switcher | | `leftContent` | `ReactNode` | `undefined` | Custom left content | | `rightContent` | `ReactNode` | `undefined` | Custom right content | | `className` | `string` | `undefined` | Additional CSS classes | | `t` | `(key: string) => string` | `defaultTranslate` | Translation function | | `containerClassName` | `string` | `undefined` | Navbar container classes (v1.1.0) | | `notificationsClassName` | `string` | `undefined` | Notifications dropdown classes (v1.1.0) | | `userMenuClassName` | `string` | `undefined` | User menu dropdown classes (v1.1.0) | | `backgroundClassName` | `string` | `undefined` | Control entire navbar background (v1.2.0) | ## Complete Examples ### Basic Layout Example ```tsx import { Sidebar, Navbar } from 'aurcare-ui'; import { Home, Users, Calendar, Settings } from 'lucide-react'; function DashboardLayout({ children }) { const [isCollapsed, setIsCollapsed] = useState(false); const sections = [ { id: 'main', title: 'Main', items: [ { id: 'home', label: 'Home', href: '/', icon: Home }, { id: 'users', label: 'Users', href: '/users', icon: Users, badge: 5 }, { id: 'calendar', label: 'Calendar', href: '/calendar', icon: Calendar }, ], }, { id: 'settings', title: 'Settings', items: [ { id: 'settings', label: 'Settings', href: '/settings', icon: Settings }, ], }, ]; const notifications = [ { id: '1', type: 'info', title: 'New Appointment', message: 'You have a new appointment scheduled', time: '5 minutes ago', read: false, }, ]; return ( <div className="flex h-screen"> <Sidebar sections={sections} isCollapsed={isCollapsed} onCollapse={setIsCollapsed} appName="Healthcare" appSubtitle="Management System" /> <div className="flex-1 flex flex-col"> <Navbar user={{ name: 'Dr. Jane Smith', email: 'jane@hospital.com', role: 'Administrator', }} notifications={notifications} onLogout={() => console.log('Logout')} onNotificationClick={(n) => console.log(n)} /> <main className="flex-1 overflow-y-auto p-6"> {children} </main> </div> </div> ); } ``` ### Complete Customization Example (v1.2.0) Combining all customization features including background control and per-item styling: ```tsx import { Sidebar, Navbar } from 'aurcare-ui'; import { NavSection } from 'aurcare-ui'; import { Home, Users, Settings, Bell } from 'lucide-react'; export function CustomLayout({ children }) { const navigationSections: NavSection[] = [ { id: 'main', title: 'Main Menu', items: [ { id: 'dashboard', label: 'Dashboard', href: '/dashboard', icon: Home, // Per-item custom styling className: 'bg-blue-50 dark:bg-blue-950' }, { id: 'users', label: 'Users', href: '/users', icon: Users, badge: '12', badgeColor: 'primary', // Per-item custom styling className: 'hover:bg-green-100 dark:hover:bg-green-900' } ] }, { id: 'system', title: 'System', items: [ { id: 'settings', label: 'Settings', href: '/settings', icon: Settings, // Per-item custom styling with border className: 'border-l-4 border-purple-500' } ] } ]; return ( <div className="flex h-screen"> <Sidebar sections={navigationSections} appName="My App" appSubtitle="Admin Panel" // Background control backgroundClassName="bg-slate-50 dark:bg-slate-950" // Logo customization (v1.1.0) logoClassName="px-8 py-4" logoContainerClassName="w-14 h-14 rounded-2xl" logoIconClassName="w-8 h-8" // Navigation items customization (v1.1.0) navItemClassName="px-5 py-4 mx-2 rounded-xl" navSectionClassName="px-5 mb-4 text-xs" /> <div className="flex-1 flex flex-col"> <Navbar user={{ name: 'John Doe', role: 'Administrator' }} notifications={[]} // Background control backgroundClassName="bg-slate-50 dark:bg-slate-950 shadow-md" // Container customization (v1.1.0) containerClassName="h-20 px-8" // Dropdown customization (v1.1.0) notificationsClassName="w-[600px]" userMenuClassName="w-96" showThemeToggle showNotifications /> <main className="flex-1 overflow-y-auto bg-white dark:bg-slate-900"> <div className="p-6"> {children} </div> </main> </div> </div> ); } ``` ### Matching Sidebar and Navbar Example Create a cohesive design with matching backgrounds: ```tsx const customTheme = { light: "bg-gray-50", dark: "bg-slate-950" }; const backgroundClasses = `${customTheme.light} dark:${customTheme.dark}`; return ( <div className="flex h-screen"> <Sidebar sections={navigationSections} backgroundClassName={backgroundClasses} appName="My App" locale={locale} /> <div className="flex-1 flex flex-col"> <Navbar user={user} backgroundClassName={backgroundClasses} notifications={notifications} /> <main className="flex-1 overflow-y-auto"> {children} </main> </div> </div> ); ``` ## TypeScript Support All components are fully typed with TypeScript. Import types as needed: ```tsx import type { NavItem, NavSection, SidebarProps, Notification, UserProfile, NavbarProps, } from 'aurcare-ui'; ``` ### Type Definitions ```typescript // NavItem interface export interface NavItem { id: string; label: string; href?: string; icon: React.ElementType; subItems?: NavItem[]; badge?: string | number; badgeColor?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger'; render?: (item: NavItem, isActive: boolean) => ReactNode; className?: string; // v1.2.0 } // NavSection interface export interface NavSection { id: string; title?: string; items: NavItem[]; } // UserProfile interface export interface UserProfile { name: string; email?: string; role?: string; avatar?: string; } // Notification interface export interface Notification { id: string; type: 'info' | 'success' | 'warning' | 'danger'; title: string; message: string; time: string; read: boolean; } ``` ## Styling This library uses Tailwind CSS and HeroUI. Make sure to include them in your project: ```js // tailwind.config.js import { heroui } from '@heroui/theme'; export default { content: [ './app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', './node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}', ], darkMode: 'class', plugins: [heroui()], }; ``` ## Migration Guide ### From v1.1.0 to v1.2.0 No breaking changes! All v1.1.0 code works perfectly in v1.2.0. **New Features:** - `backgroundClassName` prop for Sidebar and Navbar components - `className` prop for individual NavItem objects ```tsx // Before (v1.1.0) - Still works! <Sidebar sections={navigationSections} logoClassName="px-8" /> // After (v1.2.0) - With new features <Sidebar sections={navigationSections} logoClassName="px-8" backgroundClassName="bg-gray-50 dark:bg-gray-950" // NEW /> // Before (v1.1.0) - Still works! const sections = [ { id: 'main', items: [ { id: 'home', label: 'Home', href: '/', icon: Home } ] } ]; // After (v1.2.0) - With new features const sections = [ { id: 'main', items: [ { id: 'home', label: 'Home', href: '/', icon: Home, className: 'bg-blue-50 dark:bg-blue-950' // NEW } ] } ]; ``` ## Version History ### v1.2.0 - Added `backgroundClassName` prop to Sidebar and Navbar for complete background control - Added `className` prop to NavItem for per-item styling - No breaking changes ### v1.1.0 - Added extensive customization props for Sidebar (logo, nav items, sections) - Added customization props for Navbar (container, dropdowns) - No breaking changes ### v1.0.0 - Initial release with Sidebar and Navbar components ## License MIT ## Contributing Contributions are welcome! Please open an issue or submit a pull request. ## Support For issues and questions, please visit [GitHub Issues](https://github.com/aurcare/aurcare-ui/issues).