Unify Spinner / Refresh Styles (#1032)
* Unify spinner styles, enforce more SuitCSS style names * Unify spinner styles, enforce more SuitCSS style names * Hide refresh offline, adjust colors correctly.
This commit is contained in:
parent
42afff3ef2
commit
eaa9ac392c
|
@ -1,5 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36">
|
||||
<g class="nc-icon-wrapper" fill="#000000">
|
||||
<path d="M26.47 9.53C24.3 7.35 21.32 6 18 6 11.37 6 6 11.37 6 18s5.37 12 12 12c5.94 0 10.85-4.33 11.81-10h-3.04c-.91 4.01-4.49 7-8.77 7-4.97 0-9-4.03-9-9s4.03-9 9-9c2.49 0 4.71 1.03 6.34 2.66L20 16h10V6l-3.53 3.53z"></path>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 378 B |
|
@ -17,7 +17,6 @@
|
|||
&-refresh {
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin: 0px 0.5rem;
|
||||
padding: 0;
|
||||
height: 1.4rem;
|
||||
width: 1.2rem;
|
||||
|
@ -77,9 +76,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
&-balance-wrapper {
|
||||
&-balance {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
&-amount {
|
||||
margin-right: $space-sm;
|
||||
}
|
||||
}
|
||||
|
||||
&-list {
|
||||
|
|
|
@ -5,10 +5,9 @@ import React from 'react';
|
|||
import translate from 'translations';
|
||||
import './AccountInfo.scss';
|
||||
import Spinner from 'components/ui/Spinner';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { getNetworkConfig, getOffline } from 'selectors/config';
|
||||
import { AppState } from 'reducers';
|
||||
import { connect } from 'react-redux';
|
||||
import refreshIcon from 'assets/images/refresh.svg';
|
||||
import { TSetAccountBalance, setAccountBalance } from 'actions/wallet';
|
||||
|
||||
interface OwnProps {
|
||||
|
@ -18,6 +17,7 @@ interface OwnProps {
|
|||
interface StateProps {
|
||||
balance: Balance;
|
||||
network: NetworkConfig;
|
||||
isOffline: boolean;
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -70,7 +70,7 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
};
|
||||
|
||||
public render() {
|
||||
const { network, balance } = this.props;
|
||||
const { network, balance, isOffline } = this.props;
|
||||
const { address, showLongBalance, confirmAddr } = this.state;
|
||||
const { blockExplorer, tokenExplorer } = network;
|
||||
const wallet = this.props.wallet as LedgerWallet | TrezorWallet;
|
||||
|
@ -114,30 +114,30 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
<div className="AccountInfo-section">
|
||||
<h5 className="AccountInfo-section-header">{translate('sidebar_AccountBal')}</h5>
|
||||
<ul className="AccountInfo-list">
|
||||
<li className="AccountInfo-list-item AccountInfo-balance-wrapper">
|
||||
<li className="AccountInfo-list-item AccountInfo-balance">
|
||||
<span
|
||||
className="AccountInfo-list-item-clickable AccountInfo-balance-amount mono wrap"
|
||||
onClick={this.toggleShowLongBalance}
|
||||
>
|
||||
<UnitDisplay
|
||||
value={balance.wei}
|
||||
unit={'ether'}
|
||||
displayShortBalance={!showLongBalance}
|
||||
checkOffline={true}
|
||||
symbol={balance.wei ? network.name : null}
|
||||
/>
|
||||
</span>
|
||||
{balance.isPending ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<span
|
||||
className="AccountInfo-list-item-clickable mono wrap"
|
||||
onClick={this.toggleShowLongBalance}
|
||||
>
|
||||
<UnitDisplay
|
||||
value={balance.wei}
|
||||
unit={'ether'}
|
||||
displayShortBalance={!showLongBalance}
|
||||
checkOffline={true}
|
||||
symbol={balance.wei ? network.name : null}
|
||||
/>
|
||||
</span>
|
||||
!isOffline && (
|
||||
<button
|
||||
className="AccountInfo-section-refresh"
|
||||
onClick={this.props.setAccountBalance}
|
||||
>
|
||||
<img src={refreshIcon} />
|
||||
<i className="fa fa-refresh" />
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -179,7 +179,8 @@ class AccountInfo extends React.Component<Props, State> {
|
|||
function mapStateToProps(state: AppState): StateProps {
|
||||
return {
|
||||
balance: state.wallet.balance,
|
||||
network: getNetworkConfig(state)
|
||||
network: getNetworkConfig(state),
|
||||
isOffline: getOffline(state)
|
||||
};
|
||||
}
|
||||
const mapDispatchToProps: DispatchProps = { setAccountBalance };
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.Spinner {
|
||||
display: block;
|
||||
margin: auto;
|
||||
&-spinner {
|
||||
text-align: center;
|
||||
padding: 1.6rem;
|
||||
}
|
||||
|
||||
&-title {
|
||||
|
|
|
@ -158,7 +158,9 @@ class EquivalentValues extends React.Component<Props, State> {
|
|||
) : ratesError ? (
|
||||
<h5>{ratesError}</h5>
|
||||
) : isFetching ? (
|
||||
<Spinner size="x2" />
|
||||
<div className="EquivalentValues-spinner">
|
||||
<Spinner size="x3" />
|
||||
</div>
|
||||
) : (
|
||||
<div className="EquivalentValues-values">
|
||||
{pairRates.length ? (
|
||||
|
|
|
@ -1,27 +1,24 @@
|
|||
@import 'common/sass/variables';
|
||||
@import 'common/sass/mixins';
|
||||
|
||||
.nonce {
|
||||
&-label-wrapper {
|
||||
.Nonce {
|
||||
&-label {
|
||||
align-items: center;
|
||||
margin-bottom: $space-xs;
|
||||
> label {
|
||||
&-text {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
&-input-wrapper {
|
||||
&-field {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-refresh {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
margin: 0 1rem;
|
||||
height: 2.55rem;
|
||||
@include reset-button;
|
||||
height: $input-height-base;
|
||||
opacity: 0.3;
|
||||
transition: opacity 300ms;
|
||||
|
||||
> img {
|
||||
height: 1.4rem;
|
||||
}
|
||||
|
@ -33,4 +30,17 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-spinner {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
&-spinner,
|
||||
&-refresh {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) translateZ(0);
|
||||
margin: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import React from 'react';
|
||||
import { NonceFieldFactory } from 'components/NonceFieldFactory';
|
||||
import Help from 'components/ui/Help';
|
||||
import RefreshIcon from 'assets/images/refresh.svg';
|
||||
import './NonceField.scss';
|
||||
import { InlineSpinner } from 'components/ui/InlineSpinner';
|
||||
import { Spinner } from 'components/ui';
|
||||
import { connect } from 'react-redux';
|
||||
import { getNonceRequested, TGetNonceRequested } from 'actions/transaction';
|
||||
import { nonceRequestPending } from 'selectors/transaction';
|
||||
import { getOffline } from 'selectors/config';
|
||||
import { AppState } from 'reducers';
|
||||
|
||||
interface OwnProps {
|
||||
|
@ -14,7 +14,8 @@ interface OwnProps {
|
|||
}
|
||||
|
||||
interface StateProps {
|
||||
nonePending: boolean;
|
||||
isOffline: boolean;
|
||||
noncePending: boolean;
|
||||
}
|
||||
|
||||
interface DispatchProps {
|
||||
|
@ -25,35 +26,44 @@ type Props = OwnProps & DispatchProps & StateProps;
|
|||
|
||||
class NonceField extends React.Component<Props> {
|
||||
public render() {
|
||||
const { alwaysDisplay, requestNonce, nonePending } = this.props;
|
||||
const { alwaysDisplay, requestNonce, noncePending, isOffline } = this.props;
|
||||
return (
|
||||
<NonceFieldFactory
|
||||
withProps={({ nonce: { raw, value }, onChange, readOnly, shouldDisplay }) => {
|
||||
return alwaysDisplay || shouldDisplay ? (
|
||||
<React.Fragment>
|
||||
<div className="nonce-label-wrapper flex-wrapper">
|
||||
<label className="nonce-label">Nonce</label>
|
||||
<div className="Nonce-label flex-wrapper">
|
||||
<label className="Nonce-label-text">Nonce</label>
|
||||
<Help
|
||||
size={'x1'}
|
||||
link={
|
||||
'https://myetherwallet.github.io/knowledge-base/transactions/what-is-nonce.html'
|
||||
}
|
||||
/>
|
||||
<div className="flex-spacer" />
|
||||
<InlineSpinner active={nonePending} text="Calculating" />
|
||||
</div>
|
||||
<div className="nonce-input-wrapper">
|
||||
<div className="Nonce-field">
|
||||
<input
|
||||
className={`form-control nonce-input ${!!value ? 'is-valid' : 'is-invalid'}`}
|
||||
className={`Nonce-field-input form-control ${
|
||||
!!value ? 'is-valid' : 'is-invalid'
|
||||
}`}
|
||||
type="number"
|
||||
placeholder="e.g. 7"
|
||||
value={raw}
|
||||
readOnly={readOnly}
|
||||
onChange={onChange}
|
||||
disabled={noncePending}
|
||||
/>
|
||||
<button className="nonce-refresh" onClick={requestNonce}>
|
||||
<img src={RefreshIcon} alt="refresh" />
|
||||
</button>
|
||||
{noncePending ? (
|
||||
<div className="Nonce-spinner">
|
||||
<Spinner />
|
||||
</div>
|
||||
) : (
|
||||
!isOffline && (
|
||||
<button className="Nonce-refresh" onClick={requestNonce}>
|
||||
<i className="fa fa-refresh" />
|
||||
</button>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
) : null;
|
||||
|
@ -63,9 +73,10 @@ class NonceField extends React.Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
const mapStateToProps = (state: AppState): StateProps => {
|
||||
return {
|
||||
nonePending: nonceRequestPending(state)
|
||||
isOffline: getOffline(state),
|
||||
noncePending: nonceRequestPending(state)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -8,19 +8,3 @@
|
|||
left: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
.Calculating-limit {
|
||||
color: rgba(51, 51, 51, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
}
|
||||
.Spinner {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
.inline-spinner {
|
||||
@import 'common/sass/variables';
|
||||
|
||||
.InlineSpinner {
|
||||
color: $gray-light;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
.Spinner {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&--fade {
|
||||
&-enter,
|
||||
&-exit {
|
||||
transition: opacity 300ms;
|
||||
transition: opacity $transition-speed;
|
||||
}
|
||||
|
||||
&-enter {
|
||||
|
|
|
@ -3,13 +3,15 @@ import { CSSTransition } from 'react-transition-group';
|
|||
import { Spinner } from 'components/ui';
|
||||
import './InlineSpinner.scss';
|
||||
|
||||
export const InlineSpinner: React.SFC<{
|
||||
interface Props {
|
||||
active: boolean;
|
||||
text?: string;
|
||||
}> = ({ active, text }) => (
|
||||
<CSSTransition in={active} timeout={300} classNames="inline-spinner--fade">
|
||||
}
|
||||
|
||||
export const InlineSpinner: React.SFC<Props> = ({ active, text }) => (
|
||||
<CSSTransition in={active} timeout={300} classNames="InlineSpinner--fade">
|
||||
{/* TODO: when react-transition-group v2.3 releases, use '-done' classes instead of conditional 'active' class https://github.com/reactjs/react-transition-group/issues/274 */}
|
||||
<div className={`Calculating-limit small ${active ? 'active' : ''}`}>
|
||||
<div className="InlineSpinner small">
|
||||
{text}
|
||||
<Spinner />
|
||||
</div>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
@import 'common/sass/variables';
|
||||
|
||||
.Spinner {
|
||||
animation: rotate 2s linear infinite;
|
||||
|
||||
|
@ -39,7 +41,7 @@
|
|||
|
||||
&-dark {
|
||||
& .path {
|
||||
stroke: #163151;
|
||||
stroke: $ether-navy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,3 +14,4 @@ export { default as TitleBar } from './TitleBar';
|
|||
export { default as HelpLink } from './HelpLink';
|
||||
export * from './ConditionalInput';
|
||||
export * from './Expandable';
|
||||
export * from './InlineSpinner';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
$transition: 120ms opacity ease,
|
||||
120ms color ease,
|
||||
120ms background-color ease,
|
||||
120ms border-color ease;
|
||||
$transition-speed: 120ms;
|
||||
$transition: $transition-speed opacity ease,
|
||||
$transition-speed color ease,
|
||||
$transition-speed background-color ease,
|
||||
$transition-speed border-color ease;
|
||||
|
|
Loading…
Reference in New Issue