Skip to main content

Interactive Components

Interactive components provide dynamic user interaction through overlays, navigation, and state management. These components handle user actions, show/hide content, and manage complex UI states.

Accordions

CustomAccordion

Expandable/collapsible content container with Chakra UI accordion.

Location: src/components/Accordion/CustomAccordion/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | data | Array | Yes | - | Array of accordion items | | stacked | boolean | No | false | Stacked border styling | | accordionItemProps | Object | No | - | Props for accordion items | | ...rest | AccordionProps | No | - | Additional Chakra UI props |

Usage:

import CustomAccordion from 'components/Accordion/CustomAccordion';

// Basic accordion
<CustomAccordion
data={[
{ title: 'Section 1', content: 'Content 1' },
{ title: 'Section 2', content: 'Content 2' }
]}
/>

// Stacked accordion
<CustomAccordion
data={accordionData}
stacked
accordionItemProps={{ borderColor: 'gray.200' }}
/>

Tabs

WPTabbedPage

Comprehensive tabbed page layout with header, filters, and content sections.

Location: src/components/WPagesTemplates/WPTabbedPage.tsx

Components:

  • WPTabbedPage - Main wrapper
  • WPTabbedPage.Title - Page title with tooltip
  • WPTabbedPage.Body - Tab container
  • WPTabbedPage.BreadCrumb - Navigation breadcrumb
  • WPTabbedPage.HeaderSection - Header layout
  • WPTabbedPage.Table - Table content with tabs

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | pageTitle | string | No | - | Main page title | | title | string | No | - | Title text | | description | string | No | - | Description for tooltip | | hasToolTip | boolean | No | false | Show tooltip | | defaultStatus | string | No | - | Default tab status | | noFooter | boolean | No | false | Hide footer |

Usage:

import { WPTabbedPage } from 'components/WPagesTemplates/WPTabbedPage';

<WPTabbedPage pageTitle='Transactions'>
<WPTabbedPage.Title
title='Payment Details'
description='Manage payment transactions'
hasToolTip
/>

<WPTabbedPage.Body defaultIndex={0}>
&lt;TabList&gt;
&lt;Tab&gt;Pending</Tab>
&lt;Tab&gt;Completed</Tab>
</TabList>
&lt;TabPanels&gt;
&lt;TabPanel&gt;Pending content</TabPanel>
&lt;TabPanel&gt;Completed content</TabPanel>
</TabPanels>
</WPTabbedPage.Body>
</WPTabbedPage>;

TabsWrapper

Flexible tab component with horizontal/vertical orientation and custom styling.

Location: src/components/Tabs/TabsWrapper.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | tabData | Array | Yes | - | Tab configuration array | | orientation | string | No | 'horizontal' | Tab orientation | | variant | string | No | - | Custom styling variant | | defaultIndex | number | No | 0 | Default active tab | | onTabChange | function | No | - | Tab change handler |

Usage:

import TabsWrapper from 'components/Tabs/TabsWrapper';

const tabData = [
{ id: 1, title: 'Filter', children: <FilterComponent /> },
{ id: 2, title: 'Settings', children: <SettingsComponent /> },
];

<TabsWrapper
tabData={tabData}
orientation='horizontal'
variant='custom'
onTabChange={index => console.log('Tab changed:', index)}
/>;

AdvancedTabsWrapper (WPTabPage)

Advanced tab layout with header sections and content areas.

Location: src/components/Tabs/AdvancedTabsWrapper.tsx

Components:

  • WPTabPage - Main wrapper
  • WPTabPage.BreadCrumb - Navigation breadcrumb
  • WPTabPage.Title - Page title
  • WPTabPage.Body - Tab container
  • WPTabPage.HeaderSection - Header layout
  • WPTabPage.TabsNFilters - Tabs with filters
  • WPTabPage.Content - Tab content panels

Usage:

import { WPTabPage } from 'components/Tabs/AdvancedTabsWrapper';

&lt;WPTabPage&gt;
<WPTabPage.BreadCrumb>
<Link to='/dashboard'>Dashboard</Link>
</WPTabPage.BreadCrumb>

<WPTabPage.Title title='Reports' />

<WPTabPage.Body>
<WPTabPage.HeaderSection>
<WPTabPage.TabsNFilters tabData={tabData}>
<FilterComponent />
</WPTabPage.TabsNFilters>
</WPTabPage.HeaderSection>

