npm package: @rxbenefits/components
Description: Shared React components for RxBenefits applications - Layout components, data display, navigation, and utility components
Author: RxBenefits
Latest version: 1.0.0

# @rxbenefits/components

> Shared React components for RxBenefits applications

[![npm version](https://img.shields.io/npm/v/@rxbenefits/components.svg)](https://www.npmjs.com/package/@rxbenefits/components)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

## Overview

`@rxbenefits/components` provides a comprehensive collection of **shared React components** used across all RxBenefits applications. This library contains layout components, data display components, navigation components, and utility components that are common to multiple apps but don't belong in the base UI library.

### Key Features

- 🏗️ **Layout Components**: AppLayout, AppHeader, AppSidebar, ContentLayout, ExpandingPanelLayout
- 📊 **Data Display**: Table, PaginatedTable, ClientSidePagination
- 🧭 **Navigation**: Link, ScrollToTop, Profile components
- 🔧 **Utility Components**: AppIdleTimer, EnvironmentIdentifier, NotificationIcon
- 💼 **Business Components**: StatusTag, RoleTypeTags, OrganizationTypeTag, HomeCard
- 🔐 **Auth0 Integration**: Session management and authentication
- 📱 **Responsive Design**: Mobile-friendly layouts
- ♿ **Accessible**: WCAG compliant components

## Installation

```bash
npm install @rxbenefits/components
# or
yarn add @rxbenefits/components
```

### Peer Dependencies

This library requires the following peer dependencies:

```json
{
  "@auth0/auth0-react": "^2.2.4",
  "@rxbenefits/constants": "^1.0.0",
  "@rxbenefits/hooks": "^1.0.0",
  "@rxbenefits/icons": "^1.0.0",
  "@rxbenefits/types": "^1.0.0",
  "@rxbenefits/ui": "^1.0.0",
  "@rxbenefits/utils": "^1.0.0",
  "@tanstack/react-query": "^5.52.2",
  "react": "^18.3.1",
  "react-dom": "^18.3.1",
  "react-router-dom": "^6.26.0"
}
```

## Quick Start

```tsx
import {
  AppLayout,
  AppHeader,
  AppSidebar,
  PaginatedTable,
  StatusTag,
} from '@rxbenefits/components';

function App() {
  return (
    <AppLayout>
      <AppHeader />
      <AppSidebar />
      <div>
        <StatusTag status="active" />
        <PaginatedTable columns={columns} dataSource={data} total={100} pageSize={10} />
      </div>
    </AppLayout>
  );
}
```

## Component Catalog

### Layout Components

#### AppLayout

Main application layout wrapper with sidebar and content area.

```tsx
import { AppLayout } from '@rxbenefits/components';

function App() {
  return <AppLayout>{/* Your app content */}</AppLayout>;
}
```

**Props**: Standard React children props

**Features**:

- Responsive layout
- Sidebar integration
- Content area management

**Breaking Change**: `IncomingCallPopup` is no longer included in AppLayout. Apps that need it must add it separately.

#### AppHeader

Application header with user menu, notifications, and navigation.

```tsx
import { AppHeader } from '@rxbenefits/components';

function App() {
  return <AppHeader />;
}
```

**Features**:

- User profile dropdown
- Notification icons
- Environment indicator
- Responsive design

#### AppSidebar

Main application sidebar with navigation menu.

```tsx
import { AppSidebar } from '@rxbenefits/components';

function App() {
  return <AppSidebar />;
}
```

**Features**:

- Collapsible menu
- Active route highlighting
- Permission-based visibility

#### ContentLayout

Content wrapper with breadcrumbs and title.

```tsx
import { ContentLayout } from '@rxbenefits/components';

function MyPage() {
  return (
    <ContentLayout title="My Page" breadcrumbs={['Home', 'My Page']}>
      {/* Page content */}
    </ContentLayout>
  );
}
```

**Props**:

- `title?: string` - Page title
- `breadcrumbs?: string[]` - Breadcrumb trail
- `children?: ReactNode` - Page content

#### ExpandingPanelLayout

Collapsible panel layout with header.

```tsx
import { ExpandingPanelLayout } from '@rxbenefits/components';

function MyPanel() {
  return (
    <ExpandingPanelLayout title="Details" defaultExpanded>
      {/* Panel content */}
    </ExpandingPanelLayout>
  );
}
```

**Props**:

- `title: string` - Panel title
- `defaultExpanded?: boolean` - Initial state
- `children?: ReactNode` - Panel content

#### Profile Components

User profile management components.

```tsx
import { Profile } from '@rxbenefits/components';

function UserMenu() {
  return <Profile />;
}
```

**Sub-components**:

- `Profile` - Main profile modal
- `PasswordReset` - Password reset form
- `UserDetails` - User details form
- `UserPermissions` - Permission display

### Data Display Components

#### Table

Basic table wrapper around Ant Design Table.

```tsx
import { Table } from '@rxbenefits/components';

function MyTable() {
  return <Table columns={columns} dataSource={data} rowKey="id" />;
}
```

#### PaginatedTable

Server-side paginated table with react-query integration.

```tsx
import { PaginatedTable } from '@rxbenefits/components';

function MyPaginatedTable() {
  return (
    <PaginatedTable
      columns={columns}
      dataSource={data}
      total={totalRecords}
      pageSize={10}
      currentPage={1}
      onPageChange={(page) => setPage(page)}
    />
  );
}
```

#### ClientSidePagination

Client-side pagination for tables.

```tsx
import { ClientSidePagination } from '@rxbenefits/components';

function MyTable() {
  return <ClientSidePagination columns={columns} dataSource={data} pageSize={10} />;
}
```

#### StatusTag

Display status badges with colors.

```tsx
import { StatusTag } from '@rxbenefits/components';

<StatusTag status="active" />
<StatusTag status="inactive" />
<StatusTag status="pending" />
```

#### RoleTypeTags

Display user role tags.

```tsx
import { RoleTypeTags } from '@rxbenefits/components';

<RoleTypeTags roles={['admin', 'user']} />;
```

#### OrganizationTypeTag

Display organization type tags.

```tsx
import { OrganizationTypeTag } from '@rxbenefits/components';

<OrganizationTypeTag type="broker" />;
```

### Navigation Components

#### Link

Custom link component with routing.

```tsx
import { Link } from '@rxbenefits/components';

<Link to="/dashboard">Dashboard</Link>;
```

#### ScrollToTop

Scroll to top button.

```tsx
import { ScrollToTop } from '@rxbenefits/components';

<ScrollToTop />;
```

#### PageNotFound

404 error page.

```tsx
import { PageNotFound } from '@rxbenefits/components';

<Route path="*" element={<PageNotFound />} />;
```

### Utility Components

#### AppIdleTimer

Session timeout management with idle detection.

```tsx
import { AppIdleTimer } from '@rxbenefits/components';

function App() {
  return (
    <>
      <AppIdleTimer
        timeout={15 * 60 * 1000} // 15 minutes
        onTimeout={() => logout()}
      />
      {/* Rest of app */}
    </>
  );
}
```

**Props**:

- `timeout: number` - Timeout in milliseconds
- `onTimeout: () => void` - Callback when timeout occurs
- `warningTime?: number` - Warning time before timeout

**Features**:

- Idle detection
- Warning modal before timeout
- Session extension option
- Configurable timeout duration

#### EnvironmentIdentifier

Environment badge display (dev/staging/production).

```tsx
import { EnvironmentIdentifier } from '@rxbenefits/components';

<EnvironmentIdentifier />;
```

#### NotificationIcon

Notification icons with badge counts.

```tsx
import { NotificationIcon } from '@rxbenefits/components';

<NotificationIcon count={5} type="message" />;
```

#### IncomingCallToggle

Agent call handling toggle.

```tsx
import { IncomingCallToggle } from '@rxbenefits/components';

<IncomingCallToggle />;
```

#### InfiniteScrollSelect

Select dropdown with infinite scroll.

```tsx
import { InfiniteScrollSelect } from '@rxbenefits/components';

<InfiniteScrollSelect
  options={options}
  onLoadMore={() => fetchMore()}
  onChange={(value) => handleChange(value)}
/>;
```

#### Joyride

Tour/walkthrough component.

```tsx
import { Joyride } from '@rxbenefits/components';

<Joyride steps={tourSteps} run={showTour} onFinish={() => setShowTour(false)} />;
```

#### HomeCard

Dashboard card component.

```tsx
import { HomeCard } from '@rxbenefits/components';

<HomeCard title="My Card" icon={<DashboardIcon />} onClick={() => navigate('/dashboard')} />;
```

## React Router v6 Migration

This library uses **React Router v6** (`react-router-dom@^6.26.0`). If you're migrating from v5, note the following changes:

### Key Changes

1. **`useHistory` → `useNavigate`**

```tsx
// Old (v5)
import { useHistory } from 'react-router-dom';
const history = useHistory();
history.push('/dashboard');

// New (v6)
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/dashboard');
```

2. **`<Switch>` → `<Routes>`**

```tsx
// Old (v5)
import { Switch, Route } from 'react-router-dom';
<Switch>
  <Route path="/dashboard" component={Dashboard} />
</Switch>;

// New (v6)
import { Routes, Route } from 'react-router-dom';
<Routes>
  <Route path="/dashboard" element={<Dashboard />} />
</Routes>;
```

3. **Route Props Changes**

- `component` → `element`
- Removed: `exact` (now default behavior)
- Removed: `render` and `children` props

## Auth0 Integration

Several components integrate with Auth0 for authentication:

```tsx
import { Auth0Provider } from '@auth0/auth0-react';
import { AppLayout, AppIdleTimer } from '@rxbenefits/components';

function App() {
  return (
    <Auth0Provider domain="..." clientId="...">
      <AppIdleTimer timeout={900000} onTimeout={logout} />
      <AppLayout>{/* App content */}</AppLayout>
    </Auth0Provider>
  );
}
```

## React Query Integration

Table components use TanStack React Query for data fetching:

```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { PaginatedTable } from '@rxbenefits/components';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <PaginatedTable {...props} />
    </QueryClientProvider>
  );
}
```

## TypeScript Support

This library is written in TypeScript and provides full type definitions.

```tsx
import type { StatusTagProps, TableProps } from '@rxbenefits/components';

const props: StatusTagProps = {
  status: 'active',
};
```

## Testing

Components are tested with Jest and React Testing Library.

```tsx
import { render, screen } from '@testing-library/react';
import { StatusTag } from '@rxbenefits/components';

test('renders status tag', () => {
  render(<StatusTag status="active" />);
  expect(screen.getByText(/active/i)).toBeInTheDocument();
});
```

### Mocking Dependencies

When testing components that use Auth0, React Router, or React Query:

```tsx
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function renderWithProviders(component) {
  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter>{component}</MemoryRouter>
    </QueryClientProvider>
  );
}
```

## Breaking Changes

### v1.0.0

1. **IncomingCallPopup Removed from AppLayout**

   - **Impact**: Apps using AppLayout will need to add IncomingCallPopup themselves
   - **Migration**: Import and add `<IncomingCallPopup />` component in your app layout
   - **Reason**: IncomingCallPopup is agent-specific and creates circular dependency

2. **React Router v6 Required**

   - **Impact**: Must use react-router-dom v6.26.0 or higher
   - **Migration**: Update to React Router v6 and replace `useHistory` with `useNavigate`

3. **React 18 Required**
   - **Impact**: Must use React 18.3.1 or higher
   - **Migration**: Upgrade to React 18

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md) for development guidelines.

## License

MIT © RxBenefits

## Related Packages

- [@rxbenefits/ui](https://www.npmjs.com/package/@rxbenefits/ui) - Base UI component library
- [@rxbenefits/icons](https://www.npmjs.com/package/@rxbenefits/icons) - Icon library
- [@rxbenefits/hooks](https://www.npmjs.com/package/@rxbenefits/hooks) - Custom React hooks
- [@rxbenefits/types](https://www.npmjs.com/package/@rxbenefits/types) - TypeScript types
- [@rxbenefits/constants](https://www.npmjs.com/package/@rxbenefits/constants) - Constants
- [@rxbenefits/utils](https://www.npmjs.com/package/@rxbenefits/utils) - Utility functions

## Support

For issues and questions:

- GitHub Issues: https://github.com/rxbenefits/rxbenefits-components/issues
- Internal Slack: #optimize-support