Comparing version 1.0.1 to 1.1.0
@@ -21,3 +21,3 @@ 'use strict'; | ||
function useFeature(name) { | ||
function useFeatures() { | ||
var features = React.useContext(FeatureFlagsContext); | ||
@@ -29,3 +29,14 @@ | ||
return Array.isArray(features) ? features.includes(name) : features[name]; | ||
return features; | ||
} // Custom Hook API | ||
function useFeature(name) { | ||
var features = useFeatures(); | ||
if (Array.isArray(features)) return features.includes(name); | ||
if (typeof features[name] === 'boolean') return features[name]; | ||
return name.split('/').reduce(function (featureGroup, featureName) { | ||
if (typeof featureGroup === 'boolean') return featureGroup; | ||
if (featureGroup[featureName] === undefined) return false; | ||
return featureGroup[featureName]; | ||
}, features); | ||
} // High Order Component API | ||
@@ -57,3 +68,4 @@ | ||
exports.useFeature = useFeature; | ||
exports.useFeatures = useFeatures; | ||
exports.withFeature = withFeature; | ||
//# sourceMappingURL=flagged.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";var r=require("react"),e=r.createContext(null);function t(t){var n=r.useContext(e);if(null===n)throw new Error("You must wrap your components in a FlagsProvider.");return Array.isArray(n)?n.includes(t):n[t]}exports.Feature=function(r){var e=r.render,n=void 0===e?r.children:e,u=t(r.name);return"function"==typeof n?n(u):u?n:null},exports.FlagsProvider=function(t){var n=t.features,u=t.children;if(!n||null===n||"object"!=typeof n)throw new TypeError("The features prop must be an object or an array.");return r.createElement(e.Provider,{value:n},u)},exports.useFeature=t,exports.withFeature=function(e){return function(n){return function(u){return t(e)?r.createElement(n,Object.assign({},u)):null}}}; | ||
"use strict";var e=require("react"),r=e.createContext(null);function t(){var t=e.useContext(r);if(null===t)throw new Error("You must wrap your components in a FlagsProvider.");return t}function n(e){var r=t();return Array.isArray(r)?r.includes(e):"boolean"==typeof r[e]?r[e]:e.split("/").reduce((function(e,r){return"boolean"==typeof e?e:void 0!==e[r]&&e[r]}),r)}exports.Feature=function(e){var r=e.render,t=void 0===r?e.children:r,o=n(e.name);return"function"==typeof t?t(o):o?t:null},exports.FlagsProvider=function(t){var n=t.features,o=t.children;if(!n||null===n||"object"!=typeof n)throw new TypeError("The features prop must be an object or an array.");return e.createElement(r.Provider,{value:n},o)},exports.useFeature=n,exports.useFeatures=t,exports.withFeature=function(r){return function(t){return function(o){return n(r)?e.createElement(t,Object.assign({},o)):null}}}; | ||
//# sourceMappingURL=flagged.cjs.production.min.js.map |
@@ -19,3 +19,3 @@ import { createElement, useContext, createContext } from 'react'; | ||
function useFeature(name) { | ||
function useFeatures() { | ||
var features = useContext(FeatureFlagsContext); | ||
@@ -27,3 +27,14 @@ | ||
return Array.isArray(features) ? features.includes(name) : features[name]; | ||
return features; | ||
} // Custom Hook API | ||
function useFeature(name) { | ||
var features = useFeatures(); | ||
if (Array.isArray(features)) return features.includes(name); | ||
if (typeof features[name] === 'boolean') return features[name]; | ||
return name.split('/').reduce(function (featureGroup, featureName) { | ||
if (typeof featureGroup === 'boolean') return featureGroup; | ||
if (featureGroup[featureName] === undefined) return false; | ||
return featureGroup[featureName]; | ||
}, features); | ||
} // High Order Component API | ||
@@ -52,3 +63,3 @@ | ||
export { Feature, FlagsProvider, useFeature, withFeature }; | ||
export { Feature, FlagsProvider, useFeature, useFeatures, withFeature }; | ||
//# sourceMappingURL=flagged.esm.js.map |
@@ -1,5 +0,6 @@ | ||
import * as React from "react"; | ||
export declare type FeatureFlags = string[] | { | ||
[featureName: string]: boolean; | ||
} | null; | ||
import * as React from 'react'; | ||
declare type FeatureGroup = { | ||
[featureName: string]: boolean | FeatureGroup; | ||
}; | ||
export declare type FeatureFlags = string[] | FeatureGroup; | ||
export declare function FlagsProvider({ features, children, }: { | ||
@@ -9,3 +10,4 @@ features?: FeatureFlags; | ||
}): JSX.Element; | ||
export declare function useFeature(name: string): boolean; | ||
export declare function useFeatures(): FeatureFlags; | ||
export declare function useFeature(name: string): boolean | FeatureFlags; | ||
export declare function withFeature(featureName: string): (Component: Function) => (props: any) => JSX.Element | null; | ||
@@ -17,1 +19,2 @@ export declare function Feature({ name, children, render, }: { | ||
}): any; | ||
export {}; |
{ | ||
"name": "flagged", | ||
"description": "Feature flags for React made easy with hooks, HOC and Render Props", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"license": "MIT", | ||
@@ -36,3 +36,3 @@ "repository": "https://github.com/sergiodxa/flagged.git", | ||
"scripts": { | ||
"prepare": "tsdx build", | ||
"prepublishOnly": "tsdx build", | ||
"start": "tsdx watch", | ||
@@ -66,3 +66,3 @@ "build": "tsdx build", | ||
"react-dom": "^16.11.0", | ||
"tsdx": "^0.10.5", | ||
"tsdx": "^0.11.0", | ||
"tslib": "^1.10.0", | ||
@@ -69,0 +69,0 @@ "typescript": "^3.6.4" |
@@ -22,2 +22,3 @@ # Flagged | ||
- Zero Dependencies | ||
- Nested Flags | ||
@@ -52,2 +53,40 @@ ## How to Use It | ||
### Features Valid Values | ||
The features prop you pass to `FlagsProvider` could be an array of strings or an object, if you decide to use an object you could also pass nested objects to group feature flags together. | ||
**Using an Array** | ||
```tsx | ||
ReactDOM.render( | ||
<FlagsProvider features={['v2', 'moderate']}> | ||
<App /> | ||
</FlagsProvider>, | ||
document.querySelector('root') | ||
); | ||
``` | ||
**Using an Object** | ||
```tsx | ||
ReactDOM.render( | ||
<FlagsProvider features={{ v2: true, moderate: false }}> | ||
<App /> | ||
</FlagsProvider>, | ||
document.querySelector('root') | ||
); | ||
``` | ||
**Using Nested Objects** | ||
```tsx | ||
ReactDOM.render( | ||
<FlagsProvider | ||
features={{ v2: true, content: { moderate: true, admin: false } }} | ||
> | ||
<App /> | ||
</FlagsProvider>, | ||
document.querySelector('root') | ||
); | ||
``` | ||
If you use nested objects you will need to either use the `useFeatures` hook or pass a string separated by `/`, e.g. `content/moderate` to read nested flags, if you don't pass the whole path you will get an object so `content` will return `{ moderate: false }` when reading it. | ||
### `useFeature` Custom Hook | ||
@@ -165,1 +204,20 @@ | ||
``` | ||
### `useFeatures` Custom Hook | ||
The `useFeatures` custom hook is the base for the `useFeature` custom hook, it gives you the entire feature flags object or array you sent to `FlagsProvider` so you could use it however you want. | ||
```tsx | ||
import * as React from 'react'; | ||
import { useFeature } from 'flagged'; | ||
function Header() { | ||
const features = useFeatures(); | ||
return ( | ||
<header>{features.v2 ? <h1>My App v2</h1> : <h1>My App v1</h1>}</header> | ||
); | ||
} | ||
export default Header; | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
25361
14
141
221