colocate account modal styles with their components (#9150)

This one gets a bit more complicated because the styles were interwoven and needed to be untangled to be moved. Essentially, though, the goal is to put the styles where they make the most sense and colocate them with their components.
feature/default_network_editable
Brad Decker 4 years ago committed by GitHub
parent 6ba9e65712
commit 01f69d7e7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      test/e2e/ethereum-on.spec.js
  2. 4
      test/e2e/from-import-ui.spec.js
  3. 2
      test/e2e/incremental-security.spec.js
  4. 2
      test/e2e/metamask-ui.spec.js
  5. 2
      test/e2e/permissions.spec.js
  6. 2
      test/e2e/signature-request.spec.js
  7. 10
      ui/app/components/app/modals/account-details-modal/account-details-modal.component.js
  8. 37
      ui/app/components/app/modals/account-details-modal/index.scss
  9. 13
      ui/app/components/app/modals/account-modal-container/account-modal-container.component.js
  10. 50
      ui/app/components/app/modals/account-modal-container/index.scss
  11. 29
      ui/app/components/app/modals/export-private-key-modal/export-private-key-modal.component.js
  12. 106
      ui/app/components/app/modals/export-private-key-modal/index.scss
  13. 3
      ui/app/components/app/modals/index.scss
  14. 10
      ui/app/components/app/modals/tests/account-details-modal.test.js
  15. 184
      ui/app/css/itcss/components/modal.scss

@ -93,7 +93,7 @@ describe('MetaMask', function () {
publicAddress = await addressInput.getAttribute('value') publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal')) const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal)) await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)

@ -105,7 +105,7 @@ describe('Using MetaMask with an existing account', function () {
const [address] = await driver.findElements(By.css('.readonly-input__input')) const [address] = await driver.findElements(By.css('.readonly-input__input'))
assert.equal(await address.getAttribute('value'), testAddress) assert.equal(await address.getAttribute('value'), testAddress)
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.delay(largeDelayMs) await driver.delay(largeDelayMs)
}) })
@ -116,7 +116,7 @@ describe('Using MetaMask with an existing account', function () {
const detailModal = await driver.findElement(By.css('span .modal')) const detailModal = await driver.findElement(By.css('span .modal'))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(detailModal)) await driver.wait(until.stalenessOf(detailModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)
}) })

@ -100,7 +100,7 @@ describe('MetaMask', function () {
const accountModal = await driver.findElement(By.css('span .modal')) const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal)) await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)

@ -125,7 +125,7 @@ describe('MetaMask', function () {
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)
const accountModal = await driver.findElement(By.css('span .modal')) const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal)) await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)