<WPTabPage.Content tabData={tabData} />
</WPTabPage.Body>
</WPTabPage>;

Modals

ActionModal

Comprehensive modal component with header, body, and footer sections.

Location: src/components/Forms/Modals/ActionModal.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Modal open state | | onClose | function | Yes | - | Close handler | | heading | ReactNode | No | - | Modal heading | | children | ReactNode | No | - | Modal content | | footer | ReactNode | No | - | Footer content | | noDivider | boolean | No | false | Hide divider | | noHeading | boolean | No | false | Hide heading | | noCloseButton | boolean | No | false | Hide close button | | maxW | string | No | '630px' | Max width | | isSuccess | boolean | No | false | Success state | | successComponent | ReactNode | No | - | Success content |

Usage:

import ActionModal from 'components/Forms/Modals/ActionModal';

<ActionModal
isOpen={isOpen}
onClose={onClose}
heading='Edit User'
maxW='800px'
footer={
&lt;HStack&gt;
<Button variant='outline' onClick={onClose}>
Cancel
</Button>
<Button onClick={handleSave}>Save</Button>
</HStack>
}
>
<UserForm />
</ActionModal>;

WPModal

Simple modal wrapper with heading and body.

Location: src/components/WPModal.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Modal open state | | handleClose | function | Yes | - | Close handler | | heading | string | Yes | - | Modal heading | | children | ReactNode | Yes | - | Modal content | | customWidth | string | Yes | - | Custom modal width | | isLoading | boolean | No | false | Loading state |

Usage:

import WPModal from 'components/WPModal';

<WPModal
isOpen={isOpen}
handleClose={handleClose}
heading='User Details'
customWidth='600px'
isLoading={isLoading}
>
<UserProfile />
</WPModal>;

ActionConfirmationModal

Modal for confirmation actions with action buttons.

Location: src/components/Forms/Modals/ActionConfirmationModal.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Modal open state | | onClose | function | Yes | - | Close handler | | handleActionClick | function | No | - | Action button handler | | heading | ReactNode | No | - | Modal heading | | rightButtonText | string | No | 'Submit' | Action button text | | leftButtonText | string | No | 'Cancel' | Cancel button text | | isLoading | boolean | No | false | Loading state | | isSuccess | boolean | No | false | Success state | | successMessage | string | No | - | Success message |

Usage:

import ActionConfirmationModal from 'components/Forms/Modals/ActionConfirmationModal';

<ActionConfirmationModal
isOpen={isOpen}
onClose={onClose}
heading='Confirm Action'
rightButtonText='Delete'
leftButtonText='Cancel'
handleActionClick={handleDelete}
isLoading={isDeleting}
>
&lt;Text&gt;Are you sure you want to delete this item?</Text>
</ActionConfirmationModal>;

DeleteConfirmationModal

Specialized modal for delete confirmations.

Location: src/components/Forms/Modals/DeleteModal.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Modal open state | | onClose | function | Yes | - | Close handler | | handleActionClick | function | Yes | - | Delete action handler | | heading | string | No | - | Modal heading | | rightButtonText | string | No | 'Delete' | Delete button text | | leftButtonText | string | No | 'Cancel' | Cancel button text | | isLoading | boolean | Yes | - | Loading state | | loadingText | string | No | 'Deleting...' | Loading text |

Usage:

import DeleteConfirmationModal from 'components/Forms/Modals/DeleteModal';

<DeleteConfirmationModal
isOpen={isOpen}
onClose={onClose}
heading='Delete User'
handleActionClick={handleDelete}
isLoading={isDeleting}
loadingText='Deleting user...'
>
&lt;Text&gt;This action cannot be undone.</Text>
</DeleteConfirmationModal>;

Drawers

ActionDrawer

Comprehensive drawer component with header, body, and footer sections.

Location: src/components/Drawers/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Drawer open state | | onClose | function | Yes | - | Close handler | | heading | ReactNode | No | - | Drawer heading | | children | ReactNode | No | - | Drawer content | | footer | ReactNode | No | - | Footer content | | width | string | No | - | Custom width | | maxH | string | No | 'auto' | Max height | | noDivider | boolean | No | false | Hide divider | | noHeading | boolean | No | false | Hide heading | | noCloseButton | boolean | No | false | Hide close button | | isSuccess | boolean | No | false | Success state | | successComponent | ReactNode | No | - | Success content |

