Skip to main content

Top-Level Components

Top-level components are individual utility components that provide specific functionality without requiring their own directory structure. These components handle common patterns like text truncation, modals, toggles, navigation, and form inputs.

Overview​

This document covers standalone components that are directly placed in the src/components/ directory and provide focused functionality for the WorkPayCore Frontend application.

Components Overview​

Text & Display Components​

  • WPTruncateText - Text truncation with tooltip
  • ComingSoon - Empty state for features under development
  • UnderMaintenance - System maintenance page
  • WPModal - Basic modal wrapper with customizable width

Input Components​

Toggle Components​

  • ToggleSwitchOne - Multi-option toggle switch
  • ToggleSwitch - Basic toggle switch

Utility Components​

  • ScrollToTop - Scroll to top functionality
  • ProtectedRoutes - Route protection wrapper
  • RenewSubscription - Subscription renewal component

WPTruncateText​

A component that truncates text with a tooltip if it exceeds the maximum length. Shows the full text in a tooltip on hover.

Component Location​

import WPTruncatedText from 'components/WPTruncateText';

Props​

PropTypeRequiredDefaultDescription
textToTruncatestring✓-The text to be truncated
maxLengthnumber-16Maximum length before truncation occurs

TypeScript Interface​

interface WPTruncatedTextProps {
textToTruncate: string;
maxLength?: number;
}

Usage Examples​

Basic Usage​

import WPTruncatedText from 'components/WPTruncateText';

function UserName() {
return (
<WPTruncatedText
textToTruncate='This is a very long user name that needs truncation'
maxLength={20}
/>
);
}

Default Length​

import WPTruncatedText from 'components/WPTruncateText';

function FileName() {
return (
<WPTruncatedText textToTruncate='very-long-filename-that-exceeds-default-length.pdf' />
);
}

Styling​

  • Uses textStyle='body-small' from theme
  • Font weight: semi-bold
  • Font size: 13px
  • White space: nowrap
  • Tooltip placement: top-start

Accessibility​

  • Tooltip shows full text when truncated
  • Supports keyboard navigation
  • Screen reader accessible through tooltip

ComingSoon​

Empty state component for features under development or maintenance.

Component Location​

import ComingSoon from 'components/ComingSoon';

Props​

PropTypeRequiredDefaultDescription
pagestring--Page/feature name
pluralboolean-falseUse plural form
variantstring--Variant (maintenance, under-maintenance)

TypeScript Interface​

interface ComingSoonProps {
page?: string;
plural?: boolean;
variant?: 'maintenance' | 'under-maintenance';
}

Usage Examples​

Feature Coming Soon​

import ComingSoon from 'components/ComingSoon';

function ReportsPage() {
return <ComingSoon page='Reports' plural={true} />;
}

Under Maintenance​

import ComingSoon from 'components/ComingSoon';

function DashboardPage() {
return <ComingSoon page='Dashboard' variant='maintenance' />;
}

System Maintenance​

import ComingSoon from 'components/ComingSoon';

function MaintenancePage() {
return <ComingSoon variant='under-maintenance' />;
}

Styling​

  • Uses background image from assets/images/ComingSoon.svg
  • Centered layout with VStack
  • Logo positioned absolutely for maintenance variant
  • Responsive typography

WPModal​

Basic modal wrapper component with customizable width and loading states.

Component Location​

import WPModal from 'components/WPModal';

Props​

PropTypeRequiredDefaultDescription
headingstring✓-Modal heading text
isOpenboolean✓-Modal open state
handleClosefunction✓-Close handler function
childrenReactNode✓-Modal content
customWidthstring✓-Custom modal width
isLoadingboolean-falseLoading state
isCenteredboolean-falseCenter modal

TypeScript Interface​

interface WPModalProps {
heading: string;
isOpen: boolean;
handleClose: () => void;
children: React.ReactNode;
customWidth: string;
isLoading?: boolean;
isCentered?: boolean;
}

Usage Examples​

Basic Modal​

import WPModal from 'components/WPModal';

function UserEditModal() {
const [isOpen, setIsOpen] = useState(false);

return (
<WPModal
heading='Edit User'
isOpen={isOpen}
handleClose={() => setIsOpen(false)}
customWidth='600px'
>
<UserForm />
</WPModal>
);
}

