.
*/
.byline {
- color: #aaa;
overflow: hidden;
position: relative;
line-height: 1.2em;
@@ -24,6 +23,12 @@
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
+
+ color: #aaa;
+
+ * {
+ color: #aaa !important;
+ }
}
.title {
diff --git a/js/src/ui/Container/Title/title.js b/js/src/ui/Container/Title/title.js
index 03ba4be76..5be85e48e 100644
--- a/js/src/ui/Container/Title/title.js
+++ b/js/src/ui/Container/Title/title.js
@@ -24,7 +24,9 @@ export default class Title extends Component {
title: PropTypes.oneOfType([
PropTypes.string, PropTypes.node
]),
- byline: PropTypes.string
+ byline: PropTypes.oneOfType([
+ PropTypes.string, PropTypes.node
+ ])
}
state = {
@@ -34,15 +36,21 @@ export default class Title extends Component {
render () {
const { className, title, byline } = this.props;
+ const byLine = typeof byline === 'string'
+ ? (
+
+ { byline }
+
+ )
+ : byline;
+
return (
{ title }
-
- { byline }
-
+ { byLine }
);
diff --git a/js/src/ui/Form/Input/input.css b/js/src/ui/Form/Input/input.css
new file mode 100644
index 000000000..62c2e39b2
--- /dev/null
+++ b/js/src/ui/Form/Input/input.css
@@ -0,0 +1,31 @@
+/* Copyright 2015, 2016 Ethcore (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
.
+*/
+
+.container {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-end;
+ position: relative;
+}
+
+.copy {
+ margin-right: 0.5em;
+
+ svg {
+ transition: all .5s ease-in-out;
+ }
+}
diff --git a/js/src/ui/Form/Input/input.js b/js/src/ui/Form/Input/input.js
index 0c9206d0e..24a0a8089 100644
--- a/js/src/ui/Form/Input/input.js
+++ b/js/src/ui/Form/Input/input.js
@@ -16,11 +16,22 @@
import React, { Component, PropTypes } from 'react';
-import { TextField } from 'material-ui';
+import CopyToClipboard from 'react-copy-to-clipboard';
+import CopyIcon from 'material-ui/svg-icons/content/content-copy';
+import { TextField, IconButton } from 'material-ui';
+import { lightWhite, fullWhite } from 'material-ui/styles/colors';
+
+import styles from './input.css';
// TODO: duplicated in Select
const UNDERLINE_DISABLED = {
- borderColor: 'rgba(255, 255, 255, 0.298039)' // 'transparent' // 'rgba(255, 255, 255, 0.298039)'
+ borderBottom: 'dotted 2px',
+ borderColor: 'rgba(255, 255, 255, 0.125)' // 'transparent' // 'rgba(255, 255, 255, 0.298039)'
+};
+
+const UNDERLINE_READONLY = {
+ ...UNDERLINE_DISABLED,
+ cursor: 'text'
};
const UNDERLINE_NORMAL = {
@@ -34,6 +45,12 @@ export default class Input extends Component {
children: PropTypes.node,
className: PropTypes.string,
disabled: PropTypes.bool,
+ readOnly: PropTypes.bool,
+ allowCopy: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool
+ ]),
+ floatCopy: PropTypes.bool,
error: PropTypes.string,
hint: PropTypes.string,
label: PropTypes.string,
@@ -45,17 +62,24 @@ export default class Input extends Component {
rows: PropTypes.number,
type: PropTypes.string,
submitOnBlur: PropTypes.bool,
+ hideUnderline: PropTypes.bool,
value: PropTypes.oneOfType([
PropTypes.number, PropTypes.string
])
- }
+ };
static defaultProps = {
- submitOnBlur: true
+ submitOnBlur: true,
+ readOnly: false,
+ allowCopy: false,
+ hideUnderline: false,
+ floatCopy: false
}
state = {
- value: this.props.value || ''
+ value: this.props.value || '',
+ timeoutId: null,
+ copied: false
}
componentWillReceiveProps (newProps) {
@@ -64,36 +88,145 @@ export default class Input extends Component {
}
}
+ componentWillUnmount () {
+ const { timeoutId } = this.state;
+
+ if (timeoutId) {
+ window.clearTimeout(timeoutId);
+ }
+ }
+
render () {
const { value } = this.state;
- const { children, className, disabled, error, label, hint, multiLine, rows, type } = this.props;
+ const { children, className, hideUnderline, disabled, error, label, hint, multiLine, rows, type } = this.props;
+
+ const readOnly = this.props.readOnly || disabled;
+
+ const inputStyle = { overflow: 'hidden' };
+ const textFieldStyle = {};
+
+ if (readOnly) {
+ inputStyle.cursor = 'text';
+ }
+
+ if (hideUnderline && !hint) {
+ textFieldStyle.height = 'initial';
+ }
return (
-
- { children }
-
+
+ { this.renderCopyButton() }
+
+ { children }
+
+
);
}
+ renderCopyButton () {
+ const { allowCopy, hideUnderline, label, hint, floatCopy } = this.props;
+ const { copied, value } = this.state;
+
+ if (!allowCopy) {
+ return null;
+ }
+
+ const style = {
+ marginBottom: 13
+ };
+
+ const text = typeof allowCopy === 'string'
+ ? allowCopy
+ : value;
+
+ const scale = copied ? 'scale(1.15)' : 'scale(1)';
+
+ if (hideUnderline && !label) {
+ style.marginBottom = 2;
+ } else if (label && !hint) {
+ style.marginBottom = 4;
+ } else if (label && hint) {
+ style.marginBottom = 10;
+ }
+
+ if (floatCopy) {
+ style.position = 'absolute';
+ style.left = -24;
+ style.bottom = style.marginBottom;
+ style.marginBottom = 0;
+ }
+
+ return (
+
+
+
+
+
+
+
+ );
+ }
+
+ handleCopy = () => {
+ if (this.state.timeoutId) {
+ window.clearTimeout(this.state.timeoutId);
+ }
+
+ this.setState({ copied: true }, () => {
+ const timeoutId = window.setTimeout(() => {
+ this.setState({ copied: false });
+ }, 500);
+
+ this.setState({ timeoutId });
+ });
+ }
+
onChange = (event, value) => {
this.setValue(value);
@@ -130,8 +263,6 @@ export default class Input extends Component {
}
setValue (value) {
- this.setState({
- value
- });
+ this.setState({ value });
}
}
diff --git a/js/src/ui/Form/InputAddress/inputAddress.css b/js/src/ui/Form/InputAddress/inputAddress.css
index 2f65476dc..2783130d6 100644
--- a/js/src/ui/Form/InputAddress/inputAddress.css
+++ b/js/src/ui/Form/InputAddress/inputAddress.css
@@ -29,4 +29,5 @@
.icon {
position: absolute;
top: 35px;
+ left: 24px;
}
diff --git a/js/src/ui/Form/InputAddress/inputAddress.js b/js/src/ui/Form/InputAddress/inputAddress.js
index b7ad95216..f2c801edc 100644
--- a/js/src/ui/Form/InputAddress/inputAddress.js
+++ b/js/src/ui/Form/InputAddress/inputAddress.js
@@ -60,7 +60,9 @@ class InputAddress extends Component {
error={ error }
value={ text && hasAccount ? account.name : value }
onChange={ this.handleInputChange }
- onSubmit={ onSubmit } />
+ onSubmit={ onSubmit }
+ allowCopy={ disabled ? value : false }
+ />
{ icon }
);
diff --git a/js/src/ui/MethodDecoding/methodDecoding.js b/js/src/ui/MethodDecoding/methodDecoding.js
index fab293784..d35f12d5b 100644
--- a/js/src/ui/MethodDecoding/methodDecoding.js
+++ b/js/src/ui/MethodDecoding/methodDecoding.js
@@ -268,7 +268,8 @@ class MethodDecoding extends Component {
default:
return (
+ );
+
return (
@@ -54,7 +63,7 @@ export default class Summary extends Component {
address={ address } />
{ } }
- byline={ address } />
+ byline={ addressComponent } />
{ children }
diff --git a/js/src/views/Application/application.js b/js/src/views/Application/application.js
index af213faf8..6b38f90d8 100644
--- a/js/src/views/Application/application.js
+++ b/js/src/views/Application/application.js
@@ -42,7 +42,8 @@ class Application extends Component {
children: PropTypes.node,
netChain: PropTypes.string,
isTest: PropTypes.bool,
- pending: PropTypes.array
+ pending: PropTypes.array,
+ blockNumber: PropTypes.object
}
state = {
@@ -73,7 +74,7 @@ class Application extends Component {
}
renderApp () {
- const { children, pending, netChain, isTest } = this.props;
+ const { children, pending, netChain, isTest, blockNumber } = this.props;
const { showFirstRun } = this.state;
return (
@@ -85,7 +86,7 @@ class Application extends Component {
isTest={ isTest }
pending={ pending } />
{ children }
-
+ { blockNumber ? () : null }
);
}
@@ -124,7 +125,7 @@ class Application extends Component {
}
function mapStateToProps (state) {
- const { netChain, isTest } = state.nodeStatus;
+ const { netChain, isTest, blockNumber } = state.nodeStatus;
const { hasAccounts } = state.personal;
const { pending } = state.signer;
@@ -132,7 +133,8 @@ function mapStateToProps (state) {
hasAccounts,
netChain,
isTest,
- pending
+ pending,
+ blockNumber
};
}
diff --git a/js/src/views/Contract/Events/Event/event.js b/js/src/views/Contract/Events/Event/event.js
index bf9bf593c..ba24c1c8f 100644
--- a/js/src/views/Contract/Events/Event/event.js
+++ b/js/src/views/Contract/Events/Event/event.js
@@ -129,10 +129,12 @@ class Event extends Component {
return (
+ label={ name }
+ />
);
}
}
diff --git a/js/src/views/Contract/Queries/inputQuery.js b/js/src/views/Contract/Queries/inputQuery.js
index 5f528a5e0..f21379a23 100644
--- a/js/src/views/Contract/Queries/inputQuery.js
+++ b/js/src/views/Contract/Queries/inputQuery.js
@@ -16,7 +16,6 @@
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react';
-import Chip from 'material-ui/Chip';
import LinearProgress from 'material-ui/LinearProgress';
import { Card, CardActions, CardTitle, CardText } from 'material-ui/Card';
@@ -104,13 +103,21 @@ export default class InputQuery extends Component {
display: this.renderValue(results[index])
}))
.sort((outA, outB) => outA.display.length - outB.display.length)
- .map((out, index) => (
-
{ out.name }
-
- { out.display }
-
-
-
));
+ .map((out, index) => (
+
+
+ { out.name }
+
+
+
+
+
+ ));
}
renderInput (input) {
diff --git a/js/src/views/Contract/Queries/queries.css b/js/src/views/Contract/Queries/queries.css
index 0caa1006f..9a47511b4 100644
--- a/js/src/views/Contract/Queries/queries.css
+++ b/js/src/views/Contract/Queries/queries.css
@@ -63,25 +63,25 @@
}
.methodResults > div {
- margin: 0.5rem;
+ padding: 0.25rem 0.5rem;
display: flex;
flex-direction: column;
align-items: center;
- max-width: 100%;
+ flex: 1 1 50%;
+ box-sizing: border-box;
+
+ & > div {
+ width: 100%;
+ }
+}
+
+.queryValue {
+ width: 100%;
}
.queryValue, .queryValue * {
- user-select: text !important;
- max-width: 100%;
- box-sizing: border-box;
white-space: normal !important;
overflow-wrap: break-word !important;
-}
-
-.queryValue:hover {
- cursor: text !important;
-}
-
-.queryResultName {
- margin-bottom: 0.25rem;
+ max-width: 100%;
+ box-sizing: border-box;
}
diff --git a/js/src/views/Contract/Queries/queries.js b/js/src/views/Contract/Queries/queries.js
index a2dcba16e..b880140ef 100644
--- a/js/src/views/Contract/Queries/queries.js
+++ b/js/src/views/Contract/Queries/queries.js
@@ -16,11 +16,10 @@
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react';
-import Chip from 'material-ui/Chip';
import { Card, CardTitle, CardText } from 'material-ui/Card';
import InputQuery from './inputQuery';
-import { Container, ContainerTitle } from '../../../ui';
+import { Container, ContainerTitle, Input } from '../../../ui';
import styles from './queries.css';
@@ -126,9 +125,12 @@ export default class Queries extends Component {
}
return (
-
- { valueToDisplay }
-
+
);
}
diff --git a/js/src/views/Settings/Background/background.js b/js/src/views/Settings/Background/background.js
index 77c9b1810..e34c5d348 100644
--- a/js/src/views/Settings/Background/background.js
+++ b/js/src/views/Settings/Background/background.js
@@ -82,9 +82,9 @@ class Background extends Component {
const { settings } = this.props;
const { seeds } = this.state;
- return seeds.map((seed) => {
+ return seeds.map((seed, index) => {
return (
-
+
);
}
diff --git a/js/src/views/Status/components/Status/Status.js b/js/src/views/Status/components/Status/Status.js
index 3304ee233..949efc85d 100644
--- a/js/src/views/Status/components/Status/Status.js
+++ b/js/src/views/Status/components/Status/Status.js
@@ -97,21 +97,21 @@ export default class Status extends Component {