Skip to content

Commit

Permalink
replaced HOC with 2 new HOCS, updated config files (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
erhangundogan authored Jan 6, 2019
1 parent f7e4443 commit 1340952
Show file tree
Hide file tree
Showing 21 changed files with 238 additions and 163 deletions.
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
examples
node_modules
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
node_modules
*.log
dist
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
registry=http://registry.npmjs.org/
package-lock=false
17 changes: 13 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
sudo: false
language: node_js
node_js:
- "node"
cache:
directories:
- ~/.npm
notifications:
email: false
node_js: '8'
install: yarn
script:
- npm run build
- npm test
- yarn build
- yarn lint
- yarn test
branches:
only: master
61 changes: 42 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ If you don't know about **feature flippers** (**feature toggles/flags**) please

TL:DR; this technique allows you to activate/de-active your feature without changing code while your application is running. And this can be done on certain criteria and time. It can be applied to certain individuals (users) or you can use it for A/B testing.

This library offers you a React HOC (high order component) to add your component into feature flipper. Currently feature flippers should be received through a Promise object. And feature can be activated/de-activated for everyone. There is no other criteria.

We are working on a middleware add-on. This will allow you to plug-in the feature flipper delivery and criteria methods.
This library offers you a React HOC (high order component) to add your project.

Installation
============
Expand All @@ -27,16 +25,40 @@ yarn add react-feature-flipper
Usage
=====

* Import `featureFlipper` HOC (high order component) from your React project.
There are 2 HOCs:

##### featureFlipper (or alternatively featureFlipperStatic with named import)

This component is the default export of a library.

* Import `featureFlipper` into your React project with default import.

```js
import featureFlipper from 'react-feature-flipper';
```

Code below enables `<HelloWorld />` component wherever used. Second item in array param enables/disables your component.

```js
export default featureFlipper([HelloWorld, true])

```


```
import featureFlipper from 'react-feature-flipper';
```
#### featureFlipperPromise

* Pass required parameters into featureFlipper method call with an array (eg. `[Component, features, featureName]`)
1. Your Component
2. Promise to return feature flippers. It should be an object with a property `features` having type of a string array.
3. The name of the feature flipper (string) you want to bind to a Component (optional).
* Import `featureFlipperPromise` into your React project.

```js
import { featureFlipperPromise } from 'react-feature-flipper';
```

And use it as shown below.

* Pass required parameters to featureFlipperPromise method call with an array items:
* First (required): Your Component
* Second (required): Promise to return all feature flippers. It should be an object with a property `features` having feature flippers (array of string).
* Third (optional): The name of the feature flipper (string) you want to bind to a Component. If you omit this param then HOC uses the name of the component to find required feature flipper. eg. It would be `HelloWorld` for the example below.

```js
export default featureFlipper([
Expand All @@ -45,12 +67,10 @@ export default featureFlipper([
resolve({
features: ['hello_world', 'blabla']
})),
'hello_world',
'hello_world'
])
```

If you omit 3rd parameter (feature flipper name) HOC uses then name of the component to find required feature flipper. It would be `HelloWorld` if you consider the previous example.

Tools
=====

Expand All @@ -60,24 +80,27 @@ If you would like to see the example running on your local machine then:

`git clone git@github.com:erhangundogan/react-feature-flipper.git`

* Run `yarn`
* Run

* And then run `yarn dev`
* `yarn`
* `yarn build`
* `yarn dev` it should browse http://localhost:9000


Example is located in `examples/FeatureFlipper` folder.

Some other commands:

```bash
yarn test
yarn build
```

```bash
yarn lint
yarn test
```

```bash
yarn build
yarn lint
```

## LICENSE
Expand Down
1 change: 1 addition & 0 deletions dist/react-feature-flipper.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions examples/FeatureFlipper/ComponentFeatureFlippedPromise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { featureFlipperPromise } from '../../dist/react-feature-flipper';
import featureFlippersList from './features';

const Component = () => (
<div className="example-component">
<h3>Feature flipper enabled component</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
);

// FeatureFlippedComponent will be rendered if "double_column" feature enabled
export default featureFlipperPromise([Component, featureFlippersList, 'double_column']);
14 changes: 14 additions & 0 deletions examples/FeatureFlipper/ComponentFeatureFlippedStatic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import featureFlipperStatic from '../../dist/react-feature-flipper';

const Component = () => (
<div className="example-component">
<h3>Feature flipper enabled component</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</p>
</div>
);

export const ComponentFeatureFlippedStaticEnabled = featureFlipperStatic([Component]);
export const ComponentFeatureFlippedStaticDisabled = featureFlipperStatic([Component, false]);
20 changes: 20 additions & 0 deletions examples/FeatureFlipper/Container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import ComponentFeatureFlippedPromise from './ComponentFeatureFlippedPromise';
import {
ComponentFeatureFlippedStaticEnabled,
ComponentFeatureFlippedStaticDisabled
} from './ComponentFeatureFlippedStatic';

const Container = () => (
<div className="test-container">
<ComponentFeatureFlippedPromise />
<ComponentFeatureFlippedPromise />
<div className="feature-flipper-disabled">
<h3>Feature flipper disabled element/component</h3>
</div>
<ComponentFeatureFlippedStaticEnabled />
<ComponentFeatureFlippedStaticDisabled />
</div>
);

export default Container;
20 changes: 0 additions & 20 deletions examples/FeatureFlipper/ExampleComponent.js

This file was deleted.

14 changes: 0 additions & 14 deletions examples/FeatureFlipper/ExampleContainer.js

This file was deleted.

1 change: 1 addition & 0 deletions examples/FeatureFlipper/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
background-color: white;
width: 520px;
padding: 20px;
margin-bottom: 20px;
}
</style>
</head>
Expand Down
4 changes: 2 additions & 2 deletions examples/FeatureFlipper/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* eslint-disable no-undef */
import React from 'react';
import ReactDOM from 'react-dom';
import ExampleContainer from './ExampleContainer';
import Container from './Container';