Loading Modal​

import WPModal from 'components/WPModal';

function SaveModal() {
const [isLoading, setIsLoading] = useState(false);

return (
<WPModal
heading='Saving Changes'
isOpen={isOpen}
handleClose={() => setIsOpen(false)}
customWidth='400px'
isLoading={isLoading}
>
&lt;Text&gt;Please wait while we save your changes...</Text>
</WPModal>
);
}

Styling​

  • Header font size: 28px
  • Header padding bottom: 0
  • Text transform: capitalize
  • Closes on overlay click (disabled when loading)
  • Close button disabled during loading

WPNumberInput​

Numeric input component with validation and React Hook Form integration.

Component Location​

import { WPNumberInput, WPNumberInput2 } from 'components/WPNumberInput';

Props​

WPNumberInput Props​

PropTypeRequiredDefaultDescription
namestring✓-Input name
controlControl✓-React Hook Form control
placeholderstring✓-Input placeholder
requiredboolean-falseRequired field
defaultValuenumber--Default value
rulesobject--Additional validation rules
stylesobject--Custom styles

WPNumberInput2 Props​

PropTypeRequiredDefaultDescription
namestring✓-Input name
controlControl✓-React Hook Form control
labelstring✓-Input label
placeholderstring✓-Input placeholder
isRequiredboolean-falseRequired field
isDisabledboolean-falseDisabled state
errorFieldError--Error object
helperTextstring--Helper text
sizestring-'sm'Input size
inputModestring-'numeric'Input mode

TypeScript Interface​

interface WPNumberInputProps {
name: string;
control: Control;
placeholder: string;
required?: boolean;
defaultValue?: number;
rules?: object;
styles?: object;
}

interface WPNumberInput2Props {
name: string;
control: Control;
label: string;
placeholder: string;
isRequired?: boolean;
isDisabled?: boolean;
error?: FieldError;
helperText?: string;
size?: string;
inputMode?: string;
}

Usage Examples​

Basic Usage​

import { WPNumberInput } from 'components/WPNumberInput';
import { useForm } from 'react-hook-form';

function AccruedDaysForm() {
const {
control,
formState: { errors },
} = useForm();

return (
<FormControl isInvalid={errors.days_accrued}>
<FormLabel isRequired>ACCRUED DAYS</FormLabel>
<WPNumberInput
name='days_accrued'
control={control}
placeholder='Enter number of days'
required
/>
&lt;FormErrorMessage&gt;{errors.days_accrued?.message}</FormErrorMessage>
</FormControl>
);
}

Advanced Usage (WPNumberInput2)​

import { WPNumberInput2 } from 'components/WPNumberInput';
import { useForm } from 'react-hook-form';

function SalaryForm() {
const {
control,
formState: { errors },
} = useForm();

return (
<WPNumberInput2
name='salary'
control={control}
label='Monthly Salary'
placeholder='Enter salary amount'
isRequired
error={errors.salary}
helperText='Enter amount in local currency'
size='md'
/>
);
}

Validation​

  • Built-in pattern validation: /^[1-9]\d*$/
  • Custom validation messages
  • Required field validation
  • Numeric keyboard on mobile devices

Styling​

  • Focus border color: green
  • Form control integration
  • Error state styling
  • Helper text support

ToggleSwitchOne​

Multi-option toggle switch component with customizable styling and loading states.

Component Location​

import ToggleSwitchOne from 'components/ToggleSwitchOne';

Props​

PropTypeRequiredDefaultDescription
optionsArray✓-Array of option objects
selectedobject✓-Currently selected option
handleChangefunction✓-Change handler
namestring✓-Form field name
isLoadingboolean-falseLoading state
isDisabledboolean-falseDisabled state
minWidthnumber-100Minimum width per option

TypeScript Interface​

interface ToggleSwitchOneProps {
options: Array<{
value: string | number;
label: string;
}>;
selected: {
value: string | number;
label: string;
};
handleChange: (value: any) => void;
name: string;
isLoading?: boolean;
isDisabled?: boolean;
minWidth?: number;
}

Usage Examples​

Basic Toggle​

import ToggleSwitchOne from 'components/ToggleSwitchOne';

