Ui 2 additional MUI replacements (#5623)
* Loader spinner * Progressbar conversion * Update Progress * Transfer operational again * Remove List/ListItem from features * Remove extra animation * Remove iconButton * Remove underline(input to be replaced) * Convert Sort to Popup * Remove unused AutoComplete component * Simplify ModalBox * Allow empty Actionbar * Adjust shapeshift icon * Simplify MUI theme (before removal) * Update tests
This commit is contained in:
parent
c5fa9844f2
commit
c27d96a4f1
@ -101,8 +101,12 @@ class Requests extends Component {
|
|||||||
: (
|
: (
|
||||||
<Progress
|
<Progress
|
||||||
max={ 6 }
|
max={ 6 }
|
||||||
mode={ state.type === WAITING_STATE ? 'indeterminate' : 'determinate' }
|
isDeterminate={ state.type !== WAITING_STATE }
|
||||||
value={ state.type === DONE_STATE ? +request.blockHeight : 6 }
|
value={
|
||||||
|
state.type === DONE_STATE
|
||||||
|
? +request.blockHeight
|
||||||
|
: 6
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
/* This file is part of Parity.
|
|
||||||
/*
|
|
||||||
/* Parity is free software: you can redistribute it and/or modify
|
|
||||||
/* it under the terms of the GNU General Public License as published by
|
|
||||||
/* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
/* (at your option) any later version.
|
|
||||||
/*
|
|
||||||
/* Parity is distributed in the hope that it will be useful,
|
|
||||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
/* GNU General Public License for more details.
|
|
||||||
/*
|
|
||||||
/* You should have received a copy of the GNU General Public License
|
|
||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.sortButton {
|
|
||||||
min-width: 50px !important;
|
|
||||||
}
|
|
@ -18,14 +18,12 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
import IconMenu from 'material-ui/IconMenu';
|
|
||||||
import MenuItem from 'material-ui/MenuItem';
|
|
||||||
|
|
||||||
import Button from '~/ui/Button';
|
import Button from '~/ui/Button';
|
||||||
import { SortIcon } from '~/ui/Icons';
|
import { SortIcon } from '~/ui/Icons';
|
||||||
|
import List from '~/ui/List';
|
||||||
|
import Popup from '~/ui/Popup';
|
||||||
|
|
||||||
import SortStore from './sortStore';
|
import SortStore from './sortStore';
|
||||||
import styles from './sort.css';
|
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export default class ActionbarSort extends Component {
|
export default class ActionbarSort extends Component {
|
||||||
@ -53,102 +51,73 @@ export default class ActionbarSort extends Component {
|
|||||||
const { showDefault } = this.props;
|
const { showDefault } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconMenu
|
<Popup
|
||||||
iconButtonElement={
|
isOpen={ this.store.menuOpen }
|
||||||
|
trigger={
|
||||||
<Button
|
<Button
|
||||||
className={ styles.sortButton }
|
|
||||||
label=''
|
|
||||||
icon={ <SortIcon /> }
|
icon={ <SortIcon /> }
|
||||||
onClick={ this.store.handleMenuOpen }
|
onClick={ this.store.handleMenuOpen }
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
open={ this.store.menuOpen }
|
|
||||||
onRequestChange={ this.store.handleMenuChange }
|
|
||||||
onItemTouchTap={ this.store.handleSortChange }
|
|
||||||
targetOrigin={ { horizontal: 'right', vertical: 'top' } }
|
|
||||||
anchorOrigin={ { horizontal: 'right', vertical: 'top' } }
|
|
||||||
touchTapCloseDelay={ 0 }
|
|
||||||
>
|
>
|
||||||
{
|
<List
|
||||||
showDefault
|
items={ [
|
||||||
? this.renderMenuItem('', (
|
showDefault && this.renderMenuItem('', (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='ui.actionbar.sort.typeDefault'
|
id='ui.actionbar.sort.typeDefault'
|
||||||
defaultMessage='Default'
|
defaultMessage='Default'
|
||||||
/>
|
/>
|
||||||
|
)),
|
||||||
|
this.renderMenuItem('tags', (
|
||||||
|
<FormattedMessage
|
||||||
|
id='ui.actionbar.sort.typeTags'
|
||||||
|
defaultMessage='Sort by tags'
|
||||||
|
/>
|
||||||
|
)),
|
||||||
|
this.renderMenuItem('name', (
|
||||||
|
<FormattedMessage
|
||||||
|
id='ui.actionbar.sort.typeName'
|
||||||
|
defaultMessage='Sort by name'
|
||||||
|
/>
|
||||||
|
)),
|
||||||
|
this.renderMenuItem('eth', (
|
||||||
|
<FormattedMessage
|
||||||
|
id='ui.actionbar.sort.typeEth'
|
||||||
|
defaultMessage='Sort by ETH'
|
||||||
|
/>
|
||||||
))
|
))
|
||||||
: null
|
].concat(this.renderSortByMetas()) }
|
||||||
}
|
onClick={ this.store.handleSortChange }
|
||||||
{
|
/>
|
||||||
this.renderMenuItem('tags', (
|
</Popup>
|
||||||
<FormattedMessage
|
|
||||||
id='ui.actionbar.sort.typeTags'
|
|
||||||
defaultMessage='Sort by tags'
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.renderMenuItem('name', (
|
|
||||||
<FormattedMessage
|
|
||||||
id='ui.actionbar.sort.typeName'
|
|
||||||
defaultMessage='Sort by name'
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
{
|
|
||||||
this.renderMenuItem('eth', (
|
|
||||||
<FormattedMessage
|
|
||||||
id='ui.actionbar.sort.typeEth'
|
|
||||||
defaultMessage='Sort by ETH'
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
{ this.renderSortByMetas() }
|
|
||||||
</IconMenu>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSortByMetas () {
|
renderSortByMetas () {
|
||||||
const { metas } = this.props;
|
const { metas } = this.props;
|
||||||
|
|
||||||
return metas
|
return metas.map((meta) => {
|
||||||
.map((meta, index) => {
|
const label = (
|
||||||
const label = (
|
<FormattedMessage
|
||||||
<FormattedMessage
|
id='ui.actionbar.sort.sortBy'
|
||||||
id='ui.actionbar.sort.sortBy'
|
defaultMessage='Sort by {label}'
|
||||||
defaultMessage='Sort by {label}'
|
values={ {
|
||||||
values={ {
|
label: meta.label
|
||||||
label: meta.label
|
} }
|
||||||
} }
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
|
|
||||||
return this.renderMenuItem(meta.key, label, index);
|
return this.renderMenuItem(meta.key, label);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMenuItem (value, label, key = null) {
|
renderMenuItem (key, label) {
|
||||||
const { order } = this.props;
|
const { order } = this.props;
|
||||||
|
|
||||||
const props = {};
|
return {
|
||||||
|
isActive: order === key,
|
||||||
if (key !== null) {
|
key,
|
||||||
props.key = key;
|
label
|
||||||
}
|
};
|
||||||
|
|
||||||
const checked = order === value;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MenuItem
|
|
||||||
checked={ checked }
|
|
||||||
value={ value }
|
|
||||||
primaryText={ label }
|
|
||||||
innerDivStyle={ {
|
|
||||||
paddingLeft: checked ? 50 : 16
|
|
||||||
} }
|
|
||||||
{ ...props }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,8 @@ export default class SortStore {
|
|||||||
this.menuOpen = open;
|
this.menuOpen = open;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action handleSortChange = (event, child) => {
|
@action handleSortChange = (event, order) => {
|
||||||
const order = child.props.value;
|
this.handleMenuChange(false);
|
||||||
|
|
||||||
this.onChange(order);
|
this.onChange(order);
|
||||||
this.saveOrder(order);
|
this.saveOrder(order);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,10 @@ import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
|||||||
import styles from './actionbar.css';
|
import styles from './actionbar.css';
|
||||||
|
|
||||||
export default function Actionbar ({ buttons, children, className, title }) {
|
export default function Actionbar ({ buttons, children, className, title }) {
|
||||||
|
if (!buttons && !title) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ `${styles.actionbar} ${className}` }>
|
<div className={ `${styles.actionbar} ${className}` }>
|
||||||
<h3 className={ styles.title }>
|
<h3 className={ styles.title }>
|
||||||
|
@ -21,7 +21,10 @@ import Actionbar from './actionbar';
|
|||||||
|
|
||||||
function renderShallow (props) {
|
function renderShallow (props) {
|
||||||
return shallow(
|
return shallow(
|
||||||
<Actionbar { ...props } />
|
<Actionbar
|
||||||
|
title='title'
|
||||||
|
{ ...props }
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { List, ListItem } from 'material-ui/List';
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
import Checkbox from '~/ui/Form/Checkbox';
|
import Checkbox from '~/ui/Form/Checkbox';
|
||||||
|
import List from '~/ui/List';
|
||||||
|
|
||||||
import defaults, { MODES } from './defaults';
|
import defaults, { MODES } from './defaults';
|
||||||
import Store from './store';
|
import Store from './store';
|
||||||
@ -34,14 +34,14 @@ export default class Features extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List>
|
<List
|
||||||
{
|
items={
|
||||||
Object
|
Object
|
||||||
.keys(defaults)
|
.keys(defaults)
|
||||||
.filter((key) => defaults[key].mode !== MODES.PRODUCTION)
|
.filter((key) => defaults[key].mode !== MODES.PRODUCTION)
|
||||||
.map(this.renderItem)
|
.map(this.renderItem)
|
||||||
}
|
}
|
||||||
</List>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,22 +49,22 @@ export default class Features extends Component {
|
|||||||
const feature = defaults[key];
|
const feature = defaults[key];
|
||||||
const onCheck = () => this.store.toggleActive(key);
|
const onCheck = () => this.store.toggleActive(key);
|
||||||
|
|
||||||
return (
|
return {
|
||||||
<ListItem
|
description: (
|
||||||
key={ `feature_${key}` }
|
<div className={ styles.description }>
|
||||||
leftCheckbox={
|
{ feature.description }
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
key,
|
||||||
|
label: (
|
||||||
|
<div>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={ this.store.active[key] }
|
checked={ this.store.active[key] }
|
||||||
onClick={ onCheck }
|
onClick={ onCheck }
|
||||||
/>
|
/>
|
||||||
}
|
<span>{ feature.name }</span>
|
||||||
primaryText={ feature.name }
|
</div>
|
||||||
secondaryText={
|
)
|
||||||
<div className={ styles.description }>
|
};
|
||||||
{ feature.description }
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ function render (props = { visible: true }) {
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('views/Settings/Features', () => {
|
describe('ui/Features', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
render();
|
render();
|
||||||
});
|
});
|
||||||
@ -80,10 +80,6 @@ describe('views/Settings/Features', () => {
|
|||||||
it('renders an item', () => {
|
it('renders an item', () => {
|
||||||
expect(item).not.to.be.null;
|
expect(item).not.to.be.null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the correct name', () => {
|
|
||||||
expect(item.props.primaryText).to.equal(defaults[key].name);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,6 @@ import { connect } from 'react-redux';
|
|||||||
import keycode, { codes } from 'keycode';
|
import keycode, { codes } from 'keycode';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline';
|
|
||||||
|
|
||||||
import apiutil from '@parity/api/util';
|
import apiutil from '@parity/api/util';
|
||||||
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
||||||
@ -36,8 +35,6 @@ import Portal from '~/ui/Portal';
|
|||||||
import AddressSelectStore from './addressSelectStore';
|
import AddressSelectStore from './addressSelectStore';
|
||||||
import styles from './addressSelect.css';
|
import styles from './addressSelect.css';
|
||||||
|
|
||||||
const BOTTOM_BORDER_STYLE = { borderBottom: 'solid 3px' };
|
|
||||||
|
|
||||||
// Current Form ID
|
// Current Form ID
|
||||||
let currentId = 1;
|
let currentId = 1;
|
||||||
|
|
||||||
@ -178,9 +175,8 @@ class AddressSelect extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderContent () {
|
renderContent () {
|
||||||
const { muiTheme } = this.context;
|
|
||||||
const { hint, disabled, label, readOnly } = this.props;
|
const { hint, disabled, label, readOnly } = this.props;
|
||||||
const { expanded, inputFocused } = this.state;
|
const { expanded } = this.state;
|
||||||
|
|
||||||
if (disabled || readOnly) {
|
if (disabled || readOnly) {
|
||||||
return null;
|
return null;
|
||||||
@ -213,16 +209,14 @@ class AddressSelect extends Component {
|
|||||||
onChange={ this.handleChange }
|
onChange={ this.handleChange }
|
||||||
ref={ this.setInputRef }
|
ref={ this.setInputRef }
|
||||||
/>
|
/>
|
||||||
{ this.renderLoader() }
|
{
|
||||||
</div>
|
this.store.loading && (
|
||||||
|
<Loading
|
||||||
<div className={ styles.underline }>
|
className={ styles.loader }
|
||||||
<TextFieldUnderline
|
size='small'
|
||||||
focus={ inputFocused }
|
/>
|
||||||
focusStyle={ BOTTOM_BORDER_STYLE }
|
)
|
||||||
muiTheme={ muiTheme }
|
}
|
||||||
style={ BOTTOM_BORDER_STYLE }
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -234,19 +228,6 @@ class AddressSelect extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLoader () {
|
|
||||||
if (!this.store.loading) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Loading
|
|
||||||
className={ styles.loader }
|
|
||||||
size={ 0.5 }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCurrentInput () {
|
renderCurrentInput () {
|
||||||
const { inputValue } = this.state;
|
const { inputValue } = this.state;
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
/* This file is part of Parity.
|
|
||||||
/*
|
|
||||||
/* Parity is free software: you can redistribute it and/or modify
|
|
||||||
/* it under the terms of the GNU General Public License as published by
|
|
||||||
/* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
/* (at your option) any later version.
|
|
||||||
/*
|
|
||||||
/* Parity is distributed in the hope that it will be useful,
|
|
||||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
/* GNU General Public License for more details.
|
|
||||||
/*
|
|
||||||
/* You should have received a copy of the GNU General Public License
|
|
||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.item {
|
|
||||||
&:last-child {
|
|
||||||
&.divider {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,268 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import keycode from 'keycode';
|
|
||||||
import { isEqual } from 'lodash';
|
|
||||||
import { MenuItem, AutoComplete as MUIAutoComplete, Divider as MUIDivider } from 'material-ui';
|
|
||||||
import { PopoverAnimationVertical } from 'material-ui/Popover';
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
|
||||||
|
|
||||||
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
|
||||||
|
|
||||||
import styles from './autocomplete.css';
|
|
||||||
|
|
||||||
// Hack to prevent "Unknown prop `disableFocusRipple` on <hr> tag" error
|
|
||||||
class Divider extends Component {
|
|
||||||
static muiName = MUIDivider.muiName;
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={ { margin: '0.25em 0' } }
|
|
||||||
className={ [styles.item, styles.divider].join(' ') }
|
|
||||||
>
|
|
||||||
<MUIDivider style={ { height: 2 } } />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class AutoComplete extends Component {
|
|
||||||
static propTypes = {
|
|
||||||
className: PropTypes.string,
|
|
||||||
disabled: PropTypes.bool,
|
|
||||||
entry: PropTypes.object,
|
|
||||||
entries: PropTypes.oneOfType([
|
|
||||||
PropTypes.array,
|
|
||||||
PropTypes.object
|
|
||||||
]),
|
|
||||||
error: nodeOrStringProptype(),
|
|
||||||
filter: PropTypes.func,
|
|
||||||
hint: nodeOrStringProptype(),
|
|
||||||
label: nodeOrStringProptype(),
|
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
onUpdateInput: PropTypes.func,
|
|
||||||
renderItem: PropTypes.func,
|
|
||||||
value: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
state = {
|
|
||||||
lastChangedValue: undefined,
|
|
||||||
entry: null,
|
|
||||||
open: false,
|
|
||||||
dataSource: [],
|
|
||||||
dividerBreaks: []
|
|
||||||
};
|
|
||||||
|
|
||||||
dividersVisibility = {};
|
|
||||||
|
|
||||||
componentWillMount () {
|
|
||||||
const dataSource = this.getDataSource();
|
|
||||||
|
|
||||||
this.setState({ dataSource });
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
|
||||||
const prevEntries = Object.keys(this.props.entries || {}).sort();
|
|
||||||
const nextEntries = Object.keys(nextProps.entries || {}).sort();
|
|
||||||
|
|
||||||
if (!isEqual(prevEntries, nextEntries)) {
|
|
||||||
const dataSource = this.getDataSource(nextProps);
|
|
||||||
|
|
||||||
this.setState({ dataSource });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { disabled, error, hint, label, value, className, onUpdateInput } = this.props;
|
|
||||||
const { open, dataSource } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MUIAutoComplete
|
|
||||||
className={ className }
|
|
||||||
disabled={ disabled }
|
|
||||||
floatingLabelText={ label }
|
|
||||||
hintText={ hint }
|
|
||||||
errorText={ error }
|
|
||||||
onNewRequest={ this.onChange }
|
|
||||||
onUpdateInput={ onUpdateInput }
|
|
||||||
searchText={ value }
|
|
||||||
onFocus={ this.onFocus }
|
|
||||||
onClose={ this.onClose }
|
|
||||||
animation={ PopoverAnimationVertical }
|
|
||||||
filter={ this.handleFilter }
|
|
||||||
popoverProps={ { open } }
|
|
||||||
openOnFocus
|
|
||||||
menuCloseDelay={ 0 }
|
|
||||||
fullWidth
|
|
||||||
floatingLabelFixed
|
|
||||||
dataSource={ dataSource }
|
|
||||||
menuProps={ { maxHeight: 400 } }
|
|
||||||
ref='muiAutocomplete'
|
|
||||||
onKeyDown={ this.onKeyDown }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
getDataSource (props = this.props) {
|
|
||||||
const { renderItem, entries } = props;
|
|
||||||
const entriesArray = (entries instanceof Array)
|
|
||||||
? entries
|
|
||||||
: Object.values(entries);
|
|
||||||
|
|
||||||
let currentDivider = 0;
|
|
||||||
let firstSet = false;
|
|
||||||
|
|
||||||
const dataSource = entriesArray.map((entry, index) => {
|
|
||||||
// Render divider
|
|
||||||
if (typeof entry === 'string' && entry.toLowerCase() === 'divider') {
|
|
||||||
// Don't add divider if nothing before
|
|
||||||
if (!firstSet) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = {
|
|
||||||
text: '',
|
|
||||||
divider: currentDivider,
|
|
||||||
isDivider: true,
|
|
||||||
value: (
|
|
||||||
<Divider />
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
currentDivider++;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
let item;
|
|
||||||
|
|
||||||
if (renderItem && typeof renderItem === 'function') {
|
|
||||||
item = renderItem(entry);
|
|
||||||
|
|
||||||
// Add the item class to the entry
|
|
||||||
const classNames = [ styles.item ].concat(item.value.props.className);
|
|
||||||
|
|
||||||
item.value = React.cloneElement(item.value, { className: classNames.join(' ') });
|
|
||||||
} else {
|
|
||||||
item = {
|
|
||||||
text: entry,
|
|
||||||
value: (
|
|
||||||
<MenuItem
|
|
||||||
className={ styles.item }
|
|
||||||
primaryText={ entry }
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!firstSet) {
|
|
||||||
item.first = true;
|
|
||||||
firstSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
item.divider = currentDivider;
|
|
||||||
item.entry = entry;
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}).filter((item) => item !== undefined);
|
|
||||||
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleFilter = (searchText, name, item) => {
|
|
||||||
if (item.isDivider) {
|
|
||||||
return this.dividersVisibility[item.divider];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.first) {
|
|
||||||
this.dividersVisibility = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const { filter } = this.props;
|
|
||||||
const show = filter(searchText, name, item);
|
|
||||||
|
|
||||||
// Show the related divider
|
|
||||||
if (show) {
|
|
||||||
this.dividersVisibility[item.divider] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return show;
|
|
||||||
}
|
|
||||||
|
|
||||||
onKeyDown = (event) => {
|
|
||||||
const { muiAutocomplete } = this.refs;
|
|
||||||
|
|
||||||
switch (keycode(event)) {
|
|
||||||
case 'down':
|
|
||||||
const { menu } = muiAutocomplete.refs;
|
|
||||||
|
|
||||||
menu && menu.handleKeyDown(event);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'enter':
|
|
||||||
case 'tab':
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
event.which = 'useless';
|
|
||||||
|
|
||||||
const e = new CustomEvent('down');
|
|
||||||
|
|
||||||
e.which = 40;
|
|
||||||
|
|
||||||
muiAutocomplete && muiAutocomplete.handleKeyDown(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange = (item, idx) => {
|
|
||||||
if (idx === -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { dataSource } = this.state;
|
|
||||||
const { entry } = dataSource[idx];
|
|
||||||
|
|
||||||
this.handleOnChange(entry);
|
|
||||||
this.setState({ entry, open: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
onClose = (event) => {
|
|
||||||
const { onUpdateInput } = this.props;
|
|
||||||
|
|
||||||
if (!onUpdateInput) {
|
|
||||||
const { entry } = this.state;
|
|
||||||
|
|
||||||
this.handleOnChange(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onFocus = () => {
|
|
||||||
const { entry } = this.props;
|
|
||||||
|
|
||||||
this.setState({ entry, open: true }, () => {
|
|
||||||
this.handleOnChange(null, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleOnChange = (value, empty) => {
|
|
||||||
const { lastChangedValue } = this.state;
|
|
||||||
|
|
||||||
if (value !== lastChangedValue) {
|
|
||||||
this.setState({ lastChangedValue: value });
|
|
||||||
this.props.onChange(value, empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -26,7 +26,7 @@ import styles from './dropdown.css';
|
|||||||
const NAME_ID = ' ';
|
const NAME_ID = ' ';
|
||||||
|
|
||||||
// FIXME: Currently does not display the selected icon alongside
|
// FIXME: Currently does not display the selected icon alongside
|
||||||
export default function Dropdown ({ className, disabled = false, error, fullWidth = true, hint, label, onBlur, onChange, onKeyDown, options, text, value }, { intl }) {
|
export default function Dropdown ({ className, disabled = false, error, fullWidth = true, hint, label, onBlur, onChange, onKeyDown, options, text, value }, context) {
|
||||||
const _onChange = (event, { value }) => onChange(event, value);
|
const _onChange = (event, { value }) => onChange(event, value);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -53,8 +53,6 @@ export default class InputChip extends Component {
|
|||||||
const { clearOnBlur, className, hint, label, tokens } = this.props;
|
const { clearOnBlur, className, hint, label, tokens } = this.props;
|
||||||
const { focused } = this.state;
|
const { focused } = this.state;
|
||||||
|
|
||||||
const classes = `${className}`;
|
|
||||||
|
|
||||||
const textFieldStyle = {
|
const textFieldStyle = {
|
||||||
height: 55
|
height: 55
|
||||||
};
|
};
|
||||||
@ -65,7 +63,7 @@ export default class InputChip extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ChipInput
|
<ChipInput
|
||||||
className={ classes }
|
className={ className }
|
||||||
ref='chipInput'
|
ref='chipInput'
|
||||||
|
|
||||||
value={ tokens }
|
value={ tokens }
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.strength {
|
.strength {
|
||||||
margin-top: 1.25em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.feedback {
|
.feedback {
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
|
margin: -2em 0 1.5em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
@ -23,12 +23,6 @@ import Progress from '~/ui/Progress';
|
|||||||
|
|
||||||
import styles from './passwordStrength.css';
|
import styles from './passwordStrength.css';
|
||||||
|
|
||||||
const BAR_STYLE = {
|
|
||||||
borderRadius: 1,
|
|
||||||
height: 7,
|
|
||||||
marginTop: '0.5em'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class PasswordStrength extends Component {
|
export default class PasswordStrength extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
input: PropTypes.string.isRequired
|
input: PropTypes.string.isRequired
|
||||||
@ -69,10 +63,6 @@ export default class PasswordStrength extends Component {
|
|||||||
|
|
||||||
const { score, feedback } = strength;
|
const { score, feedback } = strength;
|
||||||
|
|
||||||
// Score is between 0 and 4
|
|
||||||
const value = score * 100 / 5 + 20;
|
|
||||||
const color = this.getStrengthBarColor(score);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.strength }>
|
<div className={ styles.strength }>
|
||||||
<label className={ styles.label }>
|
<label className={ styles.label }>
|
||||||
@ -82,10 +72,10 @@ export default class PasswordStrength extends Component {
|
|||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
<Progress
|
<Progress
|
||||||
color={ color }
|
color={ this.getStrengthBarColor(score) }
|
||||||
determinate
|
isDeterminate
|
||||||
style={ BAR_STYLE }
|
max={ 100 }
|
||||||
value={ value }
|
value={ score * 100 / 5 + 20 }
|
||||||
/>
|
/>
|
||||||
<div className={ styles.feedback }>
|
<div className={ styles.feedback }>
|
||||||
{ this.renderFeedback(feedback) }
|
{ this.renderFeedback(feedback) }
|
||||||
@ -111,8 +101,10 @@ export default class PasswordStrength extends Component {
|
|||||||
getStrengthBarColor (score) {
|
getStrengthBarColor (score) {
|
||||||
switch (score) {
|
switch (score) {
|
||||||
case 4:
|
case 4:
|
||||||
|
return 'green';
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
return 'lightgreen';
|
return 'blue';
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return 'yellow';
|
return 'yellow';
|
||||||
|
@ -18,13 +18,12 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { range } from 'lodash';
|
import { range } from 'lodash';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
import IconButton from 'material-ui/IconButton';
|
|
||||||
|
|
||||||
import { fromWei, toWei } from '@parity/api/util/wei';
|
import { fromWei, toWei } from '@parity/api/util/wei';
|
||||||
import { bytesToHex } from '@parity/api/util/format';
|
import { bytesToHex } from '@parity/api/util/format';
|
||||||
import { ABI_TYPES, parseAbiType } from '@parity/shared/util/abi';
|
import { ABI_TYPES, parseAbiType } from '@parity/shared/util/abi';
|
||||||
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
||||||
|
|
||||||
|
import Button from '~/ui/Button';
|
||||||
import Dropdown from '~/ui/Form/Dropdown';
|
import Dropdown from '~/ui/Form/Dropdown';
|
||||||
import Input from '~/ui/Form/Input';
|
import Input from '~/ui/Form/Input';
|
||||||
import InputAddressSelect from '~/ui/Form/InputAddressSelect';
|
import InputAddressSelect from '~/ui/Form/InputAddressSelect';
|
||||||
@ -142,40 +141,16 @@ export default class TypedInput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderLength () {
|
renderLength () {
|
||||||
const iconStyle = {
|
|
||||||
width: 16,
|
|
||||||
height: 16
|
|
||||||
};
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
padding: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const plusStyle = {
|
|
||||||
...style,
|
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.25)',
|
|
||||||
borderRadius: '50%'
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={ { marginTop: '0.75em' } }>
|
<div style={ { marginTop: '0.75em' } }>
|
||||||
<IconButton
|
<Button
|
||||||
iconStyle={ iconStyle }
|
icon={ <AddIcon /> }
|
||||||
style={ plusStyle }
|
onClick={ this.onAddField }
|
||||||
onTouchTap={ this.onAddField }
|
/>
|
||||||
>
|
<Button
|
||||||
<AddIcon />
|
icon={ <RemoveIcon /> }
|
||||||
</IconButton>
|
onClick={ this.onRemoveField }
|
||||||
|
/>
|
||||||
<IconButton
|
|
||||||
iconStyle={ iconStyle }
|
|
||||||
style={ style }
|
|
||||||
onTouchTap={ this.onRemoveField }
|
|
||||||
>
|
|
||||||
<RemoveIcon />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
|
&.active {
|
||||||
|
background: rgba(0, 0, 255, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.inactive {
|
||||||
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ import { List as SemanticList } from 'semantic-ui-react';
|
|||||||
|
|
||||||
import styles from './item.css';
|
import styles from './item.css';
|
||||||
|
|
||||||
export default function Item ({ buttons, className, description, icon, label, onClick, style }) {
|
export default function Item ({ buttons, className, description, icon, isActive, label, onClick, style }) {
|
||||||
return (
|
return (
|
||||||
<SemanticList.Item
|
<SemanticList.Item
|
||||||
className={ styles.item }
|
className={ `${styles.item} ${isActive ? styles.active : styles.inactive} ${className}` }
|
||||||
onClick={ onClick }
|
onClick={ onClick }
|
||||||
style={ style }
|
style={ style }
|
||||||
>
|
>
|
||||||
@ -52,8 +52,8 @@ Item.propTypes = {
|
|||||||
buttons: PropTypes.any,
|
buttons: PropTypes.any,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
description: PropTypes.node,
|
description: PropTypes.node,
|
||||||
key: PropTypes.any,
|
|
||||||
icon: PropTypes.node,
|
icon: PropTypes.node,
|
||||||
|
isActive: PropTypes.bool,
|
||||||
label: PropTypes.node,
|
label: PropTypes.node,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
style: PropTypes.object
|
style: PropTypes.object
|
||||||
|
@ -31,11 +31,12 @@ export default function List ({ className, items, label, onClick, style }) {
|
|||||||
<LabelComponent label={ label }>
|
<LabelComponent label={ label }>
|
||||||
<SemanticList className={ `${styles.list} ${className}` }>
|
<SemanticList className={ `${styles.list} ${className}` }>
|
||||||
{
|
{
|
||||||
items.map(({ buttons, description, icon, key, label }, index) => (
|
items.filter((item) => item).map(({ buttons, description, icon, isActive, key, label }, index) => (
|
||||||
<Item
|
<Item
|
||||||
buttons={ buttons }
|
buttons={ buttons }
|
||||||
description={ description }
|
description={ description }
|
||||||
icon={ icon }
|
icon={ icon }
|
||||||
|
isActive={ isActive }
|
||||||
key={ key || index }
|
key={ key || index }
|
||||||
label={ label }
|
label={ label }
|
||||||
onClick={ wrapOnClick(key || index) }
|
onClick={ wrapOnClick(key || index) }
|
||||||
|
@ -15,29 +15,19 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import CircularProgress from 'material-ui/CircularProgress';
|
import { Loader as SemanticLoader } from 'semantic-ui-react';
|
||||||
|
|
||||||
import styles from './loading.css';
|
import styles from './loading.css';
|
||||||
|
|
||||||
export default function Loading ({ className, size, thickness }) {
|
export default function Loading ({ className, size = 'medium' }) {
|
||||||
return (
|
return (
|
||||||
<div className={ [ styles.loading, className ].join(' ') }>
|
<div className={ `${styles.loading} ${className}` }>
|
||||||
<CircularProgress
|
<SemanticLoader />
|
||||||
size={ size * 60 }
|
|
||||||
thickness={ thickness }
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading.propTypes = {
|
Loading.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
size: PropTypes.number,
|
size: PropTypes.string
|
||||||
thickness: PropTypes.number
|
|
||||||
};
|
|
||||||
|
|
||||||
Loading.defaultProps = {
|
|
||||||
className: '',
|
|
||||||
size: 2,
|
|
||||||
thickness: 3.5
|
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,7 @@ class MethodDecoding extends Component {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.loading }>
|
<div className={ styles.loading }>
|
||||||
<Loading size={ 1 } thickness={ 2 } />
|
<Loading />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,12 @@ import styles from './busy.css';
|
|||||||
export default function Busy ({ children, state, title }) {
|
export default function Busy ({ children, state, title }) {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.center }>
|
<div className={ styles.center }>
|
||||||
<div className={ styles.title }>{ title }</div>
|
<div className={ styles.title }>
|
||||||
<div className={ styles.state }>{ state }</div>
|
{ title }
|
||||||
|
</div>
|
||||||
|
<div className={ styles.state }>
|
||||||
|
{ state }
|
||||||
|
</div>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -18,8 +18,6 @@ import React, { PropTypes } from 'react';
|
|||||||
|
|
||||||
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
||||||
|
|
||||||
import Body from './body';
|
|
||||||
import Summary from './summary';
|
|
||||||
import styles from './modalBox.css';
|
import styles from './modalBox.css';
|
||||||
|
|
||||||
export default function ModalBox ({ children, icon, summary }) {
|
export default function ModalBox ({ children, icon, summary }) {
|
||||||
@ -29,8 +27,20 @@ export default function ModalBox ({ children, icon, summary }) {
|
|||||||
{ icon }
|
{ icon }
|
||||||
</div>
|
</div>
|
||||||
<div className={ styles.content }>
|
<div className={ styles.content }>
|
||||||
<Summary summary={ summary } />
|
{
|
||||||
<Body children={ children } />
|
summary && (
|
||||||
|
<div className={ styles.summary }>
|
||||||
|
{ summary }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
children && (
|
||||||
|
<div className={ styles.body }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -52,11 +52,11 @@ describe('ui/ModalBox', () => {
|
|||||||
|
|
||||||
describe('components', () => {
|
describe('components', () => {
|
||||||
it('adds the Body as supplied', () => {
|
it('adds the Body as supplied', () => {
|
||||||
expect(component.find('Body').props().children).to.deep.equal(CHILDREN);
|
expect(component.find('#testChild').text()).to.equal('testChild');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds the Summary as supplied', () => {
|
it('adds the Summary as supplied', () => {
|
||||||
expect(component.find('Summary').props().summary).to.deep.equal(SUMMARY);
|
expect(component.find('#testSummary').text()).to.equal('testSummary');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
|
|
||||||
|
|
||||||
import styles from './modalBox.css';
|
|
||||||
|
|
||||||
export default function Summary ({ summary }) {
|
|
||||||
if (!summary) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ styles.summary }>
|
|
||||||
{ summary }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Summary.propTypes = {
|
|
||||||
summary: nodeOrStringProptype()
|
|
||||||
};
|
|
@ -24,16 +24,10 @@ import styles from './page.css';
|
|||||||
export default function Page ({ buttons, className, children, padded, title }) {
|
export default function Page ({ buttons, className, children, padded, title }) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{
|
<Actionbar
|
||||||
title || buttons
|
buttons={ buttons }
|
||||||
? (
|
title={ title }
|
||||||
<Actionbar
|
/>
|
||||||
buttons={ buttons }
|
|
||||||
title={ title }
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
[
|
[
|
||||||
|
@ -14,4 +14,4 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export default from './autocomplete';
|
export default from './popup';
|
@ -15,21 +15,25 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import { Popup as SemanticPopup } from 'semantic-ui-react';
|
||||||
|
|
||||||
import styles from './modalBox.css';
|
export default function Popup ({ children, className, isOpen, trigger, triggerOn }) {
|
||||||
|
|
||||||
export default function Body ({ children }) {
|
|
||||||
if (!children) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ styles.body }>
|
<SemanticPopup
|
||||||
|
className={ className }
|
||||||
|
on={ triggerOn }
|
||||||
|
open={ isOpen }
|
||||||
|
trigger={ trigger }
|
||||||
|
>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</SemanticPopup>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Body.propTypes = {
|
Popup.propTypes = {
|
||||||
children: PropTypes.node
|
children: PropTypes.node.isRequired,
|
||||||
|
className: PropTypes.string,
|
||||||
|
isOpen: PropTypes.bool,
|
||||||
|
trigger: PropTypes.node,
|
||||||
|
triggerOn: PropTypes.string
|
||||||
};
|
};
|
@ -14,23 +14,22 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import { LinearProgress } from 'material-ui';
|
|
||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
import { Progress as SemanticProgress } from 'semantic-ui-react';
|
||||||
|
|
||||||
export default function Progress ({ className, color, determinate, max, min, style, value }) {
|
export default function Progress ({ className, color, isDeterminate, max, style, value }) {
|
||||||
return (
|
return (
|
||||||
<LinearProgress
|
<SemanticProgress
|
||||||
className={ className }
|
className={ className }
|
||||||
color={ color }
|
color={ color }
|
||||||
max={ max }
|
indicating={ !isDeterminate }
|
||||||
min={ min }
|
percent={
|
||||||
mode={
|
isDeterminate
|
||||||
determinate
|
? 100 * value / max
|
||||||
? 'determinate'
|
: 100
|
||||||
: 'indeterminate'
|
|
||||||
}
|
}
|
||||||
|
size='small'
|
||||||
style={ style }
|
style={ style }
|
||||||
value={ value }
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -38,13 +37,8 @@ export default function Progress ({ className, color, determinate, max, min, sty
|
|||||||
Progress.propTypes = {
|
Progress.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
color: PropTypes.string,
|
color: PropTypes.string,
|
||||||
determinate: PropTypes.bool,
|
isDeterminate: PropTypes.bool,
|
||||||
max: PropTypes.number,
|
max: PropTypes.number,
|
||||||
min: PropTypes.number,
|
|
||||||
style: PropTypes.object,
|
style: PropTypes.object,
|
||||||
value: PropTypes.number
|
value: PropTypes.number
|
||||||
};
|
};
|
||||||
|
|
||||||
Progress.defaultProps = {
|
|
||||||
determinate: false
|
|
||||||
};
|
|
||||||
|
@ -16,26 +16,9 @@
|
|||||||
|
|
||||||
import GeoPattern from 'geopattern';
|
import GeoPattern from 'geopattern';
|
||||||
import getMuiTheme from 'material-ui/styles/getMuiTheme';
|
import getMuiTheme from 'material-ui/styles/getMuiTheme';
|
||||||
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
|
|
||||||
|
|
||||||
const muiTheme = getMuiTheme(lightBaseTheme);
|
const muiTheme = getMuiTheme();
|
||||||
|
|
||||||
// muiTheme.inkBar.backgroundColor = 'transparent';
|
|
||||||
// muiTheme.paper.backgroundColor = 'rgb(18, 18, 18)';
|
|
||||||
// muiTheme.raisedButton.primaryTextColor = 'white';
|
|
||||||
// muiTheme.snackbar.backgroundColor = 'rgba(255, 30, 30, 0.9)';
|
|
||||||
// muiTheme.snackbar.textColor = 'rgba(255, 255, 255, 0.75)';
|
|
||||||
// muiTheme.stepper.textColor = '#eee';
|
|
||||||
// muiTheme.stepper.disabledTextColor = '#777';
|
|
||||||
// muiTheme.tabs = lightTheme.tabs;
|
|
||||||
// muiTheme.tabs.backgroundColor = 'transparent';
|
|
||||||
// muiTheme.tabs.selectedTextColor = 'white';
|
|
||||||
// muiTheme.tabs.textColor = 'rgba(255, 255, 255, 0.5)';
|
|
||||||
// muiTheme.textField.floatingLabelColor = 'rgba(255, 255, 255, 0.5)';
|
|
||||||
// muiTheme.textField.hintColor = 'rgba(255, 255, 255, 0.5)';
|
|
||||||
// muiTheme.textField.disabledTextColor = muiTheme.textField.textColor;
|
|
||||||
// muiTheme.toolbar = lightTheme.toolbar;
|
|
||||||
// muiTheme.toolbar.backgroundColor = 'transparent';
|
|
||||||
muiTheme.zIndex.layer = 4000;
|
muiTheme.zIndex.layer = 4000;
|
||||||
muiTheme.zIndex.popover = 4100;
|
muiTheme.zIndex.popover = 4100;
|
||||||
|
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
import getMuiTheme from 'material-ui/styles/getMuiTheme';
|
|
||||||
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
|
|
||||||
|
|
||||||
const muiTheme = getMuiTheme(lightBaseTheme);
|
|
||||||
|
|
||||||
import theme from './theme';
|
|
||||||
|
|
||||||
describe('ui/Theme', () => {
|
|
||||||
it('is MUI-based', () => {
|
|
||||||
expect(Object.keys(theme)).to.deep.equal(Object.keys(muiTheme).concat('parity'));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('allows setting of Parity backgrounds', () => {
|
|
||||||
expect(typeof theme.parity.setBackgroundSeed === 'function').to.be.true;
|
|
||||||
expect(typeof theme.parity.getBackgroundStyle === 'function').to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('parity', () => {
|
|
||||||
describe('setBackgroundSeed', () => {
|
|
||||||
const SEED = 'testseed';
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
theme.parity.setBackgroundSeed(SEED);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets the correct theme values', () => {
|
|
||||||
expect(theme.parity.backgroundSeed).to.equal(SEED);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getBackgroundStyle', () => {
|
|
||||||
it('generates a style containing background', () => {
|
|
||||||
const style = theme.parity.getBackgroundStyle();
|
|
||||||
|
|
||||||
expect(style).to.have.property('background');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -181,10 +181,7 @@ class TxHash extends Component {
|
|||||||
if (!(transactionReceipt && transactionReceipt.blockNumber && transactionReceipt.blockNumber.gt(0))) {
|
if (!(transactionReceipt && transactionReceipt.blockNumber && transactionReceipt.blockNumber.gt(0))) {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.confirm }>
|
<div className={ styles.confirm }>
|
||||||
<Progress
|
<Progress className={ styles.progressbar } />
|
||||||
className={ styles.progressbar }
|
|
||||||
color='white'
|
|
||||||
/>
|
|
||||||
<div className={ styles.progressinfo }>
|
<div className={ styles.progressinfo }>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='ui.txHash.waiting'
|
id='ui.txHash.waiting'
|
||||||
@ -208,11 +205,9 @@ class TxHash extends Component {
|
|||||||
<div className={ styles.confirm }>
|
<div className={ styles.confirm }>
|
||||||
<Progress
|
<Progress
|
||||||
className={ styles.progressbar }
|
className={ styles.progressbar }
|
||||||
min={ 0 }
|
|
||||||
max={ maxConfirmations }
|
max={ maxConfirmations }
|
||||||
value={ value }
|
value={ value }
|
||||||
color='white'
|
isDeterminate
|
||||||
determinate
|
|
||||||
/>
|
/>
|
||||||
<div className={ styles.progressinfo }>
|
<div className={ styles.progressinfo }>
|
||||||
<abbr title={ `block #${blockNumber.toFormat(0)}` }>
|
<abbr title={ `block #${blockNumber.toFormat(0)}` }>
|
||||||
|
@ -132,7 +132,7 @@ describe('ui/TxHash', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders determinate progressbar', () => {
|
it('renders determinate progressbar', () => {
|
||||||
expect(child.find('Progress[determinate]')).to.have.length(1);
|
expect(child.find('Progress[isDeterminate]')).to.have.length(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders confirmation text', () => {
|
it('renders confirmation text', () => {
|
||||||
|
@ -48,6 +48,7 @@ export { Busy as BusyStep, Completed as CompletedStep } from './Modal';
|
|||||||
export ModalBox from './ModalBox';
|
export ModalBox from './ModalBox';
|
||||||
export muiTheme from './Theme';
|
export muiTheme from './Theme';
|
||||||
export Page from './Page';
|
export Page from './Page';
|
||||||
|
export Popup from './Popup';
|
||||||
export Portal from './Portal';
|
export Portal from './Portal';
|
||||||
export Progress from './Progress';
|
export Progress from './Progress';
|
||||||
export QrCode from './QrCode';
|
export QrCode from './QrCode';
|
||||||
@ -61,6 +62,7 @@ export Snackbar from './Snackbar';
|
|||||||
export Tabs from './Tabs';
|
export Tabs from './Tabs';
|
||||||
export Tags from './Tags';
|
export Tags from './Tags';
|
||||||
export Title from './Title';
|
export Title from './Title';
|
||||||
|
export TokenImage from './TokenImage';
|
||||||
export TxHash from './TxHash';
|
export TxHash from './TxHash';
|
||||||
export TxList from './TxList';
|
export TxList from './TxList';
|
||||||
export VaultCard from './VaultCard';
|
export VaultCard from './VaultCard';
|
||||||
|
@ -18,8 +18,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { nullableProptype } from '@parity/shared/util/proptypes';
|
import { nullableProptype } from '@parity/shared/util/proptypes';
|
||||||
|
import Form, { AddressSelect, Checkbox, Input, InputAddressSelect } from '@parity/ui/Form';
|
||||||
import Form, { Input, InputAddressSelect, AddressSelect, Checkbox } from '@parity/ui/Form';
|
|
||||||
|
|
||||||
import TokenSelect from './tokenSelect';
|
import TokenSelect from './tokenSelect';
|
||||||
import styles from '../transfer.css';
|
import styles from '../transfer.css';
|
||||||
|
@ -54,7 +54,8 @@ class TokenSelect extends Component {
|
|||||||
const { api } = this.context;
|
const { api } = this.context;
|
||||||
const { balance, tokens } = this.props;
|
const { balance, tokens } = this.props;
|
||||||
|
|
||||||
const items = Object.keys(balance)
|
const items = Object
|
||||||
|
.keys(balance)
|
||||||
.map((tokenId) => {
|
.map((tokenId) => {
|
||||||
const token = tokens[tokenId];
|
const token = tokens[tokenId];
|
||||||
const tokenValue = balance[tokenId];
|
const tokenValue = balance[tokenId];
|
||||||
@ -122,4 +123,7 @@ function mapStateToProps (state) {
|
|||||||
return { tokens };
|
return { tokens };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(mapStateToProps)(TokenSelect);
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(TokenSelect);
|
||||||
|
@ -15,11 +15,6 @@
|
|||||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.btnicon {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.textbox {
|
.textbox {
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1.5em;
|
||||||
|
@ -191,7 +191,7 @@ class Account extends Component {
|
|||||||
<Button
|
<Button
|
||||||
icon={
|
icon={
|
||||||
<img
|
<img
|
||||||
className={ styles.btnicon }
|
className='icon'
|
||||||
src={ shapeshiftBtn }
|
src={ shapeshiftBtn }
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ export default class CreateAccount extends Component {
|
|||||||
|
|
||||||
if (!accounts) {
|
if (!accounts) {
|
||||||
return (
|
return (
|
||||||
<Loading className={ styles.selector } size={ 1 } />
|
<Loading className={ styles.selector } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,7 @@ export default class Events extends Component {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<Container title={ TITLE }>
|
<Container title={ TITLE }>
|
||||||
<div>
|
<Loading />
|
||||||
<Loading size={ 2 } />
|
|
||||||
</div>
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -275,10 +275,7 @@ class ContractDevelop extends Component {
|
|||||||
if (selectedBuild < 0) {
|
if (selectedBuild < 0) {
|
||||||
return (
|
return (
|
||||||
<div className={ `${styles.panel} ${styles.centeredMessage}` }>
|
<div className={ `${styles.panel} ${styles.centeredMessage}` }>
|
||||||
<Loading
|
<Loading />
|
||||||
size={ 1.2 }
|
|
||||||
thickness={ 5 }
|
|
||||||
/>
|
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='writeContract.title.loading'
|
id='writeContract.title.loading'
|
||||||
@ -313,10 +310,7 @@ class ContractDevelop extends Component {
|
|||||||
content = (
|
content = (
|
||||||
<div className={ styles.panel }>
|
<div className={ styles.panel }>
|
||||||
<div className={ styles.centeredMessage }>
|
<div className={ styles.centeredMessage }>
|
||||||
<Loading
|
<Loading />
|
||||||
size={ 1.2 }
|
|
||||||
thickness={ 5 }
|
|
||||||
/>
|
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='writeContract.title.solidity'
|
id='writeContract.title.solidity'
|
||||||
@ -496,10 +490,7 @@ class ContractDevelop extends Component {
|
|||||||
if (compiling) {
|
if (compiling) {
|
||||||
return (
|
return (
|
||||||
<div className={ styles.centeredMessage }>
|
<div className={ styles.centeredMessage }>
|
||||||
<Loading
|
<Loading />
|
||||||
size={ 1.2 }
|
|
||||||
thickness={ 5 }
|
|
||||||
/>
|
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='writeContract.compiling.busy'
|
id='writeContract.compiling.busy'
|
||||||
|
@ -116,7 +116,7 @@ export default class Node extends Component {
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
onChange={ onChange }
|
onChange={ onChange }
|
||||||
value={ level }
|
value={ level }
|
||||||
values={ LOGLEVEL_OPTIONS }
|
options={ LOGLEVEL_OPTIONS }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -55,12 +55,10 @@ export default class Settings extends Component {
|
|||||||
icon: <BackgroundIcon />,
|
icon: <BackgroundIcon />,
|
||||||
label: <FormattedMessage id='settings.background.label' />
|
label: <FormattedMessage id='settings.background.label' />
|
||||||
},
|
},
|
||||||
isProxied
|
!isProxied && {
|
||||||
? null
|
icon: <EthernetIcon />,
|
||||||
: {
|
label: <FormattedMessage id='settings.proxy.label' />
|
||||||
icon: <EthernetIcon />,
|
},
|
||||||
label: <FormattedMessage id='settings.proxy.label' />
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: <img src={ imagesEthcoreBlock } className={ styles.imageIcon } />,
|
icon: <img src={ imagesEthcoreBlock } className={ styles.imageIcon } />,
|
||||||
label: <FormattedMessage id='settings.parity.label' />
|
label: <FormattedMessage id='settings.parity.label' />
|
||||||
|
@ -266,16 +266,11 @@ class WalletConfirmation extends Component {
|
|||||||
{
|
{
|
||||||
pending
|
pending
|
||||||
? (
|
? (
|
||||||
<Progress
|
<Progress style={ style } />
|
||||||
key={ `pending_${operation}` }
|
|
||||||
style={ style }
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
: (
|
: (
|
||||||
<Progress
|
<Progress
|
||||||
key={ `unpending_${operation}` }
|
isDeterminate
|
||||||
determinate
|
|
||||||
min={ 0 }
|
|
||||||
max={ require.toNumber() }
|
max={ require.toNumber() }
|
||||||
value={ confirmedBy.length }
|
value={ confirmedBy.length }
|
||||||
style={ style }
|
style={ style }
|
||||||
|
@ -49,7 +49,7 @@ class WalletContainer extends Component {
|
|||||||
|
|
||||||
if (netVersion === '0') {
|
if (netVersion === '0') {
|
||||||
return (
|
return (
|
||||||
<Loading size={ 4 } />
|
<Loading size='large' />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ class Wallet extends Component {
|
|||||||
if (!owners || !require) {
|
if (!owners || !require) {
|
||||||
return (
|
return (
|
||||||
<div style={ { marginTop: '4em' } }>
|
<div style={ { marginTop: '4em' } }>
|
||||||
<Loading size={ 4 } />
|
<Loading size='large' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user