Skip to content

Commit

Permalink
feat(api): refactor react-indie api (#7)
Browse files Browse the repository at this point in the history
Currently the indie function returns a react rendered markup. it should
be wrapped in a function so it can return a component instead.

BREAKING CHANGE: indie to render component. closes #6
  • Loading branch information
gavriguy committed Apr 16, 2016
1 parent d6891fb commit 562ac6e
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 93 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ A React high level component that holds all its logic inside.
> Works with any react Architecture out there - at the end react-indie outputs a
simple React component.

![](./react-indie-demo.gif)
> The above gif is showing the built in project example. See [Live Playground] bellow for running it on your local machine, or check out [the example code](https://github.com/gavriguy/react-indie/tree/master/example) on github.
There are cases that you want to have in your react code an independent component
that is not connected to the rest of the application global store (e.g. redux).

Expand All @@ -33,7 +30,7 @@ indie(Component, propsConfig)

**propsConfig:** and object with keys that mach the Component`s props.
the value of each key is an array with 2 arguments the first is the prop's default
value and the second is the prop's loaded value. The loaded value can be of type promise.
initial value and the second is the prop's loaded value. The loaded value can be of type promise,
and can run ajax server requests.

check out [the example code](https://github.com/gavriguy/react-indie/tree/master/example)
Expand Down
27 changes: 27 additions & 0 deletions example/SimpleComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { PropTypes } from 'react';

export const SimpleComponent = (props) => {
const styles = {
wrapper: {
padding: 10,
fontFamily: 'helvetica',
backgroundColor: props.bgColor,
color: '#fff',
maxWidth: 400,
borderRadius: 5,
margin: 5,
},
};
return (
<div style={styles.wrapper}>
<h1>{ props.title }</h1>
<p>{ props.subtitle }</p>
</div>
);
};

SimpleComponent.propTypes = {
bgColor: PropTypes.string,
subtitle: PropTypes.string,
title: PropTypes.string,
};
37 changes: 0 additions & 37 deletions example/components/my-widget/index.js

This file was deleted.

2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="utf-8">
<title></title>
</head>
<body>
<body style="font-family: 'helvetica'">
<div id="app"><div>
</body>
<script type="text/javascript" src="bundle.js"></script>
Expand Down
30 changes: 28 additions & 2 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
import React from 'react';
import ReactDOM from 'react-dom';
import MyWidget from './components/my-widget/index';
import indie from '../src/index.js';
import { SimpleComponent } from './SimpleComponent.js';

// helpers

function mockAjaxRequest() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('Loaded title');
}, 1000);
});
}

// Widget1
// * Widget get default data
// * Widgets load data from the server

const widget1propsConfig = {
title: ['Loading...', mockAjaxRequest()],
subtitle: ['Please wait', 'Loaded subtitle'],
bgColor: ['#ccc', '#1bc98e'],
};

const Widget1 = indie(SimpleComponent, widget1propsConfig);

ReactDOM.render(
<div><MyWidget /></div>,
(<div>
<h1>Example Page</h1>
<Widget1 />
</div>),
document.getElementById('app')
);
22 changes: 22 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { Component } from 'react';
import { props as promiseProps } from 'bluebird';
import { forEach } from 'lodash';

export default (ReactComponent, propsConfig) => class extends Component {
constructor(props) {
super(props);
[this.defaultProps, this.loadedProps] = [{}, {}];
forEach(propsConfig, ([defaultProp, loadedProp, errorProp], key) => {
this.defaultProps[key] = defaultProp;
this.loadedProps[key] = loadedProp || defaultProp;
});
this.state = this.defaultProps;
promiseProps(this.loadedProps)
.then(res => {
this.setState(res);
});
}
render() {
return (<ReactComponent {...this.state} />);
}
};
39 changes: 0 additions & 39 deletions src/index.jsx

This file was deleted.

23 changes: 15 additions & 8 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import jsdom from 'jsdom';
import test from 'ava';
import React from 'react';
import {shallow, mount} from 'enzyme';
import indie from '../src/index.jsx';
import React, { PropTypes } from 'react';
import { mount } from 'enzyme';
import indie from '../src/index.js';

(function init() {
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
Expand All @@ -12,15 +12,22 @@ import indie from '../src/index.jsx';
}());

const MyComponent = (props) => (<div>{ props.someValue }</div>);
MyComponent.propTypes = {
someValue: PropTypes.string,
};

test.cb('indie starts with initial data and then loads new data', t => {
const propsConfig = {
someValue: ['initial value', 'loaded'],
someValue: [
'initial',
'loaded',
],
};
const wrapper = mount(indie(MyComponent, propsConfig));
t.is(wrapper.html(), '<div><div>initial value</div></div>', 'show initial data');
const Indie = indie(MyComponent, propsConfig);
const mounted = mount(<Indie />);
t.is(mounted.html(), '<div>initial</div>', 'show initial data');
setTimeout(() => {
t.is(wrapper.html(), '<div><div>loaded</div></div>', 'show loaded data');
t.is(mounted.html(), '<div>loaded</div>', 'show loaded data');
t.end();
}, 10);
});
});
6 changes: 4 additions & 2 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*eslint-disable */
module.exports = {
context: __dirname + "/example",
entry: "./index",
entry: "./index.js",
output: {
path: __dirname + "/example",
filename: "bundle.js"
Expand All @@ -9,5 +10,6 @@ module.exports = {
loaders: [
{ test: /\.(jsx|js)$/, exclude: /node_modules/, loader: "babel-loader" }
]
}
}
};
/*eslint-enable */

0 comments on commit 562ac6e

Please sign in to comment.