mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Update account options menu design (#8654)
The `AccountDetailsDropdown` component has been rewritten to use the new `Menu` component, and to follow the latest designs. This should be functionally equivalent. A couple of the icons have changed, but that's about it. Support for a subtitle was added to `MenuItem` to support the `origin` subtitle used for the explorer link for custom RPC endpoints. A few adjustments were required to `test/helper.js` to accommodate the use of `Menu` from a JSDOM context (this is the first time it's been used in a unit test). A `popover-content` element was added to the fake DOM, and another global was added that `react-popper` used internally. An additional driver method (`clickPoint`) was added to the e2e driver to allow clicking the background behind the menu to dismiss it. This wasn't possible using the `clickElement` method, because that method would refuse to click an obscured element. The only non-obscured element to click was the menu backdrop, and that didn't work either because the center was obscured by the menu (Selenium clicks the center of whichever element is targeted).
This commit is contained in:
parent
c0e32b54eb
commit
a6f2156386
@ -1,5 +0,0 @@
|
||||
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#fff">
|
||||
<path d="M15.48.065A.846.846 0 0015.16 0h-5.047a.841.841 0 000 1.682h3.016l-4.35 4.35A.84.84 0 109.97 7.22l4.35-4.349v3.016a.84.84 0 101.681 0V.84a.846.846 0 00-.52-.776zM.52 15.935A.846.846 0 00.84 16h5.047a.841.841 0 000-1.682H2.87l4.35-4.35A.84.84 0 106.03 8.78l-4.35 4.349v-3.016a.84.84 0 10-1.681 0v5.046a.846.846 0 00.52.776z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 443 B |
@ -1,6 +0,0 @@
|
||||
<svg height="12" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#fff" fill-rule="evenodd">
|
||||
<path d="M12.792.686L2.502 11.252l.708.726L13.5 1.412zM4.53 6.332c0-1.968 1.555-3.563 3.471-3.563.402 0 .781.085 1.14.213l.882-.905A9.25 9.25 0 008 1.838c-3.36 0-6.312 1.791-8 4.494a9.649 9.649 0 002.966 2.991l1.772-1.82a3.606 3.606 0 01-.208-1.171M13.02 3.34L11.25 5.16c.126.37.208.76.208 1.172 0 1.968-1.55 3.563-3.462 3.563-.403 0-.78-.084-1.139-.214l-.879.905c.653.146 1.324.24 2.018.24 3.351 0 6.297-1.792 7.982-4.494a9.649 9.649 0 00-2.96-2.992"/>
|
||||
<path d="M8.001 8.75c1.301 0 2.354-1.082 2.354-2.418 0-.074-.014-.145-.02-.218L7.788 8.728c.071.007.14.022.212.022M8.001 3.914c-1.301 0-2.354 1.082-2.354 2.417 0 .075.014.146.02.218l2.546-2.614c-.071-.006-.14-.021-.212-.021"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 817 B |
@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 8C14 11.3137 11.3137 14 8 14C4.68629 14 2 11.3137 2 8C2 4.68629 4.68629 2 8 2C11.3137 2 14 4.68629 14 8ZM16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM8 11C9.65685 11 11 9.65685 11 8C11 6.34315 9.65685 5 8 5C6.34315 5 5 6.34315 5 8C5 9.65685 6.34315 11 8 11Z" fill="#FFFFFF"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 8C14 11.3137 11.3137 14 8 14C4.68629 14 2 11.3137 2 8C2 4.68629 4.68629 2 8 2C11.3137 2 14 4.68629 14 8ZM16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM8 11C9.65685 11 11 9.65685 11 8C11 6.34315 9.65685 5 8 5C6.34315 5 5 6.34315 5 8C5 9.65685 6.34315 11 8 11Z" fill="#24292E"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 495 B After Width: | Height: | Size: 495 B |
@ -1,8 +0,0 @@
|
||||
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="#fff" fill-rule="evenodd">
|
||||
<path d="M13.214.643V.5H.5v12.714h.143V.643z" stroke="#fff"/>
|
||||
<path d="M3.429 3.429v11.428h11.428V3.43zM2.286 2.286H16V16H2.286z" fill-rule="nonzero"/>
|
||||
<rect height="5" rx="1" width="2" x="8" y="8"/>
|
||||
<rect height="2" rx="1" width="2" x="8" y="5"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 400 B |
@ -1,3 +0,0 @@
|
||||
<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 0a1 1 0 000 2h9.586L.293 14.293a.999.999 0 101.414 1.414L14 3.414V13a1 1 0 002 0V0z" fill="#fff" fill-rule="evenodd"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 206 B |
@ -117,9 +117,12 @@ describe('MetaMask', function () {
|
||||
|
||||
describe('Show account information', function () {
|
||||
it('show account details dropdown menu', async function () {
|
||||
await driver.clickElement(By.css('button.menu-bar__account-options'))
|
||||
const options = await driver.findElements(By.css('div.menu.account-details-dropdown div.menu__item'))
|
||||
await driver.clickElement(By.css('[data-testid="account-options-menu-button"]'))
|
||||
const options = await driver.findElements(By.css('.account-options-menu .menu-item'))
|
||||
assert.equal(options.length, 4) // HD Wallet type does not have to show the Remove Account option
|
||||
// click outside of menu to dismiss
|
||||
// account menu button chosen because the menu never covers it.
|
||||
await driver.clickPoint(By.css('.account-menu__icon'), 0, 0)
|
||||
await driver.delay(regularDelayMs)
|
||||
})
|
||||
})
|
||||
|
@ -71,6 +71,15 @@ class Driver {
|
||||
await element.click()
|
||||
}
|
||||
|
||||
async clickPoint (locator, x, y) {
|
||||
const element = await this.findElement(locator)
|
||||
await this.driver
|
||||
.actions()
|
||||
.move({ origin: element, x, y })
|
||||
.click()
|
||||
.perform()
|
||||
}
|
||||
|
||||
async scrollToElement (element) {
|
||||
await this.driver.executeScript('arguments[0].scrollIntoView(true)', element)
|
||||
}
|
||||
|
@ -57,6 +57,13 @@ global.document = window.document
|
||||
// required by `react-tippy`
|
||||
global.navigator = window.navigator
|
||||
global.Element = window.Element
|
||||
// required by `react-popper`
|
||||
global.HTMLElement = window.HTMLElement
|
||||
|
||||
// required by any components anchored on `popover-content`
|
||||
const popoverContent = window.document.createElement('div')
|
||||
popoverContent.setAttribute('id', 'popover-content')
|
||||
window.document.body.appendChild(popoverContent)
|
||||
|
||||
// delete AbortController added by jsdom so it can be polyfilled correctly below
|
||||
delete window.AbortController
|
||||
|
@ -1,151 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { CONNECTED_ROUTE } from '../../../../helpers/constants/routes'
|
||||
import { Menu, Item, CloseArea } from '../components/menu'
|
||||
|
||||
export default class AccountDetailsDropdown extends Component {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
metricsEvent: PropTypes.func,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
selectedIdentity: PropTypes.object.isRequired,
|
||||
network: PropTypes.string.isRequired,
|
||||
keyrings: PropTypes.array.isRequired,
|
||||
showAccountDetailModal: PropTypes.func.isRequired,
|
||||
viewOnEtherscan: PropTypes.func.isRequired,
|
||||
showRemoveAccountConfirmationModal: PropTypes.func.isRequired,
|
||||
rpcPrefs: PropTypes.object.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
onClose = (e) => {
|
||||
e.stopPropagation()
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
selectedIdentity,
|
||||
network,
|
||||
keyrings,
|
||||
showAccountDetailModal,
|
||||
viewOnEtherscan,
|
||||
showRemoveAccountConfirmationModal,
|
||||
rpcPrefs,
|
||||
history,
|
||||
} = this.props
|
||||
|
||||
const address = selectedIdentity.address
|
||||
|
||||
const keyring = keyrings.find((kr) => {
|
||||
return kr.accounts.includes(address)
|
||||
})
|
||||
|
||||
const isRemovable = keyring.type !== 'HD Key Tree'
|
||||
|
||||
return (
|
||||
<Menu className="account-details-dropdown" isShowing>
|
||||
<CloseArea onClick={this.onClose} />
|
||||
<Item
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Clicked Expand View',
|
||||
},
|
||||
})
|
||||
global.platform.openExtensionInBrowser()
|
||||
this.props.onClose()
|
||||
}}
|
||||
text={this.context.t('expandView')}
|
||||
icon={(
|
||||
<img alt="" src="images/expand.svg" style={{ height: '15px' }} />
|
||||
)}
|
||||
/>
|
||||
<Item
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
showAccountDetailModal()
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Viewed Account Details',
|
||||
},
|
||||
})
|
||||
this.props.onClose()
|
||||
}}
|
||||
text={this.context.t('accountDetails')}
|
||||
icon={(
|
||||
<img src="images/info.svg" style={{ height: '15px' }} alt="" />
|
||||
)}
|
||||
/>
|
||||
<Item
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Clicked View on Etherscan',
|
||||
},
|
||||
})
|
||||
viewOnEtherscan(address, network, rpcPrefs)
|
||||
this.props.onClose()
|
||||
}}
|
||||
text={
|
||||
rpcPrefs.blockExplorerUrl
|
||||
? this.context.t('viewinExplorer')
|
||||
: this.context.t('viewOnEtherscan')
|
||||
}
|
||||
subText={
|
||||
rpcPrefs.blockExplorerUrl
|
||||
? rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1]
|
||||
: null
|
||||
}
|
||||
icon={(
|
||||
<img src="images/open-etherscan.svg" style={{ height: '15px' }} alt="" />
|
||||
)}
|
||||
/>
|
||||
<Item
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Opened Connected Sites',
|
||||
},
|
||||
})
|
||||
history.push(CONNECTED_ROUTE)
|
||||
this.props.onClose()
|
||||
}}
|
||||
text={this.context.t('connectedSites')}
|
||||
icon={(
|
||||
<img src="images/icons/connected-sites-white.svg" style={{ height: '15px' }} alt="" />
|
||||
)}
|
||||
/>
|
||||
{
|
||||
isRemovable
|
||||
? (
|
||||
<Item
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
showRemoveAccountConfirmationModal(selectedIdentity)
|
||||
this.props.onClose()
|
||||
}}
|
||||
text={this.context.t('removeAccount')}
|
||||
icon={<img src="images/hide.svg" style={{ height: '15px' }} alt="" />}
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import { compose } from 'redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import { connect } from 'react-redux'
|
||||
import AccountDetailsDropdown from './account-details-dropdown.component'
|
||||
import * as actions from '../../../../store/actions'
|
||||
import {
|
||||
getSelectedIdentity,
|
||||
getRpcPrefsForCurrentProvider,
|
||||
} from '../../../../selectors'
|
||||
import genAccountLink from '../../../../../lib/account-link'
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {
|
||||
selectedIdentity: getSelectedIdentity(state),
|
||||
network: state.metamask.network,
|
||||
keyrings: state.metamask.keyrings,
|
||||
rpcPrefs: getRpcPrefsForCurrentProvider(state),
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
showAccountDetailModal: () => {
|
||||
dispatch(actions.showModal({ name: 'ACCOUNT_DETAILS' }))
|
||||
},
|
||||
viewOnEtherscan: (address, network, rpcPrefs) => {
|
||||
global.platform.openTab({ url: genAccountLink(address, network, rpcPrefs) })
|
||||
},
|
||||
showRemoveAccountConfirmationModal: (identity) => {
|
||||
return dispatch(actions.showModal({ name: 'CONFIRM_REMOVE_ACCOUNT', identity }))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(withRouter, connect(mapStateToProps, mapDispatchToProps))(AccountDetailsDropdown)
|
@ -1 +0,0 @@
|
||||
export { default } from './account-details-dropdown.container'
|
@ -1,6 +0,0 @@
|
||||
.account-details-dropdown {
|
||||
position: absolute;
|
||||
top: 120px;
|
||||
right: 24px;
|
||||
z-index: 1;
|
||||
}
|
@ -102,8 +102,6 @@
|
||||
|
||||
@import './connected-status-indicator/index';
|
||||
|
||||
@import './dropdowns/account-details-dropdown/index';
|
||||
|
||||
@import '../ui/check-box/index';
|
||||
|
||||
@import '../ui/dropdown/dropdown';
|
||||
|
140
ui/app/components/app/menu-bar/account-options-menu.js
Normal file
140
ui/app/components/app/menu-bar/account-options-menu.js
Normal file
@ -0,0 +1,140 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import { showModal } from '../../../store/actions'
|
||||
import { CONNECTED_ROUTE } from '../../../helpers/constants/routes'
|
||||
import { Menu, MenuItem } from '../../ui/menu'
|
||||
import genAccountLink from '../../../../lib/account-link'
|
||||
import { getCurrentKeyring, getCurrentNetwork, getRpcPrefsForCurrentProvider, getSelectedIdentity } from '../../../selectors'
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext'
|
||||
import { useMetricEvent } from '../../../hooks/useMetricEvent'
|
||||
|
||||
export default function AccountOptionsMenu ({ anchorElement, onClose }) {
|
||||
const t = useI18nContext()
|
||||
const dispatch = useDispatch()
|
||||
const history = useHistory()
|
||||
const openFullscreenEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Clicked Expand View',
|
||||
},
|
||||
})
|
||||
const viewAccountDetailsEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Viewed Account Details',
|
||||
},
|
||||
})
|
||||
const viewOnEtherscanEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Clicked View on Etherscan',
|
||||
},
|
||||
})
|
||||
const openConnectedSitesEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Account Options',
|
||||
name: 'Opened Connected Sites',
|
||||
},
|
||||
})
|
||||
|
||||
const keyring = useSelector(getCurrentKeyring)
|
||||
const network = useSelector(getCurrentNetwork)
|
||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider)
|
||||
const selectedIdentity = useSelector(getSelectedIdentity)
|
||||
|
||||
const address = selectedIdentity.address
|
||||
const isRemovable = keyring.type !== 'HD Key Tree'
|
||||
|
||||
return (
|
||||
<Menu
|
||||
anchorElement={anchorElement}
|
||||
className="account-options-menu"
|
||||
onHide={onClose}
|
||||
>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
openFullscreenEvent()
|
||||
global.platform.openExtensionInBrowser()
|
||||
onClose()
|
||||
}}
|
||||
iconClassName="fas fa-expand-alt"
|
||||
>
|
||||
{ t('expandView') }
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
dispatch(showModal({ name: 'ACCOUNT_DETAILS' }))
|
||||
viewAccountDetailsEvent()
|
||||
onClose()
|
||||
}}
|
||||
iconClassName="fas fa-qrcode"
|
||||
>
|
||||
{ t('accountDetails') }
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
viewOnEtherscanEvent()
|
||||
global.platform.openTab({ url: genAccountLink(address, network, rpcPrefs) })
|
||||
onClose()
|
||||
}}
|
||||
subtitle={
|
||||
rpcPrefs.blockExplorerUrl
|
||||
? (
|
||||
<span className="account-options-menu__explorer-origin">
|
||||
{ rpcPrefs.blockExplorerUrl.match(/^https?:\/\/(.+)/)[1] }
|
||||
</span>
|
||||
)
|
||||
: null
|
||||
}
|
||||
iconClassName="fas fa-external-link-alt"
|
||||
>
|
||||
{
|
||||
rpcPrefs.blockExplorerUrl
|
||||
? t('viewinExplorer')
|
||||
: t('viewOnEtherscan')
|
||||
}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
openConnectedSitesEvent()
|
||||
history.push(CONNECTED_ROUTE)
|
||||
onClose()
|
||||
}}
|
||||
iconClassName="account-options-menu__connected-sites"
|
||||
>
|
||||
{ t('connectedSites') }
|
||||
</MenuItem>
|
||||
{
|
||||
isRemovable
|
||||
? (
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
dispatch(showModal({ name: 'CONFIRM_REMOVE_ACCOUNT', selectedIdentity }))
|
||||
onClose()
|
||||
}}
|
||||
iconClassName="fas fa-trash-alt"
|
||||
>
|
||||
{ t('removeAccount') }
|
||||
</MenuItem>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
AccountOptionsMenu.propTypes = {
|
||||
anchorElement: PropTypes.instanceOf(window.Element),
|
||||
onClose: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
AccountOptionsMenu.defaultProps = {
|
||||
anchorElement: undefined,
|
||||
}
|
@ -11,8 +11,6 @@
|
||||
background: none;
|
||||
font-size: inherit;
|
||||
padding: 0 8px 0 5px;
|
||||
|
||||
position: relative; // to allow the dropdown to position itself absolutely
|
||||
place-self: center end;
|
||||
}
|
||||
|
||||
@ -21,3 +19,18 @@
|
||||
place-self: center stretch;
|
||||
}
|
||||
}
|
||||
|
||||
.account-options-menu {
|
||||
&__connected-sites:before {
|
||||
content: "";
|
||||
background-image: url(/images/icons/connected-sites-black.svg);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
padding: 8px;
|
||||
}
|
||||
&__explorer-origin {
|
||||
color: $Grey-500;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react'
|
||||
import SelectedAccount from '../selected-account'
|
||||
import ConnectedStatusIndicator from '../connected-status-indicator'
|
||||
import AccountDetailsDropdown from '../dropdowns/account-details-dropdown'
|
||||
import AccountOptionsMenu from './account-options-menu'
|
||||
import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
|
||||
import { ENVIRONMENT_TYPE_POPUP } from '../../../../../app/scripts/lib/enums'
|
||||
import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'
|
||||
@ -19,7 +19,8 @@ export default function MenuBar () {
|
||||
},
|
||||
})
|
||||
const history = useHistory()
|
||||
const [accountDetailsMenuOpen, setAccountDetailsMenuOpen] = useState(false)
|
||||
const [accountOptionsButtonElement, setAccountOptionsButtonElement] = useState(null)
|
||||
const [accountOptionsMenuOpen, setAccountOptionsMenuOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="menu-bar">
|
||||
@ -33,17 +34,20 @@ export default function MenuBar () {
|
||||
|
||||
<button
|
||||
className="fas fa-ellipsis-v menu-bar__account-options"
|
||||
data-testid="account-options-menu-button"
|
||||
ref={setAccountOptionsButtonElement}
|
||||
title={t('accountOptions')}
|
||||
onClick={() => {
|
||||
openAccountOptionsEvent()
|
||||
setAccountDetailsMenuOpen(true)
|
||||
setAccountOptionsMenuOpen(true)
|
||||
}}
|
||||
/>
|
||||
|
||||
{
|
||||
accountDetailsMenuOpen && (
|
||||
<AccountDetailsDropdown
|
||||
onClose={() => setAccountDetailsMenuOpen(false)}
|
||||
accountOptionsMenuOpen && (
|
||||
<AccountOptionsMenu
|
||||
anchorElement={accountOptionsButtonElement}
|
||||
onClose={() => setAccountOptionsMenuOpen(false)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -36,11 +36,11 @@ describe('MenuBar', function () {
|
||||
<MenuBar />
|
||||
</Provider>
|
||||
)
|
||||
assert.ok(!wrapper.exists('AccountDetailsDropdown'))
|
||||
assert.ok(!wrapper.exists('AccountOptionsMenu'))
|
||||
const accountOptions = wrapper.find('.menu-bar__account-options')
|
||||
accountOptions.simulate('click')
|
||||
wrapper.update()
|
||||
assert.ok(wrapper.exists('AccountDetailsDropdown'))
|
||||
assert.ok(wrapper.exists('AccountOptionsMenu'))
|
||||
})
|
||||
|
||||
it('sets accountDetailsMenuOpen to false when closed', function () {
|
||||
@ -53,10 +53,10 @@ describe('MenuBar', function () {
|
||||
const accountOptions = wrapper.find('.menu-bar__account-options')
|
||||
accountOptions.simulate('click')
|
||||
wrapper.update()
|
||||
assert.ok(wrapper.exists('AccountDetailsDropdown'))
|
||||
const accountDetailsMenu = wrapper.find('AccountDetailsDropdown')
|
||||
assert.ok(wrapper.exists('AccountOptionsMenu'))
|
||||
const accountDetailsMenu = wrapper.find('AccountOptionsMenu')
|
||||
accountDetailsMenu.prop('onClose')()
|
||||
wrapper.update()
|
||||
assert.ok(!wrapper.exists('AccountDetailsDropdown'))
|
||||
assert.ok(!wrapper.exists('AccountOptionsMenu'))
|
||||
})
|
||||
})
|
||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
|
||||
const MenuItem = ({ children, className, iconClassName, onClick }) => (
|
||||
const MenuItem = ({ children, className, iconClassName, onClick, subtitle }) => (
|
||||
<button className={classnames('menu-item', className)} onClick={onClick}>
|
||||
{
|
||||
iconClassName
|
||||
@ -12,6 +12,7 @@ const MenuItem = ({ children, className, iconClassName, onClick }) => (
|
||||
: null
|
||||
}
|
||||
<span>{children}</span>
|
||||
{ subtitle }
|
||||
</button>
|
||||
)
|
||||
|
||||
@ -20,12 +21,14 @@ MenuItem.propTypes = {
|
||||
className: PropTypes.string,
|
||||
iconClassName: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
subtitle: PropTypes.node,
|
||||
}
|
||||
|
||||
MenuItem.defaultProps = {
|
||||
className: undefined,
|
||||
iconClassName: undefined,
|
||||
onClick: undefined,
|
||||
subtitle: undefined,
|
||||
}
|
||||
|
||||
export default MenuItem
|
||||
|
@ -33,8 +33,9 @@
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto;
|
||||
text-align: start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 14px 0;
|
||||
@ -42,6 +43,7 @@
|
||||
|
||||
&__icon {
|
||||
margin-right: 8px;
|
||||
grid-row: 1 / span 2;
|
||||
}
|
||||
|
||||
.disconnect-icon {
|
||||
|
@ -161,13 +161,6 @@ $wallet-view-bg: $alabaster;
|
||||
}
|
||||
}
|
||||
|
||||
// account options dropdown
|
||||
.account-options-menu {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin: 5% 7% 0%;
|
||||
}
|
||||
|
||||
.fiat-amount {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user