ReactDOM.render(
<ExampleContainer />,
<Container />,
document.getElementById('root')
);
40 changes: 0 additions & 40 deletions examples/FeatureFlipper/style.css

This file was deleted.

13 changes: 9 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{
"name": "react-feature-flipper",
"version": "1.0.2",
"version": "2.0.0",
"license": "MIT",
"description": "Feature flipper React HOC and middleware",
"repository": "github:erhangundogan/react-feature-flipper",
"engines": {
"node": ">=8"
},
"bugs": "https://github.com/erhangundogan/react-feature-flipper/issues",
"homepage": "https://github.com/erhangundogan/react-feature-flipper",
"keywords": [
Expand All @@ -12,14 +15,16 @@
"feature-flipper",
"feature-toggles",
"feature-flags",
"middleware",
"redux",
"redux-middleware",
"hoc",
"a/b testing"
],
"author": "Erhan Gundogan <erhan.gundogan@gmail.com>",
"main": "dist/react-feature-flipper.js",
"files": [
"dist",
"README.md",
"LICENSE"
],
"scripts": {
"prepare": "yarn build",
"lint": "./node_modules/eslint/bin/eslint.js --config .eslintrc src/",
Expand Down
15 changes: 7 additions & 8 deletions src/FeatureFlipper.js → src/FeatureFlipperPromise.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import React from 'react';

/**
* featureFlipper HOC
* featureFlipperPromise HOC
*
* @param {function} WrappedComponent - Component needs to be feature flipped
* @param {Promise} featureFlippersPromise - Promise object to resolve feature flippers
* @param {string=} feature - specify feature flipper for component or
* leave it empty to use component name as a feature
* @param {function} WrappedComponent Component needs to be feature flipped
* @param {Promise} featureFlippersPromise Promise object to resolve feature flippers
* @param {string} [feature=Component name] Specifies feature flipper name
* @returns {function}
*/
const featureFlipper = ([WrappedComponent, featureFlippersPromise, feature]) => {
const featureFlipperPromise = ([WrappedComponent, featureFlippersPromise, feature]) => {
class ff extends React.Component {
constructor(props) {
super(props);

this.state = {
features: [],
features: []
};
}

Expand Down Expand Up @@ -45,4 +44,4 @@ const featureFlipper = ([WrappedComponent, featureFlippersPromise, feature]) =>
return ff;
};

export default featureFlipper;
export default featureFlipperPromise;
21 changes: 21 additions & 0 deletions src/FeatureFlipperStatic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

/**
* featureFlipperStatic HOC
*
* @param {function} WrappedComponent Component needs to be feature flipped
* @param {boolean} [isEnabled=true] boolean value to enable/disable feature
* @returns {function}
*/
const featureFlipperStatic = ([WrappedComponent, isEnabled = true]) => () => {
if (isEnabled) {
return (
<>
<WrappedComponent />
</>
);
}
return null;
};

export default featureFlipperStatic;
Loading

0 comments on commit 1340952

Please sign in to comment.