aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorDan J Miller <danjm.com@gmail.com>2018-09-05 02:49:09 +0800
committerGitHub <noreply@github.com>2018-09-05 02:49:09 +0800
commit86bb96aaaf106f1fa16fa93e749772524b5132b2 (patch)
tree4920f6cff23e5f065fb13352697bbeff52b332ae /ui
parentb9e4feac489b8c478a7bff935c319588a2c3acf3 (diff)
parent40e0d92f572d4fff14bfac9a2b0a64ffae8ec7c5 (diff)
downloadtangerine-wallet-browser-86bb96aaaf106f1fa16fa93e749772524b5132b2.tar.gz
tangerine-wallet-browser-86bb96aaaf106f1fa16fa93e749772524b5132b2.tar.zst
tangerine-wallet-browser-86bb96aaaf106f1fa16fa93e749772524b5132b2.zip
Merge pull request #5129 from MetaMask/add-sidebar-component
Add sidebar component
Diffstat (limited to 'ui')
-rw-r--r--ui/app/actions.js6
-rw-r--r--ui/app/app.js62
-rw-r--r--ui/app/components/dropdowns/components/account-dropdowns.js2
-rw-r--r--ui/app/components/index.scss4
-rw-r--r--ui/app/components/menu-bar/menu-bar.container.js11
-rw-r--r--ui/app/components/sidebars/index.js1
-rw-r--r--ui/app/components/sidebars/index.scss74
-rw-r--r--ui/app/components/sidebars/sidebar.component.js49
-rw-r--r--ui/app/components/sidebars/sidebar.constants.js1
-rw-r--r--ui/app/components/sidebars/tests/sidebars-component.test.js88
-rw-r--r--ui/app/components/token-cell.js2
-rw-r--r--ui/app/components/wallet-view.js2
-rw-r--r--ui/app/css/itcss/components/newui-sections.scss16
-rw-r--r--ui/app/reducers/app.js16
14 files changed, 258 insertions, 76 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 845eafdf6..6d5b1ef3f 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1853,9 +1853,13 @@ function hideModal (payload) {
}
}
-function showSidebar () {
+function showSidebar ({ transitionName, type }) {
return {
type: actions.SIDEBAR_OPEN,
+ value: {
+ transitionName,
+ type,
+ },
}
}
diff --git a/ui/app/app.js b/ui/app/app.js
index e0bdac359..aa051280b 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -15,7 +15,7 @@ const SendTransactionScreen = require('./components/send/send.container')
const ConfirmTransaction = require('./components/pages/confirm-transaction')
// slideout menu
-const WalletView = require('./components/wallet-view')
+const Sidebar = require('./components/sidebars').default
// other views
import Home from './components/pages/home'
@@ -31,7 +31,6 @@ const CreateAccountPage = require('./components/pages/create-account')
const NoticeScreen = require('./components/pages/notice')
const Loading = require('./components/loading-screen')
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const NetworkDropdown = require('./components/dropdowns/network-dropdown')
const AccountMenu = require('./components/account-menu')
@@ -105,6 +104,7 @@ class App extends Component {
frequentRpcList,
currentView,
setMouseUserState,
+ sidebar,
} = this.props
const isLoadingNetwork = network === 'loading' && currentView.name !== 'config'
const loadMessage = loadingMessage || isLoadingNetwork ?
@@ -137,7 +137,12 @@ class App extends Component {
h(AppHeader),
// sidebar
- this.renderSidebar(),
+ h(Sidebar, {
+ sidebarOpen: sidebar.isOpen,
+ hideSidebar: this.props.hideSidebar,
+ transitionName: sidebar.transitionName,
+ type: sidebar.type,
+ }),
// network dropdown
h(NetworkDropdown, {
@@ -157,51 +162,6 @@ class App extends Component {
)
}
- renderSidebar () {
- return h('div', [
- h('style', `
- .sidebar-enter {
- transition: transform 300ms ease-in-out;
- transform: translateX(-100%);
- }
- .sidebar-enter.sidebar-enter-active {
- transition: transform 300ms ease-in-out;
- transform: translateX(0%);
- }
- .sidebar-leave {
- transition: transform 200ms ease-out;
- transform: translateX(0%);
- }
- .sidebar-leave.sidebar-leave-active {
- transition: transform 200ms ease-out;
- transform: translateX(-100%);
- }
- `),
-
- h(ReactCSSTransitionGroup, {
- transitionName: 'sidebar',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 200,
- }, [
- // A second instance of Walletview is used for non-mobile viewports
- this.props.sidebarOpen ? h(WalletView, {
- responsiveDisplayClassname: 'sidebar',
- style: {},
- }) : undefined,
-
- ]),
-
- // overlay
- // TODO: add onClick for overlay to close sidebar
- this.props.sidebarOpen ? h('div.sidebar-overlay', {
- style: {},
- onClick: () => {
- this.props.hideSidebar()
- },
- }, []) : undefined,
- ])
- }
-
toggleMetamaskActive () {
if (!this.props.isUnlocked) {
// currently inactive: redirect to password box
@@ -270,7 +230,7 @@ App.propTypes = {
provider: PropTypes.object,
frequentRpcList: PropTypes.array,
currentView: PropTypes.object,
- sidebarOpen: PropTypes.bool,
+ sidebar: PropTypes.object,
alertOpen: PropTypes.bool,
hideSidebar: PropTypes.func,
isMascara: PropTypes.bool,
@@ -306,7 +266,7 @@ function mapStateToProps (state) {
const { appState, metamask } = state
const {
networkDropdownOpen,
- sidebarOpen,
+ sidebar,
alertOpen,
alertMessage,
isLoading,
@@ -333,7 +293,7 @@ function mapStateToProps (state) {
return {
// state from plugin
networkDropdownOpen,
- sidebarOpen,
+ sidebar,
alertOpen,
alertMessage,
isLoading,
diff --git a/ui/app/components/dropdowns/components/account-dropdowns.js b/ui/app/components/dropdowns/components/account-dropdowns.js
index 179b6617f..b497f5c09 100644
--- a/ui/app/components/dropdowns/components/account-dropdowns.js
+++ b/ui/app/components/dropdowns/components/account-dropdowns.js
@@ -459,7 +459,7 @@ const mapDispatchToProps = (dispatch) => {
function mapStateToProps (state) {
return {
keyrings: state.metamask.keyrings,
- sidebarOpen: state.appState.sidebarOpen,
+ sidebarOpen: state.appState.sidebar.isOpen,
}
}
diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss
index bdcb5626c..cb4065fd9 100644
--- a/ui/app/components/index.scss
+++ b/ui/app/components/index.scss
@@ -33,3 +33,7 @@
@import './transaction-list-item/index';
@import './transaction-status/index';
+
+@import './app-header/index';
+
+@import './sidebars/index';
diff --git a/ui/app/components/menu-bar/menu-bar.container.js b/ui/app/components/menu-bar/menu-bar.container.js
index 2bd0ed6ed..ae32882ae 100644
--- a/ui/app/components/menu-bar/menu-bar.container.js
+++ b/ui/app/components/menu-bar/menu-bar.container.js
@@ -3,17 +3,22 @@ import MenuBar from './menu-bar.component'
import { showSidebar, hideSidebar } from '../../actions'
const mapStateToProps = state => {
- const { appState: { sidebarOpen, isMascara } } = state
+ const { appState: { sidebar: { isOpen }, isMascara } } = state
return {
- sidebarOpen,
+ sidebarOpen: isOpen,
isMascara,
}
}
const mapDispatchToProps = dispatch => {
return {
- showSidebar: () => dispatch(showSidebar()),
+ showSidebar: () => {
+ dispatch(showSidebar({
+ transitionName: 'sidebar-right',
+ type: 'wallet-view',
+ }))
+ },
hideSidebar: () => dispatch(hideSidebar()),
}
}
diff --git a/ui/app/components/sidebars/index.js b/ui/app/components/sidebars/index.js
new file mode 100644
index 000000000..732925f69
--- /dev/null
+++ b/ui/app/components/sidebars/index.js
@@ -0,0 +1 @@
+export { default } from './sidebar.component'
diff --git a/ui/app/components/sidebars/index.scss b/ui/app/components/sidebars/index.scss
new file mode 100644
index 000000000..5ab0664df
--- /dev/null
+++ b/ui/app/components/sidebars/index.scss
@@ -0,0 +1,74 @@
+.sidebar-right-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(-100%);
+}
+
+.sidebar-right-enter.sidebar-right-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+}
+
+.sidebar-right-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+}
+
+.sidebar-right-leave.sidebar-right-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(-100%);
+}
+
+.sidebar-left-enter {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(100%);
+}
+
+.sidebar-left-enter.sidebar-left-enter-active {
+ transition: transform 300ms ease-in-out;
+ transform: translateX(0%);
+}
+
+.sidebar-left-leave {
+ transition: transform 200ms ease-out;
+ transform: translateX(0%);
+}
+
+.sidebar-left-leave.sidebar-left-leave-active {
+ transition: transform 200ms ease-out;
+ transform: translateX(100%);
+}
+
+.sidebar-left {
+ flex: 1 0 230px;
+ background: rgb(250, 250, 250);
+ z-index: $sidebar-z-index;
+ position: fixed;
+ left: 15%;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ will-change: transform;
+ overflow-y: auto;
+ box-shadow: rgba(0, 0, 0, .15) 2px 2px 4px;
+ width: 85%;
+ height: 100%;
+
+ @media screen and (min-width: 769px) {
+ width: 408px;
+ left: calc(100% - 408px);
+ }
+}
+
+.sidebar-overlay {
+ z-index: $sidebar-overlay-z-index;
+ position: fixed;
+ height: 100%;
+ width: 100%;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ opacity: 1;
+ visibility: visible;
+ background-color: rgba(0, 0, 0, .3);
+} \ No newline at end of file
diff --git a/ui/app/components/sidebars/sidebar.component.js b/ui/app/components/sidebars/sidebar.component.js
new file mode 100644
index 000000000..57cdd7111
--- /dev/null
+++ b/ui/app/components/sidebars/sidebar.component.js
@@ -0,0 +1,49 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
+import WalletView from '../wallet-view'
+import { WALLET_VIEW_SIDEBAR } from './sidebar.constants'
+
+export default class Sidebar extends Component {
+
+ static propTypes = {
+ sidebarOpen: PropTypes.bool,
+ hideSidebar: PropTypes.func,
+ transitionName: PropTypes.string,
+ type: PropTypes.string,
+ };
+
+ renderOverlay () {
+ return <div className="sidebar-overlay" onClick={() => this.props.hideSidebar()} />
+ }
+
+ renderSidebarContent () {
+ const { type } = this.props
+
+ switch (type) {
+ case WALLET_VIEW_SIDEBAR:
+ return <WalletView responsiveDisplayClassname={'sidebar-right' } />
+ default:
+ return null
+ }
+
+ }
+
+ render () {
+ const { transitionName, sidebarOpen } = this.props
+
+ return (
+ <div>
+ <ReactCSSTransitionGroup
+ transitionName={transitionName}
+ transitionEnterTimeout={300}
+ transitionLeaveTimeout={200}
+ >
+ { sidebarOpen ? this.renderSidebarContent() : null }
+ </ReactCSSTransitionGroup>
+ { sidebarOpen ? this.renderOverlay() : null }
+ </div>
+ )
+ }
+
+}
diff --git a/ui/app/components/sidebars/sidebar.constants.js b/ui/app/components/sidebars/sidebar.constants.js
new file mode 100644
index 000000000..1613a8245
--- /dev/null
+++ b/ui/app/components/sidebars/sidebar.constants.js
@@ -0,0 +1 @@
+export const WALLET_VIEW_SIDEBAR = 'wallet-view'
diff --git a/ui/app/components/sidebars/tests/sidebars-component.test.js b/ui/app/components/sidebars/tests/sidebars-component.test.js
new file mode 100644
index 000000000..e2d77518a
--- /dev/null
+++ b/ui/app/components/sidebars/tests/sidebars-component.test.js
@@ -0,0 +1,88 @@
+import React from 'react'
+import assert from 'assert'
+import { shallow } from 'enzyme'
+import sinon from 'sinon'
+import ReactCSSTransitionGroup from 'react-addons-css-transition-group'
+import Sidebar from '../sidebar.component.js'
+
+import WalletView from '../../wallet-view'
+
+const propsMethodSpies = {
+ hideSidebar: sinon.spy(),
+}
+
+describe('Sidebar Component', function () {
+ let wrapper
+
+ beforeEach(() => {
+ wrapper = shallow(<Sidebar
+ sidebarOpen={false}
+ hideSidebar={propsMethodSpies.hideSidebar}
+ transitionName={'someTransition'}
+ type={'wallet-view'}
+ />)
+ })
+
+ afterEach(() => {
+ propsMethodSpies.hideSidebar.resetHistory()
+ })
+
+ describe('renderOverlay', () => {
+ let renderOverlay
+
+ beforeEach(() => {
+ renderOverlay = shallow(wrapper.instance().renderOverlay())
+ })
+
+ it('should render a overlay element', () => {
+ assert(renderOverlay.hasClass('sidebar-overlay'))
+ })
+
+ it('should pass the correct onClick function to the element', () => {
+ assert.equal(propsMethodSpies.hideSidebar.callCount, 0)
+ renderOverlay.props().onClick()
+ assert.equal(propsMethodSpies.hideSidebar.callCount, 1)
+ })
+ })
+
+ describe('renderSidebarContent', () => {
+ let renderSidebarContent
+
+ beforeEach(() => {
+ wrapper.setProps({ type: 'wallet-view' })
+ renderSidebarContent = wrapper.instance().renderSidebarContent()
+ })
+
+ it('should render sidebar content with the correct props', () => {
+ wrapper.setProps({ type: 'wallet-view' })
+ renderSidebarContent = wrapper.instance().renderSidebarContent()
+ assert.equal(renderSidebarContent.props.responsiveDisplayClassname, 'sidebar-right')
+ })
+
+ it('should not render with an unrecognized type', () => {
+ wrapper.setProps({ type: 'foobar' })
+ renderSidebarContent = wrapper.instance().renderSidebarContent()
+ assert.equal(renderSidebarContent, undefined)
+ })
+ })
+
+ describe('render', () => {
+ it('should render a div with one child', () => {
+ assert(wrapper.is('div'))
+ assert.equal(wrapper.children().length, 1)
+ })
+
+ it('should render the ReactCSSTransitionGroup without any children', () => {
+ assert(wrapper.children().at(0).is(ReactCSSTransitionGroup))
+ assert.equal(wrapper.children().at(0).children().length, 0)
+ })
+
+ it('should render sidebar content and the overlay if sidebarOpen is true', () => {
+ wrapper.setProps({ sidebarOpen: true })
+ assert.equal(wrapper.children().length, 2)
+ assert(wrapper.children().at(1).hasClass('sidebar-overlay'))
+ assert.equal(wrapper.children().at(0).children().length, 1)
+ assert(wrapper.children().at(0).children().at(0).is(WalletView))
+ })
+ })
+})
diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js
index 58a30228d..477d97597 100644
--- a/ui/app/components/token-cell.js
+++ b/ui/app/components/token-cell.js
@@ -18,7 +18,7 @@ function mapStateToProps (state) {
userAddress: selectors.getSelectedAddress(state),
contractExchangeRates: state.metamask.contractExchangeRates,
conversionRate: state.metamask.conversionRate,
- sidebarOpen: state.appState.sidebarOpen,
+ sidebarOpen: state.appState.sidebar.isOpen,
}
}
diff --git a/ui/app/components/wallet-view.js b/ui/app/components/wallet-view.js
index ffa60e3ed..6de265110 100644
--- a/ui/app/components/wallet-view.js
+++ b/ui/app/components/wallet-view.js
@@ -34,7 +34,7 @@ function mapStateToProps (state) {
return {
network: state.metamask.network,
- sidebarOpen: state.appState.sidebarOpen,
+ sidebarOpen: state.appState.sidebar.isOpen,
identities: state.metamask.identities,
accounts: state.metamask.accounts,
tokens: state.metamask.tokens,
diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss
index 29dd18ae3..7eb193d6f 100644
--- a/ui/app/css/itcss/components/newui-sections.scss
+++ b/ui/app/css/itcss/components/newui-sections.scss
@@ -148,7 +148,7 @@ $wallet-view-bg: $alabaster;
}
}
-.wallet-view.sidebar {
+.wallet-view.sidebar-right {
flex: 1 0 230px;
background: rgb(250, 250, 250);
z-index: $sidebar-z-index;
@@ -166,20 +166,6 @@ $wallet-view-bg: $alabaster;
height: calc(100% - 56px);
}
-.sidebar-overlay {
- z-index: $sidebar-overlay-z-index;
- position: fixed;
- // top: 41px;
- height: 100%;
- width: 100%;
- left: 0;
- right: 0;
- bottom: 0;
- opacity: 1;
- visibility: visible;
- background-color: rgba(0, 0, 0, .3);
-}
-
// main-container media queries
@media screen and (min-width: 576px) {
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 7be9b8d40..5c86d397d 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -48,7 +48,11 @@ function reduceApp (state, action) {
name: null,
},
},
- sidebarOpen: false,
+ sidebar: {
+ isOpen: false,
+ transitionName: '',
+ type: '',
+ },
alertOpen: false,
alertMessage: null,
qrCodeData: null,
@@ -88,12 +92,18 @@ function reduceApp (state, action) {
// sidebar methods
case actions.SIDEBAR_OPEN:
return extend(appState, {
- sidebarOpen: true,
+ sidebar: {
+ ...action.value,
+ isOpen: true,
+ },
})
case actions.SIDEBAR_CLOSE:
return extend(appState, {
- sidebarOpen: false,
+ sidebar: {
+ ...appState.sidebar,
+ isOpen: false,
+ },
})
// alert methods