From 406ec4a4af4a6b7df7566211a036f0b50be45a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=ABck=20V=C3=A9zien?= Date: Fri, 19 Jan 2018 12:20:28 +0100 Subject: [PATCH] Refacto Modal components --- .eslintrc | 1 + package.json | 4 +- .../base/{Modal.js => Modal/index.js} | 85 +++++++++++++------ src/components/base/Modal/stories.js | 23 +++++ src/components/modals/AddAccount.js | 15 +++- src/components/modals/Receive.js | 10 ++- src/components/modals/Send.js | 20 +++-- yarn.lock | 29 ++++--- 8 files changed, 135 insertions(+), 52 deletions(-) rename src/components/base/{Modal.js => Modal/index.js} (56%) create mode 100644 src/components/base/Modal/stories.js diff --git a/.eslintrc b/.eslintrc index 30d7cdca..8771a924 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,6 +12,7 @@ "camelcase": 0, "import/no-extraneous-dependencies": 0, "import/prefer-default-export": 0, + "import/no-named-as-default": 0, "jsx-a11y/anchor-is-valid": 0, "new-cap": 0, "no-nested-ternary": 0, diff --git a/package.json b/package.json index 7245ceaa..97e241d8 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "flow": "flow", "lint": "eslint src webpack .storybook", "postinstall": "bash ./scripts/postinstall.sh", - "prepush": "lint-staged", + "precommit": "lint-staged", "prettier": "prettier --write \"{src,webpack,.storybook}/**/*.js\"", "publish-storybook": "bash ./scripts/publish-storybook.sh", "release": "build", @@ -36,8 +36,8 @@ "@ledgerhq/hw-app-eth": "^1.1.2-beta.068e2a14", "@ledgerhq/hw-transport": "^1.1.2-beta.068e2a14", "@ledgerhq/hw-transport-node-hid": "^1.1.2-beta.068e2a14", - "blockchain.info": "^2.11.0", "bcryptjs": "^2.4.3", + "blockchain.info": "^2.11.0", "color": "^2.0.1", "downshift": "^1.25.0", "electron-store": "^1.3.0", diff --git a/src/components/base/Modal.js b/src/components/base/Modal/index.js similarity index 56% rename from src/components/base/Modal.js rename to src/components/base/Modal/index.js index 2611c347..6f68c23e 100644 --- a/src/components/base/Modal.js +++ b/src/components/base/Modal/index.js @@ -1,4 +1,5 @@ // @flow + /* eslint-disable jsx-a11y/click-events-have-key-events */ /* eslint-disable jsx-a11y/no-static-element-interactions */ @@ -8,12 +9,19 @@ import Mortal from 'react-mortal' import styled from 'styled-components' import noop from 'lodash/noop' +import type { Element } from 'react' + +import { rgba } from 'styles/helpers' + import { closeModal, isModalOpened } from 'reducers/modals' +import Box from 'components/base/Box' + type Props = { isOpened?: boolean, onClose: Function, - children: any, + preventBackdropClick: boolean, + render: Function, } const springConfig = { @@ -33,56 +41,58 @@ const mapDispatchToProps = (dispatch, { name, onClose = noop }) => ({ : onClose, }) -const Container = styled.div.attrs({ +const Container = styled(Box).attrs({ + align: 'center', + justify: 'flex-start', + sticky: true, style: p => ({ pointerEvents: p.isVisible ? 'auto' : 'none', }), })` + overflow: hidden; position: fixed; z-index: 1; - top: 0; - left: 0; - right: 0; - bottom: 0; - overflow: hidden; - display: flex; - align-items: flex-start; - justify-content: center; ` -const Backdrop = styled.div.attrs({ +const Backdrop = styled(Box).attrs({ + bg: p => rgba(p.theme.colors.black, 0.4), + sticky: true, style: p => ({ opacity: p.op, }), })` position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.4); ` -const Body = styled.div.attrs({ +const Wrapper = styled(Box).attrs({ + bg: 'transparent', + flow: 20, + mt: 100, style: p => ({ opacity: p.op, transform: `translate3d(0, ${p.offset}px, 0)`, }), })` - padding: 20px; - margin-top: 100px; - background: white; - width: 400px; + width: 430px; z-index: 2; ` -class Modal extends PureComponent { +const Body = styled(Box).attrs({ + bg: p => p.theme.colors.white, + p: 20, +})` + border-radius: 5px; +` + +export class Modal extends PureComponent { static defaultProps = { + onClose: noop, + preventBackdropClick: true, isOpened: false, } render() { - const { isOpened, onClose, children } = this.props + const { preventBackdropClick, isOpened, onClose, render } = this.props return ( { > {(m, isVisible) => ( - - - {children} - + + + {render({ onClose })} + )} @@ -105,4 +115,25 @@ class Modal extends PureComponent { } } +export const ModalBody = ({ + children, + onClose, +}: { + children: Element | string, + onClose?: Function, +}) => ( + + {onClose && ( + + [x] + + )} + {children} + +) + +ModalBody.defaultProps = { + onClose: undefined, +} + export default connect(mapStateToProps, mapDispatchToProps)(Modal) diff --git a/src/components/base/Modal/stories.js b/src/components/base/Modal/stories.js new file mode 100644 index 00000000..a532d3fb --- /dev/null +++ b/src/components/base/Modal/stories.js @@ -0,0 +1,23 @@ +import React, { Fragment } from 'react' +import { storiesOf } from '@storybook/react' +import { boolean } from '@storybook/addon-knobs' + +import { Modal, ModalBody } from 'components/base/Modal' + +const stories = storiesOf('Modal', module) + +stories.add('basic', () => { + const isOpened = boolean('isOpened', false) + return ( + ( + + Hey! + Hoy! + Hu! + + )} + /> + ) +}) diff --git a/src/components/modals/AddAccount.js b/src/components/modals/AddAccount.js index 8760f097..2669b5dd 100644 --- a/src/components/modals/AddAccount.js +++ b/src/components/modals/AddAccount.js @@ -15,7 +15,7 @@ import { addAccount } from 'actions/accounts' import Button from 'components/base/Button' import Input from 'components/base/Input' -import Modal from 'components/base/Modal' +import Modal, { ModalBody } from 'components/base/Modal' import Select from 'components/base/Select' const Label = styled.label` @@ -219,9 +219,16 @@ class AddAccountModal extends PureComponent { const Step = Steps[step] return ( - - - + ( + + + + )} + /> ) } } diff --git a/src/components/modals/Receive.js b/src/components/modals/Receive.js index 18de7d98..a85e3e4d 100644 --- a/src/components/modals/Receive.js +++ b/src/components/modals/Receive.js @@ -2,13 +2,19 @@ import React, { PureComponent } from 'react' -import Modal from 'components/base/Modal' +import Modal, { ModalBody } from 'components/base/Modal' type Props = {} class ReceiveModal extends PureComponent { render() { - return receive modal + return ( + receive modal} + /> + ) } } diff --git a/src/components/modals/Send.js b/src/components/modals/Send.js index 172b4435..164f636b 100644 --- a/src/components/modals/Send.js +++ b/src/components/modals/Send.js @@ -1,6 +1,6 @@ // @flow -import React, { PureComponent } from 'react' +import React, { Fragment, PureComponent } from 'react' import styled from 'styled-components' import { connect } from 'react-redux' @@ -11,7 +11,7 @@ import { getAccounts } from 'reducers/accounts' import Button from 'components/base/Button' import Input from 'components/base/Input' -import Modal from 'components/base/Modal' +import Modal, { ModalBody } from 'components/base/Modal' import Select from 'components/base/Select' const Label = styled.label` @@ -147,9 +147,19 @@ class Send extends PureComponent { const Step = Steps[step] return ( - - - + ( + + {step} + + + + + )} + /> ) } } diff --git a/yarn.lock b/yarn.lock index 4d57a317..ddd2614e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2552,13 +2552,13 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" -cosmiconfig@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397" +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" dependencies: is-directory "^0.3.1" js-yaml "^3.9.0" - parse-json "^3.0.0" + parse-json "^4.0.0" require-from-string "^2.0.1" create-ecdh@^4.0.0: @@ -4702,8 +4702,8 @@ i18next-node-fs-backend@^1.0.0: json5 "0.5.0" i18next@^10.2.2: - version "10.2.2" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-10.2.2.tgz#1f2dc55ca2e8d7e071f7aff9f78654ef7f003c0e" + version "10.3.0" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-10.3.0.tgz#6866d14f6ae7b3629921f78bc028d04914f0654c" iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@^0.4.19, iconv-lite@~0.4.13: version "0.4.19" @@ -5255,6 +5255,10 @@ json-loader@^0.5.4, json-loader@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" +json-parse-better-errors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -5409,13 +5413,13 @@ levn@^0.3.0, levn@~0.3.0: type-check "~0.3.2" lint-staged@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-6.0.0.tgz#7ab7d345f2fe302ff196f1de6a005594ace03210" + version "6.0.1" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-6.0.1.tgz#855f2993ab4a265430e2fd9828427e648d65e6b4" dependencies: app-root-path "^2.0.0" chalk "^2.1.0" commander "^2.11.0" - cosmiconfig "^3.1.0" + cosmiconfig "^4.0.0" debug "^3.1.0" dedent "^0.7.0" execa "^0.8.0" @@ -6441,11 +6445,12 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-3.0.0.tgz#fa6f47b18e23826ead32f263e744d0e1e847fb13" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" dependencies: error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" parseurl@~1.3.2: version "1.3.2"