Usage:

import ActionDrawer from 'components/Drawers';

<ActionDrawer
isOpen={isOpen}
onClose={onClose}
heading='Edit Settings'
width='400px'
footer={
&lt;HStack&gt;
<Button variant='outline' onClick={onClose}>
Cancel
</Button>
<Button onClick={handleSave}>Save</Button>
</HStack>
}
>
<SettingsForm />
</ActionDrawer>;

SideBarDrawer

Mobile sidebar drawer wrapper.

Location: src/components/SideBarDrawer/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Drawer open state | | onClose | function | Yes | - | Close handler |

Usage:

import SideBarDrawer from 'components/SideBarDrawer';

<SideBarDrawer
isOpen={isMobileMenuOpen}
onClose={() => setIsMobileMenuOpen(false)}
/>;

Filter

Filter drawer with tabbed interface.

Location: src/components/Filter/Filter.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | isOpen | boolean | Yes | - | Drawer open state | | onClose | function | Yes | - | Close handler |

Usage:

import Filter from 'components/Filter/Filter';

<Filter isOpen={isFilterOpen} onClose={() => setIsFilterOpen(false)} />;

Popovers

ReusableFilter

Popover-based filter component with form integration.

Location: src/components/ReusableFilter/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | children | ReactNode | Yes | - | Filter form content | | handleSubmit | function | Yes | - | Form submit handler | | query | Object | Yes | - | Current filter state | | setQuery | function | Yes | - | Filter state setter | | isOpen | boolean | Yes | - | Popover open state | | onOpen | function | Yes | - | Open handler | | onClose | function | Yes | - | Close handler | | isLoading | boolean | Yes | - | Loading state | | isDisabled | boolean | Yes | - | Disabled state | | handleReset | function | No | - | Reset handler |

Usage:

import FilteringComponent from 'components/ReusableFilter';

<FilteringComponent
handleSubmit={handleFilterSubmit}
query={filters}
setQuery={setFilters}
isOpen={isFilterOpen}
onOpen={onFilterOpen}
onClose={onFilterClose}
isLoading={isFiltering}
isDisabled={false}
>
<VStack spacing={4}>
&lt;FormControl&gt;
&lt;FormLabel&gt;Status</FormLabel>
<Select {...register('status')}>
<option value='active'>Active</option>
<option value='inactive'>Inactive</option>
</Select>
</FormControl>
</VStack>
</FilteringComponent>;

FilterContainer

Simple filter popover container.

Location: src/components/Filter/FilterContainer.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | children | ReactNode | Yes | - | Filter content | | selectedFiltersCount | number | No | - | Active filters count |

Usage:

import { FilterContainer } from 'components/Filter/FilterContainer';

<FilterContainer selectedFiltersCount={3}>
<VStack spacing={4}>
<FilterOption label='Status' />
<FilterOption label='Date Range' />
</VStack>
</FilterContainer>;

EWASignupGuide

Popover guide for Earned Wage Access signup.

Location: src/components/Navbar/EWASignupGuide.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | hiddenFields | Object | No | - | Hidden form fields |

Usage:

import EWASignupGuide from 'components/Navbar/EWASignupGuide';

<EWASignupGuide
hiddenFields={{
userId: user.id,
companyId: company.id,
}}
/>;

CustomSelectDropdown

Custom dropdown with search and selection functionality.

Location: src/components/Selects/CustomSelect.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | options | Array | Yes | - | Select options | | onChange | function | Yes | - | Change handler | | onVariantChange | function | Yes | - | Variant change handler | | variant | string | Yes | - | Dropdown variant | | name | string | Yes | - | Input name | | myValue | string | Yes | - | Current value | | queryParamValue | string | Yes | - | Query param value | | isClearable | boolean | No | true | Allow clearing | | isDisabled | boolean | No | false | Disabled state |

Usage:

import CustomSelectDropdown from 'components/Selects/CustomSelect';

