WA-278 - Feature Create Safe

Included routes, forms, validators, tests and in general everything for making possible create safes, save them, load them and visualize them.
This commit is contained in:
Adolfo Panizo
2018-04-13 15:18:11 +02:00
committed by GitHub
parent 354d3bcb2e
commit 0cf8fae871
168 changed files with 27850 additions and 423 deletions
+8 -1
View File
@@ -34,7 +34,14 @@
"always", {
"annotationStyle": "line"
}
]
],
"jsx-a11y/anchor-is-valid": [ "error", {
"components": [ "Link" ],
"specialLink": [ "to", "hrefLeft", "hrefRight" ],
"aspects": [ "noHref", "invalidHref", "preferButton" ]
}],
"react/require-default-props": 0,
"react/no-array-index-key": 0
},
"env": {
"jest/globals": true,
+2
View File
@@ -1,6 +1,8 @@
node_modules/
build/
build_webpack/
build_storybook/
build/contracts/
truffle-config.js
gnosis-safe-contracts/
.DS_Store
+3
View File
@@ -0,0 +1,3 @@
import '@storybook/addon-actions/register'
import '@storybook/addon-links/register'
import '@storybook/addon-knobs/register'
+35
View File
@@ -0,0 +1,35 @@
import 'babel-polyfill'
import { addDecorator, configure } from '@storybook/react'
import { withKnobs } from '@storybook/addon-knobs'
import { MuiThemeProvider } from 'material-ui/styles'
import * as React from 'react'
import { Provider } from 'react-redux'
import StoryRouter from 'storybook-router'
import { store } from '~/store'
import theme from '~/theme/mui'
import 'index.scss'
(function (global) {
//Useful for adding data and libraries to window object.
})(typeof window !== 'undefined' ? window : {});
addDecorator(withKnobs);
addDecorator(StoryRouter())
addDecorator((story) => (
<Provider store={store}>
<MuiThemeProvider theme={theme}>
{ story() }
</MuiThemeProvider>
</Provider>
))
const components = require.context('../src/components', true, /\.stories\.((js|ts)x?)$/)
const routes = require.context('../src/routes', true, /\.stories\.((js|ts)x?)$/)
function loadStories() {
components.keys().forEach((filename) => components(filename))
routes.keys().forEach((filename) => routes(filename))
}
configure(loadStories, module)
+2
View File
@@ -0,0 +1,2 @@
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
+13
View File
@@ -0,0 +1,13 @@
process.env.NODE_ENV = 'development'
const prodConfig = require('../config/webpack.config.dev');
module.exports = function(storybookConfig, configType) {
const config = Object.assign({}, prodConfig);
storybookConfig.module.rules = storybookConfig.module.rules.concat(config.module.rules)
storybookConfig.resolve = config.resolve;
return storybookConfig;
};
+5 -3
View File
@@ -4,18 +4,20 @@ node_js:
os:
- linux
before_script:
- npm install -g truffle
- npm install -g surge
- yarn global add truffle@4.1.3
- yarn global add surge
- git clone https://github.com/gnosis/gnosis-safe-contracts.git
- cd gnosis-safe-contracts
- truffle compile && cd ..
after_success:
- npm run build
- yarn build-storybook
- yarn build
- |
if [ ${TRAVIS_BRANCH} = "master" ]; then
export NODE_ENV=production;
else
export NODE_ENV=development;
fi
- cd build_webpack/ && cp index.html 200.html && cd ..
- chmod ugo+x ./config/deploy/deploy.sh
- ./config/deploy/deploy.sh
+12 -4
View File
@@ -3,12 +3,18 @@
echo "Deployment script for gnosis-safe-team"
RANGE=500
number=$RANDOM
let "number %= $RANGE"
# Split on "/", ref: http://stackoverflow.com/a/5257398/689223
REPO_SLUG_ARRAY=(${TRAVIS_REPO_SLUG//\// })
REPO_OWNER=${REPO_SLUG_ARRAY[0]}
REPO_NAME=${REPO_SLUG_ARRAY[1]}
DEPLOY_PATH=./build_webpack
DEPLOY_PATH_STORYBOOK=./build_storybook
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST=()
@@ -16,9 +22,9 @@ if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then
if [ "$NODE_ENV" == "production" ]
then
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(release-${TRAVIS_PULL_REQUEST}-pr)
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(release-${TRAVIS_PULL_REQUEST}-pr-${number})
else
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(staging-${TRAVIS_PULL_REQUEST}-pr)
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(staging-${TRAVIS_PULL_REQUEST}-pr-${number})
fi
elif [ -n "${TRAVIS_TAG// }" ] #TAG is not empty
then
@@ -58,16 +64,18 @@ do
echo $DEPLOY_SUBDOMAIN
DEPLOY_DOMAIN=https://${DEPLOY_SUBDOMAIN}-${REPO_NAME}-${REPO_OWNER}.surge.sh
DEPLOY_STORYBOOK=https://storybook-${DEPLOY_SUBDOMAIN}-${REPO_NAME}-${REPO_OWNER}.surge.sh
surge --project ${DEPLOY_PATH} --domain $DEPLOY_DOMAIN;
surge --project ${DEPLOY_PATH_STORYBOOK} --domain $DEPLOY_STORYBOOK
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
then
# Using the Issues api instead of the PR api
# Done so because every PR is an issue, and the issues api allows to post general comments,
# while the PR api requires that comments are made to specific files and specific commits
GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments
curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment: '${DEPLOY_DOMAIN}'"}'
curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment:\r\n '${DEPLOY_DOMAIN}' \r\n \r\n Storybook book automatic deployment: \r\n '${DEPLOY_STORYBOOK}'"}'
fi
done
+26
View File
@@ -0,0 +1,26 @@
// @flow
class LocalStorageMock {
store: Object
constructor() {
this.store = {}
}
clear() {
this.store = {}
}
getItem(key) {
return this.store[key] || null
}
setItem(key, value) {
this.store[key] = value.toString()
}
removeItem(key) {
delete this.store[key]
}
}
global.localStorage = new LocalStorageMock()
+8
View File
@@ -0,0 +1,8 @@
// @flow
import Web3 from 'web3'
const window = global.window || {}
window.web3 = window.web3 || {}
window.web3.currentProvider = new Web3.providers.HttpProvider('http://localhost:8545')
global.window = window
+15 -2
View File
@@ -1,4 +1,6 @@
/*eslint-disable*/
const autoprefixer = require('autoprefixer');
const cssmixins = require('postcss-mixins');
const cssvars = require('postcss-simple-vars');
const webpack = require('webpack');
const HtmlWebPackPlugin = require("html-webpack-plugin");
@@ -26,6 +28,7 @@ const postcssPlugins = [
'not ie < 9', // React doesn't support IE8 anyway
]
}),
cssmixins,
cssvars({
variables: function () {
return Object.assign({}, cssvariables);
@@ -115,7 +118,7 @@ module.exports = {
},
},
],
},
},
{
test: /\.html$/,
use: [
@@ -124,7 +127,17 @@ module.exports = {
options: { minimize: false }
}
]
}
},
{
test: /\.(jpe?g|png|svg)$/i,
exclude: /node_modules/,
use: [{
loader: "file-loader",
options: {
name: 'img/[hash].[ext]'
}
}]
},
]
},
plugins: [
+17 -1
View File
@@ -1,5 +1,7 @@
/*eslint-disable*/
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const autoprefixer = require('autoprefixer')
const cssmixins = require('postcss-mixins');
const cssvars = require('postcss-simple-vars')
const webpack = require('webpack')
@@ -23,6 +25,7 @@ const postcssPlugins = [
'not ie < 9', // React doesn't support IE8 anyway
],
}),
cssmixins,
cssvars({
variables() {
return Object.assign({}, cssvariables)
@@ -149,6 +152,16 @@ module.exports = {
],
}),
},
{
test: /\.(jpe?g|png|svg)$/i,
exclude: /node_modules/,
use: [{
loader: "file-loader",
options: {
name: 'img/[hash].[ext]'
}
}]
},
],
},
plugins: [
@@ -175,7 +188,10 @@ module.exports = {
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin('static/css/[name].[contenthash:8].css'),
new ExtractTextPlugin({
filename: 'static/css/[name].[contenthash:8].css',
allChunks: true
}),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
// having to parse `index.html`.
+2 -1
View File
@@ -1 +1,2 @@
import '@babel/polyfill';
// @flow
import '@babel/polyfill'
+12
View File
@@ -0,0 +1,12 @@
// flow-typed signature: d33e1b8f0888822895515e3ca6a3f8eb
// flow-typed version: 1709d3212d/@storybook/addon-actions_v3.x.x/flow_>=v0.25.x
declare module '@storybook/addon-actions' {
declare type Action = (name: string) => Function;
declare type DecorateFn = (args: Array<any>) => Array<any>;
declare module.exports: {
action: Action,
decorateAction(args: Array<DecorateFn>): Action;
};
}
+445
View File
@@ -0,0 +1,445 @@
// flow-typed signature: c905b8c93e093290a3c272e675bae6a2
// flow-typed version: <<STUB>>/@storybook/addon-knobs_v^3.3.15/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* '@storybook/addon-knobs'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@storybook/addon-knobs' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@storybook/addon-knobs/angular' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/angular/helpers' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/angular/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/angular/utils' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/base' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/Panel' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/PropField' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/PropForm' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Array' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Boolean' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Button' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Color' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Date/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Date/styles' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Number' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Object' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Select' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/components/types/Text' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/KnobManager' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/KnobStore' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/react/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/react/WrapStory' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/register' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/dist/vue/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/example/stories/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/react' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/register' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/angular/helpers' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/angular/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/angular/utils' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/base' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/__tests__/Array' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/__tests__/Panel' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/Panel' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/PropField' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/PropForm' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Array' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Boolean' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Button' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Color' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Date/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Date/styles' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Number' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Object' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Select' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/components/types/Text' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/KnobManager' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/KnobManager.test' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/KnobStore' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/react/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/react/index.test' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/react/WrapStory' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/register' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/vue/index' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/src/vue/index.test' {
declare module.exports: any;
}
declare module '@storybook/addon-knobs/vue' {
declare module.exports: any;
}
// Filename aliases
declare module '@storybook/addon-knobs/angular.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/angular'>;
}
declare module '@storybook/addon-knobs/dist/angular/helpers.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/angular/helpers'>;
}
declare module '@storybook/addon-knobs/dist/angular/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/angular/index'>;
}
declare module '@storybook/addon-knobs/dist/angular/utils.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/angular/utils'>;
}
declare module '@storybook/addon-knobs/dist/base.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/base'>;
}
declare module '@storybook/addon-knobs/dist/components/Panel.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/Panel'>;
}
declare module '@storybook/addon-knobs/dist/components/PropField.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/PropField'>;
}
declare module '@storybook/addon-knobs/dist/components/PropForm.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/PropForm'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Array.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Array'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Boolean.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Boolean'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Button.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Button'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Color.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Color'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Date/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Date/index'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Date/styles.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Date/styles'>;
}
declare module '@storybook/addon-knobs/dist/components/types/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/index'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Number.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Number'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Object.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Object'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Select.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Select'>;
}
declare module '@storybook/addon-knobs/dist/components/types/Text.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/components/types/Text'>;
}
declare module '@storybook/addon-knobs/dist/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/index'>;
}
declare module '@storybook/addon-knobs/dist/KnobManager.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/KnobManager'>;
}
declare module '@storybook/addon-knobs/dist/KnobStore.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/KnobStore'>;
}
declare module '@storybook/addon-knobs/dist/react/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/react/index'>;
}
declare module '@storybook/addon-knobs/dist/react/WrapStory.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/react/WrapStory'>;
}
declare module '@storybook/addon-knobs/dist/register.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/register'>;
}
declare module '@storybook/addon-knobs/dist/vue/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/dist/vue/index'>;
}
declare module '@storybook/addon-knobs/example/stories/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/example/stories/index'>;
}
declare module '@storybook/addon-knobs/react.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/react'>;
}
declare module '@storybook/addon-knobs/register.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/register'>;
}
declare module '@storybook/addon-knobs/src/angular/helpers.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/angular/helpers'>;
}
declare module '@storybook/addon-knobs/src/angular/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/angular/index'>;
}
declare module '@storybook/addon-knobs/src/angular/utils.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/angular/utils'>;
}
declare module '@storybook/addon-knobs/src/base.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/base'>;
}
declare module '@storybook/addon-knobs/src/components/__tests__/Array.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/__tests__/Array'>;
}
declare module '@storybook/addon-knobs/src/components/__tests__/Panel.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/__tests__/Panel'>;
}
declare module '@storybook/addon-knobs/src/components/Panel.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/Panel'>;
}
declare module '@storybook/addon-knobs/src/components/PropField.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/PropField'>;
}
declare module '@storybook/addon-knobs/src/components/PropForm.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/PropForm'>;
}
declare module '@storybook/addon-knobs/src/components/types/Array.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Array'>;
}
declare module '@storybook/addon-knobs/src/components/types/Boolean.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Boolean'>;
}
declare module '@storybook/addon-knobs/src/components/types/Button.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Button'>;
}
declare module '@storybook/addon-knobs/src/components/types/Color.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Color'>;
}
declare module '@storybook/addon-knobs/src/components/types/Date/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Date/index'>;
}
declare module '@storybook/addon-knobs/src/components/types/Date/styles.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Date/styles'>;
}
declare module '@storybook/addon-knobs/src/components/types/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/index'>;
}
declare module '@storybook/addon-knobs/src/components/types/Number.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Number'>;
}
declare module '@storybook/addon-knobs/src/components/types/Object.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Object'>;
}
declare module '@storybook/addon-knobs/src/components/types/Select.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Select'>;
}
declare module '@storybook/addon-knobs/src/components/types/Text.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/components/types/Text'>;
}
declare module '@storybook/addon-knobs/src/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/index'>;
}
declare module '@storybook/addon-knobs/src/KnobManager.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/KnobManager'>;
}
declare module '@storybook/addon-knobs/src/KnobManager.test.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/KnobManager.test'>;
}
declare module '@storybook/addon-knobs/src/KnobStore.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/KnobStore'>;
}
declare module '@storybook/addon-knobs/src/react/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/react/index'>;
}
declare module '@storybook/addon-knobs/src/react/index.test.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/react/index.test'>;
}
declare module '@storybook/addon-knobs/src/react/WrapStory.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/react/WrapStory'>;
}
declare module '@storybook/addon-knobs/src/register.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/register'>;
}
declare module '@storybook/addon-knobs/src/vue/index.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/vue/index'>;
}
declare module '@storybook/addon-knobs/src/vue/index.test.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/src/vue/index.test'>;
}
declare module '@storybook/addon-knobs/vue.js' {
declare module.exports: $Exports<'@storybook/addon-knobs/vue'>;
}
+123
View File
@@ -0,0 +1,123 @@
// flow-typed signature: b5b0573c75eb87c83febb95b4fa850d9
// flow-typed version: <<STUB>>/@storybook/addon-links_v^3.3.15/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* '@storybook/addon-links'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@storybook/addon-links' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@storybook/addon-links/dist/index' {
declare module.exports: any;
}
declare module '@storybook/addon-links/dist/manager' {
declare module.exports: any;
}
declare module '@storybook/addon-links/dist/preview' {
declare module.exports: any;
}
declare module '@storybook/addon-links/dist/react/components/link' {
declare module.exports: any;
}
declare module '@storybook/addon-links/dist/react/index' {
declare module.exports: any;
}
declare module '@storybook/addon-links/react' {
declare module.exports: any;
}
declare module '@storybook/addon-links/register' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/index' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/manager' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/preview' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/preview.test' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/react/components/link' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/react/components/link.test' {
declare module.exports: any;
}
declare module '@storybook/addon-links/src/react/index' {
declare module.exports: any;
}
// Filename aliases
declare module '@storybook/addon-links/dist/index.js' {
declare module.exports: $Exports<'@storybook/addon-links/dist/index'>;
}
declare module '@storybook/addon-links/dist/manager.js' {
declare module.exports: $Exports<'@storybook/addon-links/dist/manager'>;
}
declare module '@storybook/addon-links/dist/preview.js' {
declare module.exports: $Exports<'@storybook/addon-links/dist/preview'>;
}
declare module '@storybook/addon-links/dist/react/components/link.js' {
declare module.exports: $Exports<'@storybook/addon-links/dist/react/components/link'>;
}
declare module '@storybook/addon-links/dist/react/index.js' {
declare module.exports: $Exports<'@storybook/addon-links/dist/react/index'>;
}
declare module '@storybook/addon-links/react.js' {
declare module.exports: $Exports<'@storybook/addon-links/react'>;
}
declare module '@storybook/addon-links/register.js' {
declare module.exports: $Exports<'@storybook/addon-links/register'>;
}
declare module '@storybook/addon-links/src/index.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/index'>;
}
declare module '@storybook/addon-links/src/manager.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/manager'>;
}
declare module '@storybook/addon-links/src/preview.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/preview'>;
}
declare module '@storybook/addon-links/src/preview.test.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/preview.test'>;
}
declare module '@storybook/addon-links/src/react/components/link.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/react/components/link'>;
}
declare module '@storybook/addon-links/src/react/components/link.test.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/react/components/link.test'>;
}
declare module '@storybook/addon-links/src/react/index.js' {
declare module.exports: $Exports<'@storybook/addon-links/src/react/index'>;
}
+37
View File
@@ -0,0 +1,37 @@
// flow-typed signature: c2e1b132d2729c977d6b3e54e0134de5
// flow-typed version: 1709d3212d/@storybook/react_v3.x.x/flow_>=v0.28.x
type NodeModule = typeof module;
declare module '@storybook/react' {
declare type Renderable = React$Element<any>;
declare type RenderFunction = () => Renderable;
declare type StoryDecorator = (
story: RenderFunction,
context: { kind: string, story: string }
) => Renderable | null;
declare interface Story {
add(storyName: string, callback: RenderFunction): Story,
addDecorator(decorator: StoryDecorator): Story,
}
declare interface StoryObject {
name: string,
render: RenderFunction,
}
declare interface StoryBucket {
kind: string,
stories: Array<StoryObject>,
}
declare function addDecorator(decorator: StoryDecorator): void;
declare function configure(fn: () => void, module: NodeModule): void;
declare function setAddon(addon: Object): void;
declare function storiesOf(name: string, module: NodeModule): Story;
declare function storiesOf<T>(name: string, module: NodeModule): Story & T;
declare function getStorybook(): Array<StoryBucket>;
}
+70 -27
View File
@@ -1,5 +1,5 @@
// flow-typed signature: fcc9dbf1cac1f2da664ba4bd010b8b49
// flow-typed version: <<STUB>>/babel-eslint_v^7.2.3/flow_v0.66.0
// flow-typed signature: fd24127108857b4ae2691098e95c7678
// flow-typed version: <<STUB>>/babel-eslint_v8/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
@@ -22,59 +22,102 @@ declare module 'babel-eslint' {
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'babel-eslint/babylon-to-espree/attachComments' {
declare module 'babel-eslint/lib/analyze-scope' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/convertComments' {
declare module 'babel-eslint/lib/babylon-to-espree/attachComments' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/convertTemplateType' {
declare module 'babel-eslint/lib/babylon-to-espree/convertComments' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/index' {
declare module 'babel-eslint/lib/babylon-to-espree/convertTemplateType' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/toAST' {
declare module 'babel-eslint/lib/babylon-to-espree/index' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/toToken' {
declare module 'babel-eslint/lib/babylon-to-espree/toAST' {
declare module.exports: any;
}
declare module 'babel-eslint/babylon-to-espree/toTokens' {
declare module 'babel-eslint/lib/babylon-to-espree/toToken' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/babylon-to-espree/toTokens' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/index' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/parse-with-patch' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/parse-with-scope' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/parse' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/patch-eslint-scope' {
declare module.exports: any;
}
declare module 'babel-eslint/lib/visitor-keys' {
declare module.exports: any;
}
// Filename aliases
declare module 'babel-eslint/babylon-to-espree/attachComments.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/attachComments'>;
declare module 'babel-eslint/lib/analyze-scope.js' {
declare module.exports: $Exports<'babel-eslint/lib/analyze-scope'>;
}
declare module 'babel-eslint/babylon-to-espree/convertComments.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/convertComments'>;
declare module 'babel-eslint/lib/babylon-to-espree/attachComments.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/attachComments'>;
}
declare module 'babel-eslint/babylon-to-espree/convertTemplateType.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/convertTemplateType'>;
declare module 'babel-eslint/lib/babylon-to-espree/convertComments.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/convertComments'>;
}
declare module 'babel-eslint/babylon-to-espree/index.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/index'>;
declare module 'babel-eslint/lib/babylon-to-espree/convertTemplateType.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/convertTemplateType'>;
}
declare module 'babel-eslint/babylon-to-espree/toAST.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toAST'>;
declare module 'babel-eslint/lib/babylon-to-espree/index.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/index'>;
}
declare module 'babel-eslint/babylon-to-espree/toToken.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toToken'>;
declare module 'babel-eslint/lib/babylon-to-espree/toAST.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toAST'>;
}
declare module 'babel-eslint/babylon-to-espree/toTokens.js' {
declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toTokens'>;
declare module 'babel-eslint/lib/babylon-to-espree/toToken.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toToken'>;
}
declare module 'babel-eslint/index' {
declare module.exports: $Exports<'babel-eslint'>;
declare module 'babel-eslint/lib/babylon-to-espree/toTokens.js' {
declare module.exports: $Exports<'babel-eslint/lib/babylon-to-espree/toTokens'>;
}
declare module 'babel-eslint/index.js' {
declare module.exports: $Exports<'babel-eslint'>;
declare module 'babel-eslint/lib/index.js' {
declare module.exports: $Exports<'babel-eslint/lib/index'>;
}
declare module 'babel-eslint/lib/parse-with-patch.js' {
declare module.exports: $Exports<'babel-eslint/lib/parse-with-patch'>;
}
declare module 'babel-eslint/lib/parse-with-scope.js' {
declare module.exports: $Exports<'babel-eslint/lib/parse-with-scope'>;
}
declare module 'babel-eslint/lib/parse.js' {
declare module.exports: $Exports<'babel-eslint/lib/parse'>;
}
declare module 'babel-eslint/lib/patch-eslint-scope.js' {
declare module.exports: $Exports<'babel-eslint/lib/patch-eslint-scope'>;
}
declare module 'babel-eslint/lib/visitor-keys.js' {
declare module.exports: $Exports<'babel-eslint/lib/visitor-keys'>;
}
+32
View File
@@ -0,0 +1,32 @@
// flow-typed signature: 28e21cd69ea80cb16ce55bf99f590519
// flow-typed version: <<STUB>>/babel-jest_v^22.4.1/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* 'babel-jest'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'babel-jest' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'babel-jest/build/index' {
declare module.exports: any;
}
// Filename aliases
declare module 'babel-jest/build/index.js' {
declare module.exports: $Exports<'babel-jest/build/index'>;
}
+21 -7
View File
@@ -1,4 +1,4 @@
// flow-typed signature: d1fdbccfd5feef333d71c618ec662a23
// flow-typed signature: d8f8afedb19b5b1272a22bfa78fb62b8
// flow-typed version: <<STUB>>/babel-loader_v^8.0.0-beta.0/flow_v0.66.0
/**
@@ -22,7 +22,15 @@ declare module 'babel-loader' {
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'babel-loader/lib/fs-cache' {
declare module 'babel-loader/lib/cache' {
declare module.exports: any;
}
declare module 'babel-loader/lib/config' {
declare module.exports: any;
}
declare module 'babel-loader/lib/Error' {
declare module.exports: any;
}
@@ -30,7 +38,7 @@ declare module 'babel-loader/lib/index' {
declare module.exports: any;
}
declare module 'babel-loader/lib/resolve-rc' {
declare module 'babel-loader/lib/transform' {
declare module.exports: any;
}
@@ -47,14 +55,20 @@ declare module 'babel-loader/lib/utils/relative' {
}
// Filename aliases
declare module 'babel-loader/lib/fs-cache.js' {
declare module.exports: $Exports<'babel-loader/lib/fs-cache'>;
declare module 'babel-loader/lib/cache.js' {
declare module.exports: $Exports<'babel-loader/lib/cache'>;
}
declare module 'babel-loader/lib/config.js' {
declare module.exports: $Exports<'babel-loader/lib/config'>;
}
declare module 'babel-loader/lib/Error.js' {
declare module.exports: $Exports<'babel-loader/lib/Error'>;
}
declare module 'babel-loader/lib/index.js' {
declare module.exports: $Exports<'babel-loader/lib/index'>;
}
declare module 'babel-loader/lib/resolve-rc.js' {
declare module.exports: $Exports<'babel-loader/lib/resolve-rc'>;
declare module 'babel-loader/lib/transform.js' {
declare module.exports: $Exports<'babel-loader/lib/transform'>;
}
declare module 'babel-loader/lib/utils/exists.js' {
declare module.exports: $Exports<'babel-loader/lib/utils/exists'>;
@@ -0,0 +1,32 @@
// flow-typed signature: 4f035977b728b8f099957c29ba25421d
// flow-typed version: <<STUB>>/babel-plugin-dynamic-import-node_v^1.2.0/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* 'babel-plugin-dynamic-import-node'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'babel-plugin-dynamic-import-node' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'babel-plugin-dynamic-import-node/lib/index' {
declare module.exports: any;
}
// Filename aliases
declare module 'babel-plugin-dynamic-import-node/lib/index.js' {
declare module.exports: $Exports<'babel-plugin-dynamic-import-node/lib/index'>;
}
+23
View File
@@ -0,0 +1,23 @@
// flow-typed signature: cf86673cc32d185bdab1d2ea90578d37
// flow-typed version: 614bf49aa8/classnames_v2.x.x/flow_>=v0.25.x
type $npm$classnames$Classes =
| string
| { [className: string]: * }
| false
| void
| null;
declare module "classnames" {
declare module.exports: (
...classes: Array<$npm$classnames$Classes | $npm$classnames$Classes[]>
) => string;
}
declare module "classnames/bind" {
declare module.exports: $Exports<"classnames">;
}
declare module "classnames/dedupe" {
declare module.exports: $Exports<"classnames">;
}
+127
View File
@@ -0,0 +1,127 @@
// flow-typed signature: 984f6785a321187ac15c3434bbd7f25d
// flow-typed version: 568ec63cee/history_v4.x.x/flow_>=v0.25.x
declare module "history/createBrowserHistory" {
declare function Unblock(): void;
declare export type Action = "PUSH" | "REPLACE" | "POP";
declare export type BrowserLocation = {
pathname: string,
search: string,
hash: string,
// Browser and Memory specific
state: string,
key: string,
};
declare export type BrowserHistory = {
length: number,
location: BrowserLocation,
action: Action,
push: (path: string, Array<mixed>) => void,
replace: (path: string, Array<mixed>) => void,
go: (n: number) => void,
goBack: () => void,
goForward: () => void,
listen: Function,
block: (message: string) => Unblock,
block: ((location: BrowserLocation, action: Action) => string) => Unblock,
push: (path: string) => void,
};
declare type HistoryOpts = {
basename?: string,
forceRefresh?: boolean,
getUserConfirmation?: (
message: string,
callback: (willContinue: boolean) => void,
) => void,
};
declare export default (opts?: HistoryOpts) => BrowserHistory;
}
declare module "history/createMemoryHistory" {
declare function Unblock(): void;
declare export type Action = "PUSH" | "REPLACE" | "POP";
declare export type MemoryLocation = {
pathname: string,
search: string,
hash: string,
// Browser and Memory specific
state: string,
key: string,
};
declare export type MemoryHistory = {
length: number,
location: MemoryLocation,
action: Action,
index: number,
entries: Array<string>,
push: (path: string, Array<mixed>) => void,
replace: (path: string, Array<mixed>) => void,
go: (n: number) => void,
goBack: () => void,
goForward: () => void,
// Memory only
canGo: (n: number) => boolean,
listen: Function,
block: (message: string) => Unblock,
block: ((location: MemoryLocation, action: Action) => string) => Unblock,
push: (path: string) => void,
};
declare type HistoryOpts = {
initialEntries?: Array<string>,
initialIndex?: number,
keyLength?: number,
getUserConfirmation?: (
message: string,
callback: (willContinue: boolean) => void,
) => void,
};
declare export default (opts?: HistoryOpts) => MemoryHistory;
}
declare module "history/createHashHistory" {
declare function Unblock(): void;
declare export type Action = "PUSH" | "REPLACE" | "POP";
declare export type HashLocation = {
pathname: string,
search: string,
hash: string,
};
declare export type HashHistory = {
length: number,
location: HashLocation,
action: Action,
push: (path: string, Array<mixed>) => void,
replace: (path: string, Array<mixed>) => void,
go: (n: number) => void,
goBack: () => void,
goForward: () => void,
listen: Function,
block: (message: string) => Unblock,
block: ((location: HashLocation, action: Action) => string) => Unblock,
push: (path: string) => void,
};
declare type HistoryOpts = {
basename?: string,
hashType: "slash" | "noslash" | "hashbang",
getUserConfirmation?: (
message: string,
callback: (willContinue: boolean) => void,
) => void,
};
declare export default (opts?: HistoryOpts) => HashHistory;
}
+16 -14
View File
@@ -1,5 +1,5 @@
// flow-typed signature: 18018da6c1a1d95b4ab1c64bb5fe86ca
// flow-typed version: c1ad61e7d4/jest_v22.x.x/flow_>=v0.39.x
// flow-typed signature: ebbcd423b1fcd29d6804fca91bb68879
// flow-typed version: 7b9f6d2713/jest_v22.x.x/flow_>=v0.39.x
type JestMockFn<TArguments: $ReadOnlyArray<*>, TReturn> = {
(...args: TArguments): TReturn,
@@ -126,14 +126,16 @@ type EnzymeMatchersType = {
toBeChecked(): void,
toBeDisabled(): void,
toBeEmpty(): void,
toBeEmptyRender(): void,
toBePresent(): void,
toContainReact(element: React$Element<any>): void,
toExist(): void,
toHaveClassName(className: string): void,
toHaveHTML(html: string): void,
toHaveProp(propKey: string, propValue?: any): void,
toHaveProp: ((propKey: string, propValue?: any) => void) & ((props: Object) => void),
toHaveRef(refName: string): void,
toHaveState(stateKey: string, stateValue?: any): void,
toHaveStyle(styleKey: string, styleValue?: any): void,
toHaveState: ((stateKey: string, stateValue?: any) => void) & ((state: Object) => void),
toHaveStyle: ((styleKey: string, styleValue?: any) => void) & ((style: Object) => void),
toHaveTagName(tagName: string): void,
toHaveText(text: string): void,
toIncludeText(text: string): void,
@@ -559,12 +561,12 @@ declare var expect: {
assertions(expectedAssertions: number): void,
hasAssertions(): void,
any(value: mixed): JestAsymmetricEqualityType,
anything(): void,
arrayContaining(value: Array<mixed>): void,
objectContaining(value: Object): void,
anything(): any,
arrayContaining(value: Array<mixed>): Array<mixed>,
objectContaining(value: Object): Object,
/** Matches any received string that contains the exact expected string. */
stringContaining(value: string): void,
stringMatching(value: string | RegExp): void
stringContaining(value: string): string,
stringMatching(value: string | RegExp): string
};
// TODO handle return type
@@ -581,14 +583,14 @@ declare var jest: JestObjectType;
declare var jasmine: {
DEFAULT_TIMEOUT_INTERVAL: number,
any(value: mixed): JestAsymmetricEqualityType,
anything(): void,
arrayContaining(value: Array<mixed>): void,
anything(): any,
arrayContaining(value: Array<mixed>): Array<mixed>,
clock(): JestClockType,
createSpy(name: string): JestSpyType,
createSpyObj(
baseName: string,
methodNames: Array<string>
): { [methodName: string]: JestSpyType },
objectContaining(value: Object): void,
stringMatching(value: string): void
objectContaining(value: Object): Object,
stringMatching(value: string): string
};
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
// flow-typed signature: 04ff32665baee4af652d15fb60267d4e
// flow-typed version: <<STUB>>/postcss-mixins_v^6.2.0/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* 'postcss-mixins'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'postcss-mixins' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'postcss-mixins/index' {
declare module.exports: $Exports<'postcss-mixins'>;
}
declare module 'postcss-mixins/index.js' {
declare module.exports: $Exports<'postcss-mixins'>;
}
+50 -10
View File
@@ -1,16 +1,56 @@
// flow-typed signature: 27a1e0b05716361b7ef0637f8b240a02
// flow-typed version: 59aa644df6/react-loadable_v5.x.x/flow_>=v0.56.0
// flow-typed signature: aad2151aafb250a7bce85c55144caa7a
// flow-typed version: 34fcf12a99/react-loadable_v5.x.x/flow_>=v0.56.0
declare module 'react-loadable' {
declare type LoaderResult<T> = T | { 'default': T };
declare type LoadingProps = {
isLoading: boolean,
pastDelay: boolean,
timedOut: boolean,
error: boolean
};
declare module.exports: <P>(opts: {
loader(): Promise<LoaderResult<React$ComponentType<P>>>,
loading: React$ComponentType<*>,
declare type CommonOptions = {
loading: React$ComponentType<LoadingProps>,
delay?: number,
timeout?: number,
render?: (r: LoaderResult<React$ComponentType<P>>, p: P) => React$Node,
webpack?: () => Array<string>,
modules?: Array<string>
}) => React$ComponentType<P>;
modules?: Array<string>,
webpack?: () => Array<number>
};
declare type OptionsWithoutRender<TProps> = {
...CommonOptions,
loader(): Promise<React$ComponentType<TProps> | { default: React$ComponentType<TProps> }>
};
declare type OptionsWithRender<TProps, TModule> = {
...CommonOptions,
loader(): Promise<TModule>,
render(loaded: TModule, props: TProps): React$Node
};
declare type Options<TProps, TModule> = OptionsWithoutRender<TProps> | OptionsWithRender<TProps, TModule>;
declare type MapOptions<TProps, TModules: { [key: string]: * }> = {
...CommonOptions,
loader: {
[key: $Keys<TModules>]: () => Promise<*>
},
render(loaded: TModules, props: TProps): React$Node
};
declare class LoadableComponent<TProps> extends React$Component<TProps> {
static preload(): Promise<void>
}
declare type CaptureProps = {
report(moduleName: string): void
};
declare module.exports: {
<TProps, TModule>(opts: Options<TProps, TModule>): Class<LoadableComponent<TProps>>,
Map<TProps, TModules>(opts: MapOptions<TProps, TModules>): Class<LoadableComponent<TProps>>,
Capture: React$ComponentType<CaptureProps>,
preloadAll(): Promise<void>,
preloadReady(): Promise<void>,
};
}
+98
View File
@@ -0,0 +1,98 @@
// flow-typed signature: a2c406bd25fca4586c361574e555202d
// flow-typed version: dcd1531faf/react-redux_v5.x.x/flow_>=v0.62.0
import type { Dispatch, Store } from "redux";
declare module "react-redux" {
import type { ComponentType, ElementConfig } from 'react';
declare export class Provider<S, A> extends React$Component<{
store: Store<S, A>,
children?: any
}> {}
declare export function createProvider(
storeKey?: string,
subKey?: string
): Provider<*, *>;
/*
S = State
A = Action
OP = OwnProps
SP = StateProps
DP = DispatchProps
MP = Merge props
MDP = Map dispatch to props object
RSP = Returned state props
RDP = Returned dispatch props
RMP = Returned merge props
Com = React Component
*/
declare type MapStateToProps<SP: Object, RSP: Object> = (state: Object, props: SP) => RSP;
declare type MapDispatchToProps<A, OP: Object, RDP: Object> = (dispatch: Dispatch<A>, ownProps: OP) => RDP;
declare type MergeProps<SP: Object, DP: Object, MP: Object, RMP: Object> = (
stateProps: SP,
dispatchProps: DP,
ownProps: MP
) => RMP;
declare type ConnectOptions<S: Object, OP: Object, RSP: Object, RMP: Object> = {|
pure?: boolean,
withRef?: boolean,
areStatesEqual?: (next: S, prev: S) => boolean,
areOwnPropsEqual?: (next: OP, prev: OP) => boolean,
areStatePropsEqual?: (next: RSP, prev: RSP) => boolean,
areMergedPropsEqual?: (next: RMP, prev: RMP) => boolean,
storeKey?: string
|};
declare type OmitDispatch<Component> = $Diff<Component, {dispatch: Dispatch<*>}>;
declare export function connect<Com: ComponentType<*>, DP: Object, RSP: Object>(
mapStateToProps: MapStateToProps<DP, RSP>,
mapDispatchToProps?: null
): (component: Com) => ComponentType<$Diff<OmitDispatch<ElementConfig<Com>>, RSP> & DP>;
declare export function connect<Com: ComponentType<*>>(
mapStateToProps?: null,
mapDispatchToProps?: null
): (component: Com) => ComponentType<OmitDispatch<ElementConfig<Com>>>;
declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToProps: MapDispatchToProps<A, DP, RDP>
): (component: Com) => ComponentType<$Diff<$Diff<ElementConfig<Com>, RSP>, RDP> & SP & DP>;
declare export function connect<Com: ComponentType<*>, A, OP: Object, DP: Object,PR: Object>(
mapStateToProps?: null,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>
): (Com) => ComponentType<$Diff<ElementConfig<Com>, DP> & OP>;
declare export function connect<Com: ComponentType<*>, MDP: Object>(
mapStateToProps?: null,
mapDispatchToProps: MDP
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, MDP>>;
declare export function connect<Com: ComponentType<*>, SP: Object, RSP: Object, MDP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToPRops: MDP
): (component: Com) => ComponentType<$Diff<$Diff<ElementConfig<Com>, RSP>, MDP> & SP>;
declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object, MP: Object, RMP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToProps: ?MapDispatchToProps<A, DP, RDP>,
mergeProps: MergeProps<RSP, RDP, MP, RMP>
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, RMP> & SP & DP & MP>;
declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object, MP: Object, RMP: Object>(
mapStateToProps: ?MapStateToProps<SP, RSP>,
mapDispatchToProps: ?MapDispatchToProps<A, DP, RDP>,
mergeProps: ?MergeProps<RSP, RDP, MP, RMP>,
options: ConnectOptions<*, SP & DP & MP, RSP, RMP>
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, RMP> & SP & DP & MP>;
}
+122
View File
@@ -0,0 +1,122 @@
// flow-typed signature: 745c3d09cfb6878b75900da197effc4a
// flow-typed version: <<STUB>>/react-router-redux_v^5.0.0-alpha.9/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* 'react-router-redux'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'react-router-redux' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'react-router-redux/actions' {
declare module.exports: any;
}
declare module 'react-router-redux/ConnectedRouter' {
declare module.exports: any;
}
declare module 'react-router-redux/es/actions' {
declare module.exports: any;
}
declare module 'react-router-redux/es/ConnectedRouter' {
declare module.exports: any;
}
declare module 'react-router-redux/es/index' {
declare module.exports: any;
}
declare module 'react-router-redux/es/middleware' {
declare module.exports: any;
}
declare module 'react-router-redux/es/reducer' {
declare module.exports: any;
}
declare module 'react-router-redux/es/selectors' {
declare module.exports: any;
}
declare module 'react-router-redux/middleware' {
declare module.exports: any;
}
declare module 'react-router-redux/reducer' {
declare module.exports: any;
}
declare module 'react-router-redux/selectors' {
declare module.exports: any;
}
declare module 'react-router-redux/umd/react-router-redux' {
declare module.exports: any;
}
declare module 'react-router-redux/umd/react-router-redux.min' {
declare module.exports: any;
}
// Filename aliases
declare module 'react-router-redux/actions.js' {
declare module.exports: $Exports<'react-router-redux/actions'>;
}
declare module 'react-router-redux/ConnectedRouter.js' {
declare module.exports: $Exports<'react-router-redux/ConnectedRouter'>;
}
declare module 'react-router-redux/es/actions.js' {
declare module.exports: $Exports<'react-router-redux/es/actions'>;
}
declare module 'react-router-redux/es/ConnectedRouter.js' {
declare module.exports: $Exports<'react-router-redux/es/ConnectedRouter'>;
}
declare module 'react-router-redux/es/index.js' {
declare module.exports: $Exports<'react-router-redux/es/index'>;
}
declare module 'react-router-redux/es/middleware.js' {
declare module.exports: $Exports<'react-router-redux/es/middleware'>;
}
declare module 'react-router-redux/es/reducer.js' {
declare module.exports: $Exports<'react-router-redux/es/reducer'>;
}
declare module 'react-router-redux/es/selectors.js' {
declare module.exports: $Exports<'react-router-redux/es/selectors'>;
}
declare module 'react-router-redux/index' {
declare module.exports: $Exports<'react-router-redux'>;
}
declare module 'react-router-redux/index.js' {
declare module.exports: $Exports<'react-router-redux'>;
}
declare module 'react-router-redux/middleware.js' {
declare module.exports: $Exports<'react-router-redux/middleware'>;
}
declare module 'react-router-redux/reducer.js' {
declare module.exports: $Exports<'react-router-redux/reducer'>;
}
declare module 'react-router-redux/selectors.js' {
declare module.exports: $Exports<'react-router-redux/selectors'>;
}
declare module 'react-router-redux/umd/react-router-redux.js' {
declare module.exports: $Exports<'react-router-redux/umd/react-router-redux'>;
}
declare module 'react-router-redux/umd/react-router-redux.min.js' {
declare module.exports: $Exports<'react-router-redux/umd/react-router-redux.min'>;
}
+107
View File
@@ -0,0 +1,107 @@
// flow-typed signature: 0d100808ca0e414fd249523ecc748952
// flow-typed version: a33adf9931/redux-actions_v2.x.x/flow_>=v0.39.x
declare module "redux-actions" {
/*
* Use `ActionType` to get the type of the action created by a given action
* creator. For example:
*
* import { createAction, type ActionType } from 'redux-actions'
*
* const increment = createAction(INCREMENT, (count: number) => count)
*
* function myReducer(state: State = initState, action: ActionType<typeof increment>): State {
* // Flow will infer that the type of `action.payload` is `number`
* }
*/
declare type ActionType<ActionCreator> = _ActionType<*, ActionCreator>;
declare type _ActionType<R, Fn: (...rest: *) => R> = R;
/*
* To get the most from Flow type checking use a `payloadCreator` argument
* with `createAction`. Make sure that Flow can infer the argument type of the
* `payloadCreator`. That will allow Flow to infer the payload type of actions
* created by that action creator in other parts of the program. For example:
*
* const increment = createAction(INCREMENT, (count: number) => count)
*
*/
declare function createAction<T, P>(
type: T,
$?: empty // hack to force Flow to not use this signature when more than one argument is given
): {(payload: P, ...rest: any[]): { type: T, payload: P, error?: boolean }, toString: () => T};
declare function createAction<T, A, P>(
type: T,
payloadCreator: (...rest: A) => P,
$?: empty
): {(...rest: A): { type: T, payload: P, error?: boolean }, toString: () => T};
declare function createAction<T, A, P, M>(
type: T,
payloadCreator: (...rest: A) => P,
metaCreator: (...rest: A) => M
): {(...rest: A): { type: T, payload: P, error?: boolean, meta: M }, toString: () => T};
declare function createAction<T, P, M>(
type: T,
payloadCreator: null | void,
metaCreator: (payload: P, ...rest: any[]) => M
): {(
payload: P,
...rest: any[]
): { type: T, payload: P, error?: boolean, meta: M }, toString: () => T};
// `createActions` is quite difficult to write a type for. Maybe try not to
// use this one?
declare function createActions(
actionMap: Object,
...identityActions: string[]
): Object;
declare function createActions(...identityActions: string[]): Object;
declare type Reducer<S, A> = (state: S, action: A) => S;
declare type ReducerMap<S, A> =
| { next: Reducer<S, A> }
| { throw: Reducer<S, A> }
| { next: Reducer<S, A>, throw: Reducer<S, A> };
/*
* To get full advantage from Flow, use a type annotation on the action
* argument to your reducer when creating a reducer with `handleAction` or
* `handleActions`. For example:
*
* import { type Reducer } from 'redux'
* import { createAction, handleAction, type Action } from 'redux-actions'
*
* const increment = createAction(INCREMENT, (count: number) => count)
*
* const reducer = handleAction(INCREMENT, (state, { payload }: ActionType<typeof increment>) => {
* // Flow infers that the type of `payload` is number
* }, defaultState)
*/
declare type ReducerDefinition<State, Action> = {
[key: string]:
| (Reducer<State, Action> | ReducerDefinition<State, Action>)
| ReducerMap<State, Action>
};
declare function handleAction<Type, State, Action: { type: Type }>(
type: Type,
reducer: ReducerDefinition<State, Action>,
defaultState: State
): Reducer<State, Action>;
declare function handleActions<State, Action>(
reducers: {
[key: string]: Reducer<State, Action> | ReducerMap<State, Action>
},
defaultState?: State
): Reducer<State, Action>;
declare function combineActions(
...types: (string | Symbol | Function)[]
): string;
}
+60
View File
@@ -0,0 +1,60 @@
// flow-typed signature: 6d66322fcd005cac32bee606dc6ac879
// flow-typed version: <<STUB>>/redux-thunk_v^2.2.0/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
*
* 'redux-thunk'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'redux-thunk' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'redux-thunk/dist/redux-thunk' {
declare module.exports: any;
}
declare module 'redux-thunk/dist/redux-thunk.min' {
declare module.exports: any;
}
declare module 'redux-thunk/es/index' {
declare module.exports: any;
}
declare module 'redux-thunk/lib/index' {
declare module.exports: any;
}
declare module 'redux-thunk/src/index' {
declare module.exports: any;
}
// Filename aliases
declare module 'redux-thunk/dist/redux-thunk.js' {
declare module.exports: $Exports<'redux-thunk/dist/redux-thunk'>;
}
declare module 'redux-thunk/dist/redux-thunk.min.js' {
declare module.exports: $Exports<'redux-thunk/dist/redux-thunk.min'>;
}
declare module 'redux-thunk/es/index.js' {
declare module.exports: $Exports<'redux-thunk/es/index'>;
}
declare module 'redux-thunk/lib/index.js' {
declare module.exports: $Exports<'redux-thunk/lib/index'>;
}
declare module 'redux-thunk/src/index.js' {
declare module.exports: $Exports<'redux-thunk/src/index'>;
}
View File
+890
View File
@@ -0,0 +1,890 @@
// flow-typed signature: 7242133add1d3bd16fc3e9d648152c63
// flow-typed version: 00301f0d29/reselect_v3.x.x/flow_>=v0.47.x
// flow-typed signature: 0199525b667f385f2e61dbeae3215f21
// flow-typed version: b43dff3e0e/reselect_v3.x.x/flow_>=v0.28.x
declare module "reselect" {
declare type Selector<-TState, TProps, TResult> =
(state: TState, props: TProps, ...rest: any[]) => TResult
declare type SelectorCreator = {
<TState, TProps, TResult, T1>(
selector1: Selector<TState, TProps, T1>,
resultFunc: (arg1: T1) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1>(
selectors: [Selector<TState, TProps, T1>],
resultFunc: (arg1: T1) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
resultFunc: (arg1: T1, arg2: T2) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2>(
selectors: [Selector<TState, TProps, T1>, Selector<TState, TProps, T2>],
resultFunc: (arg1: T1, arg2: T2) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
resultFunc: (arg1: T1, arg2: T2, arg3: T3) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>
],
resultFunc: (arg1: T1, arg2: T2, arg3: T3) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
resultFunc: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>
],
resultFunc: (arg1: T1, arg2: T2, arg3: T3, arg4: T4) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
resultFunc: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>
],
resultFunc: (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11
) => TResult
): Selector<TState, TProps, TResult>,
<TState, TProps, TResult, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12
>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
selector12: Selector<TState, TProps, T12>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12
>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>,
Selector<TState, TProps, T12>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13
>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
selector12: Selector<TState, TProps, T12>,
selector13: Selector<TState, TProps, T13>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13
>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>,
Selector<TState, TProps, T12>,
Selector<TState, TProps, T13>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14
>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
selector12: Selector<TState, TProps, T12>,
selector13: Selector<TState, TProps, T13>,
selector14: Selector<TState, TProps, T14>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14
>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>,
Selector<TState, TProps, T12>,
Selector<TState, TProps, T13>,
Selector<TState, TProps, T14>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14,
T15
>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
selector12: Selector<TState, TProps, T12>,
selector13: Selector<TState, TProps, T13>,
selector14: Selector<TState, TProps, T14>,
selector15: Selector<TState, TProps, T15>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14,
arg15: T15
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14,
T15
>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>,
Selector<TState, TProps, T12>,
Selector<TState, TProps, T13>,
Selector<TState, TProps, T14>,
Selector<TState, TProps, T15>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14,
arg15: T15
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14,
T15,
T16
>(
selector1: Selector<TState, TProps, T1>,
selector2: Selector<TState, TProps, T2>,
selector3: Selector<TState, TProps, T3>,
selector4: Selector<TState, TProps, T4>,
selector5: Selector<TState, TProps, T5>,
selector6: Selector<TState, TProps, T6>,
selector7: Selector<TState, TProps, T7>,
selector8: Selector<TState, TProps, T8>,
selector9: Selector<TState, TProps, T9>,
selector10: Selector<TState, TProps, T10>,
selector11: Selector<TState, TProps, T11>,
selector12: Selector<TState, TProps, T12>,
selector13: Selector<TState, TProps, T13>,
selector14: Selector<TState, TProps, T14>,
selector15: Selector<TState, TProps, T15>,
selector16: Selector<TState, TProps, T16>,
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14,
arg15: T15,
arg16: T16
) => TResult
): Selector<TState, TProps, TResult>,
<
TState,
TProps,
TResult,
T1,
T2,
T3,
T4,
T5,
T6,
T7,
T8,
T9,
T10,
T11,
T12,
T13,
T14,
T15,
T16
>(
selectors: [
Selector<TState, TProps, T1>,
Selector<TState, TProps, T2>,
Selector<TState, TProps, T3>,
Selector<TState, TProps, T4>,
Selector<TState, TProps, T5>,
Selector<TState, TProps, T6>,
Selector<TState, TProps, T7>,
Selector<TState, TProps, T8>,
Selector<TState, TProps, T9>,
Selector<TState, TProps, T10>,
Selector<TState, TProps, T11>,
Selector<TState, TProps, T12>,
Selector<TState, TProps, T13>,
Selector<TState, TProps, T14>,
Selector<TState, TProps, T15>,
Selector<TState, TProps, T16>
],
resultFunc: (
arg1: T1,
arg2: T2,
arg3: T3,
arg4: T4,
arg5: T5,
arg6: T6,
arg7: T7,
arg8: T8,
arg9: T9,
arg10: T10,
arg11: T11,
arg12: T12,
arg13: T13,
arg14: T14,
arg15: T15,
arg16: T16
) => TResult
): Selector<TState, TProps, TResult>
};
declare type Reselect = {
createSelector: SelectorCreator,
defaultMemoize: <TFunc: Function>(
func: TFunc,
equalityCheck?: (a: any, b: any) => boolean
) => TFunc,
createSelectorCreator: (
memoize: Function,
...memoizeOptions: any[]
) => SelectorCreator,
createStructuredSelector: <TState, TProps>(
inputSelectors: {
[k: string | number]: Selector<TState, TProps, any>
},
selectorCreator?: SelectorCreator
) => Selector<TState, TProps, any>
};
declare module.exports: Reselect;
}
+23
View File
@@ -0,0 +1,23 @@
// flow-typed signature: 26d5f1a6f2ea08c6adaea50d44628e9e
// flow-typed version: 0c975ef003/storybook-host_v4.x.x/flow_>=v0.54.1
declare module 'storybook-host' {
declare type Props = {|
mobXDevTools?:boolean,
title?:string,
hr?:boolean,
align?:string,
height?:number | string,
width?:number | string,
background?:boolean | number | string,
backdrop?:boolean | number | string,
cropMarks?:boolean,
border?:boolean | number | string,
padding?:number | string
|};
declare export function host(props: Props): (
story: () => React$Element<any>,
context?: { kind: string, story: string }
) => React$Element<any>;
}
+40
View File
@@ -0,0 +1,40 @@
// flow-typed signature: b2706d3b0f5dd8a525bfb666480ca78b
// flow-typed version: 3b9d983701/storybook-router_v0.x.x/flow_>=v0.25.x
import type { Element } from "react";
type LocationShape = {
pathname?: string,
search?: string,
hash?: string,
state?: any
};
type GetUserConfirmation = (
message: string,
callback: (confirmed: boolean) => void
) => void;
type Renderable = Element<*>;
type RenderFunction = () => Renderable;
type StoryDecorator = (story: RenderFunction) => Renderable;
declare module "storybook-router" {
declare type Links = {
[key: string]: (kind: string, story: string) => Function
};
declare type RouterProps = {
initialEntry?: Array<string>,
autoRoute?: boolean,
initialEntries?: Array<LocationShape | string>,
initialIndex?: number,
getUserConfirmation?: GetUserConfirmation,
keyLength?: number,
children?: Element<*>
};
declare module.exports: {
(links?: Links, routerProps?: RouterProps): StoryDecorator
};
}
+8 -8
View File
@@ -1,4 +1,4 @@
// flow-typed signature: 24a95d93ba3f02fcd36080150b9c4714
// flow-typed signature: e79c3736e47e9140aa90aeea345017d5
// flow-typed version: <<STUB>>/webpack-cli_v^2.0.8/flow_v0.66.0
/**
@@ -162,10 +162,6 @@ declare module 'webpack-cli/lib/init/transformations/externals/externals' {
declare module.exports: any;
}
declare module 'webpack-cli/lib/init/transformations/index' {
declare module.exports: any;
}
declare module 'webpack-cli/lib/init/transformations/mode/mode' {
declare module.exports: any;
}
@@ -310,6 +306,10 @@ declare module 'webpack-cli/lib/utils/hashtable' {
declare module.exports: any;
}
declare module 'webpack-cli/lib/utils/is-local-path' {
declare module.exports: any;
}
declare module 'webpack-cli/lib/utils/modify-config-helper' {
declare module.exports: any;
}
@@ -444,9 +444,6 @@ declare module 'webpack-cli/lib/init/transformations/entry/entry.js' {
declare module 'webpack-cli/lib/init/transformations/externals/externals.js' {
declare module.exports: $Exports<'webpack-cli/lib/init/transformations/externals/externals'>;
}
declare module 'webpack-cli/lib/init/transformations/index.js' {
declare module.exports: $Exports<'webpack-cli/lib/init/transformations/index'>;
}
declare module 'webpack-cli/lib/init/transformations/mode/mode.js' {
declare module.exports: $Exports<'webpack-cli/lib/init/transformations/mode/mode'>;
}
@@ -555,6 +552,9 @@ declare module 'webpack-cli/lib/utils/defineTest.js' {
declare module 'webpack-cli/lib/utils/hashtable.js' {
declare module.exports: $Exports<'webpack-cli/lib/utils/hashtable'>;
}
declare module 'webpack-cli/lib/utils/is-local-path.js' {
declare module.exports: $Exports<'webpack-cli/lib/utils/is-local-path'>;
}
declare module 'webpack-cli/lib/utils/modify-config-helper.js' {
declare module.exports: $Exports<'webpack-cli/lib/utils/modify-config-helper'>;
}
+2 -2
View File
@@ -1,5 +1,5 @@
// flow-typed signature: ab90e625067e5035473d7b08ece96ab7
// flow-typed version: <<STUB>>/webpack_v^4.0.0/flow_v0.66.0
// flow-typed signature: 3557fbc190b720039ecba5ac8ae2be41
// flow-typed version: <<STUB>>/webpack_v^4.1.1/flow_v0.66.0
/**
* This is an autogenerated libdef stub for:
+2342 -15
View File
File diff suppressed because it is too large Load Diff
+33 -14
View File
@@ -8,9 +8,12 @@
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom",
"test": "run-with-testrpc -l 40000000 'node scripts/test.js --env=jsdom'",
"test-local": "node scripts/test.js --env=jsdom",
"precommit": "./precommit.sh",
"flow": "flow"
"flow": "flow",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook -o build_storybook"
},
"repository": {
"type": "git",
@@ -34,13 +37,20 @@
"@babel/preset-flow": "^7.0.0-beta.40",
"@babel/preset-react": "^7.0.0-beta.40",
"@babel/preset-stage-0": "^7.0.0-beta.40",
"@sambego/storybook-state": "^1.0.7",
"@storybook/addon-actions": "^3.3.15",
"@storybook/addon-knobs": "^3.3.15",
"@storybook/addon-links": "^3.3.15",
"@storybook/react": "^3.3.15",
"autoprefixer": "^8.1.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^7.2.3",
"babel-eslint": "8",
"babel-jest": "^22.4.1",
"babel-loader": "^8.0.0-beta.0",
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
"babel-plugin-transform-es3-property-literals": "^6.22.0",
"classnames": "^2.2.5",
"css-loader": "^0.28.10",
"detect-port": "^1.2.2",
"dotenv": "^5.0.1",
@@ -57,20 +67,31 @@
"fs-extra": "^5.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.0.4",
"immutable": "^4.0.0-rc.9",
"jest": "^22.4.2",
"json-loader": "^0.5.7",
"postcss-loader": "^2.1.1",
"postcss-mixins": "^6.2.0",
"postcss-simple-vars": "^4.1.0",
"pre-commit": "^1.2.2",
"react": "^16.2.0",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.7",
"react-router-redux": "^5.0.0-alpha.9",
"redux": "^3.7.2",
"redux-actions": "^2.3.0",
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1",
"run-with-testrpc": "^0.3.0",
"storybook-host": "^4.1.5",
"storybook-router": "^0.3.3",
"style-loader": "^0.20.2",
"truffle-contract": "^1.1.8",
"truffle-solidity-loader": "0.0.8",
"uglifyjs-webpack-plugin": "^1.2.2",
"web3": "0.18.4",
"webpack": "^4.0.0",
"webpack": "^4.1.1",
"webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.8",
"webpack-dev-server": "^3.1.0",
@@ -78,6 +99,7 @@
},
"dependencies": {
"final-form": "^4.2.1",
"history": "^4.7.2",
"material-ui": "^1.0.0-beta.35",
"material-ui-icons": "^1.0.0-beta.35",
"react-final-form": "^3.1.2",
@@ -85,12 +107,15 @@
"react-router-dom": "^4.2.2"
},
"jest": {
"verbose": true,
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"setupFiles": [
"<rootDir>/config/webpack.config.test.js",
"<rootDir>/config/polyfills.js"
"<rootDir>/config/polyfills.js",
"<rootDir>/config/jest/LocalStorageMock.js",
"<rootDir>/config/jest/Web3Mock.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
@@ -104,19 +129,13 @@
"^(?!.*\\.(js|jsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$"
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$",
"[/\\\\]flow-typed[/\\\\].+\\.(js|jsx)$"
],
"moduleNameMapper": {
"~(.*)$": "<rootDir>/src/$1",
"#(.*)$": "<rootDir>/gnosis-safe-contracts/build/contracts/$1",
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx"
]
}
}
}
-3
View File
@@ -2,7 +2,6 @@
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep ".jsx\{0,1\}$")
ESLINT="$(git rev-parse --show-toplevel)/node_modules/.bin/eslint"
ADD_FILES_TO_COMMIT="git add ."
if [[ "$STAGED_FILES" = "" ]]; then
exit 0
@@ -39,6 +38,4 @@ else
echo -e "\033[42mCOMMIT SUCCEEDED\033[0m\n"
fi
eval $ADD_FILES_TO_COMMIT
exit $?
+1
View File
@@ -1,3 +1,4 @@
/*eslint-disable*/
process.env.NODE_ENV = 'development';
// Load environment variables from .env file. Suppress warnings using silent
-11
View File
@@ -1,11 +0,0 @@
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import AppRoutes from './routes'
const ReactRouterApp = () => (
<BrowserRouter>
<AppRoutes />
</BrowserRouter>
)
export default ReactRouterApp
-8
View File
@@ -1,8 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
it('renders without crashing', () => {
const div = document.createElement('div')
ReactDOM.render(<App />, div)
})
+19
View File
@@ -0,0 +1,19 @@
// @flow
import React from 'react'
import Block from '~/components/layout/Block'
import Link from '~/components/layout/Link'
import { WELCOME_ADDRESS, SAFELIST_ADDRESS } from '~/routes/routes'
import styles from './index.scss'
const Footer = () => (
<Block className={styles.footer}>
<Link padding="md" to={WELCOME_ADDRESS}>
Welcome
</Link>
<Link to={SAFELIST_ADDRESS}>
Safe List
</Link>
</Block>
)
export default Footer
+18
View File
@@ -0,0 +1,18 @@
.footer {
display: grid;
grid-template-columns: 1fr auto auto;
justify-items: end;
}
@media only screen and (max-width: $(screenXs)px) {
.footer {
grid-template-columns: none;
grid-template-rows: auto auto;
grid-row-gap: $sm;
justify-items: center;
}
.footer > a {
padding: 0;
}
}
+16
View File
@@ -0,0 +1,16 @@
// @flow
import { storiesOf } from '@storybook/react'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
<div style={{ flex: '1' }} />
{ story() }
</div>
)
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('Footer', () => <Component />)
+6
View File
@@ -0,0 +1,6 @@
// @flow
import { fetchProvider } from '~/wallets/store/actions'
export default {
fetchProvider,
}
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Isolation_Mode" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 697.7 119.5" style="enable-background:new 0 0 697.7 119.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#00A6C4;}
</style>
<g>
<g>
<path class="st0" d="M399.6,64.3v22.6c-6.2,4.7-15.4,8-23.8,8c-18.1,0-32.2-13.6-32.2-31.1c0-17.5,14.3-30.9,32.9-30.9
c8.8,0,17.5,3.3,23.6,8.6l-5.9,7.6c-4.7-4.4-11.3-7-17.7-7c-12.5,0-22.3,9.5-22.3,21.7c0,12.3,9.9,21.8,22.4,21.8
c4.6,0,9.7-1.6,14.1-4.2V64.3H399.6z"/>
<path class="st0" d="M461.2,94.4l-32.7-44v44h-10.3V33.1h10.2l32.9,44.1V33.1h10.2v61.3H461.2z"/>
<path class="st0" d="M551.4,63.7c0,17.5-14.2,31.1-32.5,31.1c-18.3,0-32.5-13.6-32.5-31.1c0-17.6,14.2-30.9,32.5-30.9
C537.3,32.8,551.4,46.2,551.4,63.7z M496.9,63.7c0,12.2,10.1,21.8,22.1,21.8c12,0,21.8-9.6,21.8-21.8c0-12.2-9.8-21.6-21.8-21.6
C506.9,42.1,496.9,51.6,496.9,63.7z"/>
<path class="st0" d="M608.1,38.9l-4.3,9.1c-6.7-4-13.3-5.7-18-5.7c-6,0-10,2.3-10,6.4c0,13.4,33.1,6.2,33,28.3
c0,11-9.6,17.7-23.1,17.7c-9.6,0-18.7-3.9-25.1-9.7l4.5-8.9c6.3,5.8,14.2,8.9,20.8,8.9c7.2,0,11.5-2.7,11.5-7.4
c0-13.7-33.1-6-33.1-27.9c0-10.5,9-17.1,22.3-17.1C594.6,32.6,602.4,35.2,608.1,38.9z"/>
<path class="st0" d="M624.9,94.4V33.1h10.3v61.3H624.9z"/>
<path class="st0" d="M696.9,38.9l-4.3,9.1c-6.7-4-13.3-5.7-18-5.7c-6,0-10,2.3-10,6.4c0,13.4,33.1,6.2,33,28.3
c0,11-9.6,17.7-23.1,17.7c-9.6,0-18.7-3.9-25.1-9.7l4.5-8.9c6.3,5.8,14.2,8.9,20.8,8.9c7.2,0,11.5-2.7,11.5-7.4
c0-13.7-33.1-6-33.1-27.9c0-10.5,9-17.1,22.3-17.1C683.4,32.6,691.2,35.2,696.9,38.9z"/>
</g>
<g>
<path class="st0" d="M200.7,29.9l-4.4,4.4c3.5,5.5,4.6,12.4,2.2,19c-4,11.2-16.4,17.1-27.7,13.1c-1.6-0.6-3.1-1.3-4.4-2.2
l-14.1,14.1L140,65.9c-5.7,3.8-13,4.9-19.9,2.5c-11.6-4.2-17.6-16.9-13.4-28.4c0.6-1.8,1.5-3.4,2.5-4.9l-5.3-5.3l-1,1.7
c-5.5,9-8.5,19.4-8.5,30.1c-0.1,31.9,25.9,58,57.8,58h0.1c31.9,0,57.8-25.9,57.9-57.8c0-10.6-2.9-21-8.4-30.1L200.7,29.9z"/>
<path class="st0" d="M115.7,41.6c-1.5,2-2.4,4.5-2.4,7.2c0,6.5,5.3,11.8,11.8,11.8c2.7,0,5.2-0.9,7.2-2.5L115.7,41.6z"/>
<g>
<path class="st0" d="M173.6,57.1c1.9,1.3,4.1,2,6.6,2c6.5,0,11.8-5.3,11.8-11.8c0-2.4-0.7-4.7-2-6.6L173.6,57.1z"/>
</g>
<g>
<path class="st0" d="M152.5,69.5l-47.8-48l1.9-2C118.4,7,134.5,0,151.8,0h0.1c17.5,0,34.3,7.5,46,20.5l1.8,2L152.5,69.5z
M112.5,21.5l40,40.1l39.5-39.3c-10.6-10.6-25-16.7-40-16.7h-0.1C137,5.6,123.1,11.2,112.5,21.5z"/>
</g>
<g>
<g>
<path class="st0" d="M99.8,100.4l-5.6-0.4c-23.8-1.5-56.6-7.4-77.8-26.5C3.3,61.8,0.8,50.7,0.7,50.2L0,46.8h86.6L86.1,50
c-0.4,2.9-0.6,5.9-0.6,8.8c0,13.2,3.8,26,11.1,36.9L99.8,100.4z"/>
</g>
<g>
<path class="st0" d="M204.6,100.4l3.1-4.7c7.3-10.9,11.1-23.6,11.1-36.7c0-3-0.2-6.1-0.6-9l-0.4-3.2h86.6l-0.7,3.4
c-0.1,0.5-2.6,11.6-15.6,23.3c-21.2,19.1-54.1,25-77.9,26.5L204.6,100.4z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ebene_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1077 881" style="enable-background:new 0 0 1077 881;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#000000;stroke-width:8;stroke-miterlimit:10;}
.st1{stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st2{fill:none;stroke:#000000;stroke-width:5;stroke-miterlimit:10;}
</style>
<polygon id="outline" class="st0" points="343,282 323,340 333,400 326,405 339,415 329,421 341,432 333,438 350,457 321,543
344,627 432,598 484,624 543,625 590,597 675,625 698,541 671,457 687,438 677,432 689,422 681,415 693,406 685,401 696,339
678,286 561,332 460,332 "/>
<polygon class="st1" points="483,389 427,437 350,457 333,438 341,432 329,421 339,415 326,405 333,400 323,340 343,282 "/>
<polygon class="st1" points="539,389 678,286 696,337 685,401 693,406 681,415 689,422 677,432 687,438 671,457 593,436 "/>
<polygon class="st1" points="483,512 439,501 468,487 "/>
<polygon class="st1" points="544,512 583,501 555,487 "/>
<polygon class="st1" points="494,556 535,556 543,561 547,594 544,591 487,591 483,595 486,561 "/>
<path class="st2" d="M696.5,541.5l-111-5l-38,23c-5,3-10,6-10,6"/>
<path class="st2" d="M488.5,565.5c0,0-5-3-10-6l-38-23l-111,5l-9,1"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ebene_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1077 881" style="enable-background:new 0 0 1077 881;" xml:space="preserve">
<g>
<path d="M1038,396c-1.6,0.5-1,1.9-1,3c0,2.3-0.2,4.6-0.5,6.9c-1.1,8.8-3.7,23.2-5.8,31.9c-0.4,1.8-0.9,3.6-1.4,5.4
c-2.1,7.5-4.3,15-7.3,22.2c-4.1,9.6-8.4,19.2-13.7,28.2c-3.2,5.3-6.3,10.7-9.9,15.8c-4.5,6.4-9.4,12.6-14.5,18.6
c-4.9,5.9-10.4,11.1-15.8,16.6c-7.3,7.4-15.3,14-23.8,20c-5.9,4.1-11.6,8.5-17.6,12.5c-10.7,7-21.8,13.4-33.5,18.5
c-7.6,3.3-15.3,6.4-23.1,9.1c-7,2.4-14.2,4.5-21.4,6.3c-6,1.5-12.1,2.3-18.2,3.3c-5.6,1-11.3,1.6-17,2.3c-3.6,0.4-7.2,0.3-10.8,0.8
c-9.2,1.4-18.5,0.9-27.8,0.9c-3.1,0-6.2-0.7-9.3-0.9c-3-0.2-6,0.3-9-0.1c-5.7-0.8-11.3-1.6-17-2c-4.8-0.4-9.5-2.1-14.3-2.7
c-10.3-1.3-20.3-4.2-30.3-6.8c-5.5-1.5-11-3-16.4-4.9c-12.6-4.2-25.1-8.6-37.3-13.9c-4.5-1.9-9-3.9-13.6-5.5c-4.2-1.4-5-4.9-2-7.4
c1-0.9,2-0.8,3.2-0.3c6.9,2.4,13.8,4.7,20.8,6.9c12.8,3.9,25.7,7.7,38.8,10.7c6.5,1.5,12.8,3.5,19.3,4.8c7.8,1.6,15.7,2.6,23.5,4.2
c5.3,1,10.7,1.4,16,2.2c4.5,0.7,8.9,0.5,13.3,0.8c4.4,0.3,8.8,1.2,13.3,1.1c6.8-0.2,13.5-0.7,20.2-1.3c9.6-0.8,19.3-2.5,28.8-4.5
c11.3-2.3,22.4-5.5,33.2-9.5c16.9-6.2,32.8-14.7,47.5-25.2c5.1-3.6,9.6-8.1,14.3-12.1c2-1.7,4.1-3.3,6-5.1c1.8-1.7,3.3-3.5,4.9-5.3
c0.9-1,1.6-2.1,2.5-3c8.1-8,14.9-17.1,21.3-26.5c7.5-11,13.9-22.6,19.3-34.7c4.2-9.3,7.5-19,10.2-28.9c1.6-6.1,2.4-12.4,4-18.5
c1.1-4.2-0.1-8.5,1.7-12.6c0.4-1,0.1-2.3,0.1-3.5c0-7.3,0.1-14.7,0-22c-0.1-5.6-0.2-11.2-1-16.7c-2.1-14.1-4.9-28.2-10-41.5
c-4.5-11.8-10.3-23-17.6-33.3c-4.4-6.2-8.9-12.3-14.4-17.5c-5.4-5.1-10.6-10.5-16.4-15.2c-5.6-4.5-11.7-8.3-17.8-12.1
c-5-3.2-10-6.4-15.3-8.8c-9.2-4.1-18.4-8.2-28.1-11.1c-7.5-2.2-14.9-4.3-22.7-5.2c-5.5-0.7-11-1.3-16.5-2.1
c-6-0.9-11.9-1.1-17.8-0.6c-5.3,0.4-10.7,0.3-16.1,1.6c-2.6,0.7-5.5,0.6-8.2,1.1c-5.8,0.9-11.4,2.3-17.1,3.8
c-13.2,3.4-25.7,8.6-37.5,15.3c-5.9,3.4-11.6,7.3-17.1,11.4c-13.2,9.9-24.3,22.1-35.8,33.8c-5.5,5.6-10.2,12-15.3,18.1
c-5.1,6.1-10.3,12-15.1,18.2c-5.5,7.1-10.8,14.4-16.1,21.6c-5.8,7.9-11.7,15.8-17.3,23.8c-4.4,6.3-8.5,12.8-12.7,19.2
c-5.4,8.2-10.9,16.3-16.1,24.6c-4.4,6.9-8.5,14-12.8,20.9c-3.6,5.9-7.2,11.7-10.8,17.5c-5.1,8.2-10.1,16.4-15.3,24.6
c-2.9,4.7-6,9.3-9,14c-7,11-14,22.1-21,33.1c-6,9.3-12.2,18.6-18.2,27.9c-5.9,9-11.8,18.1-17.7,27.1c-6.4,9.7-12.8,19.3-19.4,28.9
c-6.2,9-12.5,18-18.9,26.9c-5.8,8.1-11.9,16-17.8,24.1c-5.4,7.4-10.7,14.8-16.3,22.1c-3.5,4.6-7.6,8.7-11,13.3
c-5.5,7.3-12,13.7-18.2,20.3c-3.4,3.6-7.2,6.7-10.5,10.3c-1.9,2-2.9,1.9-4.6,0.3c-1.7-1.7-1.8-3.4-0.4-5.2c1.4-1.8,2.9-3.6,4.4-5.3
c4.3-5,8.8-9.9,12.9-15c6.5-8,12.5-16.4,17.8-25.2c5.3-8.8,10.6-17.6,15.8-26.5c5.1-8.7,10.1-17.5,15.1-26.4
c2.2-3.8,4.2-7.8,6.2-11.7c4.4-8.4,8.8-16.9,13.2-25.3c5.4-10.3,10.7-20.7,16-31c13.8-27.2,28-54.2,41.3-81.7
c10-20.8,20.5-41.4,30.6-62.1c4.2-8.7,8.3-17.4,12.6-26c5.1-10.2,10.4-20.4,15.7-30.5c4.3-8.1,8.6-16.2,13.1-24.2
c7.5-13,15.3-25.9,22.8-38.9c8.1-14,17.4-27.3,26.4-40.7c5.2-7.7,11.1-15,16.8-22.4c3.2-4.2,6.2-8.4,9.6-12.5
c3-3.7,6.3-7.2,9.6-10.7c3.7-3.9,7.5-7.6,11.3-11.3c13.6-13.4,29.2-23.9,46.6-31.6c12.2-5.4,24.8-9.6,37.9-12.4
c6.6-1.4,13.4-2.4,20.2-3.4c14.5-2.1,29-1.7,43.5-1.8c4.7,1.5,9.8,0.4,14.5,1.9c2.6,0.8,5.5,0.8,8.2,1.1c7.3,0.9,14.4,2.5,21.4,4.4
c11.6,3.1,22.9,7.3,33.9,12.1c8.1,3.5,15.7,8.1,23.6,12.2c6.8,3.6,13.2,7.8,19.5,12.3c3.6,2.6,7.3,5,10.6,7.9
c7,6.1,14.2,12,20.5,18.7c6.6,6.9,12.9,14,18.4,21.8c3.7,5.4,7.6,10.6,11.1,16.2c5.3,8.7,10,17.6,14.1,26.9c3,6.9,5.6,13.8,7.9,21
c2.4,7.6,4.7,15.1,5.8,23.1c0.7,4.6,2.2,9.1,2.8,13.8c0.7,5.2,0.7,10.5,1.1,15.7c0.1,1-0.7,2.4,1,2.9V396z"/>
<path d="M39,638c3.4-2.4,4-2.5,7,0.5c3.4,3.4,6.5,7.1,9.6,10.7c1.4,1.6,2.6,3.4,4.1,4.9c3.1,3.2,6.2,6.5,9.6,9.5
c7.6,6.8,15.1,13.7,23.4,19.7c8.4,6.1,17,11.7,26.4,16.1c7.7,3.6,15.7,6.1,24.1,7.6c5.2,0.9,10.3,1.8,15.5,2.2
c2.7,0.2,5.5,0.7,8.3,0.8c7.2,0.1,14.4-0.9,21.5-1.8c7.6-1,15-2.8,22.2-5.3c12.4-4.3,24.1-10,34.5-18.3c4.5-3.6,9.1-7.1,13.1-11.3
c4.8-5,9.8-9.7,14.7-14.7c6.7-6.8,12.9-14.1,18.7-21.7c5.2-6.8,10.8-13.2,15.9-20.1c6.4-8.8,12.5-18,18.6-27.1
c6.6-9.9,13.2-19.9,19.5-30c4.6-7.3,8.9-14.9,13.3-22.3c3.9-6.6,8-13.1,11.8-19.8c3.5-6.1,6.9-12.3,10.3-18.4
c3.5-6.1,7-12.2,10.5-18.3c2-3.6,3.9-7.2,5.9-10.8c4.2-7.6,8.3-15.2,12.6-22.8c5.3-9.4,10.7-18.7,16-28.1c3.6-6.4,7-13,10.6-19.4
c5.6-9.8,11.4-19.5,17.1-29.2c3.8-6.5,7.5-13,11.3-19.5c3.3-5.6,6.6-11.3,10.2-16.7c8.2-12.4,16.4-24.8,24.8-37.1
c4.9-7.2,10-14.1,15.2-21c4.7-6.3,9.6-12.5,14.6-18.6c2.9-3.6,6.2-6.9,9.3-10.3c3.2-3.6,6.3-7.3,9.7-10.6
c7.8-7.6,15.9-14.8,24.4-21.7c7.3-5.9,15-11.1,22.7-16.4c2.8-1.9,5.9-3.4,8.9-5.1c7.4-4.1,15.1-7.9,23-10.9
c8.2-3.2,16.5-6,24.8-8.8c7.2-2.4,14.7-4,22.2-5.3c3.8-0.6,7.5-0.4,11.3-0.8c1.9-0.2,2.2,1.2,2.7,2.3c0.6,1.4,0.9,3-0.5,4.1
c-0.9,0.7-2,1.1-3,1.6c-14,7.2-27.3,15.5-39.7,25.1c-4.8,3.7-9.5,7.6-13.9,11.9c-2.5,2.4-5.4,4.4-7.8,6.9
c-5.6,6-11.1,12.2-16.5,18.4c-5.5,6.3-11,12.7-16.2,19.3c-5.2,6.5-10.3,13.2-15,20c-9.3,13.4-18.6,26.9-27.6,40.5
c-6,9.1-11.6,18.5-17.4,27.8c-5.2,8.3-10.4,16.6-15.5,25c-3.8,6.3-7.4,12.7-11.1,19.1c-5.9,10-12,19.9-17.8,29.9
c-4.1,6.9-7.9,13.9-12,20.8c-3.4,5.8-6.8,11.5-10.2,17.3c-2.9,4.9-5.8,9.9-8.8,14.7c-6.3,10.3-12.6,20.6-18.9,31
c-5.9,9.8-11.7,19.6-17.8,29.3c-5.7,9.1-11.7,18.1-17.7,27.1c-4.2,6.4-8.5,12.8-13,19.1c-6.5,9.2-13,18.4-19.6,27.6
c-5.3,7.3-10.5,14.6-15.9,21.7c-3.3,4.3-6.9,8.4-10.4,12.6c-4.4,5.3-8.7,10.7-13.1,16c-0.1,0.1-0.2,0.2-0.3,0.4
c-10.6,11-20.9,22.3-32.1,32.8c-6.3,5.9-13.5,10.8-21.3,14.8c-5.2,2.7-10.3,5.9-15.6,8.3c-12.4,5.7-25.2,10.5-38.5,13.6
c-5.9,1.3-11.8,2.3-17.7,3.2c-9.8,1.5-19.6,1-29.3,0.6c-8.2-0.4-16.4-2-24.4-4.2c-14.1-3.8-27.5-9.3-40.2-16.2
c-7.3-4-14.2-8.7-20.8-13.8c-5.4-4.1-10.2-9-15.4-13.1c-5.9-4.7-10.4-10.6-15.4-16.1c-6.9-7.6-13.1-15.9-18.4-24.8
c-0.1-0.2-0.5-0.3-0.8-0.5C39,640.7,39,639.3,39,638z"/>
<path d="M909.2,422c-0.4-5.7-0.4-11.6-1.3-17.2c-1.8-11.4-4-22.7-8.2-33.5c-5-12.5-12-23.9-20.3-34.6c-6-7.7-12.4-15.1-19.8-21.5
c-8.1-7.1-16.2-14.3-25.9-19.4c-4.9-2.6-9.5-5.8-14.5-8.2c-12.4-5.8-25.2-10.5-38.5-13.7c-5.8-1.4-11.7-2.6-17.5-4.1
c-1.2-0.3-3-0.4-3.2-2.5c-0.2-2.7,0-3.7,2.7-4.6c4.4-1.5,9-2.6,13.5-3.8c5.2-1.4,10.6-1.5,15.8-3c0.2,0,0.3,0,0.5,0
c6.9-0.3,13.9-1.5,20.7-0.8c6.9,0.7,13.9,0.9,20.8,2.5c6.6,1.5,13.3,2.9,19.7,5.4c11.8,4.5,22.9,10.3,33.1,18
c8.7,6.5,16.2,14.2,23.6,22c4.1,4.4,7.6,9.5,10.5,14.8c5.5,9.8,9.8,20.2,12.2,31.3c1,4.6,1.5,9.3,2.2,14c0.6,4.1,0.7,8.2,0.8,12.3
c0.1,7.6-1.3,14.9-2.8,22.3c-1.6,8.1-4.1,15.8-8.2,22.9c-2.6,4.5-5.5,8.8-8.5,13.2c-0.6,0.9-1.8,1.3-2.8,1.9
c-1.4,0.8-2.7,0.4-3.4-0.9c-0.7-1.4-1.2-3.1-1.3-4.6c-0.2-2.6-0.1-5.3-0.1-8C909.1,422.1,909.1,422.1,909.2,422z"/>
<path d="M754.9,685c-4.6,0-7.7,0.1-10.9,0c-6.4-0.3-12.9-0.1-19.2-1.1c-13.9-2.1-27.8-4.4-41.4-8.5c-9.8-3-19.6-6-29-9.8
c-10.5-4.2-20.6-9.2-30.7-14.3c-16.1-8.3-31.2-18.4-46.3-28.5c-3.4-2.3-6.5-5-9.8-7.5c-1.3-1-2.1-3.5-1.6-4.6
c0.7-1.4,4.2-2.2,5.8-1.2c3.2,1.9,6.5,3.8,9.7,5.8c6.1,3.6,12.1,7.3,18.2,10.7c8.4,4.7,16.9,9.4,25.5,13.7
c15.5,7.6,31.4,14.2,48,19.3c9.3,2.9,18.7,5.3,28.3,7.1c6.7,1.3,13.5,2.3,20.3,3.1c3.9,0.5,7.9,0.2,11.8,1
c8.1,1.6,16.2,0.7,24.3,0.8c6.7,0,13.5-0.2,20.2-1c7.3-0.9,14.6-1.7,21.8-3c8.4-1.6,16.6-4.1,25-6.2c10.6-2.6,20.7-6.7,30.7-11
c8.9-3.8,17.2-8.9,25.8-13.3c9.7-4.9,18.5-11.1,27.3-17.3c4.3-3,8.5-6,12.8-9c1.4-1,3.3-0.7,4.7,0.6c1.1,1.1,1.3,3.1,0.2,4.5
c-0.6,0.8-1.3,1.5-2.1,2.1c-4.9,3.9-9.7,7.8-14.6,11.6c-5.6,4.3-11.1,8.7-16.8,12.8c-7.9,5.6-16,10.7-24.5,15.3
c-10,5.5-20.5,10-31.1,14.1c-9.4,3.7-19.2,5.9-28.8,8.7c-4.3,1.2-9,1.3-13.5,2.2c-5.8,1.2-11.7,1.3-17.5,2.2
C769.4,685.4,761.5,684.4,754.9,685z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

@@ -0,0 +1,40 @@
// @flow
import * as React from 'react'
import Img from '~/components/layout/Img'
import Span from '~/components/layout/Span'
import { upperFirst } from '~/utils/css'
const IconParity = require('~/components/Header/assets/icon_parity.svg')
const IconMetamask = require('~/components/Header/assets/icon_metamask.svg')
type Props = {
provider: string,
}
const PROVIDER_METAMASK = 'METAMASK'
const PROVIDER_PARITY = 'PARITY'
const PROVIDER_ICONS = {
[PROVIDER_METAMASK]: IconMetamask,
[PROVIDER_PARITY]: IconParity,
}
const Connected = ({ provider }: Props) => {
const msg = `You are using ${upperFirst(provider.toLowerCase())} to connect to your Safe`
return (
<React.Fragment>
{ PROVIDER_ICONS[provider] &&
<Img
height={40}
src={PROVIDER_ICONS[provider]}
title={msg}
alt={msg}
/>
}
<Span>Connected</Span>
</React.Fragment>
)
}
export default Connected
@@ -0,0 +1,30 @@
// @flow
import React from 'react'
import Col from '~/components/layout/Col'
import Img from '~/components/layout/Img'
import Refresh from '~/components/Refresh'
import Row from '~/components/layout/Row'
import Connected from './Connected'
import NotConnected from './NotConnected'
const logo = require('../assets/gnosis_logo.svg')
type Props = {
provider: string,
reloadWallet: Function,
}
const Header = ({ provider, reloadWallet }: Props) => (
<Row>
<Col xs={12} center="xs" sm={6} start="sm" margin="lg">
<Img src={logo} height={40} alt="Gnosis Safe" />
</Col>
<Col xs={12} center="xs" sm={6} end="sm" margin="lg">
{ provider ? <Connected provider={provider} /> : <NotConnected /> }
<Refresh callback={reloadWallet} />
</Col>
</Row>
)
export default Header
@@ -0,0 +1,20 @@
// @flow
import { select } from '@storybook/addon-knobs'
import { storiesOf } from '@storybook/react'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('Header', () => {
// https://github.com/storybooks/storybook/tree/master/addons/knobs#select
const provider = select('Status by Provider', ['', 'UNKNOWN', 'METAMASK', 'PARITY'], 'METAMASK')
return <Component provider={provider} reloadWallet={() => {}} />
})
@@ -0,0 +1,5 @@
// @flow
import React from 'react'
import Span from '~/components/layout/Span'
export default () => <Span>Not Connected</Span>
+28 -9
View File
@@ -1,11 +1,30 @@
import React from 'react'
import styles from './index.scss';
// @flow
import * as React from 'react'
import { connect } from 'react-redux'
import Layout from './component/Layout'
import actions from './actions'
import selector from './selector'
const Header = () => (
<header className={styles.header}>
<h1>GNOSIS DAPP BOILERPLATE</h1>
<div>Multisig 2.0</div>
</header>
)
type Props = {
provider: string,
fetchProvider: Function,
}
export default Header
class Header extends React.PureComponent<Props> {
componentDidMount() {
this.props.fetchProvider()
}
reloadWallet = () => {
this.props.fetchProvider()
}
render() {
const { provider } = this.props
return (
<Layout provider={provider} reloadWallet={this.reloadWallet} />
)
}
}
export default connect(selector, actions)(Header)
-11
View File
@@ -1,11 +0,0 @@
.header {
display: grid;
grid-template-columns: auto auto;
grid-column-gap: 20px;
align-items: center;
margin: 0 20px;
}
.subtitle {
justify-self: center;
}
+7
View File
@@ -0,0 +1,7 @@
// @flow
import { createStructuredSelector } from 'reselect'
import { providerNameSelector } from '~/wallets/store/selectors/index'
export default createStructuredSelector({
provider: providerNameSelector,
})
+15
View File
@@ -0,0 +1,15 @@
// @flow
import { storiesOf } from '@storybook/react'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import Component from './index'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
storiesOf('Components', module)
.addDecorator(FrameDecorator)
.add('Loader', () => <Component />)
+16
View File
@@ -0,0 +1,16 @@
// @flow
import * as React from 'react'
import Page from '~/components/layout/Page'
import { CircularProgress } from 'material-ui/Progress'
const centerStyle = {
margin: 'auto 0',
}
const Loader = () => (
<Page align="center">
<CircularProgress style={centerStyle} size={60} />
</Page>
)
export default Loader
+27
View File
@@ -0,0 +1,27 @@
// @flow
import * as React from 'react'
import Bold from '~/components/layout/Bold'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import Paragraph from '~/components/layout/Paragraph/index'
import { CreateSafe } from '~/routes/welcome/components/Layout'
type Props = {
text: string,
provider: string,
}
const NoSafe = ({ text, provider }: Props) => (
<Row>
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
<Paragraph size="lg">
<Bold>{text}</Bold>
</Paragraph>
</Col>
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
<CreateSafe provider={provider} />
</Col>
</Row>
)
export default NoSafe
+47
View File
@@ -0,0 +1,47 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import RefreshIcon from 'material-ui-icons/Refresh'
import { sm, secondary } from '~/theme/variables'
type Props = {
callback: () => void,
}
type State = {
loading: boolean,
}
const loaderStyle = {
margin: `0px 0px 0px ${sm}`,
color: secondary,
}
class Loader extends React.Component<Props, State> {
constructor() {
super()
this.state = {
loading: false,
}
}
onReload = async () => {
this.setState({ loading: true }, await this.props.callback())
this.setState({ loading: false })
}
render() {
const { loading } = this.state
return (
<div style={loaderStyle}>
{loading
? <CircularProgress color="inherit" size={24} />
: <RefreshIcon color="inherit" onClick={this.onReload} /> }
</div>
)
}
}
export default Loader
+75
View File
@@ -0,0 +1,75 @@
// @flow
import * as React from 'react'
import Button from '~/components/layout/Button'
import Link from '~/components/layout/Link'
import { SAFELIST_ADDRESS } from '~/routes/routes'
type NextButtonProps = {
text: string,
disabled: boolean,
}
const NextButton = ({ text, disabled }: NextButtonProps) => (
<Button
variant="raised"
color="primary"
type="submit"
disabled={disabled}
>
{text}
</Button>
)
const GoButton = () => (
<Link to={SAFELIST_ADDRESS}>
<NextButton text="VISIT SAFES" disabled={false} />
</Link>
)
type ControlProps = {
next: string,
onPrevious: () => void,
firstPage: boolean,
submitting: boolean,
}
const ControlButtons = ({
next, firstPage, onPrevious, submitting,
}: ControlProps) => (
<React.Fragment>
<Button
type="button"
disabled={firstPage || submitting}
onClick={onPrevious}
>
Back
</Button>
<NextButton text={next} disabled={submitting} />
</React.Fragment>
)
type Props = {
finishedTx: boolean,
onPrevious: () => void,
firstPage: boolean,
lastPage: boolean,
submitting: boolean,
}
const Controls = ({
finishedTx, onPrevious, firstPage, lastPage, submitting,
}: Props) => (
<React.Fragment>
{ finishedTx
? <GoButton />
: <ControlButtons
submitting={submitting}
next={lastPage ? 'Finish' : 'Next'}
firstPage={firstPage}
onPrevious={onPrevious}
/>
}
</React.Fragment>
)
export default Controls
+14
View File
@@ -0,0 +1,14 @@
// @flow
import * as React from 'react'
type Props = {
children: React$Node,
}
const Step = ({ children }: Props) => (
<div>
{children}
</div>
)
export default Step
+118
View File
@@ -0,0 +1,118 @@
// @flow
import Stepper, { Step as FormStep, StepLabel } from 'material-ui/Stepper'
import * as React from 'react'
import type { FormApi } from 'react-final-form'
import GnoForm from '~/components/forms/GnoForm'
import Col from '~/components/layout/Col'
import Row from '~/components/layout/Row'
import Controls from './Controls'
export { default as Step } from './Step'
type Props = {
steps: string[],
finishedTransaction: boolean,
initialValues?: Object,
children: React$Node,
onSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void,
}
type State = {
page: number,
values: Object,
}
type PageProps = {
children: Function,
}
class GnoStepper extends React.PureComponent<Props, State> {
static Page = ({ children }: PageProps) => children
constructor(props: Props) {
super(props)
this.state = {
page: 0,
values: props.initialValues || {},
}
}
getActivePageFrom = (pages: React$Node) => {
const activePageProps = React.Children.toArray(pages)[this.state.page].props
const { children, ...props } = activePageProps
return children(props)
}
validate = (values: Object) => {
const activePage = React.Children.toArray(this.props.children)[
this.state.page
]
return activePage.props.validate ? activePage.props.validate(values) : {}
}
next = (values: Object) =>
this.setState(state => ({
page: Math.min(state.page + 1, React.Children.count(this.props.children) - 1),
values,
}))
previous = () =>
this.setState(state => ({
page: Math.max(state.page - 1, 0),
}))
handleSubmit = (values: Object) => {
const { children, onSubmit } = this.props
const { page } = this.state
const isLastPage = page === React.Children.count(children) - 1
if (isLastPage) {
return onSubmit(values)
}
return this.next(values)
}
render() {
const { steps, children, finishedTransaction } = this.props
const { page, values } = this.state
const activePage = this.getActivePageFrom(children)
const isLastPage = page === steps.length - 1
return (
<React.Fragment>
<Stepper activeStep={page} alternativeLabel>
{steps.map(label => (
<FormStep key={label}>
<StepLabel>{label}</StepLabel>
</FormStep>
))}
</Stepper>
<GnoForm
onSubmit={this.handleSubmit}
initialValues={values}
padding={15}
validation={this.validate}
render={activePage}
>
{(submitting: boolean) => (
<Row align="end" margin="lg" grow>
<Col xs={12} center="xs">
<Controls
submitting={submitting}
finishedTx={finishedTransaction}
onPrevious={this.previous}
firstPage={page === 0}
lastPage={isLastPage}
/>
</Col>
</Row>
)}
</GnoForm>
</React.Fragment>
)
}
}
export default GnoStepper
+4
View File
@@ -0,0 +1,4 @@
// @flow
import { Field } from 'react-final-form'
export default Field
+38
View File
@@ -0,0 +1,38 @@
// @flow
import * as React from 'react'
import { Form } from 'react-final-form'
import type { FormApi } from 'react-final-form'
type Props = {
onSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void,
children: Function,
padding: number,
validation?: (values: Object) => Object | Promise<Object>,
initialValues?: Object,
render: Function,
}
const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
padding: `0 ${padding}%`,
display: 'flex',
flexDirection: 'column',
flex: '1 0 auto',
})
const GnoForm = ({
onSubmit, validation, initialValues, children, padding, render,
}: Props) => (
<Form
validate={validation}
onSubmit={onSubmit}
initialValues={initialValues}
render={({ handleSubmit, ...rest }) => (
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
{render(rest)}
{children(rest.submitting)}
</form>
)}
/>
)
export default GnoForm
+36 -17
View File
@@ -1,21 +1,40 @@
// @flow
import React from 'react'
import { default as MuiTextField } from 'material-ui/TextField'
import MuiTextField, { TextFieldProps } from 'material-ui/TextField'
const TextField = ({
input: { name, onChange, value, ...restInput },
meta,
render,
...rest
}) => (
<MuiTextField
{...rest}
name={name}
helperText={meta.touched ? meta.error : undefined}
error={meta.error && meta.touched}
inputProps={restInput}
onChange={onChange}
value={value}
/>
)
// Neded for solving a fix in Windows browsers
const overflowStyle = {
overflow: 'hidden',
}
class TextField extends React.PureComponent<TextFieldProps> {
render() {
const {
input: {
name, onChange, value, ...restInput
},
meta,
render,
text,
...rest
} = this.props
const helperText = value ? text : undefined
const showError = (meta.touched || !meta.pristine) && !meta.valid
return (
<MuiTextField
style={overflowStyle}
{...rest}
name={name}
helperText={showError ? meta.error : helperText}
error={meta.error && (meta.touched || !meta.pristine)}
inputProps={restInput}
onChange={onChange}
value={value}
fullWidth
/>
)
}
}
export default TextField
+41
View File
@@ -0,0 +1,41 @@
// @flow
import { getWeb3 } from '~/wallets/getWeb3'
type Field = boolean | string
export const required = (value: Field) => (value ? undefined : 'Required')
export const mustBeNumber = (value: number) =>
(Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
export const minValue = (min: number) => (value: string) => {
if (Number.isNaN(Number(value)) || Number.parseInt(value, 10) >= Number(min)) {
return undefined
}
return `Should be at least ${min}`
}
export const maxValue = (max: number) => (value: string) => {
if (Number.isNaN(Number(value)) || Number.parseInt(value, 10) <= Number(max)) {
return undefined
}
return `Maximum value is ${max}`
}
export const ok = () => undefined
export const mustBeEthereumAddress = (address: Field) => {
const isAddress: boolean = getWeb3().isAddress(address)
return isAddress ? undefined : 'Address should be a valid Ethereum address'
}
export const ADDRESS_REPEATED_ERROR = 'Address already introduced'
export const uniqueAddress = (addresses: string[]) => (value: string) =>
(addresses.includes(value) ? ADDRESS_REPEATED_ERROR : undefined)
export const composeValidators = (...validators: Function[]) => (value: Field) =>
validators.reduce((error, validator) => error || validator(value), undefined)
+34
View File
@@ -0,0 +1,34 @@
// @flow
import classNames from 'classnames/bind'
import React, { PureComponent } from 'react'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Size = 'sm' | 'md' | 'lg' | 'xl'
type Props = {
margin?: Size,
padding?: Size,
center?: boolean,
children: React$Node,
className?: string,
}
class Block extends PureComponent<Props> {
render() {
const {
margin, padding, center, children, className, ...props
} = this.props
const paddingStyle = padding ? capitalize(padding, 'padding') : undefined
return (
<div className={cx(className, 'block', margin, paddingStyle, { center })} {...props}>
{ children }
</div>
)
}
}
export default Block
+43
View File
@@ -0,0 +1,43 @@
.block {
display: inline-block;
width: 100%;
overflow: hidden;
}
.sm {
margin-bottom: $sm;
}
.md {
margin-bottom: $md;
}
.lg {
margin-bottom: $lg;
}
.xl {
margin-bottom: $xl;
}
.paddingSm {
padding-top: $sm;
}
.paddingMd {
padding-top: $md;
}
.paddingLg {
padding-top: $lg;
}
.paddingXl {
padding-top: $xl;
}
.center {
display: flex;
align-items: center;
justify-content: center;
}
+20
View File
@@ -0,0 +1,20 @@
// @flow
import * as React from 'react'
type Props = {
children: React$Node,
}
class Bold extends React.PureComponent<Props> {
render() {
const { children, ...props } = this.props
return (
<b {...props}>
{ children }
</b>
)
}
}
export default Bold
+4
View File
@@ -0,0 +1,4 @@
// @flow
import Button from 'material-ui/Button'
export default Button
+67
View File
@@ -0,0 +1,67 @@
// @flow
import classNames from 'classnames/bind'
import React from 'react'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
start?: 'xs' | 'sm' | 'md' | 'lg',
center?: 'xs' | 'sm' | 'md' | 'lg',
end?: 'xs' | 'sm' | 'md' | 'lg',
top?: 'xs' | 'sm' | 'md' | 'lg',
middle?: 'xs' | 'sm' | 'md' | 'lg',
bottom?: 'xs' | 'sm' | 'md' | 'lg',
around?: 'xs' | 'sm' | 'md' | 'lg',
between?: 'xs' | 'sm' | 'md' | 'lg',
margin?: 'sm' | 'md' | 'lg' | 'xl',
xs?: number | boolean,
sm?: number | boolean,
md?: number | boolean,
lg?: number | boolean,
xsOffset?: number,
smOffset?: number,
mdOffset?: number,
lgOffset?: number,
className?: string,
children: React$Node,
}
const Col = ({
children, margin,
xs, sm, md, lg,
start, center, end, top, middle, bottom, around, between,
xsOffset, smOffset, mdOffset, lgOffset,
...props
}: Props) => {
const colClassNames = cx(
'col',
start ? capitalize(start, 'start') : undefined,
center ? capitalize(center, 'center') : undefined,
end ? capitalize(end, 'end') : undefined,
top ? capitalize(top, 'top') : undefined,
middle ? capitalize(middle, 'middle') : undefined,
bottom ? capitalize(bottom, 'bottom') : undefined,
around ? capitalize(around, 'around') : undefined,
between ? capitalize(between, 'between') : undefined,
margin ? capitalize(margin, 'margin') : undefined,
xs ? capitalize(xs, 'xs') : undefined,
sm ? capitalize(sm, 'sm') : undefined,
md ? capitalize(md, 'md') : undefined,
lg ? capitalize(lg, 'lg') : undefined,
xsOffset ? capitalize(xsOffset, 'xsOffset') : undefined,
smOffset ? capitalize(smOffset, 'smOffset') : undefined,
mdOffset ? capitalize(mdOffset, 'mdOffset') : undefined,
lgOffset ? capitalize(lgOffset, 'lgOffset') : undefined,
props.className,
)
return (
<div className={colClassNames} {...props}>
{ children }
</div>
)
}
export default Col
+199
View File
@@ -0,0 +1,199 @@
.col {
flex: 1 1 auto;
display: flex;
align-items: center;
}
.marginSm {
margin-bottom: $sm;
}
.marginMd {
margin-bottom: $md;
}
.marginLg {
margin-bottom: $xl;
}
.marginXl {
margin-bottom: $xl;
}
@define-mixin col $size {
.$(size)1 {
flex-basis: 8.333%;
max-width: 8.333%;
}
.$(size)2 {
flex-basis: 16.667%;
max-width: 16.667%;
}
.$(size)3 {
flex-basis: 25%;
max-width: 25%;
}
.$(size)4 {
flex-basis: 33.333%;
max-width: 33.333%;
}
.$(size)5 {
flex-basis: 41.667%;
max-width: 41.667%;
}
.$(size)6 {
flex-basis: 50%;
max-width: 50%;
}
.$(size)7 {
flex-basis: 58.333%;
max-width: 58.333%;
}
.$(size)8 {
flex-basis: 66.667%;
max-width: 66.667%;
}
.$(size)9 {
flex-basis: 75%;
max-width: 75%;
}
.$(size)10 {
flex-basis: 83.333%;
max-width: 83.333%;
}
.$(size)11 {
flex-basis: 91.667%;
max-width: 91.667%;
}
.$(size)12 {
flex-basis: 100%;
max-width: 100%;
}
.$(size)Offset1 {
margin-left: 8.333%;
}
.$(size)Offset2 {
margin-left: 16.667%;
}
.$(size)Offset3 {
margin-left: 25%;
}
.$(size)Offset4 {
margin-left: 33.333%;
}
.$(size)Offset5 {
margin-left: 41.667%;
}
.$(size)Offset6 {
margin-left: 50%;
}
.$(size)Offset7 {
margin-left: 58.333%;
}
.$(size)Offset8 {
margin-left: 66.667%;
}
.$(size)Offset9 {
margin-left: 75%;
}
.$(size)Offset10 {
margin-left: 83.333%;
}
.$(size)Offset11 {
margin-left: 91.667%;
}
}
@define-mixin autoWidth $size {
.$(size) {
-ms-flex-positive: 1;
flex-grow: 1;
-ms-flex-preferred-size: 0;
flex-basis: 0;
max-width: 100%;
}
}
@mixin col xs;
@mixin autoWidth xs;
@media only screen and (min-width: $(screenSm)px) {
@mixin col sm;
@mixin autoWidth sm;
}
@media only screen and (min-width: $(screenMd)px) {
@mixin col md;
@mixin autoWidth md;
}
@media only screen and (min-width: $(screenLg)px) {
@mixin col lg;
@mixin autoWidth lg;
}
@define-mixin row $size {
.start$(size) {
justify-content: flex-start;
text-align: start;
}
.center$(size) {
justify-content: center;
text-align: center;
}
.end$(size) {
justify-content: flex-end;
text-align: end;
}
.top$(size) {
align-items: flex-start;
}
.middle$(size) {
align-items: center;
}
.bottom$(size) {
align-items: flex-end;
}
.around$(size) {
justify-content: space-around;
}
.between$(size) {
justify-content: space-between;
}
}
@mixin row Xs;
@media only screen and (min-width: $(screenSm)px) {
@mixin row Sm;
}
@media only screen and (min-width: $(screenMd)px) {
@mixin row Md;
}
@media only screen and (min-width: $(screenLg)px) {
@mixin row Lg;
}
+37
View File
@@ -0,0 +1,37 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
const cx = classNames.bind(styles)
type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4';
type Props = {
align?: 'left' | 'center' | 'right',
margin?: 'sm' | 'md' | 'lg',
tag: HeadingTag,
truncate?: boolean,
children: React$Node,
}
class Heading extends React.PureComponent<Props> {
render() {
const {
align, tag, truncate, margin, children, ...props
} = this.props
const className = cx(
'heading',
align,
tag,
margin ? capitalize(margin, 'margin') : undefined,
{ truncate },
)
return React.createElement(tag, { ...props, className }, children)
}
}
export default Heading
+47
View File
@@ -0,0 +1,47 @@
.heading {
font-weight: $boldFontWeight;
line-height: normal;
margin: 0;
}
.h1 {
font-size: $(fontSizeHeadingLg)px;
}
.h2 {
font-size: $(fontSizeHeadingMd)px;
}
.h3 {
font-size: $(fontSizeHeadingSm)px;
}
.h4 {
font-size: $(fontSizeHeadingXs)px;
}
.center {
text-align: center;
}
.right {
text-align: right;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.marginSm {
margin: 0 0 $sm 0;
}
.marginMd {
margin: 0 0 $md 0;
}
.marginLg {
margin: 0 0 $lg 0;
}
+33
View File
@@ -0,0 +1,33 @@
// @flow
import classNames from 'classnames/bind'
import React, { PureComponent } from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
alt: string,
fullwidth?: boolean,
bordered?: boolean,
className?: string,
style?: React$Node
}
class Img extends PureComponent<Props> {
render() {
const {
fullwidth, alt, bordered, className, style, ...props
} = this.props
return (
<img
alt={alt}
style={style}
{...props}
className={cx(styles.img, { fullwidth, bordered }, className)}
/>
)
}
}
export default Img
+14
View File
@@ -0,0 +1,14 @@
.img {
max-width: 100%;
box-sizing: border-box;
}
.bordered {
border: 1px solid #ddd;
}
.fullwidth {
padding: 0;
width: 40% !important;
margin: 0 60% 25px !important;
}
+35
View File
@@ -0,0 +1,35 @@
// @flow
import classNames from 'classnames/bind'
import React from 'react'
import { Link } from 'react-router-dom'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
padding?: 'xs' | 'sm' | 'md',
to: string,
children: React$Node,
color?: 'regular' | 'white',
className?: string,
}
const GnosisLink = ({
to, children, color, className, padding, ...props
}: Props) => {
const classes = cx(
styles.link,
color || 'regular',
padding ? capitalize(padding, 'padding') : undefined,
className,
)
return (
<Link className={classes} to={to} {...props}>
{ children }
</Link>
)
}
export default GnosisLink
+23
View File
@@ -0,0 +1,23 @@
.link {
text-decoration: none;
}
.regular {
color: $secondary;
}
.white {
color: white;
}
.paddingXs {
padding-right: $xs;
}
.paddingSm {
padding-right: $sm;
}
.paddingMd {
padding-right: $md;
}
+14 -6
View File
@@ -1,12 +1,20 @@
// @flow
import classNames from 'classnames/bind'
import React from 'react'
import Header from '../../Header'
import styles from './index.scss';
import styles from './index.scss'
const Page = ({children}) => (
<div className={styles.page}>
<Header />
const cx = classNames.bind(styles)
type Props = {
children: React$Node,
align?: 'center',
overflow?: boolean
}
const Page = ({ children, align, overflow }: Props) => (
<main className={cx(styles.page, align, { overflow })}>
{children}
</div>
</main>
)
export default Page
+11 -1
View File
@@ -1,3 +1,13 @@
.page {
margin: 0px 30px;
display: flex;
flex-direction: column;
flex: 1 0 auto;
}
.center {
align-self: center;
}
.overflow {
overflow-x: scroll;
}
+14 -5
View File
@@ -1,10 +1,19 @@
// @flow
import React from 'react'
import styles from './index.scss';
import Footer from '~/components/Footer'
import Header from '~/components/Header'
import styles from './index.scss'
const PageFrame = ({ children }) => (
<main className={styles.container}>
{ children }
</main>
type Props = {
children: React$Node,
}
const PageFrame = ({ children }: Props) => (
<div className={styles.frame}>
<Header />
{children}
<Footer />
</div>
)
export default PageFrame
+7 -3
View File
@@ -1,3 +1,7 @@
.container {
margin: 0px 20px;
}
.frame {
display: flex;
flex-direction: column;
flex: 1 0 auto;
background-color: white;
padding: $xl;
}
+31
View File
@@ -0,0 +1,31 @@
// @flow
import * as React from 'react'
import classNames from 'classnames/bind'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
center?: boolean,
noMargin?: boolean,
bold?: boolean,
size?: 'sm' | 'md' | 'lg' | 'xl',
color?: 'soft' | 'medium' | 'dark' | 'primary',
children: React$Node
}
class Paragraph extends React.PureComponent<Props> {
render() {
const {
bold, children, color, center, size, noMargin, ...props
} = this.props
return (
<p className={cx(styles.paragraph, { bold }, { noMargin }, size, { center })} {...props}>
{ children }
</p>
)
}
}
export default Paragraph
@@ -0,0 +1,48 @@
.paragraph {
text-overflow: ellipsis;
overflow-x: inherit;
}
.soft {
color: #888888;
}
.medium {
color: #686868;
}
.dark {
color: black;
}
.primary {
color: #00a6c4;
}
.noMargin{
margin: 0;
}
.center {
text-align: center;
}
.sm {
font-size: $smallFontSize;
}
.md {
font-size: $mediumFontSize;
}
.lg {
font-size: $largeFontSize;
}
.lg {
font-size: $extraLargeFontSize;
}
.bold {
font-weight: bold;
}
+18
View File
@@ -0,0 +1,18 @@
// @flow
import classNames from 'classnames/bind'
import * as React from 'react'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
children: React$Node,
}
const Pre = ({ children, ...props }: Props) => (
<pre className={cx(styles.pre)} {...props}>
{children}
</pre>
)
export default Pre
+4
View File
@@ -0,0 +1,4 @@
.pre {
text-overflow: ellipsis;
overflow-x: hidden;
}
+35
View File
@@ -0,0 +1,35 @@
// @flow
import classNames from 'classnames/bind'
import React from 'react'
import { capitalize } from '~/utils/css'
import styles from './index.scss'
const cx = classNames.bind(styles)
type Props = {
className?: string,
children: React$Node,
margin?: 'sm' | 'md' | 'lg' | 'xl',
align?: 'center' | 'end' | 'start',
grow?: boolean,
}
const Row = ({
children, className, margin, align, grow, ...props
}: Props) => {
const rowClassNames = cx(
styles.row,
margin ? capitalize(margin, 'margin') : undefined,
align ? capitalize(align, 'align') : undefined,
{ grow },
className,
)
return (
<div className={rowClassNames} {...props}>
{ children }
</div>
)
}
export default Row
+36
View File
@@ -0,0 +1,36 @@
.row {
display: flex;
flex: 0 1 auto;
flex-direction: row;
flex-wrap: wrap;
}
.grow {
flex: 1 1 auto;
}
.marginSm {
margin-bottom: $sm;
}
.marginMd {
margin-bottom: $md;
}
.marginLg {
margin-bottom: $xl;
}
.marginXl {
margin-bottom: $xl;
}
.alignStart {
align-items: flex-start;
}
.alignEnd {
align-items: flex-end;
}
.alignCenter {
align-items: center;
}
+20
View File
@@ -0,0 +1,20 @@
// @flow
import React, { PureComponent } from 'react'
type Props = {
children: React$Node
}
class Span extends PureComponent<Props> {
render() {
const { children, ...props } = this.props
return (
<span {...props}>
{ children }
</span>
)
}
}
export default Span
+34
View File
@@ -0,0 +1,34 @@
// @flow
import * as React from 'react'
import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table'
export { TableBody, TableCell, TableHead, TableRow }
type Props = {
children: React$Node,
size?: number
}
const buildWidthFrom = (size: number) => ({
minWidth: `${size}px`,
})
const overflowStyle = {
overflowX: 'scroll',
}
// see: https://css-tricks.com/responsive-data-tables/
const GnoTable = ({ size, children }: Props) => {
const style = size ? buildWidthFrom(size) : undefined
return (
<div style={overflowStyle}>
<Table style={style}>
{children}
</Table>
</div>
)
}
export default GnoTable
+17 -4
View File
@@ -1,14 +1,27 @@
// @flow
import 'babel-polyfill'
import { MuiThemeProvider } from 'material-ui/styles'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import PageFrame from '~/components/layout/PageFrame'
import { history, store } from '~/store'
import theme from '~/theme/mui'
import App from './App'
import AppRoutes from '~/routes'
import './index.scss'
const Root = () => (
<MuiThemeProvider theme={theme}>
<App />
</MuiThemeProvider>
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<ConnectedRouter history={history}>
<PageFrame>
<AppRoutes />
</PageFrame>
</ConnectedRouter>
</MuiThemeProvider>
</Provider>
)
ReactDOM.render(
+30
View File
@@ -0,0 +1,30 @@
html, body {
height: 100%;
width: 100%;
}
body {
position: absolute;
bottom: 0;
top: 0;
left: 0;
right: 0;
overflow-x: hidden;
color: #1f5f76;
font-family: 'Montserrat', sans-serif;
font-size: $mediumFontSize;
margin: 0;
}
body>div:first-child {
display: flex;
flex: 1 1 auto;
flex-direction: column;
min-height: calc(100% - (2 * $xl));
padding: $xl;
background-image: linear-gradient(to bottom, $primary, #1a829d, #1a829d, #1f5f76);
}
h1, h2, h3 {
font-family: 'Montserrat', sans-serif;
}
+24 -11
View File
@@ -1,23 +1,36 @@
// @flow
import { CircularProgress } from 'material-ui/Progress'
import React from 'react'
import Loadable from 'react-loadable'
import { Switch, Redirect, Route } from 'react-router-dom'
import Welcome from './welcome/components/Layout'
import Loader from '~/components/Loader'
import Welcome from './welcome/container'
import { SAFELIST_ADDRESS, OPEN_ADDRESS, SAFE_PARAM_ADDRESS, WELCOME_ADDRESS } from './routes'
const Loading = () => <CircularProgress size={50} />
const Transactions = Loadable({
loader: () => import('./transactions/components/Layout'),
loading: Loading,
const Safe = Loadable({
loader: () => import('./safe/container'),
loading: Loader,
})
const SafeList = Loadable({
loader: () => import('./safeList/container'),
loading: Loader,
})
const Open = Loadable({
loader: () => import('./open/container/Open'),
loading: Loader,
})
const SAFE_ADDRESS = `${SAFELIST_ADDRESS}/:${SAFE_PARAM_ADDRESS}`
const Routes = () => (
<Switch>
<Redirect exact from="/" to="/welcome" />
<Route exact path='/welcome' component={Welcome} />
<Route exact path='/transactions' component={Transactions} />
</Switch>
<Redirect exact from="/" to={WELCOME_ADDRESS} />
<Route exact path={WELCOME_ADDRESS} component={Welcome} />
<Route exact path={OPEN_ADDRESS} component={Open} />
<Route exact path={SAFELIST_ADDRESS} component={SafeList} />
<Route exact path={SAFE_ADDRESS} component={Safe} />
</Switch>
)
export default Routes
@@ -0,0 +1,56 @@
// @flow
import * as React from 'react'
import { CircularProgress } from 'material-ui/Progress'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Col from '~/components/layout/Col'
import Paragraph from '~/components/layout/Paragraph'
import Pre from '~/components/layout/Pre'
import Row from '~/components/layout/Row'
type FormProps = {
submitting: boolean,
}
type Props = {
address: string,
tx: Object,
}
export const DEPLOYED_COMPONENT_ID = 'deployedSafeComponent'
const Deployment = ({ address, tx }: Props) => (
<Block className={DEPLOYED_COMPONENT_ID}>
<Paragraph><Bold>Deployed safe to: </Bold>{address}</Paragraph>
<Pre>
{JSON.stringify(tx, null, 2) }
</Pre>
</Block>
)
export default ({ address, tx }: Props) => ({ submitting }: FormProps) => {
const txFinished = !!address
return (
<Block>
{ !txFinished &&
<React.Fragment>
<Paragraph center size="lg">
You are about to create a Safe for keeping your funds more secure.
</Paragraph>
<Paragraph center size="lg">
Remember to check you have enough funds in your wallet.
</Paragraph>
</React.Fragment>
}
<Row>
<Col xs={12} center={submitting ? 'xs' : undefined} margin="lg">
{ submitting
? <CircularProgress size={50} />
: txFinished && <Deployment address={address} tx={tx} />
}
</Col>
</Row>
</Block>
)
}
+59
View File
@@ -0,0 +1,59 @@
// @flow
import * as React from 'react'
import type { FormApi } from 'react-final-form'
import Stepper from '~/components/Stepper'
import Confirmation from '~/routes/open/components/FormConfirmation'
import Review from '~/routes/open/components/ReviewInformation'
import SafeFields, { safeFieldsValidation } from '~/routes/open/components/SafeForm'
const getSteps = () => [
'Fill Safe Form', 'Review Information', 'Deploy it',
]
const initialValuesFrom = (userAccount: string) => ({
owner0Address: userAccount,
})
type Props = {
provider: string,
userAccount: string,
safeAddress: string,
safeTx: string,
onCallSafeContractSubmit: (values: Object, form: FormApi, callback: ?(errors: ?Object) => void)
=> ?Object | Promise<?Object> | void,
}
const Layout = ({
provider, userAccount, safeAddress, safeTx, onCallSafeContractSubmit,
}: Props) => {
const steps = getSteps()
const initialValues = initialValuesFrom(userAccount)
return (
<React.Fragment>
{ provider
? (
<Stepper
onSubmit={onCallSafeContractSubmit}
finishedTransaction={!!safeAddress}
steps={steps}
initialValues={initialValues}
>
<Stepper.Page validate={safeFieldsValidation}>
{ SafeFields }
</Stepper.Page>
<Stepper.Page>
{ Review }
</Stepper.Page>
<Stepper.Page address={safeAddress} tx={safeTx}>
{ Confirmation }
</Stepper.Page>
</Stepper>
)
: <div>No metamask detected</div>
}
</React.Fragment>
)
}
export default Layout
@@ -0,0 +1,60 @@
// @flow
import { storiesOf } from '@storybook/react'
import { State, Store } from '@sambego/storybook-state'
import * as React from 'react'
import styles from '~/components/layout/PageFrame/index.scss'
import { getAccountsFrom, getThresholdFrom } from '~/routes/open/utils/safeDataExtractor'
import { getProviderInfo } from '~/wallets/getWeb3'
import { sleep } from '~/utils/timer'
import Component from './Layout'
const FrameDecorator = story => (
<div className={styles.frame}>
{ story() }
</div>
)
const store = new Store({
safeAddress: '',
safeTx: '',
})
storiesOf('Routes /open', module)
.addDecorator(FrameDecorator)
.add('Open safe with all props set', () => {
getProviderInfo()
const provider = 'METAMASK'
const userAccount = '0x03db1a8b26d08df23337e9276a36b474510f0023'
const onCallSafeContractSubmit = async (values: Object) => {
const accounts = getAccountsFrom(values)
const numConfirmations = getThresholdFrom(values)
const data = {
userAccount,
accounts,
requiredConfirmations: numConfirmations,
}
// eslint-disable-next-line
console.log(`Generating and sending a eth tx based on: ${JSON.stringify(data, null, 2)}`)
await sleep(3000)
store.set({
safeAddress: '0x03db1a8b26d08df23337e9276a36b474510f0025',
// eslint-disable-next-line
safeTx: {"transactionHash":"0x4603de1ab6a92b4ee1fd67189089f5c02f5df5d135bf85af84083c27808c0544","transactionIndex":0,"blockHash":"0x593ce7d85fef2a492e8f759f485c8b66ff803773e77182c68dd45c439b7a956d","blockNumber":19,"gasUsed":3034193,"cumulativeGasUsed":3034193,"contractAddress":"0xfddda33736fb95b587cbfecc1ff4a50f717adc00","logs":[],"status":"0x01","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},
})
}
return (
<State store={store}>
<Component
provider={provider}
userAccount={userAccount}
safeAddress={store.get('safeAddress')}
safeTx={store.get('safeTx')}
onCallSafeContractSubmit={onCallSafeContractSubmit}
/>
</State>
)
})
+78
View File
@@ -0,0 +1,78 @@
// @flow
import * as React from 'react'
import TestUtils from 'react-dom/test-utils'
import Open from '~/routes/open/container/Open'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import { FIELD_NAME, FIELD_OWNERS, FIELD_CONFIRMATIONS, getOwnerNameBy, getOwnerAddressBy } from '~/routes/open/components/fields'
import { DEPLOYED_COMPONENT_ID } from '~/routes/open/components/FormConfirmation'
import { history, store } from '~/store'
import { sleep } from '~/utils/timer'
import { getProviderInfo } from '~/wallets/getWeb3'
import addProvider from '~/wallets/store/actions/addProvider'
import { makeProvider } from '~/wallets/store/model/provider'
describe('React DOM TESTS > Create Safe form', () => {
let open
let provider
beforeEach(async () => {
// init app web3 instance
provider = await getProviderInfo()
const walletRecord = makeProvider(provider)
store.dispatch(addProvider(walletRecord))
open = TestUtils.renderIntoDocument((
<Provider store={store}>
<ConnectedRouter history={history}>
<Open />
</ConnectedRouter>
</Provider>
))
})
it('should create a 1 owner safe after rendering correctly the form', async () => {
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
const fieldName = inputs[0]
expect(fieldName.name).toEqual(FIELD_NAME)
const fieldOwners = inputs[1]
expect(fieldOwners.name).toEqual(FIELD_OWNERS)
const fieldConfirmations = inputs[2]
expect(fieldConfirmations.name).toEqual(FIELD_CONFIRMATIONS)
TestUtils.Simulate.change(fieldOwners, { target: { value: '1' } })
const inputsExpanded = TestUtils.scryRenderedDOMComponentsWithTag(open, 'input')
const ownerName = inputsExpanded[2]
expect(ownerName.name).toEqual(getOwnerNameBy(0))
const ownerAddress = inputsExpanded[3]
expect(ownerAddress.name).toEqual(getOwnerAddressBy(0))
expect(ownerAddress.value).toEqual(provider.account)
// WHEN
TestUtils.Simulate.change(fieldName, { target: { value: 'Adolfo Safe' } })
TestUtils.Simulate.change(fieldConfirmations, { target: { value: '1' } })
TestUtils.Simulate.change(ownerName, { target: { value: 'Adolfo Eth Account' } })
const form = TestUtils.findRenderedDOMComponentWithTag(open, 'form')
// One submit per step when creating a safe
TestUtils.Simulate.submit(form) // fill the form
TestUtils.Simulate.submit(form) // confirming data
TestUtils.Simulate.submit(form) // Executing transaction
// giving some time to the component for updating its state with safe
// before destroying its context
await sleep(1500)
// THEN
const deployed = TestUtils.findRenderedDOMComponentWithClass(open, DEPLOYED_COMPONENT_ID)
if (deployed) {
const transactionHash = JSON.parse(deployed.getElementsByTagName('pre')[0].innerHTML)
delete transactionHash.logsBloom
// eslint-disable-next-line
console.log(transactionHash)
}
})
})
@@ -0,0 +1,47 @@
// @flow
import * as React from 'react'
import { getNamesFrom, getAccountsFrom } from '~/routes/open/utils/safeDataExtractor'
import Block from '~/components/layout/Block'
import Bold from '~/components/layout/Bold'
import Col from '~/components/layout/Col'
import Heading from '~/components/layout/Heading'
import Row from '~/components/layout/Row'
import Paragraph from '~/components/layout/Paragraph'
type FormProps = {
values: Object,
}
const ReviewInformation = () => ({ values }: FormProps) => {
const names = getNamesFrom(values)
const addresses = getAccountsFrom(values)
return (
<Block>
<Heading tag="h2">Review the Safe information</Heading>
<Paragraph>
<Bold>Safe Name: </Bold> {values.name}
</Paragraph>
<Paragraph>
<Bold>Required confirmations: </Bold> {values.confirmations}
</Paragraph>
<Heading tag="h3">Owners</Heading>
{ names.map((name, index) => (
<Row key={`name${(index)}`} margin="md">
<Col xs={11} xsOffset={1}margin="sm">
<Block>
<Paragraph noMargin>{name}</Paragraph>
</Block>
</Col>
<Col xs={11} xsOffset={1} margin="sm">
<Block>
<Paragraph noMargin>{addresses[index]}</Paragraph>
</Block>
</Col>
</Row>
))}
</Block>
)
}
export default ReviewInformation

Some files were not shown because too many files have changed in this diff Show More