function StatusToggle() {
const [selected, setSelected] = useState({
value: 'active',
label: 'Active',
});

const options = [
{ value: 'active', label: 'Active' },
{ value: 'inactive', label: 'Inactive' },
{ value: 'pending', label: 'Pending' },
];

return (
<ToggleSwitchOne
options={options}
selected={selected}
handleChange={setSelected}
name='status'
/>
);
}

Loading State​

import ToggleSwitchOne from 'components/ToggleSwitchOne';

function PayrollToggle() {
const [isLoading, setIsLoading] = useState(false);

const handleChange = async value => {
setIsLoading(true);
// API call
await updatePayrollStatus(value);
setIsLoading(false);
};

return (
<ToggleSwitchOne
options={payrollOptions}
selected={currentStatus}
handleChange={handleChange}
name='payroll_status'
isLoading={isLoading}
minWidth={120}
/>
);
}

Styling​

  • Background color: skeletonTable
  • Border radius: 28px
  • Height: 35px
  • Animated selection indicator
  • Loading spinner integration
  • Cursor states for disabled/loading

Global application sidebar with navigation menu for multi-tenant applications.

Component Location​

import GlobalSidebar from 'components/GlobalSidebar';

Features​

  • Role-based navigation (admin/employee views)
  • Feature flag integration
  • Permission-based access control
  • Subscription-based menu visibility
  • Hierarchical menu structure
  • Remote payroll support
  • Country-specific features

Usage Examples​

Basic Usage​

import GlobalSidebar from 'components/GlobalSidebar';

function AppLayout() {
return (
&lt;Flex&gt;
<GlobalSidebar />
<Box flex={1}>
<MainContent />
</Box>
</Flex>
);
}

Employee Menu Items​

  • Home
  • People (with submenus)
  • Payroll (with submenus)
  • Expenses
  • Leave
  • Performance Management
  • Documents

Admin Menu Items​

  • All employee items plus:
  • Settings
  • Analytics
  • Billing
  • Admin tools

Integration​

  • Works with feature flags system
  • Integrates with subscription status
  • Supports remote payroll switching
  • Country-specific menu items

OnboardingStepper​

Onboarding progress indicator showing completion steps.

Component Location​

import OnboardingStepper from 'components/OnboardingStepper';

Features​

  • 5-step onboarding process
  • Progress visualization
  • Step completion indicators
  • Responsive design

Usage Examples​

Basic Usage​

import OnboardingStepper from 'components/OnboardingStepper';

function OnboardingLayout() {
return (
&lt;Box&gt;
<OnboardingStepper />
<OnboardingContent />
</Box>
);
}

Steps​

  1. Create Organization
  2. Adjust Settings
  3. Add People
  4. Run Payroll
  5. Choose Plan

Styling​

  • Background: green-dark
  • Progress bar with whiteAlpha color scheme
  • Circular step indicators
  • Responsive step layout

ScrollArea​

Custom scrollable area with styled scrollbar and drag functionality.

Component Location​

import ScrollArea from 'components/ScrollArea';

Props​

PropTypeRequiredDefaultDescription
childrenReactNode✓-Scrollable content
scrollThumbColorstring-'whiteAlpha.500'Scroll thumb color

Features​

  • Custom scrollbar styling
  • Drag-to-scroll functionality
  • Hidden native scrollbars
  • Smooth scrolling animation
  • Responsive thumb sizing

Usage Examples​

Basic Usage​

import ScrollArea from 'components/ScrollArea';

function LongContent() {
return (
&lt;ScrollArea&gt;
<Box height='2000px'>
&lt;Text&gt;Very long content that needs scrolling...</Text>
</Box>
</ScrollArea>
);
}

Custom Thumb Color​

import ScrollArea from 'components/ScrollArea';

function CustomScrollArea() {
return (
<ScrollArea scrollThumbColor='green.500'>
<LongContentList />
</ScrollArea>
);
}

Styling​

  • Hidden native scrollbars
  • Custom thumb appearance
  • Hover states
  • Drag states
  • Responsive sizing

BoxInput​

Read-only input display component that mimics input styling.

Component Location​

import BoxInput from 'components/BoxInput';

Props​

PropTypeRequiredDefaultDescription
titlestring-'This is a readonly field'Tooltip text
widthstring-'full'Input width
isDisabledboolean-falseDisabled state
isRequiredboolean-falseRequired field
labelstring--Field label
labelSizestring-'md'Label size
childrenReactNode--Input content

