Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

flagged

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flagged - npm Package Compare versions

Comparing version
1.0.1
to
1.1.0
+1
dist/test/hoc.test.d.ts
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom/extend-expect';
+14
-2

@@ -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
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"flagged.cjs.development.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\nexport type FeatureFlags =\n | string[]\n | {\n [featureName: string]: boolean;\n }\n | null;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return Array.isArray(features) ? features.includes(name) : features[name];\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","FlagsProvider","features","children","TypeError","Provider","value","useFeature","name","Error","Array","isArray","includes","withFeature","featureName","Component","props","hasFeature","Object","assign","Feature","render"],"mappings":";;;;AASA,IAAMA,mBAAmB;;AAAGC,mBAAA,CAAkC,IAAlC,CAA5B;AAEA,AAAM,SAAUC,aAAV,OAML;MALCC,QAKD,QALCA,QAKD;MAJCC,QAID,QAJCA,QAID;;MACK,CAACD,QAAD,IAAaA,QAAQ,KAAK,IAA1B,IAAkC,OAAOA,QAAP,KAAoB,UAAU;UAC5D,IAAIE,SAAJ,CAAc,kDAAd;;;SAGNJ,mBAAA,CAACD,mBAAmB,CAACM,QAArB,EAA6B;IAACC,KAAK,EAAEJ;GAArC,EACGC,QADH;;;AAOJ,AAAM,SAAUI,UAAV,CAAqBC,IAArB,EAAiC;MAC/BN,QAAQ,GAAGF,gBAAA,CAAiBD,mBAAjB;;MACbG,QAAQ,KAAK,MAAM;UACf,IAAIO,KAAJ,CAAU,mDAAV;;;SAEDC,KAAK,CAACC,OAAN,CAAcT,QAAd,IAA0BA,QAAQ,CAACU,QAAT,CAAkBJ,IAAlB,CAA1B,GAAoDN,QAAQ,CAACM,IAAD;;;AAIrE,AAAM,SAAUK,WAAV,CAAsBC,WAAtB,EAAyC;SACrC,UAAAC,SAAD;WAA0B,UAAAC,KAAD,EAAqC;UAC7DC,UAAU,GAAGV,UAAU,CAACO,WAAD;UACzB,CAACG,YAAY,OAAO,IAAP;aACVjB,mBAAA,CAACe,SAAD,EAAUG,MAAA,CAAAC,MAAA,CAAA,EAAA,EAAKH,KAAL,CAAV;KAHF;;;;AAQT,AAAM,SAAUI,OAAV,QAQL;MAPCZ,IAOD,SAPCA,IAOD;MANCL,QAMD,SANCA,QAMD;2BALCkB,MAKD;MALCA,MAKD,6BALUlB,QAKV;MACOc,UAAU,GAAGV,UAAU,CAACC,IAAD;MACzB,OAAOa,MAAP,KAAkB,YAAY,OAAOA,MAAM,CAACJ,UAAD,CAAb;MAC9B,CAACA,YAAY,OAAO,IAAP;SACVI;;;;;;;;"}
{"version":3,"file":"flagged.cjs.development.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\ntype FeatureGroup = {\n [featureName: string]: boolean | FeatureGroup;\n};\n\nexport type FeatureFlags = string[] | FeatureGroup;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags | null>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeatures(): FeatureFlags {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return features;\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean | FeatureFlags {\n const features = useFeatures();\n if (Array.isArray(features)) return features.includes(name);\n if (typeof features[name] === 'boolean') return features[name];\n return name\n .split('/')\n .reduce<FeatureGroup | boolean>((featureGroup, featureName: string) => {\n if (typeof featureGroup === 'boolean') return featureGroup;\n if (featureGroup[featureName] === undefined) return false;\n return featureGroup[featureName];\n }, features);\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","FlagsProvider","features","children","TypeError","Provider","value","useFeatures","Error","useFeature","name","Array","isArray","includes","split","reduce","featureGroup","featureName","undefined","withFeature","Component","props","hasFeature","Feature","render"],"mappings":";;;;AAQA,IAAMA,mBAAmB;;AAAGC,mBAAA,CAAyC,IAAzC,CAA5B;AAEA,SAAgBC;MACdC,gBAAAA;MACAC,gBAAAA;;MAKI,CAACD,QAAD,IAAaA,QAAQ,KAAK,IAA1B,IAAkC,OAAOA,QAAP,KAAoB,QAA1D,EAAoE;UAC5D,IAAIE,SAAJ,CAAc,kDAAd,CAAN;;;SAGAJ,mBAAA,CAACD,mBAAmB,CAACM,QAArB;IAA8BC,KAAK,EAAEJ;GAArC,EACGC,QADH,CADF;;;AAQF,SAAgBI;MACRL,QAAQ,GAAGF,gBAAA,CAAiBD,mBAAjB,CAAjB;;MACIG,QAAQ,KAAK,IAAjB,EAAuB;UACf,IAAIM,KAAJ,CAAU,mDAAV,CAAN;;;SAEKN,QAAP;;;AAIF,SAAgBO,WAAWC;MACnBR,QAAQ,GAAGK,WAAW,EAA5B;MACII,KAAK,CAACC,OAAN,CAAcV,QAAd,CAAJ,EAA6B,OAAOA,QAAQ,CAACW,QAAT,CAAkBH,IAAlB,CAAP;MACzB,OAAOR,QAAQ,CAACQ,IAAD,CAAf,KAA0B,SAA9B,EAAyC,OAAOR,QAAQ,CAACQ,IAAD,CAAf;SAClCA,IAAI,CACRI,KADI,CACE,GADF,EAEJC,MAFI,CAE2B,UAACC,YAAD,EAAeC,WAAf;QAC1B,OAAOD,YAAP,KAAwB,SAA5B,EAAuC,OAAOA,YAAP;QACnCA,YAAY,CAACC,WAAD,CAAZ,KAA8BC,SAAlC,EAA6C,OAAO,KAAP;WACtCF,YAAY,CAACC,WAAD,CAAnB;GALG,EAMFf,QANE,CAAP;;;AAUF,SAAgBiB,YAAYF;SACnB,UAACG,SAAD;WAAyB,UAACC,KAAD;UACxBC,UAAU,GAAGb,UAAU,CAACQ,WAAD,CAA7B;UACI,CAACK,UAAL,EAAiB,OAAO,IAAP;aACVtB,mBAAA,CAACoB,SAAD,oBAAeC,MAAf,CAAP;KAHK;GAAP;;;AAQF,SAAgBE;MACdb,aAAAA;MACAP,iBAAAA;2BACAqB;MAAAA,mCAASrB;MAMHmB,UAAU,GAAGb,UAAU,CAACC,IAAD,CAA7B;MACI,OAAOc,MAAP,KAAkB,UAAtB,EAAkC,OAAOA,MAAM,CAACF,UAAD,CAAb;MAC9B,CAACA,UAAL,EAAiB,OAAO,IAAP;SACVE,MAAP;;;;;;;;;"}

