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.
- 🎯 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
npm install @carlesfelix/features-react// src/enums/Permissions.ts
enum Permissions {
Permission1 = 'Permission1',
Permission2 = 'Permission2',
Permission3 = 'Permission3',
// ... more permissions
}
export default Permissions// 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>()// 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>
)
}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 availabilityfallback(optional): Content to render when feature is not availablechildren: Content to render when feature is available
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 availablechildren: Content to render when at least one feature is available
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()Check if a single feature is available.
const isPermission1Available = featureAvailable(Permissions.Permission1)
// Returns: booleanCheck if at least one feature from an array is available.
const hasAnyPermission = someFeatureAvailable([
Permissions.Permission5,
Permissions.Permission6
])
// Returns: booleanAdd a single feature to available features.
addAvailableFeature(Permissions.Permission1)Add multiple features to available features.
addAvailableFeatures([Permissions.Permission5, Permissions.Permission6])Remove a single feature from available features.
removeAvailableFeature(Permissions.Permission1)Remove multiple features from available features.
removeAvailableFeatures([Permissions.Permission5, Permissions.Permission6])Reset available features. Optionally set new features.
// Reset to empty
resetAvailableFeatures()
// Reset and set new features
resetAvailableFeatures([Permissions.Permission1])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 featuresFilter 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 featureArray of currently available features.
const { availableFeatures } = usePermissionFeatures()
console.log(availableFeatures) // [Permissions.Permission1, Permissions.Permission2]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>()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>
)
}function Navigation() {
const { someFeatureAvailable } = usePermissionFeatures()
return (
<nav>
<Link to="/">Home</Link>
{someFeatureAvailable([Permissions.Permission1, Permissions.Permission2]) && (
<Link to="/admin">Admin Panel</Link>
)}
</nav>
)
}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>()Please read our contributing guidelines before submitting pull requests.
This project is licensed under the MIT License.