Skip to content

A powerful and type-safe React library for managing feature flags and permissions in your applications

License

Notifications You must be signed in to change notification settings

carlesfelix/features-react

Repository files navigation

Features React Library

A powerful and type-safe React library for managing feature flags and permissions in your applications. This library provides components, hooks, and utilities to conditionally render content based on available features.

Features

  • 🎯 Type-safe: Full TypeScript support with generic types
  • 🚀 Easy to use: Simple API with intuitive components and hooks
  • đź”§ Flexible: Support for any feature type (enums, strings, etc.)
  • ⚡ Performance: Efficient context-based state management
  • 🎨 Declarative: JSX components for conditional rendering
  • 🛠️ Utilities: Helper functions for filtering and checking features

Installation

npm install @carlesfelix/features-react

Quick Start

1. Define your features/permissions

// src/enums/Permissions.ts
enum Permissions {
  Permission1 = 'Permission1',
  Permission2 = 'Permission2',
  Permission3 = 'Permission3',
  // ... more permissions
}

export default Permissions

2. Create your feature configuration

// src/config/permissions.ts
import { createFeatures } from "@carlesfelix/features-react";
import Permissions from "../enums/Permissions";

export const {
  FeaturesProvider: PermissionFeaturesProvider,
  useFeatures: usePermissionFeatures,
  Features: PermissionFeatures,
  Feature: PermissionFeature
} = createFeatures<Permissions>()

3. Setup the provider

// src/App.tsx
import { PermissionFeaturesProvider } from "./config/permissions"
import Permissions from "./enums/Permissions"

const initialPermissions = [
  Permissions.Permission1, 
  Permissions.Permission2
]

function App() {
  return (
    <PermissionFeaturesProvider initialAvailableFeatures={initialPermissions}>
      {/* Your app content */}
    </PermissionFeaturesProvider>
  )
}

API Reference

Components

Feature

Conditionally renders content based on a single feature.

<PermissionFeature feature={Permissions.Permission1}>
  <div>This content is only visible if Permission1 is available</div>
</PermissionFeature>

// With fallback
<PermissionFeature 
  feature={Permissions.Permission5} 
  fallback={<div>Permission5 is not available</div>}
>
  <div>This content requires Permission5</div>
</PermissionFeature>

Props:

  • feature: The feature to check for availability
  • fallback (optional): Content to render when feature is not available
  • children: Content to render when feature is available

Features

Conditionally renders content based on multiple features (OR logic).

<PermissionFeatures features={[Permissions.Permission1, Permissions.Permission2]}>
  <div>This content is visible if Permission1 OR Permission2 is available</div>
</PermissionFeatures>

// With fallback
<PermissionFeatures 
  features={[Permissions.Permission5, Permissions.Permission6]} 
  fallback={<div>Neither Permission5 nor Permission6 is available</div>}
>
  <div>This content requires Permission5 OR Permission6</div>
</PermissionFeatures>

Props:

  • features: Array of features to check (OR logic)
  • fallback (optional): Content to render when no features are available
  • children: Content to render when at least one feature is available

Hooks

useFeatures()

Returns an object with methods and state for managing features.

const {
  // State
  availableFeatures,
  
  // Feature checking
  featureAvailable,
  someFeatureAvailable,
  
  // Feature management
  addAvailableFeature,
  addAvailableFeatures,
  removeAvailableFeature,
  removeAvailableFeatures,
  resetAvailableFeatures,
  
  // Utilities
  filterArrayWithFeature,
  filterArrayWithFeatures,
} = usePermissionFeatures()

Methods

Feature Checking

featureAvailable(feature)

Check if a single feature is available.

const isPermission1Available = featureAvailable(Permissions.Permission1)
// Returns: boolean
someFeatureAvailable(features)

Check if at least one feature from an array is available.

const hasAnyPermission = someFeatureAvailable([
  Permissions.Permission5, 
  Permissions.Permission6
])
// Returns: boolean

Feature Management

addAvailableFeature(feature)

Add a single feature to available features.

addAvailableFeature(Permissions.Permission1)
addAvailableFeatures(features)

Add multiple features to available features.

addAvailableFeatures([Permissions.Permission5, Permissions.Permission6])
removeAvailableFeature(feature)

Remove a single feature from available features.

removeAvailableFeature(Permissions.Permission1)
removeAvailableFeatures(features)

Remove multiple features from available features.

removeAvailableFeatures([Permissions.Permission5, Permissions.Permission6])
resetAvailableFeatures(newFeatures?)

Reset available features. Optionally set new features.

// Reset to empty
resetAvailableFeatures()

// Reset and set new features
resetAvailableFeatures([Permissions.Permission1])

Utility Functions

filterArrayWithFeature(items)

Filter an array of items based on single feature availability.

const filteredItems = filterArrayWithFeature([
  { data: 'Item 1', feature: Permissions.Permission1 },
  { data: 'Item 2', feature: Permissions.Permission2 },
  { data: 'Item 3', feature: Permissions.Permission5 }
])
// Returns: string[] - Array of data from items with available features
filterArrayWithFeatures(items)

Filter an array of items based on multiple features availability (OR logic).

const filteredItems = filterArrayWithFeatures([
  { 
    data: 'Item 1', 
    features: [Permissions.Permission1, Permissions.Permission2] 
  },
  { 
    data: 'Item 2', 
    features: [Permissions.Permission5, Permissions.Permission6] 
  }
])
// Returns: string[] - Array of data from items with at least one available feature

State

availableFeatures

Array of currently available features.

const { availableFeatures } = usePermissionFeatures()
console.log(availableFeatures) // [Permissions.Permission1, Permissions.Permission2]

Advanced Usage

Multiple Feature Systems

You can create multiple feature systems for different domains:

// Permissions system
export const {
  FeaturesProvider: PermissionFeaturesProvider,
  useFeatures: usePermissionFeatures,
  Features: PermissionFeatures,
  Feature: PermissionFeature
} = createFeatures<Permissions>()

// Chat features system
export const {
  FeaturesProvider: ChatFeaturesProvider,
  useFeatures: useChatFeatures,
  Features: ChatFeatures,
  Feature: ChatFeature
} = createFeatures<string>()

Dynamic Feature Updates

function FeatureManager() {
  const { addAvailableFeature, removeAvailableFeature } = usePermissionFeatures()
  
  const handleUserRoleChange = (newRole: string) => {
    if (newRole === 'admin') {
      addAvailableFeature(Permissions.Permission1)
    } else {
      removeAvailableFeature(Permissions.Permission1)
    }
  }
  
  return (
    <button onClick={() => handleUserRoleChange('admin')}>
      Grant Admin Access
    </button>
  )
}

Conditional Navigation

function Navigation() {
  const { someFeatureAvailable } = usePermissionFeatures()
  
  return (
    <nav>
      <Link to="/">Home</Link>
      {someFeatureAvailable([Permissions.Permission1, Permissions.Permission2]) && (
        <Link to="/admin">Admin Panel</Link>
      )}
    </nav>
  )
}

TypeScript Support

The library is fully typed and supports generic feature types:

// Works with enums
createFeatures<MyPermissionEnum>()

// Works with string literals
createFeatures<'feature1' | 'feature2' | 'feature3'>()

// Works with any type
createFeatures<string>()

Contributing

Please read our contributing guidelines before submitting pull requests.

License

This project is licensed under the MIT License.

About

A powerful and type-safe React library for managing feature flags and permissions in your applications

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published