@@ -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

@@ -1,1 +0,1 @@

{"version":3,"file":"flagged.cjs.production.min.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\nexport type FeatureFlags =\n | string[]\n | {\n [featureName: string]: boolean;\n }\n | null;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return Array.isArray(features) ? features.includes(name) : features[name];\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","useFeature","name","features","Error","Array","isArray","includes","render","children","hasFeature","TypeError","Provider","value","featureName","Component","props","Object","assign"],"mappings":"oCASMA,EAAsBC,gBAAkC,MAoBxD,SAAUC,EAAWC,OACnBC,EAAWH,aAAiBD,MACjB,OAAbI,QACI,IAAIC,MAAM,4DAEXC,MAAMC,QAAQH,GAAYA,EAASI,SAASL,GAAQC,EAASD,mBAahE,oBAGJM,OAAAA,eADAC,WAOMC,EAAaT,IARnBC,YASsB,mBAAXM,EAA8BA,EAAOE,GAC3CA,EACEF,EADiB,4BA/CpB,gBACJL,IAAAA,SACAM,IAAAA,aAKKN,GAAyB,OAAbA,GAAyC,iBAAbA,QACrC,IAAIQ,UAAU,2DAGpBX,gBAACD,EAAoBa,SAAQ,CAACC,MAAOV,GAClCM,6CAeD,SAAsBK,UAClB,SAAAC,UAAyB,SAAAC,UACZf,EAAWa,GAEvBd,gBAACe,EAASE,OAAAC,OAAA,GAAKF,IADE"}
{"version":3,"file":"flagged.cjs.production.min.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\ntype FeatureGroup = {\n [featureName: string]: boolean | FeatureGroup;\n};\n\nexport type FeatureFlags = string[] | FeatureGroup;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags | null>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeatures(): FeatureFlags {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return features;\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean | FeatureFlags {\n const features = useFeatures();\n if (Array.isArray(features)) return features.includes(name);\n if (typeof features[name] === 'boolean') return features[name];\n return name\n .split('/')\n .reduce<FeatureGroup | boolean>((featureGroup, featureName: string) => {\n if (typeof featureGroup === 'boolean') return featureGroup;\n if (featureGroup[featureName] === undefined) return false;\n return featureGroup[featureName];\n }, features);\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","useFeatures","features","Error","useFeature","name","Array","isArray","includes","split","reduce","featureGroup","featureName","undefined","render","children","hasFeature","TypeError","Provider","value","Component","props"],"mappings":"oCAQMA,EAAsBC,gBAAyC,MAoBrE,SAAgBC,QACRC,EAAWF,aAAiBD,MACjB,OAAbG,QACI,IAAIC,MAAM,4DAEXD,WAIOE,EAAWC,OACnBH,EAAWD,WACbK,MAAMC,QAAQL,GAAkBA,EAASM,SAASH,GACxB,kBAAnBH,EAASG,GAA4BH,EAASG,GAClDA,EACJI,MAAM,KACNC,QAA+B,SAACC,EAAcC,SACjB,kBAAjBD,EAAmCA,OACZE,IAA9BF,EAAaC,IACVD,EAAaC,KACnBV,uCAgBLY,OAAAA,eADAC,WAOMC,EAAaZ,IARnBC,YASsB,mBAAXS,EAA8BA,EAAOE,GAC3CA,EACEF,EADiB,4CA5DxBZ,IAAAA,SACAa,IAAAA,aAKKb,GAAyB,OAAbA,GAAyC,iBAAbA,QACrC,IAAIe,UAAU,2DAGpBjB,gBAACD,EAAoBmB,UAASC,MAAOjB,GAClCa,4EA6BqBH,UACnB,SAACQ,UAAwB,SAACC,UACZjB,EAAWQ,GAEvBZ,gBAACoB,mBAAcC,IADE"}

