Skip to content
Permalink
Browse files

feat: build prototype

  • Loading branch information...
danhayden committed Jul 19, 2017
1 parent c489f60 commit f350db35c650c48b18587c13515bd3a47bf5b8f6
@@ -0,0 +1,8 @@
import {configure} from '@storybook/react'

function loadStories() {
const storyFiles = require.context('../src/', true, /\.stories\.js$/)
storyFiles.keys().forEach(filename => storyFiles(filename))
}

configure(loadStories, module)
BIN +7.1 KB docs/favicon.ico
Binary file not shown.
@@ -0,0 +1,22 @@

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
if (window.parent !== window) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
}
</script>
<title>Storybook</title>


</head>
<body>
<div id="root"></div>
<div id="error-display"></div>
<script src="static/preview.306107e2529a59ca0606.bundle.js"></script>
</body>
</html>

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="storybook-version" content="3.1.9">
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<title>Storybook</title>
<style>
/*
When resizing panels, the drag event breaks if the cursor
moves over the iframe. Add the 'dragging' class to the body
at drag start and remove it when the drag ends.
*/
.dragging iframe {
pointer-events: none;
}
/* Styling the fuzzy search box placeholders */
.searchBox::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: #ddd;
font-size: 16px;
}
.searchBox::-moz-placeholder { /* Firefox 19+ */
color: #ddd;
font-size: 16px;
}
.searchBox:focus{
border-color: #EEE !important;
}
.btn:hover{
background-color: #eee
}
</style>

</head>
<body style="margin: 0;">
<div id="root"></div>
<script src="static/manager.7ac5971b94b4969a12fb.bundle.js"></script>
</body>
</html>

Large diffs are not rendered by default.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -23,8 +23,10 @@
"changelog": "standard-version",
"size": "npx gzip-size-cli ./dist/react-simple-experiment.js ",
"precommit": "lint-staged",
"prepush": "npm test",
"prepublish": "npm run build"
"prepush": "npm test && npm run build-storybook",
"prepublish": "npm run build",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook -o docs"
},
"lint-staged": {
"src/**/*.{js,json}": [
@@ -35,8 +37,13 @@
"peerDependencies": {
"react": "^15.0.0-0"
},
"dependencies": {},
"dependencies": {
"localforage": "1.5.0",
"pick-one-by-weight": "1.0.2",
"prop-types": "15.5.10"
},
"devDependencies": {
"@storybook/react": "3.1.9",
"babel-eslint": "7.2.3",
"babel-preset-env": "1.6.0",
"babel-preset-react": "6.24.1",
@@ -55,6 +62,8 @@
"lint-staged": "4.0.2",
"prettier": "1.5.3",
"prettier-eslint-cli": "4.1.1",
"react": "^15.0.0-0",
"react-dom": "15.6.1",
"rollup": "0.45.2",
"rollup-plugin-babel": "2.7.1",
"rollup-plugin-node-resolve": "3.0.0",
@@ -8,6 +8,13 @@ const pkg = JSON.parse(fs.readFileSync('./package.json'))
export default {
entry: 'src/react-simple-experiment.js',
moduleName: 'ReactSimpleExperiment',
external: ['react', 'prop-types', 'pick-one-by-weight', 'localforage'],
globals: {
react: 'React',
'prop-types': 'PropTypes',
'pick-one-by-weight': 'pickOneByWeight',
localforage: 'localforage'
},
targets: [
{dest: pkg.main, format: 'cjs'},
{dest: pkg.module, format: 'es'},
@@ -1 +1,60 @@
export default {}
import React from 'react'
import PropTypes from 'prop-types'
import pickOneByWeight from 'pick-one-by-weight'
import Storage from './storage'

const storage = Storage({name: 'react-simple-experiment'})

export class Experiment extends React.Component {
static displayName = 'Experiment'
static propTypes = {
name: PropTypes.string.isRequired,
children: PropTypes.array.isRequired,
onLoad: PropTypes.func
}

state = {variant: null}

componentDidMount () {
const storageName = `experiment--${this.props.name}`
const variantNames = []
const data = {}

React.Children.forEach(this.props.children, variant => {
variantNames.push(variant.props.name)
data[variant.props.name] = parseInt(variant.props.weight, 10)
})

storage.getItem(storageName).then(variant => {
if (!variant || !variantNames.includes(variant)) {
variant = pickOneByWeight(data)
storage.setItem(storageName, variant)
}

this.setState({variant}, () => {
this.props.onLoad(this.props.name, this.state.variant)
})
})
}

render () {
if (!this.props.children) return null
const variant = this.props.children.find(
child => child.props.name === this.state.variant
)
return variant || null
}
}

export class Variant extends React.Component {
static displayName = 'Variant'
static propTypes = {
name: PropTypes.string.isRequired,
weight: PropTypes.number.isRequired,
children: PropTypes.node
}

render () {
return this.props.children
}
}
@@ -0,0 +1,22 @@
import React from 'react'
import {storiesOf} from '@storybook/react'
import {Experiment, Variant} from './react-simple-experiment'

storiesOf('React Simple Experiment', module).add('Default variation', () =>
<Experiment
name='storybook-test'
onLoad={(name, variant) => console.log(name, variant)}
>
<Variant name='variant1' weight={60}>
<div>Variant1</div>
</Variant>

<Variant name='variant2' weight={20}>
<div>Variant2</div>
</Variant>

<Variant name='variant3' weight={20}>
<div>Variant3</div>
</Variant>
</Experiment>
)
@@ -0,0 +1,49 @@
import localforage from 'localforage'

let storage = {}

function getItem (key) {
return new Promise(resolve => {
try {
localforage
.getItem(key)
.then(value => resolve(value || storage[key]))
.catch(() => resolve(storage[key]))
} catch (error) {
resolve(storage[key])
}
})
}

function setItem (key, value) {
storage[key] = value
return new Promise(resolve => {
try {
// avoid clone error from localforage
const safeValue = JSON.parse(JSON.stringify(value))
localforage.setItem(key, safeValue).then(resolve).catch(resolve)
} catch (error) {
resolve()
}
})
}

function removeItem (key) {
if (storage[key]) delete storage[key]
return new Promise(resolve => {
try {
localforage.removeItem(key).then(resolve).catch(resolve)
} catch (error) {
resolve()
}
})
}

export default function (options) {
localforage.config(options)
return {
getItem,
setItem,
removeItem
}
}

0 comments on commit f350db3

Please sign in to comment.
You can’t perform that action at this time.