npm package: @rxbenefits/contexts
Description: React context providers for RxBenefits applications - feature flags and module configuration
Author: RxBenefits
Latest version: 1.0.0

# @rxbenefits/contexts

React context providers for RxBenefits applications - feature flags and module configuration.

[![npm version](https://img.shields.io/npm/v/@rxbenefits/contexts.svg)](https://www.npmjs.com/package/@rxbenefits/contexts)
[![CI](https://github.com/rxbenefits/rxbenefits-contexts/workflows/CI/badge.svg)](https://github.com/rxbenefits/rxbenefits-contexts/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Overview

This library provides two essential React context providers used across RxBenefits applications:

- **FeatureFlagsProvider** - Feature flag management with localStorage persistence
- **ModuleConfigProvider** - Base path configuration for modules

## Installation

```bash
npm install @rxbenefits/contexts
```

```bash
yarn add @rxbenefits/contexts
```

## Usage

### Feature Flags

The FeatureFlagsProvider manages feature flags with localStorage persistence per user.

```tsx
import { FeatureFlagsProvider, PortalFeatureFlags } from '@rxbenefits/contexts';

// In your app root
function App() {
  const { user } = useUser(); // Your auth hook

  return (
    <FeatureFlagsProvider userId={user?.id}>
      <YourApp />
    </FeatureFlagsProvider>
  );
}

// In your components
import { useContext } from 'react';
import { FeatureFlagsContext, PortalFeatureFlags } from '@rxbenefits/contexts';

function MyComponent() {
  const { featureFlags, checkFeatureFlag, patchFeatureFlag } = useContext(FeatureFlagsContext);

  const showPermissions = checkFeatureFlag(PortalFeatureFlags.SHOW_USER_PERMISSIONS);

  const toggleFlag = () => {
    patchFeatureFlag({
      title: PortalFeatureFlags.SHOW_USER_PERMISSIONS,
      value: !showPermissions,
    });
  };

  return (
    <div>
      {showPermissions && <UserPermissionsPanel />}
      <button onClick={toggleFlag}>Toggle Permissions</button>
    </div>
  );
}
```

#### Available Feature Flags

```typescript
enum PortalFeatureFlags {
  SHOW_USER_PERMISSIONS = 'Show User Permissions',
  SHOW_ROLES_PAGE = 'Show Roles Page',
}
```

#### Feature Flag Storage

Feature flags are stored in localStorage per user:

- **Key**: `portal_feature_flags`
- **Format**: `{ [userId]: FeatureFlag[] }`
- **Behavior**: If no `userId` is provided, flags are not persisted

### Module Config

The ModuleConfigProvider manages base paths for modules.

```tsx
import { ModuleConfigProvider } from '@rxbenefits/contexts';

// In your module root
function AdminModule() {
  return (
    <ModuleConfigProvider defaultPath="/admin">
      <AdminRoutes />
    </ModuleConfigProvider>
  );
}

// In your components
import { useContext } from 'react';
import { ModuleConfigContext } from '@rxbenefits/contexts';

function Navigation() {
  const { basePath, setBasePath } = useContext(ModuleConfigContext);

  return (
    <nav>
      <Link to={`${basePath}/users`}>Users</Link>
      <Link to={`${basePath}/settings`}>Settings</Link>
    </nav>
  );
}
```

## API Reference

### FeatureFlagsProvider

#### Props

| Prop       | Type        | Required | Description                          |
| ---------- | ----------- | -------- | ------------------------------------ |
| `children` | `ReactNode` | Yes      | React children to wrap               |
| `userId`   | `number`    | No       | User ID for localStorage persistence |

#### Context Value

```typescript
type FeatureFlagContextType = {
  featureFlags: FeatureFlag[];
  isLoadingFlags: boolean;
  patchFeatureFlag: (featureFlag: FeatureFlag) => void;
  checkFeatureFlag: (featureFlag: PortalFeatureFlags) => boolean | undefined;
};
```

### ModuleConfigProvider

#### Props

| Prop          | Type        | Required | Description            |
| ------------- | ----------- | -------- | ---------------------- |
| `children`    | `ReactNode` | Yes      | React children to wrap |
| `defaultPath` | `string`    | No       | Default base path      |

#### Context Value

```typescript
type ModuleConfigContextType = {
  basePath: string;
  setBasePath: (val: string) => void;
};
```

## Migration from Monorepo

### Breaking Change: FeatureFlagsProvider API

If migrating from the monorepo version, note the API change:

**Before (Monorepo):**

```tsx
<FeatureFlagsProvider>
  <App />
</FeatureFlagsProvider>
```

**After (Standalone Package):**

```tsx
const { user } = useUser(); // Get user from your auth solution

<FeatureFlagsProvider userId={user?.id}>
  <App />
</FeatureFlagsProvider>;
```

**Rationale**: Removed circular dependency with the hooks library. The provider now accepts `userId` as a prop instead of using `useUser` internally, providing better separation of concerns.

### Import Changes

Update your imports:

```typescript
// Before
import { FeatureFlagsProvider } from '@optimize/contexts';

// After
import { FeatureFlagsProvider } from '@rxbenefits/contexts';
```

## TypeScript

This library is written in TypeScript and includes type definitions.

```typescript
import type { FeatureFlag } from '@rxbenefits/contexts';

const flag: FeatureFlag = {
  title: PortalFeatureFlags.SHOW_USER_PERMISSIONS,
  value: true,
};
```

## Browser Compatibility

This library requires:

- React >= 16.8.0 (hooks support)
- localStorage support (for feature flag persistence)
- Modern browsers (ES2020+)

## Development

```bash
# Install dependencies
npm install

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

# Type check
npm run typecheck

# Lint
npm run lint

# Format code
npm run format

# Build
npm run build

# Validate (typecheck + lint + test)
npm run validate
```

## Contributing

We welcome contributions! Please see our [contributing guidelines](CONTRIBUTING.md) for details.

## License

MIT © RxBenefits

## Support

For issues and questions:

- [GitHub Issues](https://github.com/rxbenefits/rxbenefits-contexts/issues)
- [RxBenefits Documentation](https://docs.rxbenefits.com)

## Related Packages

- [`@rxbenefits/types`](https://www.npmjs.com/package/@rxbenefits/types) - TypeScript type definitions
- [`@rxbenefits/hooks`](https://www.npmjs.com/package/@rxbenefits/hooks) - Custom React hooks
- [`@rxbenefits/ui`](https://www.npmjs.com/package/@rxbenefits/ui) - UI component library