<CustomSelectDropdown
options={[
{ label: 'Option 1', value: 'opt1' },
{ label: 'Option 2', value: 'opt2' },
]}
onChange={handleChange}
onVariantChange={handleVariantChange}
variant='base'
name='selection'
myValue={selectedValue}
queryParamValue=''
isClearable
/>;

ComboBoxButton

Button group with dropdown menu.

Location: src/components/Forms/Buttons/ComboBox.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | data | Array | Yes | - | Menu items | | variant | string | Yes | - | Button variant | | size | string | Yes | - | Button size | | defaultIndex | number | Yes | - | Default selected item | | isDisabled | boolean | No | false | Disabled state | | isLoading | boolean | No | false | Loading state |

Usage:

import ComboBoxButton from 'components/Forms/Buttons/ComboBox';

<ComboBoxButton
data={[
{ label: 'Action 1', value: 'action1', handleClick: handleAction1 },
{ label: 'Action 2', value: 'action2', handleClick: handleAction2 },
]}
variant='outline'
size='md'
defaultIndex={0}
isLoading={isLoading}
/>;

CustomMenu

Flexible menu component with various configurations.

Location: src/components/Menu/CustomMenu/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | options | Array | Yes | - | Menu options | | name | string | No | - | Menu button text | | action | boolean | No | false | Show as action menu | | leftIcon | ReactNode | No | - | Left icon | | rightIcon | ReactNode | No | - | Right icon | | baseIconButton | ReactNode | No | - | Icon button mode | | baseVariant | string | No | - | Button variant | | baseBg | string | No | - | Background color |

Usage:

import CustomMenu from 'components/Menu/CustomMenu';

<CustomMenu
options={[
{ label: 'Edit', onClick: handleEdit },
{ label: 'Delete', onClick: handleDelete },
]}
name='Actions'
action
leftIcon={<SettingsIcon />}
/>;

Tooltips

CustomTooltip

Custom tooltip component with positioning options.

Location: src/components/Tooltips/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | label | string | Yes | - | Tooltip content | | children | ReactNode | Yes | - | Trigger element | | isImprest | boolean | Yes | - | Position variant |

Usage:

import { CustomTooltip } from 'components/Tooltips';

<CustomTooltip label='This is a helpful tooltip' isImprest={false}>
&lt;Button&gt;Hover me</Button>
</CustomTooltip>;

CustomIconButton

Icon button with integrated tooltip.

Location: src/components/Button/CustomIconButton/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | icon | ReactNode | Yes | - | Button icon | | label | string | Yes | - | Tooltip label | | size | string | Yes | - | Button size | | noTooltip | boolean | No | false | Disable tooltip | | ...rest | ButtonProps | No | - | Additional props |

Usage:

import CustomIconButton from 'components/Button/CustomIconButton';

<CustomIconButton
icon={<EditIcon />}
label="Edit item"
size="sm"
onClick={handleEdit}
variant="outline"
/>

// Without tooltip
<CustomIconButton
icon={<DeleteIcon />}
label="Delete item"
size="sm"
noTooltip
onClick={handleDelete}
/>

Calendars

WPCalendar

Basic calendar component with event display.

Location: src/components/Calendar/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | events | Array | Yes | - | Calendar events | | loading | boolean | Yes | - | Loading state | | views | Array | No | ['month'] | Available views | | viewDate | Date | No | new Date() | Initial view date | | onSelectEvent | function | No | - | Event selection handler | | tooltipAccessor | string | No | - | Event tooltip property | | onShowMore | function | No | - | Show more handler | | eventPropGetter | function | No | - | Event styling getter | | showAllEvents | boolean | No | false | Show all events | | components | Object | No | - | Custom components |

Usage:

import WPCalendar from 'components/Calendar';

<WPCalendar
events={[
{
title: 'Meeting',
start: new Date(2024, 0, 15, 10, 0),
end: new Date(2024, 0, 15, 11, 0),
},
]}
loading={false}
views={['month', 'week', 'day']}
onSelectEvent={handleEventSelect}
eventPropGetter={event => ({
style: { backgroundColor: event.color },
})}
/>;

WPCalendarV2

Advanced calendar with filtering and event popup.

