Beauty is in the eye of the beerholder (#1328)

* Beuty is in the eye of the beerholder

* Signer dialog

* .multiple with address

* Transfer wrapper

* Multiple input height

* 2rem -> 1.75rem

* Adjustments for invalid

* Break IdentityIcon out of box

* Small layout adjustments

* Row adjustment

* Remove commented styles

* Remove commented code

* Remove unneeded padding

* Remove unused i81n

* Display messages with input-like styling

* InputFile & Messages overrides

* Adjust input margins (non-flex)

* Center icon

* Adjust labelExtra placement, staking dropdown

* Combine linked lists into one

* Fix developer settings
This commit is contained in:
Jaco Greeff 2019-07-08 22:33:57 +02:00 committed by GitHub
parent 93800106fb
commit 68a523a778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 161 additions and 109 deletions

View File

@ -43,7 +43,7 @@ class Import extends TxComponent<Props, State> {
dimmer='inverted'
open
>
<Modal.Header>{t('Add an account via seed')}</Modal.Header>
<Modal.Header>{t('Add via backup file')}</Modal.Header>
{this.renderInput()}
<Modal.Actions>
<Button.Group>

View File

@ -11,7 +11,7 @@ import BN from 'bn.js';
import React from 'react';
import styled from 'styled-components';
import { Index } from '@polkadot/types';
import { Button, InputAddress, InputBalance, Modal, TxButton, media } from '@polkadot/ui-app';
import { Button, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/ui-app';
import { Available } from '@polkadot/ui-reactive';
import Checks, { calcSignatureLength } from '@polkadot/ui-signer/Checks';
import { withApi, withCalls, withMulti } from '@polkadot/ui-api';
@ -143,19 +143,19 @@ class Transfer extends React.PureComponent<Props> {
help={t('The account you will send funds from.')}
isDisabled={!!propSenderId}
label={t('send from account')}
labelExtra={<Available label={available} params={senderId} />}
onChange={this.onChangeFrom}
type='account'
/>
<div className='balance'><Available label={available} params={senderId} /></div>
<InputAddress
defaultValue={propRecipientId}
help={t('Select a contact or paste the address you want to send funds to.')}
isDisabled={!!propRecipientId}
label={t('send to address')}
labelExtra={<Available label={available} params={recipientId} />}
onChange={this.onChangeTo}
type='allPlus'
/>
<div className='balance'><Available label={available} params={recipientId} /></div>
<InputBalance
help={t('Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 mili is equivalent to sending 0.001.')}
isError={!hasAvailable}
@ -236,6 +236,7 @@ export default withMulti(
styled(Transfer)`
article.padded {
box-shadow: none;
margin-left: 2rem;
}
.balance {
@ -248,13 +249,6 @@ export default withMulti(
}
}
${media.DESKTOP`
article.padded {
margin: .75rem 0 0.75rem 15rem;
padding: 0.25rem 1rem;
}
`}
label.with-help {
flex-basis: 10rem;
}

View File

@ -121,6 +121,7 @@ class ABI extends React.PureComponent<Props, State> {
<Messages
contractAbi={contractAbi!}
onRemove={onRemove || this.onRemove}
isLabelled={!!label}
isRemovable={!isDisabled}
/>
</Labelled>

View File

@ -8,7 +8,7 @@ import React from 'react';
import store from 'store';
import styled from 'styled-components';
import { getTypeRegistry } from '@polkadot/types';
import { Button, Editor, InputFile, Labelled } from '@polkadot/ui-app';
import { Button, Editor, InputFile } from '@polkadot/ui-app';
import { ActionStatus } from '@polkadot/ui-app/Status/types';
import { isJsonObject, stringToU8a, u8aToString } from '@polkadot/util';
@ -59,7 +59,7 @@ class Developer extends React.PureComponent<Props, State> {
clearContent={typesHasNoEntries && isTypesValid}
help={t('Save the type definitions for your custom structures as key-value pairs in a valid JSON file. The key should be the name of your custom structure and the value an object containing your type definitions.')}
isError={!isTypesValid}
label={t('Upload your additional type definitions as a JSON file')}
label={t('Additional types as a JSON file (or edit below)')}
onChange={this.onChangeTypes}
placeholder={typesPlaceholder}
/>
@ -67,17 +67,12 @@ class Developer extends React.PureComponent<Props, State> {
</div>
<div className='ui--row'>
<div className='full'>
<Labelled
help={t('Please create a key-value pair for each of your custom structures. The key should be the name of your custom structure and the value an object containing your custom type definitions.')}
label={t('Manually enter your custom type definitions as valid JSON')}
>
<Editor
className='editor'
code={code}
isValid={isJsonValid}
onEdit={this.onEditTypes}
/>
</Labelled>
<Editor
className='editor'
code={code}
isValid={isJsonValid}
onEdit={this.onEditTypes}
/>
</div>
</div>
<Button.Group>
@ -191,7 +186,8 @@ class Developer extends React.PureComponent<Props, State> {
export default translate(styled(Developer)`
.editor {
height: 300px;
height: 21rem;
margin-left: 2rem;
position: relative;
}
`);

View File

@ -54,11 +54,10 @@ class CurrentList extends React.PureComponent<Props, State> {
<div>
<FilterOverlay>
<Dropdown
help={t('Select which validators/intentions you want to display.')}
label={t('filter')}
onChange={this.onChangeFilter}
options={filterOptions}
value={filter}
withLabel={false}
/>
</FilterOverlay>
<Columar className='validator--ValidatorsList'>

View File

@ -22,6 +22,7 @@ type Props<Option> = BareProps & {
isError?: boolean,
isMultiple?: boolean,
label?: React.ReactNode,
labelExtra?: React.ReactNode,
onAdd?: (value: any) => void,
onBlur?: () => void,
onChange?: (value: any) => void,
@ -64,7 +65,7 @@ export default class Dropdown<Option> extends React.PureComponent<Props<Option>>
}
render () {
const { allowAdd = false, className, defaultValue, dropdownClassName, help, isButton, isDisabled, isError, isMultiple, label, onSearch, options, placeholder, renderLabel, searchInput, style, withEllipsis, withLabel, value } = this.props;
const { allowAdd = false, className, defaultValue, dropdownClassName, help, isButton, isDisabled, isError, isMultiple, label, labelExtra, onSearch, options, placeholder, renderLabel, searchInput, style, withEllipsis, withLabel, value } = this.props;
const dropdown = (
<SUIDropdown
allowAdditions={allowAdd}
@ -104,6 +105,7 @@ export default class Dropdown<Option> extends React.PureComponent<Props<Option>>
className={classes('ui--Dropdown', className)}
help={help}
label={label}
labelExtra={labelExtra}
style={style}
withEllipsis={withEllipsis}
withLabel={withLabel}

View File

@ -26,6 +26,7 @@ type Props = BareProps & {
isInput?: boolean,
isMultiple?: boolean,
label?: string,
labelExtra?: React.ReactNode,
onChange?: (value: string | null) => void,
onChangeMulti?: (value: Array<string>) => void,
options?: Array<KeyringSectionOption>,
@ -121,7 +122,7 @@ class InputAddress extends React.PureComponent<Props, State> {
}
render () {
const { className, defaultValue, help, hideAddress = false, isDisabled = false, isError, isMultiple, label, options, optionsAll, placeholder, type = DEFAULT_TYPE, style, withEllipsis, withLabel } = this.props;
const { className, defaultValue, help, hideAddress = false, isDisabled = false, isError, isMultiple, label, labelExtra, options, optionsAll, placeholder, type = DEFAULT_TYPE, style, withEllipsis, withLabel } = this.props;
const { value } = this.state;
const hasOptions = (options && options.length !== 0) || (optionsAll && Object.keys(optionsAll[type]).length !== 0);
@ -166,6 +167,7 @@ class InputAddress extends React.PureComponent<Props, State> {
isError={isError}
isMultiple={isMultiple}
label={label}
labelExtra={labelExtra}
onChange={
isMultiple
? this.onChangeMulti
@ -292,8 +294,19 @@ export default withMulti(
width: 100%;
}
.ui.search.selection.dropdown > input.search {
padding-left: 4rem;
.ui.search.selection.dropdown {
> .text > .ui--KeyPair {
.ui--IdentityIcon {
border: 1px solid #888;
border-radius: 50%;
left: -2.75rem;
top: -1.2rem;
}
.name {
margin-left: 0;
}
}
}
&.hideAddress .ui--KeyPair .address {

View File

@ -7,6 +7,7 @@ import { BareProps } from './types';
import React from 'react';
import Dropzone from 'react-dropzone';
import styled from 'styled-components';
import { classes } from './util';
import Labelled from './Labelled';
@ -63,7 +64,7 @@ class InputFile extends React.PureComponent<Props, State> {
ref={this.dropZone}
onDrop={this.onDrop}
>
<div className='label'>
<em className='label'>
{
!file || clearContent
? placeholder || t('click to select or drag and drop the file here')
@ -71,7 +72,7 @@ class InputFile extends React.PureComponent<Props, State> {
replace: file
})
}
</div>
</em>
</Dropzone>
);
@ -123,4 +124,26 @@ class InputFile extends React.PureComponent<Props, State> {
}
}
export default translate(InputFile);
export default translate(styled(InputFile)`
background: #fff;
border: 1px solid rgba(34, 36, 38, 0.15);
border-radius: 0.28571429rem;
font-size: 1rem;
margin: 0.25rem 0;
padding: 1rem;
width: 100% !important;
&.error {
background: #fff6f6;
border-color: #e0b4b4;
}
&:hover {
background: #fefefe;
cursor: pointer;
}
.label {
color: rgba(0, 0, 0, .6);
}
`);

View File

@ -8,7 +8,6 @@ import React from 'react';
import styled from 'styled-components';
import LabelHelp from './LabelHelp';
import media from './media';
import { classes } from './util';
type Props = BareProps & {
@ -16,17 +15,19 @@ type Props = BareProps & {
isHidden?: boolean,
isSmall?: boolean,
label?: React.ReactNode,
labelExtra?: React.ReactNode,
children: React.ReactNode,
withLabel?: boolean,
withEllipsis?: boolean
};
const defaultLabel: any = (// node?
const defaultLabel: React.ReactNode = (
<div>&nbsp;</div>
);
const Wrapper = styled.div`
display: block;
position: relative;
.withEllipsis {
overflow: hidden;
@ -34,13 +35,6 @@ const Wrapper = styled.div`
white-space: nowrap;
}
> label {
margin: 0.25rem 0 0 0;
padding-right: 0.5rem;
position: relative;
text-align: left;
}
&.label-small {
display: block;
@ -51,34 +45,80 @@ const Wrapper = styled.div`
}
}
> .ui--Labelled-content {
box-sizing: border-box;
flex: 1 1;
min-width: 0;
}
&:not(.label-small) {
padding-left: 2rem;
${media.DESKTOP`
align-items: flex-start;
display: flex;
flex: 1 1;
margin: 0;
text-align: left;
> label,
.labelExtra {
position: absolute;
text-align: left;
top: 0.5rem;
z-index: 1;
}
> label {
align-items: center;
display: flex;
flex: 0 0 15rem;
justify-content: flex-end;
min-height: 2.715rem; /* more-or-less 2 lines with adjustments, 38px as per input box */
min-width: 15rem;
left: 3.55rem;
text-align: left;
}
.labelExtra {
color: rgba(78, 78, 78, .75);
font-weight: 100;
right: 1.75rem;
text-align: right;
}
`}
> .ui--Labelled-content {
box-sizing: border-box;
flex: 1 1;
min-width: 0;
.ui.selection.dropdown {
&:not(.floating) {
padding-left: 1.45rem;
padding-top: 1.75rem;
}
&.floating {
> .dropdown.icon {
top: 1.25rem;
}
.text {
padding: 0.45rem 0
}
}
&.search:not(.multiple) > input.search {
padding-left: 1.45rem;
padding-top: 1.75rem;
}
> .delete.icon,
> .dropdown.icon,
> .search.icon {
top: 1.75rem;
}
}
.ui.input > input,
.ui--output {
padding-left: 1.45rem;
padding-top: 1.75rem;
}
.ui--InputFile,
.ui--Messages {
padding-left: 1.45rem;
padding-top: 2rem;
}
}
}
`;
export default class Labelled extends React.PureComponent<Props> {
render () {
const { className, children, help, isSmall, isHidden, label = defaultLabel, style, withEllipsis, withLabel = true } = this.props;
const { className, children, help, isSmall, isHidden, label = defaultLabel, labelExtra, style, withEllipsis, withLabel = true } = this.props;
if (isHidden) {
return null;
@ -100,6 +140,7 @@ export default class Labelled extends React.PureComponent<Props> {
: label
}{help && <LabelHelp help={help} />}
</label>
{labelExtra && <div className='labelExtra'>{labelExtra}</div>}
<div className='ui--Labelled-content'>
{children}
</div>

View File

@ -15,6 +15,7 @@ import { classes } from './util';
export type Props = I18nProps & {
address?: string,
contractAbi: Abi,
isLabelled?: boolean,
isRemovable: boolean,
onRemove?: () => void,
onSelect?: (callAddress?: string, callMethod?: string) => void
@ -22,10 +23,10 @@ export type Props = I18nProps & {
class Messages extends React.PureComponent<Props> {
render () {
const { className, contractAbi: { abi: { messages } }, isRemovable, onRemove = () => null, onSelect, t } = this.props;
const { className, contractAbi: { abi: { messages } }, isLabelled, isRemovable, onRemove = () => null, onSelect, t } = this.props;
return (
<div className={classes(className, onSelect && 'select')}>
<div className={classes(className, 'ui--Messages', isLabelled && 'labelled', onSelect && 'select')}>
{messages.map((_, index) => {
return this.renderMessage(index);
})}
@ -92,6 +93,15 @@ export default translate(styled(Messages)`
align-items: center;
flex-wrap: wrap;
&.labelled {
background: white;
box-sizing: border-box;
border: 1px solid rgba(34,36,38,.15);
border-radius: .28571429rem;
padding: 1rem 1rem 0.5rem;
width: 100%;
}
& > .message {
font-family: monospace;
font-weight: normal;

View File

@ -3,16 +3,15 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { MethodFunction } from '@polkadot/types/primitive/Method';
import { I18nProps } from '@polkadot/ui-app/types';
import { RawParam$OnChange, RawParam$OnEnter } from '@polkadot/ui-params/types';
import { BareProps } from '../types';
import React from 'react';
import { Method } from '@polkadot/types';
import BaseExtrinsic from '../Extrinsic';
import translate from '../translate';
type Props = I18nProps & {
type Props = BareProps & {
defaultValue: MethodFunction,
isDisabled?: boolean,
isError?: boolean,
@ -23,9 +22,9 @@ type Props = I18nProps & {
withLabel?: boolean
};
class ExtrinsicDisplay extends React.PureComponent<Props> {
export default class ExtrinsicDisplay extends React.PureComponent<Props> {
render () {
const { className, defaultValue, isDisabled, isError, isPrivate, label, onEnter, style, t, withLabel } = this.props;
const { className, defaultValue, isDisabled, isError, isPrivate, label, onEnter, style, withLabel } = this.props;
return (
<BaseExtrinsic
@ -34,7 +33,7 @@ class ExtrinsicDisplay extends React.PureComponent<Props> {
isDisabled={isDisabled}
isError={isError}
isPrivate={isPrivate}
label={<>{label} {t('(extrinsic)')}</>}
label={label}
onChange={this.onChange}
onEnter={onEnter}
style={style}
@ -52,5 +51,3 @@ class ExtrinsicDisplay extends React.PureComponent<Props> {
});
}
}
export default translate(ExtrinsicDisplay);

View File

@ -20,8 +20,8 @@ export const styles = `
&.inline {
display: flex;
.ui--Row-children {
padding: 0 0 0 3rem;
.ui--Row-accountId {
white-space: nowrap;
}
}
@ -95,6 +95,7 @@ export const styles = `
.ui--Row-children {
display: block;
padding-left: 1rem;
padding-top: 1rem;
}

View File

@ -84,7 +84,7 @@ article {
}
&.padded {
padding: 0.75rem 2.5rem;
padding: 0.75rem 1rem;
> div {
margin: 0.25rem;

View File

@ -55,11 +55,16 @@ button.ui.icon.iconButton {
.ui--DropdownLinked.ui--row {
.small .ui.selection.dropdown {
border-right: none;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
min-width: 5rem;
}
.ui--DropdownLinked-Items {
padding-left: 0.5rem;
.large .ui.selection.dropdown {
border-left: none;
border-bottom-left-radius: 0;
border-top-left-radius: 0;
}
}
@ -90,34 +95,6 @@ button.ui.icon.iconButton {
}
}
.ui--InputFile {
align-items: center;
background: #fff;
border: 1px dashed rgba(34, 36, 38, 0.15);
border-radius: $small-corner;
display: flex;
font-size: 1rem;
height: 3.5rem;
justify-content: center;
margin: 0.25rem 0;
width: 100% !important;
&.error {
background: #fff6f6;
border-color: #e0b4b4;
}
&:hover {
background: #fefefe;
border-style: solid;
cursor: pointer;
}
.label {
color: rgba(0, 0, 0, .6);
}
}
.ui--Static {
min-width: 2rem; /* adjust width from normal dropdown sizing */
overflow: hidden;

View File

@ -52,8 +52,7 @@
}
.ui.input {
/* from .ui.fluid.input */
display: flex;
width: 100%;
&.disabled {
opacity: 1;

View File

@ -4,8 +4,7 @@
@import '../../ui-app/src/styles/partials/_variables.css';
.ui--signer-Signer-Decoded,
.ui--signer-Signer-Unlock {
.ui--signer-Signer-Decoded {
align-content: center;
display: flex;
line-height: 1.5em;