@@ -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,1 +0,1 @@

{"version":3,"file":"flagged.esm.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\nexport type FeatureFlags =\n | string[]\n | {\n [featureName: string]: boolean;\n }\n | null;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return Array.isArray(features) ? features.includes(name) : features[name];\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","FlagsProvider","features","children","TypeError","Provider","value","useFeature","name","Error","Array","isArray","includes","withFeature","featureName","Component","props","hasFeature","Object","assign","Feature","render"],"mappings":";;AASA,IAAMA,mBAAmB;;AAAGC,aAAA,CAAkC,IAAlC,CAA5B;AAEA,AAAM,SAAUC,aAAV,OAML;MALCC,QAKD,QALCA,QAKD;MAJCC,QAID,QAJCA,QAID;;MACK,CAACD,QAAD,IAAaA,QAAQ,KAAK,IAA1B,IAAkC,OAAOA,QAAP,KAAoB,UAAU;UAC5D,IAAIE,SAAJ,CAAc,kDAAd;;;SAGNJ,aAAA,CAACD,mBAAmB,CAACM,QAArB,EAA6B;IAACC,KAAK,EAAEJ;GAArC,EACGC,QADH;;;AAOJ,AAAM,SAAUI,UAAV,CAAqBC,IAArB,EAAiC;MAC/BN,QAAQ,GAAGF,UAAA,CAAiBD,mBAAjB;;MACbG,QAAQ,KAAK,MAAM;UACf,IAAIO,KAAJ,CAAU,mDAAV;;;SAEDC,KAAK,CAACC,OAAN,CAAcT,QAAd,IAA0BA,QAAQ,CAACU,QAAT,CAAkBJ,IAAlB,CAA1B,GAAoDN,QAAQ,CAACM,IAAD;;;AAIrE,AAAM,SAAUK,WAAV,CAAsBC,WAAtB,EAAyC;SACrC,UAAAC,SAAD;WAA0B,UAAAC,KAAD,EAAqC;UAC7DC,UAAU,GAAGV,UAAU,CAACO,WAAD;UACzB,CAACG,YAAY,OAAO,IAAP;aACVjB,aAAA,CAACe,SAAD,EAAUG,MAAA,CAAAC,MAAA,CAAA,EAAA,EAAKH,KAAL,CAAV;KAHF;;;;AAQT,AAAM,SAAUI,OAAV,QAQL;MAPCZ,IAOD,SAPCA,IAOD;MANCL,QAMD,SANCA,QAMD;2BALCkB,MAKD;MALCA,MAKD,6BALUlB,QAKV;MACOc,UAAU,GAAGV,UAAU,CAACC,IAAD;MACzB,OAAOa,MAAP,KAAkB,YAAY,OAAOA,MAAM,CAACJ,UAAD,CAAb;MAC9B,CAACA,YAAY,OAAO,IAAP;SACVI;;;;;"}
{"version":3,"file":"flagged.esm.js","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react';\n\ntype FeatureGroup = {\n [featureName: string]: boolean | FeatureGroup;\n};\n\nexport type FeatureFlags = string[] | FeatureGroup;\n\nconst FeatureFlagsContext = React.createContext<FeatureFlags | null>(null);\n\nexport function FlagsProvider({\n features,\n children,\n}: {\n features?: FeatureFlags;\n children: React.ReactChild;\n}) {\n if (!features || features === null || typeof features !== 'object') {\n throw new TypeError('The features prop must be an object or an array.');\n }\n return (\n <FeatureFlagsContext.Provider value={features}>\n {children}\n </FeatureFlagsContext.Provider>\n );\n}\n\n// Custom Hook API\nexport function useFeatures(): FeatureFlags {\n const features = React.useContext(FeatureFlagsContext);\n if (features === null) {\n throw new Error('You must wrap your components in a FlagsProvider.');\n }\n return features;\n}\n\n// Custom Hook API\nexport function useFeature(name: string): boolean | FeatureFlags {\n const features = useFeatures();\n if (Array.isArray(features)) return features.includes(name);\n if (typeof features[name] === 'boolean') return features[name];\n return name\n .split('/')\n .reduce<FeatureGroup | boolean>((featureGroup, featureName: string) => {\n if (typeof featureGroup === 'boolean') return featureGroup;\n if (featureGroup[featureName] === undefined) return false;\n return featureGroup[featureName];\n }, features);\n}\n\n// High Order Component API\nexport function withFeature(featureName: string) {\n return (Component: Function) => (props: React.ComponentProps<any>) => {\n const hasFeature = useFeature(featureName);\n if (!hasFeature) return null;\n return <Component {...props} />;\n };\n}\n\n// Render Prop API\nexport function Feature({\n name,\n children,\n render = children,\n}: {\n name: string;\n children?: React.ReactChild | Function;\n render?: React.ReactChild | Function;\n}) {\n const hasFeature = useFeature(name);\n if (typeof render === 'function') return render(hasFeature);\n if (!hasFeature) return null;\n return render;\n}\n"],"names":["FeatureFlagsContext","React","FlagsProvider","features","children","TypeError","Provider","value","useFeatures","Error","useFeature","name","Array","isArray","includes","split","reduce","featureGroup","featureName","undefined","withFeature","Component","props","hasFeature","Feature","render"],"mappings":";;AAQA,IAAMA,mBAAmB;;AAAGC,aAAA,CAAyC,IAAzC,CAA5B;AAEA,SAAgBC;MACdC,gBAAAA;MACAC,gBAAAA;;MAKI,CAACD,QAAD,IAAaA,QAAQ,KAAK,IAA1B,IAAkC,OAAOA,QAAP,KAAoB,QAA1D,EAAoE;UAC5D,IAAIE,SAAJ,CAAc,kDAAd,CAAN;;;SAGAJ,aAAA,CAACD,mBAAmB,CAACM,QAArB;IAA8BC,KAAK,EAAEJ;GAArC,EACGC,QADH,CADF;;;AAQF,SAAgBI;MACRL,QAAQ,GAAGF,UAAA,CAAiBD,mBAAjB,CAAjB;;MACIG,QAAQ,KAAK,IAAjB,EAAuB;UACf,IAAIM,KAAJ,CAAU,mDAAV,CAAN;;;SAEKN,QAAP;;;AAIF,SAAgBO,WAAWC;MACnBR,QAAQ,GAAGK,WAAW,EAA5B;MACII,KAAK,CAACC,OAAN,CAAcV,QAAd,CAAJ,EAA6B,OAAOA,QAAQ,CAACW,QAAT,CAAkBH,IAAlB,CAAP;MACzB,OAAOR,QAAQ,CAACQ,IAAD,CAAf,KAA0B,SAA9B,EAAyC,OAAOR,QAAQ,CAACQ,IAAD,CAAf;SAClCA,IAAI,CACRI,KADI,CACE,GADF,EAEJC,MAFI,CAE2B,UAACC,YAAD,EAAeC,WAAf;QAC1B,OAAOD,YAAP,KAAwB,SAA5B,EAAuC,OAAOA,YAAP;QACnCA,YAAY,CAACC,WAAD,CAAZ,KAA8BC,SAAlC,EAA6C,OAAO,KAAP;WACtCF,YAAY,CAACC,WAAD,CAAnB;GALG,EAMFf,QANE,CAAP;;;AAUF,SAAgBiB,YAAYF;SACnB,UAACG,SAAD;WAAyB,UAACC,KAAD;UACxBC,UAAU,GAAGb,UAAU,CAACQ,WAAD,CAA7B;UACI,CAACK,UAAL,EAAiB,OAAO,IAAP;aACVtB,aAAA,CAACoB,SAAD,oBAAeC,MAAf,CAAP;KAHK;GAAP;;;AAQF,SAAgBE;MACdb,aAAAA;MACAP,iBAAAA;2BACAqB;MAAAA,mCAASrB;MAMHmB,UAAU,GAAGb,UAAU,CAACC,IAAD,CAA7B;MACI,OAAOc,MAAP,KAAkB,UAAtB,EAAkC,OAAOA,MAAM,CAACF,UAAD,CAAb;MAC9B,CAACA,UAAL,EAAiB,OAAO,IAAP;SACVE,MAAP;;;;;"}

@@ -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;
```