Shared UI Component Library
All reusable UI primitives live under src/shared/components/ui/. These components ensure consistent visual style, accessibility, and interaction patterns across every feature.
Component Catalog​
| Component | File Path | Usage & Props |
|---|---|---|
Button | shared/components/ui/Button.tsx | Standard button with variants (primary, secondary, danger, outline, ghost), loading spinners, and disabled states. |
Modal | shared/components/ui/Modal.tsx | Headless UI-powered accessible dialog with backdrop, title, custom width, and close button. |
Stepper | shared/components/ui/Stepper.tsx | Multi-step progress bar indicator used in Wizards. |
SearchBar | shared/components/ui/SearchBar.tsx | Input with search icon, clear button, and debounce integration. |
SearchableSelect | shared/components/ui/SearchableSelect.tsx | Filterable dropdown selector for selecting employees, departments, or roles. |
DataTable | shared/components/DataTable.tsx | Sortable data table with empty states, loading skeletons, and sticky headers. |
CollapsibleSection | shared/components/ui/CollapsibleSection.tsx | Accordion section card with chevron toggle and smooth height transitions. |
PageHeader | shared/components/ui/PageHeader.tsx | Standard page header with title, subtitle, breadcrumbs, and right-aligned CTA buttons. |
PageToggle | shared/components/PageToggle.tsx | Segmented pill tab switcher (e.g. My Timesheets vs Team Timesheets). |
EmptyState | shared/components/ui/EmptyState.tsx | Illustrated empty placeholder with title, description, and optional action button. |
LoadingSpinner | shared/components/ui/LoadingSpinner.tsx | Centered CSS spinner for route and card loading fallbacks. |
Tooltip | shared/components/Tooltip.tsx | Hover tooltip for truncations and icon explanation badges. |
Code Examples​
1. Button Component​
import Button from '@/shared/components/ui/Button';
import { Plus } from 'lucide-react';
<Button
variant="primary"
size="md"
isLoading={isSubmitting}
leftIcon={<Plus className="w-4 h-4" />}
onClick={handleCreate}>
Create Employee
</Button>
2. Modal Component​
import Modal from '@/shared/components/ui/Modal';
import Button from '@/shared/components/ui/Button';
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Confirm Action"
size="md">
<div className="p-4 space-y-4">
<p>Are you sure you want to approve this request?</p>
<div className="flex justify-end gap-2">
<Button variant="secondary" onClick={() => setIsOpen(false)}>Cancel</Button>
<Button variant="primary" onClick={handleConfirm}>Confirm</Button>
</div>
</div>
</Modal>
3. Stepper Component​
import Stepper from '@/shared/components/ui/Stepper';
const steps = ['Personal Info', 'Job & Role', 'Compensation', 'Review'];
<Stepper
steps={steps}
currentStep={currentStep}
onStepClick={(stepIndex) => setCurrentStep(stepIndex)}
/>