TypeScript Interface​

interface BoxInputProps {
title?: string;
width?: string;
isDisabled?: boolean;
isRequired?: boolean;
label?: string;
labelSize?: string;
children?: React.ReactNode;
}

Usage Examples​

Basic Usage​

import BoxInput from 'components/BoxInput';

function ReadOnlyField() {
return (
<BoxInput label='Employee ID' title='This field is automatically generated'>
&lt;Text&gt;EMP-001</Text>
</BoxInput>
);
}

Disabled State​

import BoxInput from 'components/BoxInput';

function DisabledField() {
return (
<BoxInput
label='Calculated Value'
isDisabled
title='This value is calculated automatically'
>
&lt;Text&gt;$5,000.00</Text>
</BoxInput>
);
}

Styling​

  • Background color: #F2F2F2
  • Border: 1px transparent
  • Height: 2.5rem
  • Padding: 1rem
  • Disabled opacity: 0.8
  • Cursor: not-allowed when disabled

UnderMaintenance​

System maintenance page with contact information and support channels.

Component Location​

import { UnderMaintenance } from 'components/UnderMaintenance';

Features​

  • Full-page maintenance message
  • Contact information with copy functionality
  • Country-specific phone numbers
  • Support email integration
  • Responsive design

Usage Examples​

Basic Usage​

import { UnderMaintenance } from 'components/UnderMaintenance';

function MaintenancePage() {
return <UnderMaintenance />;
}

Contact Channels​

  • Email: support@myworkpay.com
  • Kenya: +254 711 082123 / +254 730 731303
  • Nigeria: +234 810 401 5886 / +234 906 382 9334
  • Uganda: +256 323 200 740

Styling​

  • Centered layout
  • Logo positioning
  • Country flag integration
  • Copy-to-clipboard functionality
  • Responsive design

Migration Notes​

Breaking Changes​

  • WPNumberInput: Updated validation patterns
  • GlobalSidebar: New menu structure for remote payroll
  • ToggleSwitchOne: Improved loading states

Deprecation Warnings​

  • Old modal patterns should migrate to WPModal
  • Legacy number inputs should use WPNumberInput2

Upgrade Paths​

  1. Replace old text truncation with WPTruncateText
  2. Update modal implementations to use WPModal
  3. Migrate number inputs to WPNumberInput2
  4. Update sidebar implementations to use GlobalSidebar

Best Practices​

Text Truncation​

  • Use appropriate maxLength based on container width
  • Provide meaningful tooltips
  • Consider responsive truncation lengths
  • Always provide proper close handlers
  • Use loading states for async operations
  • Set appropriate modal widths

Number Inputs​

  • Use proper validation rules
  • Provide clear error messages
  • Set appropriate input modes for mobile
  • Implement proper permission checks
  • Use feature flags for conditional navigation
  • Provide clear visual hierarchy

Scrolling​

  • Use ScrollArea for custom scroll styling
  • Implement proper keyboard navigation
  • Consider mobile scroll behavior

Accessibility​

General Guidelines​

  • All components support keyboard navigation
  • Proper ARIA attributes where applicable
  • Screen reader friendly implementations
  • High contrast mode support

Specific Features​

  • WPTruncateText: Tooltip accessibility
  • WPModal: Focus management
  • ToggleSwitchOne: Keyboard selection
  • GlobalSidebar: Navigation accessibility
  • ScrollArea: Keyboard scrolling support

Performance Considerations​

Optimization Tips​

  • Use React.memo for expensive components
  • Implement proper loading states
  • Optimize menu rendering with visibility checks
  • Use efficient scroll handling

Memory Management​

  • Proper cleanup in useEffect hooks
  • Event listener removal
  • Animation frame cancellation
  • Ref cleanup

Testing Strategies​

Unit Testing​

  • Test prop validation
  • Test state changes
  • Test event handlers
  • Test accessibility features

Integration Testing​

  • Test with React Hook Form
  • Test navigation flows
  • Test permission systems
  • Test responsive behavior

E2E Testing​

  • Test complete user flows
  • Test accessibility compliance
  • Test performance metrics
  • Test cross-browser compatibility