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:
Jaco Greeff 2017-05-15 14:49:47 +02:00 committed by GitHub
parent c5fa9844f2
commit c27d96a4f1
45 changed files with 208 additions and 727 deletions

View File

@ -101,8 +101,12 @@ class Requests extends Component {
: (
<Progress
max={ 6 }
mode={ state.type === WAITING_STATE ? 'indeterminate' : 'determinate' }
value={ state.type === DONE_STATE ? +request.blockHeight : 6 }
isDeterminate={ state.type !== WAITING_STATE }
value={
state.type === DONE_STATE
? +request.blockHeight
: 6
}
/>
)
}

View File

@ -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;
}

View File

@ -18,14 +18,12 @@ import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import Button from '~/ui/Button';
import { SortIcon } from '~/ui/Icons';
import List from '~/ui/List';
import Popup from '~/ui/Popup';
import SortStore from './sortStore';
import styles from './sort.css';
@observer
export default class ActionbarSort extends Component {
@ -53,102 +51,73 @@ export default class ActionbarSort extends Component {
const { showDefault } = this.props;
return (
<IconMenu
iconButtonElement={
<Popup
isOpen={ this.store.menuOpen }
trigger={
<Button
className={ styles.sortButton }
label=''
icon={ <SortIcon /> }
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 }
>
{
showDefault
? this.renderMenuItem('', (
<List
items={ [
showDefault && this.renderMenuItem('', (
<FormattedMessage
id='ui.actionbar.sort.typeDefault'
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
}
{
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'
/>
))
}
{ this.renderSortByMetas() }
</IconMenu>
].concat(this.renderSortByMetas()) }
onClick={ this.store.handleSortChange }
/>
</Popup>
);
}
renderSortByMetas () {
const { metas } = this.props;
return metas
.map((meta, index) => {
const label = (
<FormattedMessage
id='ui.actionbar.sort.sortBy'
defaultMessage='Sort by {label}'
values={ {
label: meta.label
} }
/>
);
return metas.map((meta) => {
const label = (
<FormattedMessage
id='ui.actionbar.sort.sortBy'
defaultMessage='Sort by {label}'
values={ {
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 props = {};
if (key !== null) {
props.key = key;
}
const checked = order === value;
return (
<MenuItem
checked={ checked }
value={ value }
primaryText={ label }
innerDivStyle={ {
paddingLeft: checked ? 50 : 16
} }
{ ...props }
/>
);
return {
isActive: order === key,
key,
label
};
}
}

View File

@ -37,9 +37,8 @@ export default class SortStore {
this.menuOpen = open;
}
@action handleSortChange = (event, child) => {
const order = child.props.value;
@action handleSortChange = (event, order) => {
this.handleMenuChange(false);
this.onChange(order);
this.saveOrder(order);
}

View File

@ -21,6 +21,10 @@ import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
import styles from './actionbar.css';
export default function Actionbar ({ buttons, children, className, title }) {
if (!buttons && !title) {
return null;
}
return (
<div className={ `${styles.actionbar} ${className}` }>
<h3 className={ styles.title }>

View File

@ -21,7 +21,10 @@ import Actionbar from './actionbar';
function renderShallow (props) {
return shallow(
<Actionbar { ...props } />
<Actionbar
title='title'
{ ...props }
/>
);
}

View File

@ -15,10 +15,10 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { observer } from 'mobx-react';
import { List, ListItem } from 'material-ui/List';
import React, { Component } from 'react';
import Checkbox from '~/ui/Form/Checkbox';
import List from '~/ui/List';
import defaults, { MODES } from './defaults';
import Store from './store';
@ -34,14 +34,14 @@ export default class Features extends Component {
}
return (
<List>
{
<List
items={
Object
.keys(defaults)
.filter((key) => defaults[key].mode !== MODES.PRODUCTION)
.map(this.renderItem)
}
</List>
/>
);
}
@ -49,22 +49,22 @@ export default class Features extends Component {
const feature = defaults[key];
const onCheck = () => this.store.toggleActive(key);
return (
<ListItem
key={ `feature_${key}` }
leftCheckbox={
return {
description: (
<div className={ styles.description }>
{ feature.description }
</div>
),
key,
label: (
<div>
<Checkbox
checked={ this.store.active[key] }
onClick={ onCheck }
/>
}
primaryText={ feature.name }
secondaryText={
<div className={ styles.description }>
{ feature.description }
</div>
}
/>
);
<span>{ feature.name }</span>
</div>
)
};
}
}

View File

@ -33,7 +33,7 @@ function render (props = { visible: true }) {
return component;
}
describe('views/Settings/Features', () => {
describe('ui/Features', () => {
beforeEach(() => {
render();
});
@ -80,10 +80,6 @@ describe('views/Settings/Features', () => {
it('renders an item', () => {
expect(item).not.to.be.null;
});
it('displays the correct name', () => {
expect(item.props.primaryText).to.equal(defaults[key].name);
});
});
});
});

View File

@ -20,7 +20,6 @@ import { connect } from 'react-redux';
import keycode, { codes } from 'keycode';
import { FormattedMessage } from 'react-intl';
import { observer } from 'mobx-react';
import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline';
import apiutil from '@parity/api/util';
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
@ -36,8 +35,6 @@ import Portal from '~/ui/Portal';
import AddressSelectStore from './addressSelectStore';
import styles from './addressSelect.css';
const BOTTOM_BORDER_STYLE = { borderBottom: 'solid 3px' };
// Current Form ID
let currentId = 1;
@ -178,9 +175,8 @@ class AddressSelect extends Component {
}
renderContent () {
const { muiTheme } = this.context;
const { hint, disabled, label, readOnly } = this.props;
const { expanded, inputFocused } = this.state;
const { expanded } = this.state;
if (disabled || readOnly) {
return null;
@ -213,16 +209,14 @@ class AddressSelect extends Component {
onChange={ this.handleChange }
ref={ this.setInputRef }
/>
{ this.renderLoader() }
</div>
<div className={ styles.underline }>
<TextFieldUnderline
focus={ inputFocused }
focusStyle={ BOTTOM_BORDER_STYLE }
muiTheme={ muiTheme }
style={ BOTTOM_BORDER_STYLE }
/>
{
this.store.loading && (
<Loading
className={ styles.loader }
size='small'
/>
)
}
</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 () {
const { inputValue } = this.state;

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -26,7 +26,7 @@ import styles from './dropdown.css';
const NAME_ID = ' ';
// 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);
return (

View File

@ -53,8 +53,6 @@ export default class InputChip extends Component {
const { clearOnBlur, className, hint, label, tokens } = this.props;
const { focused } = this.state;
const classes = `${className}`;
const textFieldStyle = {
height: 55
};
@ -65,7 +63,7 @@ export default class InputChip extends Component {
return (
<ChipInput
className={ classes }
className={ className }
ref='chipInput'
value={ tokens }

View File

@ -16,11 +16,11 @@
*/
.strength {
margin-top: 1.25em;
}
.feedback {
font-size: 0.75em;
margin: -2em 0 1.5em 0;
}
.label {

View File

@ -23,12 +23,6 @@ import Progress from '~/ui/Progress';
import styles from './passwordStrength.css';
const BAR_STYLE = {
borderRadius: 1,
height: 7,
marginTop: '0.5em'
};
export default class PasswordStrength extends Component {
static propTypes = {
input: PropTypes.string.isRequired
@ -69,10 +63,6 @@ export default class PasswordStrength extends Component {
const { score, feedback } = strength;
// Score is between 0 and 4
const value = score * 100 / 5 + 20;
const color = this.getStrengthBarColor(score);
return (
<div className={ styles.strength }>
<label className={ styles.label }>
@ -82,10 +72,10 @@ export default class PasswordStrength extends Component {
/>
</label>
<Progress
color={ color }
determinate
style={ BAR_STYLE }
value={ value }
color={ this.getStrengthBarColor(score) }
isDeterminate
max={ 100 }
value={ score * 100 / 5 + 20 }
/>
<div className={ styles.feedback }>
{ this.renderFeedback(feedback) }
@ -111,8 +101,10 @@ export default class PasswordStrength extends Component {
getStrengthBarColor (score) {
switch (score) {
case 4:
return 'green';
case 3:
return 'lightgreen';
return 'blue';
case 2:
return 'yellow';

View File

@ -18,13 +18,12 @@ import React, { Component, PropTypes } from 'react';
import { range } from 'lodash';
import BigNumber from 'bignumber.js';
import IconButton from 'material-ui/IconButton';
import { fromWei, toWei } from '@parity/api/util/wei';
import { bytesToHex } from '@parity/api/util/format';
import { ABI_TYPES, parseAbiType } from '@parity/shared/util/abi';
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
import Button from '~/ui/Button';
import Dropdown from '~/ui/Form/Dropdown';
import Input from '~/ui/Form/Input';
import InputAddressSelect from '~/ui/Form/InputAddressSelect';
@ -142,40 +141,16 @@ export default class TypedInput extends Component {
}
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 (
<div style={ { marginTop: '0.75em' } }>
<IconButton
iconStyle={ iconStyle }
style={ plusStyle }
onTouchTap={ this.onAddField }
>
<AddIcon />
</IconButton>
<IconButton
iconStyle={ iconStyle }
style={ style }
onTouchTap={ this.onRemoveField }
>
<RemoveIcon />
</IconButton>
<Button
icon={ <AddIcon /> }
onClick={ this.onAddField }
/>
<Button
icon={ <RemoveIcon /> }
onClick={ this.onRemoveField }
/>
</div>
);
}

View File

@ -16,6 +16,13 @@
*/
.item {
&.active {
background: rgba(0, 0, 255, 0.25);
}
&.inactive {
}
.description {
}

View File

@ -19,10 +19,10 @@ import { List as SemanticList } from 'semantic-ui-react';
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 (
<SemanticList.Item
className={ styles.item }
className={ `${styles.item} ${isActive ? styles.active : styles.inactive} ${className}` }
onClick={ onClick }
style={ style }
>
@ -52,8 +52,8 @@ Item.propTypes = {
buttons: PropTypes.any,
className: PropTypes.string,
description: PropTypes.node,
key: PropTypes.any,
icon: PropTypes.node,
isActive: PropTypes.bool,
label: PropTypes.node,
onClick: PropTypes.func,
style: PropTypes.object

View File

@ -31,11 +31,12 @@ export default function List ({ className, items, label, onClick, style }) {
<LabelComponent label={ label }>
<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
buttons={ buttons }
description={ description }
icon={ icon }
isActive={ isActive }
key={ key || index }
label={ label }
onClick={ wrapOnClick(key || index) }

View File

@ -15,29 +15,19 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { PropTypes } from 'react';
import CircularProgress from 'material-ui/CircularProgress';
import { Loader as SemanticLoader } from 'semantic-ui-react';
import styles from './loading.css';
export default function Loading ({ className, size, thickness }) {
export default function Loading ({ className, size = 'medium' }) {
return (
<div className={ [ styles.loading, className ].join(' ') }>
<CircularProgress
size={ size * 60 }
thickness={ thickness }
/>
<div className={ `${styles.loading} ${className}` }>
<SemanticLoader />
</div>
);
}
Loading.propTypes = {
className: PropTypes.string,
size: PropTypes.number,
thickness: PropTypes.number
};
Loading.defaultProps = {
className: '',
size: 2,
thickness: 3.5
size: PropTypes.string
};

View File

@ -100,7 +100,7 @@ class MethodDecoding extends Component {
if (isLoading) {
return (
<div className={ styles.loading }>
<Loading size={ 1 } thickness={ 2 } />
<Loading />
</div>
);
}

View File

@ -23,8 +23,12 @@ import styles from './busy.css';
export default function Busy ({ children, state, title }) {
return (
<div className={ styles.center }>
<div className={ styles.title }>{ title }</div>
<div className={ styles.state }>{ state }</div>
<div className={ styles.title }>
{ title }
</div>
<div className={ styles.state }>
{ state }
</div>
{ children }
</div>
);

View File

@ -18,8 +18,6 @@ import React, { PropTypes } from 'react';
import { nodeOrStringProptype } from '@parity/shared/util/proptypes';
import Body from './body';
import Summary from './summary';
import styles from './modalBox.css';
export default function ModalBox ({ children, icon, summary }) {
@ -29,8 +27,20 @@ export default function ModalBox ({ children, icon, summary }) {
{ icon }
</div>
<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>
);

View File

@ -52,11 +52,11 @@ describe('ui/ModalBox', () => {
describe('components', () => {
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', () => {
expect(component.find('Summary').props().summary).to.deep.equal(SUMMARY);
expect(component.find('#testSummary').text()).to.equal('testSummary');
});
});
});

View File

@ -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()
};

View File

@ -24,16 +24,10 @@ import styles from './page.css';
export default function Page ({ buttons, className, children, padded, title }) {
return (
<div>
{
title || buttons
? (
<Actionbar
buttons={ buttons }
title={ title }
/>
)
: null
}
<Actionbar
buttons={ buttons }
title={ title }
/>
<div
className={
[

View File

@ -14,4 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './autocomplete';
export default from './popup';

View File

@ -15,21 +15,25 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import React, { PropTypes } from 'react';
import { Popup as SemanticPopup } from 'semantic-ui-react';
import styles from './modalBox.css';
export default function Body ({ children }) {
if (!children) {
return null;
}
export default function Popup ({ children, className, isOpen, trigger, triggerOn }) {
return (
<div className={ styles.body }>
<SemanticPopup
className={ className }
on={ triggerOn }
open={ isOpen }
trigger={ trigger }
>
{ children }
</div>
</SemanticPopup>
);
}
Body.propTypes = {
children: PropTypes.node
Popup.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
isOpen: PropTypes.bool,
trigger: PropTypes.node,
triggerOn: PropTypes.string
};

View File

@ -14,23 +14,22 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { LinearProgress } from 'material-ui';
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 (
<LinearProgress
<SemanticProgress
className={ className }
color={ color }
max={ max }
min={ min }
mode={
determinate
? 'determinate'
: 'indeterminate'
indicating={ !isDeterminate }
percent={
isDeterminate
? 100 * value / max
: 100
}
size='small'
style={ style }
value={ value }
/>
);
}
@ -38,13 +37,8 @@ export default function Progress ({ className, color, determinate, max, min, sty
Progress.propTypes = {
className: PropTypes.string,
color: PropTypes.string,
determinate: PropTypes.bool,
isDeterminate: PropTypes.bool,
max: PropTypes.number,
min: PropTypes.number,
style: PropTypes.object,
value: PropTypes.number
};
Progress.defaultProps = {
determinate: false
};

View File

@ -16,26 +16,9 @@
import GeoPattern from 'geopattern';
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.popover = 4100;

View File

@ -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');
});
});
});
});

View File

@ -181,10 +181,7 @@ class TxHash extends Component {
if (!(transactionReceipt && transactionReceipt.blockNumber && transactionReceipt.blockNumber.gt(0))) {
return (
<div className={ styles.confirm }>
<Progress
className={ styles.progressbar }
color='white'
/>
<Progress className={ styles.progressbar } />
<div className={ styles.progressinfo }>
<FormattedMessage
id='ui.txHash.waiting'
@ -208,11 +205,9 @@ class TxHash extends Component {
<div className={ styles.confirm }>
<Progress
className={ styles.progressbar }
min={ 0 }
max={ maxConfirmations }
value={ value }
color='white'
determinate
isDeterminate
/>
<div className={ styles.progressinfo }>
<abbr title={ `block #${blockNumber.toFormat(0)}` }>

View File

@ -132,7 +132,7 @@ describe('ui/TxHash', () => {
});
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', () => {

View File

@ -48,6 +48,7 @@ export { Busy as BusyStep, Completed as CompletedStep } from './Modal';
export ModalBox from './ModalBox';
export muiTheme from './Theme';
export Page from './Page';
export Popup from './Popup';
export Portal from './Portal';
export Progress from './Progress';
export QrCode from './QrCode';
@ -61,6 +62,7 @@ export Snackbar from './Snackbar';
export Tabs from './Tabs';
export Tags from './Tags';
export Title from './Title';
export TokenImage from './TokenImage';
export TxHash from './TxHash';
export TxList from './TxList';
export VaultCard from './VaultCard';

View File

@ -18,8 +18,7 @@ import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import { nullableProptype } from '@parity/shared/util/proptypes';
import Form, { Input, InputAddressSelect, AddressSelect, Checkbox } from '@parity/ui/Form';
import Form, { AddressSelect, Checkbox, Input, InputAddressSelect } from '@parity/ui/Form';
import TokenSelect from './tokenSelect';
import styles from '../transfer.css';

View File

@ -54,7 +54,8 @@ class TokenSelect extends Component {
const { api } = this.context;
const { balance, tokens } = this.props;
const items = Object.keys(balance)
const items = Object
.keys(balance)
.map((tokenId) => {
const token = tokens[tokenId];
const tokenValue = balance[tokenId];
@ -122,4 +123,7 @@ function mapStateToProps (state) {
return { tokens };
}
export default connect(mapStateToProps)(TokenSelect);
export default connect(
mapStateToProps,
null
)(TokenSelect);

View File

@ -15,11 +15,6 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/
.btnicon {
width: 24px;
height: 24px;
}
.textbox {
line-height: 1.5em;
margin-bottom: 1.5em;

View File

@ -191,7 +191,7 @@ class Account extends Component {
<Button
icon={
<img
className={ styles.btnicon }
className='icon'
src={ shapeshiftBtn }
/>
}

View File

@ -163,7 +163,7 @@ export default class CreateAccount extends Component {
if (!accounts) {
return (
<Loading className={ styles.selector } size={ 1 } />
<Loading className={ styles.selector } />
);
}

View File

@ -58,9 +58,7 @@ export default class Events extends Component {
if (isLoading) {
return (
<Container title={ TITLE }>
<div>
<Loading size={ 2 } />
</div>
<Loading />
</Container>
);
}

View File

@ -275,10 +275,7 @@ class ContractDevelop extends Component {
if (selectedBuild < 0) {
return (
<div className={ `${styles.panel} ${styles.centeredMessage}` }>
<Loading
size={ 1.2 }
thickness={ 5 }
/>
<Loading />
<p>
<FormattedMessage
id='writeContract.title.loading'
@ -313,10 +310,7 @@ class ContractDevelop extends Component {
content = (
<div className={ styles.panel }>
<div className={ styles.centeredMessage }>
<Loading
size={ 1.2 }
thickness={ 5 }
/>
<Loading />
<p>
<FormattedMessage
id='writeContract.title.solidity'
@ -496,10 +490,7 @@ class ContractDevelop extends Component {
if (compiling) {
return (
<div className={ styles.centeredMessage }>
<Loading
size={ 1.2 }
thickness={ 5 }
/>
<Loading />
<p>
<FormattedMessage
id='writeContract.compiling.busy'

View File

@ -116,7 +116,7 @@ export default class Node extends Component {
<Dropdown
onChange={ onChange }
value={ level }
values={ LOGLEVEL_OPTIONS }
options={ LOGLEVEL_OPTIONS }
/>
</div>
);

View File

@ -55,12 +55,10 @@ export default class Settings extends Component {
icon: <BackgroundIcon />,
label: <FormattedMessage id='settings.background.label' />
},
isProxied
? null
: {
icon: <EthernetIcon />,
label: <FormattedMessage id='settings.proxy.label' />
},
!isProxied && {
icon: <EthernetIcon />,
label: <FormattedMessage id='settings.proxy.label' />
},
{
icon: <img src={ imagesEthcoreBlock } className={ styles.imageIcon } />,
label: <FormattedMessage id='settings.parity.label' />

View File

@ -266,16 +266,11 @@ class WalletConfirmation extends Component {
{
pending
? (
<Progress
key={ `pending_${operation}` }
style={ style }
/>
<Progress style={ style } />
)
: (
<Progress
key={ `unpending_${operation}` }
determinate
min={ 0 }
isDeterminate
max={ require.toNumber() }
value={ confirmedBy.length }
style={ style }

View File

@ -49,7 +49,7 @@ class WalletContainer extends Component {
if (netVersion === '0') {
return (
<Loading size={ 4 } />
<Loading size='large' />
);
}
@ -193,7 +193,7 @@ class Wallet extends Component {
if (!owners || !require) {
return (
<div style={ { marginTop: '4em' } }>
<Loading size={ 4 } />
<Loading size='large' />
</div>
);
}