import * as React from 'react';
import type { FeatureFlags } from './FeatureContext';
import { useFeature } from './useFeature.hook';
interface FeatureProps {
feature: keyof FeatureFlags;
children?: React.ReactNode;
render?: React.ReactNode;
}
/**
* Renders content conditionally based on the specified feature flag.
*
* @param {Object} props - The properties for the Feature component.
* @param {keyof FeatureFlags} props.feature - The name of the feature flag to check.
* @param {React.ReactNode} [props.children] - The content to render if the feature is enabled.
* @param {React.ReactNode} [props.render=children] - Optional custom render content; defaults to `children`.
*
* @returns {JSX.Element | null} - The rendered content if the feature is enabled; otherwise, `null`.
*
* @example
* // Example usage with children
*
*
*
*
* @example
* // Example usage with a custom render prop
* }
* />
*/
export function Feature({ feature, children, render = children }: FeatureProps): JSX.Element | null {
const hasFeature = useFeature(feature);
// If the feature is disabled, render nothing.
if (!hasFeature) {
return null;
}
// Otherwise, render the node content.
return {render};
}
/**
* An alias of the `` component.
* Renders the provided content if the specified feature is enabled.
*
* @example
*
*
*
*/
export function IfFeatureEnabled({ feature, children, render = children }: FeatureProps): JSX.Element | null {
return ;
}
/**
* Higher-order function to wrap a component with a feature flag check.
* Ensures that the component only renders if the specified feature is enabled.
*
* @template Props
* @param {keyof FeatureFlags} feature - The name of the feature flag to check.
* @returns {(Component: React.ComponentType) => React.ComponentType} -
* A higher-order component (HOC) that conditionally renders the wrapped component.
*
* @example
* // Example usage
* const EnhancedComponent = withFeature('newFeature')(MyComponent);
*
* ;
*/
export function withFeature(
feature: keyof FeatureFlags,
): (Component: React.ComponentType) => React.ComponentType {
return function wrapWithFeature(Component: React.ComponentType) {
/**
* Wraps the provided component with the component,
* checking the specified feature flag before rendering.
*
* @param {Props} props - Props passed to the wrapped component.
* @returns {JSX.Element} - The wrapped component if the feature is enabled, or nothing if it is disabled.
*/
function WithFeature(props: Props): JSX.Element {
return (
);
}
WithFeature.displayName = `WithFeature(${Component.displayName || Component.name})`;
return WithFeature;
};
}