Location: src/components/CalendarV2/index.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | events | Array | Yes | - | Calendar events | | loading | boolean | Yes | - | Loading state | | views | Array | Yes | - | Available views | | viewDate | Date | No | new Date() | Initial view date | | eventPropGetter | function | Yes | - | Event styling getter | | components | Object | Yes | - | Custom components | | handleResetFilters | function | Yes | - | Reset filters handler | | searchText | string | Yes | - | Search text | | setSearchText | function | Yes | - | Search text setter | | LeaveStatusOption | Array | Yes | - | Status options | | leaveStatus | string | Yes | - | Current status | | handleLeaveStatusFilter | function | Yes | - | Status filter handler | | handleChangeDate | function | Yes | - | Date change handler | | setFilters | function | Yes | - | Filters setter | | filters | Object | Yes | - | Current filters |

Usage:

import WPCalendar from 'components/CalendarV2';

<WPCalendar
events={calendarEvents}
loading={isLoading}
views={['month', 'week', 'day']}
viewDate={currentDate}
eventPropGetter={getEventStyles}
components={{ event: CustomEvent }}
handleResetFilters={resetFilters}
searchText={searchText}
setSearchText={setSearchText}
LeaveStatusOption={statusOptions}
leaveStatus={currentStatus}
handleLeaveStatusFilter={handleStatusFilter}
handleChangeDate={handleDateChange}
setFilters={setFilters}
filters={filters}
/>;

Date Pickers

WPDatepicker

Form-integrated date picker with validation.

Location: src/components/Forms/WPDatepicker.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | name | string | Yes | - | Field name | | control | Control | Yes | - | React Hook Form control | | label | string | Yes | - | Field label | | error | FieldError | No | - | Validation error | | isRequired | boolean | No | false | Required field | | rules | Object | No | - | Validation rules | | defaultValue | Date | No | - | Default value | | isClearable | boolean | No | false | Allow clearing | | helperText | string | No | - | Helper text | | isLoading | boolean | No | false | Loading state |

Usage:

import { WPDatepicker } from 'components/Forms/WPDatepicker';

<WPDatepicker
name='startDate'
control={control}
label='Start Date'
rules={{ required: 'Start date is required' }}
error={errors.startDate}
isClearable
helperText='Select your preferred start date'
/>;

WPDateCustomInput

Custom date input with calendar icon.

Location: src/components/Forms/WPDateCustomInput.tsx

Props: | Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | selectedDate | Date | Yes | - | Selected date | | placeholderText | string | Yes | - | Placeholder text | | ...restProps | ButtonProps | No | - | Additional props |

Usage:

import WPDateCustomInput from 'components/Forms/WPDateCustomInput';

<WPDateCustomInput
selectedDate={selectedDate}
placeholderText='Select date'
onClick={handleDateClick}
variant='outline'
/>;

Best Practices

// Use disclosure hook for modal state
const { isOpen, onOpen, onClose } = useDisclosure();

// Handle loading states
const [isLoading, setIsLoading] = useState(false);

const handleSubmit = async () => {
setIsLoading(true);
try {
await submitAction();
onClose();
} finally {
setIsLoading(false);
}
};

Tab State Management

// Use controlled tabs for complex state
const [activeTab, setActiveTab] = useState(0);

const handleTabChange = index => {
setActiveTab(index);
// Reset other states
resetPagination();
};

Calendar Event Handling

// Implement event handlers
const handleSelectEvent = event => {
setSelectedEvent(event);
onEventModalOpen();
};

const handleNavigate = date => {
setCurrentDate(date);
// Fetch events for new date range
fetchEvents(date);
};

Filter Management

// Handle filter state
const [filters, setFilters] = useState({});

const handleFilterSubmit = newFilters => {
setFilters(newFilters);
// Apply filters to data
applyFilters(newFilters);
};

const handleResetFilters = () => {
setFilters({});
// Reset data
resetData();
};
  • Form Components: Integration with form validation
  • Button Components: Trigger elements for interactions
  • Table Components: Data display with interactive features
  • Layout Components: Container layouts for interactive elements

Styling and Theming

All interactive components support:

  • Chakra UI theme integration
  • Custom variants and sizes
  • Responsive design patterns
  • Accessibility features
  • Focus management
  • Keyboard navigation

Performance Considerations

  • Use React.memo for expensive modal content
  • Implement lazy loading for tab content
  • Optimize calendar event rendering
  • Use proper cleanup for event listeners
  • Consider virtualization for large dropdowns