aurcare-ui
Version:
Aurcare UI component library for healthcare applications with dynamic sidebar, navbar, and stats cards
820 lines (705 loc) • 20.4 kB
Markdown
# 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).