@ -94,7 +94,7 @@ describe('MetaMask', function () {
publicAddress = await addressInput.getAttribute('value') publicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal')) const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal)) await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)

@ -128,7 +128,7 @@ describe('MetaMask', function () {
const newPublicAddress = await addressInput.getAttribute('value') const newPublicAddress = await addressInput.getAttribute('value')
const accountModal = await driver.findElement(By.css('span .modal')) const accountModal = await driver.findElement(By.css('span .modal'))
await driver.clickElement(By.css('.account-modal-close')) await driver.clickElement(By.css('.account-modal__close'))
await driver.wait(until.stalenessOf(accountModal)) await driver.wait(until.stalenessOf(accountModal))
await driver.delay(regularDelayMs) await driver.delay(regularDelayMs)

@ -42,9 +42,9 @@ export default class AccountDetailsModal extends Component {
} }
return ( return (
<AccountModalContainer> <AccountModalContainer className="account-details-modal">
<EditableLabel <EditableLabel
className="account-modal__name" className="account-details-modal__name"
defaultValue={name} defaultValue={name}
onSubmit={(label) => setAccountLabel(address, label)} onSubmit={(label) => setAccountLabel(address, label)}
/> />
@ -56,11 +56,11 @@ export default class AccountDetailsModal extends Component {
}} }}
/> />
<div className="account-modal-divider" /> <div className="account-details-modal__divider" />
<Button <Button
type="secondary" type="secondary"
className="account-modal__button" className="account-details-modal__button"
onClick={() => { onClick={() => {
global.platform.openTab({ url: genAccountLink(address, network, rpcPrefs) }) global.platform.openTab({ url: genAccountLink(address, network, rpcPrefs) })
}} }}
@ -75,7 +75,7 @@ export default class AccountDetailsModal extends Component {
? ( ? (
<Button <Button
type="secondary" type="secondary"
className="account-modal__button" className="account-details-modal__button"
onClick={() => showExportPrivateKeyModal()} onClick={() => showExportPrivateKeyModal()}
> >
{this.context.t('exportPrivateKey')} {this.context.t('exportPrivateKey')}

@ -0,0 +1,37 @@
.account-details-modal {
&__name {
margin-top: 9px;
font-size: 20px;
}
&__button {
margin-top: 17px;
padding: 10px 22px;
width: 286px;
}
&__divider {
width: 100%;
height: 1px;
margin: 19px 0 8px 0;
background-color: $alto;
}
& .qr-header {
margin-top: 9px;
font-size: 20px;
}
& .qr-wrapper {
margin-top: 5px;
}
& .ellip-address-wrapper {
display: flex;
justify-content: center;
border: 1px solid $alto;
padding: 5px 10px;
margin-top: 7px;
width: 286px;
}
}

@ -1,9 +1,11 @@
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import React from 'react' import React from 'react'
import Identicon from '../../../ui/identicon' import Identicon from '../../../ui/identicon'
import classnames from 'classnames'
export default function AccountModalContainer (props, context) { export default function AccountModalContainer (props, context) {
const { const {
className,
selectedIdentity, selectedIdentity,
showBackButton, showBackButton,
backButtonAction, backButtonAction,
@ -12,8 +14,8 @@ export default function AccountModalContainer (props, context) {
} = props } = props
return ( return (
<div style={{ borderRadius: '4px' }}> <div className={classnames(className, 'account-modal')} style={{ borderRadius: '4px' }}>
<div className="account-modal-container"> <div className="account-modal__container">
<div> <div>
<Identicon <Identicon
address={selectedIdentity.address} address={selectedIdentity.address}
@ -21,12 +23,12 @@ export default function AccountModalContainer (props, context) {
/> />
</div> </div>
{showBackButton && ( {showBackButton && (
<div className="account-modal-back" onClick={backButtonAction}> <div className="account-modal__back" onClick={backButtonAction}>
<i className="fa fa-angle-left fa-lg" /> <i className="fa fa-angle-left fa-lg" />
<span className="account-modal-back__text">{' ' + context.t('back')}</span> <span className="account-modal__text">{' ' + context.t('back')}</span>
</div> </div>
)} )}
<button className="account-modal-close" onClick={hideModal} /> <button className="account-modal__close" onClick={hideModal} />
{children} {children}
</div> </div>
</div> </div>
@ -44,6 +46,7 @@ AccountModalContainer.defaultProps = {
} }
AccountModalContainer.propTypes = { AccountModalContainer.propTypes = {
className: PropTypes.string,
selectedIdentity: PropTypes.object.isRequired, selectedIdentity: PropTypes.object.isRequired,
showBackButton: PropTypes.bool, showBackButton: PropTypes.bool,
backButtonAction: PropTypes.func, backButtonAction: PropTypes.func,

@ -0,0 +1,50 @@
// Account Modal Container
.account-modal {
&__container {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
position: relative;
padding: 5px 0 31px 0;
border: 1px solid $silver;
border-radius: 4px;
}
&__back {
color: $dusty-gray;
position: absolute;
top: 13px;
left: 17px;
cursor: pointer;
}
&__text {
margin-top: 2px;
font-size: 14px;
line-height: 18px;
}
&__close {
font-size: 40px;
background-color: transparent;
color: $dusty-gray;
position: absolute;
cursor: pointer;
top: 10px;
right: 12px;
&::after {
content: '\00D7';
}
}
& .identicon {
position: relative;
left: 0;
right: 0;
margin: 0 auto;
top: -32px;
margin-bottom: -32px;
}
}

@ -47,7 +47,7 @@ export default class ExportPrivateKeyModal extends Component {
renderPasswordLabel (privateKey) { renderPasswordLabel (privateKey) {
return ( return (
<span className="private-key-password-label"> <span className="export-private-key-modal__password-label">
{ {
privateKey privateKey
? this.context.t('copyPrivateKey') ? this.context.t('copyPrivateKey')
@ -64,7 +64,7 @@ export default class ExportPrivateKeyModal extends Component {
return ( return (
<input <input
type="password" type="password"
className="private-key-password-input" className="export-private-key-modal__password-input"
onChange={(event) => this.setState({ password: event.target.value })} onChange={(event) => this.setState({ password: event.target.value })}
/> />
) )
@ -72,8 +72,8 @@ export default class ExportPrivateKeyModal extends Component {
return ( return (
<ReadOnlyInput <ReadOnlyInput
wrapperClass="private-key-password-display-wrapper" wrapperClass="export-private-key-modal__password-display-wrapper"
inputClass="private-key-password-display-textarea" inputClass="export-private-key-modal__password-display-textarea"
textarea textarea
value={plainKey} value={plainKey}
onClick={() => copyToClipboard(plainKey)} onClick={() => copyToClipboard(plainKey)}
@ -83,12 +83,12 @@ export default class ExportPrivateKeyModal extends Component {
renderButtons (privateKey, address, hideModal) { renderButtons (privateKey, address, hideModal) {
return ( return (
<div className="export-private-key-buttons"> <div className="export-private-key-modal__buttons">
{!privateKey && ( {!privateKey && (
<Button <Button
type="default" type="default"
large large
className="export-private-key__button export-private-key__button--cancel" className="export-private-key-modal__button export-private-key-modal__button--cancel"
onClick={() => hideModal()} onClick={() => hideModal()}
> >
{this.context.t('cancel')} {this.context.t('cancel')}
@ -101,7 +101,7 @@ export default class ExportPrivateKeyModal extends Component {
onClick={() => hideModal()} onClick={() => hideModal()}
type="secondary" type="secondary"
large large
className="export-private-key__button" className="export-private-key-modal__button"
> >
{this.context.t('done')} {this.context.t('done')}
</Button> </Button>
@ -111,7 +111,7 @@ export default class ExportPrivateKeyModal extends Component {
onClick={() => this.exportAccountAndGetPrivateKey(this.state.password, address)} onClick={() => this.exportAccountAndGetPrivateKey(this.state.password, address)}
type="secondary" type="secondary"
large large
className="export-private-key__button" className="export-private-key-modal__button"
disabled={!this.state.password} disabled={!this.state.password}
> >
{this.context.t('confirm')} {this.context.t('confirm')}
@ -139,27 +139,28 @@ export default class ExportPrivateKeyModal extends Component {
return ( return (
<AccountModalContainer <AccountModalContainer
className="export-private-key-modal"
selectedIdentity={selectedIdentity} selectedIdentity={selectedIdentity}
showBackButton={previousModalState === 'ACCOUNT_DETAILS'} showBackButton={previousModalState === 'ACCOUNT_DETAILS'}
backButtonAction={() => showAccountDetailModal()} backButtonAction={() => showAccountDetailModal()}
> >
<span className="account-name">{name}</span> <span className="export-private-key-modal__account-name">{name}</span>
<ReadOnlyInput <ReadOnlyInput
wrapperClass="ellip-address-wrapper" wrapperClass="ellip-address-wrapper"
value={checksumAddress(address)} value={checksumAddress(address)}
/> />
<div className="account-modal-divider" /> <div className="export-private-key-modal__divider" />
<span className="modal-body-title">{this.context.t('showPrivateKeys')}</span> <span className="export-private-key-modal__body-title">{this.context.t('showPrivateKeys')}</span>
<div className="private-key-password"> <div className="export-private-key-modal__password">
{this.renderPasswordLabel(privateKey)} {this.renderPasswordLabel(privateKey)}
{this.renderPasswordInput(privateKey)} {this.renderPasswordInput(privateKey)}
{ {
(showWarning && warning) (showWarning && warning)
? <span className="private-key-password-error">{warning}</span> ? <span className="export-private-key-modal__password--error">{warning}</span>
: null : null
} }
</div> </div>
<div className="private-key-password-warning">{this.context.t('privateKeyWarning')}</div> <div className="export-private-key-modal__password--warning">{this.context.t('privateKeyWarning')}</div>
{this.renderButtons(privateKey, address, hideModal)} {this.renderButtons(privateKey, address, hideModal)}
</AccountModalContainer> </AccountModalContainer>
) )

@ -0,0 +1,106 @@
.export-private-key-modal {
&__body-title {
margin-top: 16px;
margin-bottom: 16px;
font-size: 18px;
}
&__divider {
width: 100%;
height: 1px;
margin: 19px 0 8px 0;
background-color: $alto;
}
&__account-name {
margin-top: 9px;
font-size: 20px;
}
&__password {
display: flex;
flex-direction: column;
}
&__password-label,
&__password--error {
color: $scorpion;
font-size: 14px;
line-height: 18px;
margin-bottom: 10px;
}
&__password--error {
color: $crimson;
margin-bottom: 0;
}
&__password-input {
padding: 10px 0 13px 17px;
font-size: 16px;
line-height: 21px;
width: 291px;
height: 44px;
}
&__password::-webkit-input-placeholder {
color: $dusty-gray;
}
&__password--warning {
border-radius: 8px;
background-color: #fff6f6;
font-size: 12px;
font-weight: 500;
line-height: 15px;
color: $crimson;
width: 292px;
padding: 9px 15px;
margin-top: 18px;
}
&__password-display-wrapper {
height: 80px;
width: 291px;
border: 1px solid $silver;
border-radius: 2px;
}
&__password-display-textarea {
color: $crimson;
font-size: 16px;
line-height: 21px;
border: none;
height: 75px;
width: 100%;
overflow: hidden;
resize: none;
padding: 9px 13px 8px;
}
&__buttons {
display: flex;
flex-direction: row;
justify-content: center;
}
&__button {
margin-top: 17px;
width: 141px;
min-width: initial;
}
&__button--cancel {
margin-right: 15px;
}
& .ellip-address-wrapper {
display: flex;
justify-content: center;
border: 1px solid $alto;
padding: 5px 10px;
margin-top: 7px;
width: 286px;
}
}

@ -1,6 +1,9 @@
@import 'account-details-modal/index';
@import 'account-modal-container/index';
@import 'cancel-transaction/index'; @import 'cancel-transaction/index';
@import 'confirm-remove-account/index'; @import 'confirm-remove-account/index';
@import 'deposit-ether-modal/index'; @import 'deposit-ether-modal/index';
@import 'export-private-key-modal/index';
@import 'hide-token-confirmation-modal/index'; @import 'hide-token-confirmation-modal/index';
@import 'notification-modal/index'; @import 'notification-modal/index';
@import 'qr-scanner/index'; @import 'qr-scanner/index';

@ -46,7 +46,7 @@ describe('Account Details Modal', function () {
}) })
it('sets account label when changing default account label', function () { it('sets account label when changing default account label', function () {
const accountLabel = wrapper.find('.account-modal__name').first() const accountLabel = wrapper.find('.account-details-modal__name').first()
accountLabel.simulate('submit', 'New Label') accountLabel.simulate('submit', 'New Label')
assert(props.setAccountLabel.calledOnce) assert(props.setAccountLabel.calledOnce)
@ -54,7 +54,7 @@ describe('Account Details Modal', function () {
}) })
it('opens new tab when view block explorer is clicked', function () { it('opens new tab when view block explorer is clicked', function () {
const modalButton = wrapper.find('.account-modal__button') const modalButton = wrapper.find('.account-details-modal__button')
const etherscanLink = modalButton.first() const etherscanLink = modalButton.first()
etherscanLink.simulate('click') etherscanLink.simulate('click')
@ -62,7 +62,7 @@ describe('Account Details Modal', function () {
}) })
it('shows export private key modal when clicked', function () { it('shows export private key modal when clicked', function () {
const modalButton = wrapper.find('.account-modal__button') const modalButton = wrapper.find('.account-details-modal__button')
const etherscanLink = modalButton.last() const etherscanLink = modalButton.last()
etherscanLink.simulate('click') etherscanLink.simulate('click')
@ -73,9 +73,9 @@ describe('Account Details Modal', function () {
const blockExplorerUrl = 'https://block.explorer' const blockExplorerUrl = 'https://block.explorer'
wrapper.setProps({ rpcPrefs: { blockExplorerUrl } }) wrapper.setProps({ rpcPrefs: { blockExplorerUrl } })
const modalButton = wrapper.find('.account-modal__button') const modalButton = wrapper.find('.account-details-modal__button')
const blockExplorerLink = modalButton.first() const blockExplorerLink = modalButton.first()
assert.equal(blockExplorerLink.html(), '<button class="button btn-secondary account-modal__button">blockExplorerView</button>') assert.equal(blockExplorerLink.html(), '<button class="button btn-secondary account-details-modal__button">blockExplorerView</button>')
}) })
}) })

@ -28,187 +28,3 @@
.modal > div:focus { .modal > div:focus {
outline: none !important; outline: none !important;
} }
// Account Modal Container
.account-modal-container {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
position: relative;
padding: 5px 0 31px 0;
border: 1px solid $silver;
border-radius: 4px;
button {
cursor: pointer;
}
}
.account-modal-back {
color: $dusty-gray;
position: absolute;
top: 13px;
left: 17px;
cursor: pointer;
&__text {
margin-top: 2px;
font-size: 14px;
line-height: 18px;
}
}
.account-modal-close {
font-size: 40px;
background-color: transparent;
color: $dusty-gray;
position: absolute;
top: 10px;
right: 12px;
}
.account-modal-close::after {
content: '\00D7';
}
.account-modal-container .identicon {
position: relative;
left: 0;
right: 0;
margin: 0 auto;
top: -32px;
margin-bottom: -32px;
}
// Account Details Modal
.account-modal-container {
.qr-code__header {
margin-top: 9px;
font-size: 20px;
}
.qr-code__wrapper {
margin-top: 5px;
}
.ellip-address-wrapper {
display: flex;
justify-content: center;
border: 1px solid $alto;
padding: 5px 10px;
margin-top: 7px;
width: 286px;
}
.account-modal__button {
margin-top: 17px;
padding: 10px 22px;
width: 286px;
}
}
.account-modal-divider {
width: 100%;
height: 1px;
margin: 19px 0 8px 0;
background-color: $alto;
}
// Export Private Key Modal
.account-modal-container .account-name {
margin-top: 9px;
font-size: 20px;
}
.account-modal-container .modal-body-title {
margin-top: 16px;
margin-bottom: 16px;
font-size: 18px;
}
.account-modal__name {
margin-top: 9px;
font-size: 20px;
}
.private-key-password {
display: flex;
flex-direction: column;
}
.private-key-password-label,
.private-key-password-error {
color: $scorpion;
font-size: 14px;
line-height: 18px;
margin-bottom: 10px;
}
.private-key-password-error {
color: $crimson;
margin-bottom: 0;
}
.private-key-password-input {
padding: 10px 0 13px 17px;
font-size: 16px;
line-height: 21px;
width: 291px;
height: 44px;
}
.private-key-password::-webkit-input-placeholder {
color: $dusty-gray;
}
.private-key-password-warning {
border-radius: 8px;
background-color: #fff6f6;
font-size: 12px;
font-weight: 500;
line-height: 15px;
color: $crimson;
width: 292px;
padding: 9px 15px;
margin-top: 18px;
}
.export-private-key-buttons {
display: flex;
flex-direction: row;
justify-content: center;
}
.export-private-key__button {
margin-top: 17px;
width: 141px;
min-width: initial;
}
.export-private-key__button--cancel {
margin-right: 15px;
}
.private-key-password-display-wrapper {
height: 80px;
width: 291px;
border: 1px solid $silver;
border-radius: 2px;
}
.private-key-password-display-textarea {
color: $crimson;
font-size: 16px;
line-height: 21px;
border: none;
height: 75px;
width: 100%;
overflow: hidden;
resize: none;
padding: 9px 13px 8px;
}

Loading…
Cancel
Save