Layout
AppRail
A narrow vertical icon navigation strip typically placed on the far left of the application. Works with AppRailItem for icon-based section navigation.
Overview
The AppRail component provides a compact, icon-based navigation strip for switching between major application sections. It's typically used alongside a Sidebar for a dual-navigation pattern common in modern applications.
Components
The AppRail system includes these components:
| Component | Description |
|---|---|
AppRail | Container component with header, navigation items, and footer slots |
AppRailItem | Individual navigation item with icon and label |
Props
AppRail Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | - | AppRailItem components |
activeSection | string | null | - | Currently active section (controlled) |
defaultActiveSection | string | null | null | Default active section (uncontrolled) |
onActiveSectionChange | (section: string | null) => void | - | Callback when active section changes |
header | ReactNode | - | Header content (typically logo) |
footer | ReactNode | - | Footer content (typically user avatar) |
AppRailItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
section | string | - | Unique section identifier (required) |
icon | ReactNode | - | Icon to display (required) |
label | string | - | Accessible label for the item (required) |
Examples
Basic AppRail
<AppRail defaultActiveSection="home">
<AppRailItem
section="home"
icon={<HomeIcon />}
label="Home"
/>
<AppRailItem
section="settings"
icon={<SettingsIcon />}
label="Settings"
/>
</AppRail> With Header and Footer
<AppRail
header={<EnaraLogo size="sm" />}
footer={<Avatar name="John Doe" size="sm" />}
defaultActiveSection="clinical"
>
<AppRailItem section="clinical" icon={<Icon />} label="Clinical" />
<AppRailItem section="admin" icon={<Icon />} label="Admin" />
<AppRailItem section="reports" icon={<Icon />} label="Reports" />
</AppRail> Controlled Mode
Use controlled mode to manage the active section externally.
const [activeSection, setActiveSection] = useState('dashboard');
<AppRail
activeSection={activeSection}
onActiveSectionChange={setActiveSection}
>
<AppRailItem section="dashboard" icon={<Icon />} label="Dashboard" />
<AppRailItem section="patients" icon={<Icon />} label="Patients" />
</AppRail>
// Use activeSection to conditionally render Sidebar content
{activeSection === "dashboard" && <DashboardSidebar />} Using useAppRail Hook
Access the rail context from nested components.
import { useAppRail } from '@enara-health/ui-react';
function SidebarContent() {
const { activeSection } = useAppRail();
switch (activeSection) {
case 'dashboard':
return <DashboardNav />;
case 'patients':
return <PatientsNav />;
default:
return null;
}
} Common Patterns
Dual Navigation Pattern
AppRail is commonly used with a Sidebar for two-level navigation. The rail handles section switching while the sidebar shows section-specific navigation.
<AppLayout>
<AppRail
activeSection={section}
onActiveSectionChange={setSection}
header={<EnaraLogo />}
footer={<Avatar />}
>
<AppRailItem section="clinical" ... />
<AppRailItem section="admin" ... />
</AppRail>
<Sidebar open={!!section}>
{section === "clinical" && <ClinicalNavItems />}
{section === "admin" && <AdminNavItems />}
</Sidebar>
<main>...</main>
</AppLayout> Accessibility
- Navigation Landmark: Uses
<aside>and<nav>elements for proper landmark structure. - Keyboard Support: Tab navigates through items, Enter or Space activates the selected item.
- Labels: Each AppRailItem requires a
labelprop that provides an accessible name viaaria-label. - Active State: The active item is indicated via
aria-pressedfor screen readers.
Best Practices
- Always provide descriptive labels for each AppRailItem
- Limit rail items to 5-7 for clarity and usability
- Use recognizable icons that represent section content
- Consider tooltips on hover for additional context