Pull in ui-app components only (#46)

* Pull in ui-app components only

* Undefined check

* Small overall layout updates (buttons)

* Password hide/unhide icons

* Automatically assign name to inputs
This commit is contained in:
Jaco Greeff 2018-05-12 15:05:41 +02:00 committed by GitHub
parent 905e9c8ff8
commit ea50c4f1fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 439 additions and 255 deletions

View File

@ -6,8 +6,8 @@
import type { I18nProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Input from '@polkadot/ui-app/src/Input';
import Password from '@polkadot/ui-app/src/Password';
import keyring from '@polkadot/ui-keyring/src';
@ -28,7 +28,6 @@ type Props = I18nProps & {
type State = {
address: string,
fieldName: string,
isNameValid: boolean,
isSeedValid: boolean,
isPassValid: boolean,
@ -63,7 +62,7 @@ class Creator extends React.PureComponent<Props, State> {
render (): React$Node {
const { className, style, t } = this.props;
const { address, fieldName, isNameValid, isPassValid, isSeedValid, isValid, name, password, seed } = this.state;
const { address, isNameValid, isPassValid, isSeedValid, isValid, name, password, seed } = this.state;
return (
<div
@ -87,7 +86,6 @@ class Creator extends React.PureComponent<Props, State> {
label={t('creator.seed', {
defaultValue: 'create from the following seed (hex or string)'
})}
name={`${fieldName}_seed`}
onChange={this.onChangeSeed}
value={seed}
/>
@ -99,7 +97,6 @@ class Creator extends React.PureComponent<Props, State> {
label={t('creator.name', {
defaultValue: 'name the account'
})}
name={`${fieldName}_name`}
onChange={this.onChangeName}
value={name}
/>
@ -111,31 +108,28 @@ class Creator extends React.PureComponent<Props, State> {
label={t('creator.password', {
defaultValue: 'encrypt it using the password'
})}
name={`${fieldName}_pass`}
onChange={this.onChangePass}
value={password}
/>
</div>
</div>
</div>
<div className='ui--row-buttons'>
<Button.Group>
<Button
onClick={this.onDiscard}
>
{t('creator.discard', {
text={t('creator.discard', {
defaultValue: 'Reset'
})}
</Button>
/>
<Button
disabled={!isValid}
isDisabled={!isValid}
isPrimary
onClick={this.onCommit}
primary
>
{t('creator.save', {
text={t('creator.save', {
defaultValue: 'Save'
})}
</Button>
</div>
/>
</Button.Group>
</div>
);
}
@ -146,7 +140,6 @@ class Creator extends React.PureComponent<Props, State> {
return {
address,
fieldName: `field_${Date.now()}`,
isNameValid: true,
isPassValid: false,
isSeedValid: true,

View File

@ -7,8 +7,8 @@ import type { KeyringPair } from '@polkadot/util-keyring/types';
import type { I18nProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Input from '@polkadot/ui-app/src/Input';
import InputAddress from '@polkadot/ui-app/src/InputAddress';
import keyring from '@polkadot/ui-keyring/src';
@ -98,34 +98,31 @@ class Editor extends React.PureComponent<Props, State> {
</div>
</div>
</div>
<div className='ui--row-buttons'>
<Button.Group>
<Button
disabled={!isEdited}
onClick={this.onDiscard}
>
{t('editor.reset', {
defaultValue: 'Reset'
})}
</Button>
<Button
disabled={!isEdited}
onClick={this.onCommit}
primary
>
{t('editor.save', {
defaultValue: 'Save'
})}
</Button>
<Button
negative
isNegative
onClick={this.onForget}
primary
>
{t('editor.forget', {
text={t('editor.forget', {
defaultValue: 'Forget'
})}
</Button>
</div>
/>
<Button.Group.Divider />
<Button
isDisabled={!isEdited}
onClick={this.onDiscard}
text={t('editor.reset', {
defaultValue: 'Reset'
})}
/>
<Button
isDisabled={!isEdited}
isPrimary
onClick={this.onCommit}
text={t('editor.save', {
defaultValue: 'Save'
})}
/>
</Button.Group>
</div>
);
}

View File

@ -6,7 +6,7 @@
padding: 1em 2em;
}
.accounts--App-navigation {
.accounts--App-navigation.ui--Button-Group {
margin-bottom: 2em;
text-align: center;
}

View File

@ -8,7 +8,8 @@ import type { I18nProps } from '@polkadot/ui-app/types';
import './index.css';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Creator from './Creator';
import Editor from './Editor';
@ -41,31 +42,23 @@ class App extends React.PureComponent<Props, State> {
className={['accounts--App', className].join(' ')}
style={style}
>
<div className='accounts--App-navigation'>
<Button.Group>
<Button
onClick={this.selectEdit}
primary={action === 'edit'}
>
{t('app.edit', {
defaultValue: 'Edit account'
})}
</Button>
<Button.Or
text={t('app.or', {
defaultValue: 'or'
})}
/>
<Button
onClick={this.selectCreate}
primary={action === 'create'}
>
{t('app.create', {
defaultValue: 'Create account'
})}
</Button>
</Button.Group>
</div>
<Button.Group className='accounts--App-navigation'>
<Button
isPrimary={action === 'edit'}
onClick={this.selectEdit}
text={t('app.edit', {
defaultValue: 'Edit account'
})}
/>
<Button.Or />
<Button
isPrimary={action === 'create'}
onClick={this.selectCreate}
text={t('app.create', {
defaultValue: 'Create account'
})}
/>
</Button.Group>
<Component onBack={this.selectEdit} />
</div>
);

View File

@ -6,8 +6,8 @@
import type { I18nProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Input from '@polkadot/ui-app/src/Input';
import keyring from '@polkadot/ui-keyring/src';
import addressDecode from '@polkadot/util-keyring/address/decode';
@ -22,7 +22,6 @@ type Props = I18nProps & {
type State = {
address: string,
fieldName: string,
isAddressValid: boolean,
isNameValid: boolean,
isValid: boolean,
@ -40,7 +39,7 @@ class Creator extends React.PureComponent<Props, State> {
render (): React$Node {
const { className, style, t } = this.props;
const { address, fieldName, isAddressValid, isNameValid, isValid, name } = this.state;
const { address, isAddressValid, isNameValid, isValid, name } = this.state;
return (
<div
@ -60,7 +59,6 @@ class Creator extends React.PureComponent<Props, State> {
label={t('creator.address', {
defaultValue: 'add the following address'
})}
name={`${fieldName}_address`}
onChange={this.onChangeAddress}
value={address}
/>
@ -72,31 +70,28 @@ class Creator extends React.PureComponent<Props, State> {
label={t('creator.name', {
defaultValue: 'name the entry'
})}
name={`${fieldName}_name`}
onChange={this.onChangeName}
value={name}
/>
</div>
</div>
</div>
<div className='ui--row-buttons'>
<Button.Group>
<Button
onClick={this.onDiscard}
>
{t('creator.discard', {
text={t('creator.discard', {
defaultValue: 'Reset'
})}
</Button>
/>
<Button
disabled={!isValid}
isDisabled={!isValid}
isPrimary
onClick={this.onCommit}
primary
>
{t('creator.save', {
text={t('creator.save', {
defaultValue: 'Save'
})}
</Button>
</div>
/>
</Button.Group>
</div>
);
}
@ -104,7 +99,6 @@ class Creator extends React.PureComponent<Props, State> {
emptyState (): State {
return {
address: '',
fieldName: `field_${Date.now()}`,
isAddressValid: false,
isNameValid: true,
isValid: false,

View File

@ -7,8 +7,8 @@ import type { KeyringAddress } from '@polkadot/ui-keyring/types';
import type { I18nProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Input from '@polkadot/ui-app/src/Input';
import InputAddress from '@polkadot/ui-app/src/InputAddress';
import keyring from '@polkadot/ui-keyring/src';
@ -99,34 +99,31 @@ class Editor extends React.PureComponent<Props, State> {
</div>
</div>
</div>
<div className='ui--row-buttons'>
<Button.Group>
<Button
disabled={!isEdited}
onClick={this.onDiscard}
>
{t('editor.reset', {
defaultValue: 'Reset'
})}
</Button>
<Button
disabled={!isEdited}
onClick={this.onCommit}
primary
>
{t('editor.save', {
defaultValue: 'Save'
})}
</Button>
<Button
negative
isNegative
onClick={this.onForget}
primary
>
{t('editor.forget', {
text={t('editor.forget', {
defaultValue: 'Forget'
})}
</Button>
</div>
/>
<Button.Group.Divider />
<Button
isDisabled={!isEdited}
onClick={this.onDiscard}
text={t('editor.reset', {
defaultValue: 'Reset'
})}
/>
<Button
isDisabled={!isEdited}
isPrimary
onClick={this.onCommit}
text={t('editor.save', {
defaultValue: 'Save'
})}
/>
</Button.Group>
</div>
);
}

View File

@ -6,7 +6,7 @@
padding: 1em 2em;
}
.addresses--App-navigation {
.addresses--App-navigation.ui--Button-Group {
margin-bottom: 2em;
text-align: center;
}

View File

@ -8,7 +8,8 @@ import type { I18nProps } from '@polkadot/ui-app/types';
import './index.css';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Creator from './Creator';
import Editor from './Editor';
@ -41,31 +42,23 @@ class App extends React.PureComponent<Props, State> {
className={['addresses--App', className].join(' ')}
style={style}
>
<div className='addresses--App-navigation'>
<Button.Group>
<Button
onClick={this.selectEdit}
primary={action === 'edit'}
>
{t('app.edit', {
defaultValue: 'Edit address'
})}
</Button>
<Button.Or
text={t('app.or', {
defaultValue: 'or'
})}
/>
<Button
onClick={this.selectCreate}
primary={action === 'create'}
>
{t('app.create', {
defaultValue: 'Add address'
})}
</Button>
</Button.Group>
</div>
<Button.Group className='addresses--App-navigation'>
<Button
isPrimary={action === 'edit'}
onClick={this.selectEdit}
text={t('app.edit', {
defaultValue: 'Edit address'
})}
/>
<Button.Or />
<Button
isPrimary={action === 'create'}
onClick={this.selectCreate}
text={t('app.create', {
defaultValue: 'Add address'
})}
/>
</Button.Group>
<Component onBack={this.selectEdit} />
</div>
);

View File

@ -8,8 +8,9 @@ import type { I18nProps } from '@polkadot/ui-app/types';
import type { EncodedMessage, QueueTx } from './types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import extrinsics from '@polkadot/extrinsics-substrate';
import Button from '@polkadot/ui-app/src/Button';
import Account from './Account';
import Extrinsic from './Extrinsic';
@ -67,17 +68,16 @@ class Selection extends React.PureComponent<Props, State> {
onChange={this.onChangeNonce}
value={publicKey}
/>
<div className='ui--row-buttons'>
<Button.Group>
<Button
disabled={!isValid}
isDisabled={!isValid}
isPrimary
onClick={this.onQueue}
primary
>
{t('submit.label', {
text={t('submit.label', {
defaultValue: 'Submit Extrinsic'
})}
</Button>
</div>
/>
</Button.Group>
</div>
);
}

View File

@ -11,17 +11,13 @@
line-height: 1.5em;
}
.extrinsics--Signer-Decoded {
padding-top: 2rem;
}
.extrinsics--Signer-Decoded {}
.extrinsics--Signer-Unlock {
padding-top: 1.5rem;
}
.extrinsics--Signer-Content {
padding: 1.5rem 3rem !important;
}
.extrinsics--Signer-Content {}
.extrinsics--Signer-Content .expanded {
padding-right: 2em;

View File

@ -22,7 +22,6 @@ type Props = I18nProps & {
}
type State = {
fieldName: string,
isError: boolean,
isLocked: boolean,
pair: KeyringPair
@ -36,7 +35,6 @@ class Unlock extends React.PureComponent<Props, State> {
const isLocked = !pair.hasSecretKey();
return {
fieldName: `pass_${Date.now()}`,
isError: !!error,
isLocked,
pair
@ -45,7 +43,7 @@ class Unlock extends React.PureComponent<Props, State> {
render (): React$Node {
const { className, onChange, password, style, t } = this.props;
const { fieldName, isError, isLocked } = this.state;
const { isError, isLocked } = this.state;
if (!isLocked) {
return null;
@ -63,7 +61,6 @@ class Unlock extends React.PureComponent<Props, State> {
label={t('unlock.password', {
defaultValue: 'unlock account using'
})}
name={fieldName}
onChange={onChange}
value={password}
/>

View File

@ -10,9 +10,9 @@ import type { QueueTx } from '../types';
import './Signer.css';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Modal from 'semantic-ui-react/dist/es/modules/Modal';
import Button from '@polkadot/ui-app/src/Button';
import Modal from '@polkadot/ui-app/src/Modal';
import keyring from '@polkadot/ui-keyring/src';
import withApi from '@polkadot/ui-react-rx/with/api';
@ -74,6 +74,11 @@ class Signer extends React.PureComponent<Props, State> {
open
style={style}
>
<Modal.Header>
{t('signer.header', {
defaultValue: 'Extrinsic submission'
})}
</Modal.Header>
<Modal.Content className='extrinsics--Signer-Content'>
<Decoded value={currentItem} />
<Unlock
@ -84,19 +89,23 @@ class Signer extends React.PureComponent<Props, State> {
/>
</Modal.Content>
<Modal.Actions>
<Button onClick={this.onCancel}>
{t('signer.cancel', {
defaultValue: 'Cancel'
})}
</Button>
<Button
onClick={this.onSign}
primary
>
{t('signer.send', {
defaultValue: 'Sign and Submit'
})}
</Button>
<Button.Group>
<Button
isNegative
onClick={this.onCancel}
text={t('signer.cancel', {
defaultValue: 'Cancel'
})}
/>
<Button.Or />
<Button
isPrimary
onClick={this.onSign}
text={t('signer.send', {
defaultValue: 'Sign and Submit'
})}
/>
</Button.Group>
</Modal.Actions>
</Modal>
);

View File

@ -7,8 +7,8 @@ import type { I18nProps } from '@polkadot/ui-app/types';
import type { StorageQuery } from '../types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Labelled from '@polkadot/ui-app/src/Labelled';
import typeToText from '@polkadot/ui-app/src/Params/typeToText';
import withStorageDiv from '@polkadot/ui-react-rx/with/storageDiv';
@ -82,7 +82,7 @@ class Query extends React.PureComponent<Props, State> {
<Labelled className='storage--actionrow-button'>
<Button
icon='close'
negative
isNegative
onClick={this.onRemove}
/>
</Labelled>

View File

@ -9,9 +9,9 @@ import type { RawParams } from '@polkadot/ui-app/Params/types';
import type { StorageQuery } from './types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import storage from '@polkadot/storage-substrate/keys';
import Button from '@polkadot/ui-app/src/Button';
import InputStorage from '@polkadot/ui-app/src/InputStorage';
import Labelled from '@polkadot/ui-app/src/Labelled';
import Params from '@polkadot/ui-app/src/Params';
@ -61,10 +61,10 @@ class Selection extends React.PureComponent<Props, State> {
</div>
<Labelled className='storage--actionrow-button'>
<Button
disabled={!isValid}
icon='plus'
isDisabled={!isValid}
isPrimary
onClick={this.onAdd}
primary
/>
</Labelled>
</div>

View File

@ -6,9 +6,9 @@
import type { BareProps } from '@polkadot/ui-app/types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import CopyButton from '@polkadot/ui-app/src/CopyButton';
import Button from '@polkadot/ui-app/src/Button';
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
import u8aToHex from '@polkadot/util/u8a/toHex';
@ -60,7 +60,8 @@ export default class Match extends React.PureComponent<Props, State> {
<CopyButton value={hexSeed} />
<Button
icon='close'
negative
isCircular
isNegative
onClick={this.onRemove}
size='tiny'
/>

View File

@ -9,8 +9,8 @@ import type { Generator$Matches, Generator$Result } from './generator/types';
import './index.css';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from '@polkadot/ui-app/src/Button';
import Dropdown from '@polkadot/ui-app/src/Dropdown';
import Input from '@polkadot/ui-app/src/Input';
import Labelled from '@polkadot/ui-app/src/Labelled';
@ -97,19 +97,18 @@ class App extends React.PureComponent<Props, State> {
</div>
</Labelled>
</div>
<div className='ui--row-buttons'>
<Button.Group>
<Button
disabled={!isMatchValid}
primary={!isRunning}
isDisabled={!isMatchValid}
isPrimary={!isRunning}
onClick={this.toggleStart}
>
{
text={
isRunning
? t('vanity.stop', { defaultValue: 'Stop generation' })
: t('vanity.start', { defaultValue: 'Start generation' })
}
</Button>
</div>
/>
</Button.Group>
{
keyCount
? (

View File

@ -10,8 +10,9 @@ import './Item.css';
import React from 'react';
import { NavLink } from 'react-router-dom';
import Icon from 'semantic-ui-react/dist/es/elements/Icon';
import Menu from 'semantic-ui-react/dist/es/collections/Menu';
import Icon from '@polkadot/ui-app/src/Icon';
import Menu from '@polkadot/ui-app/src/Menu';
type Props = I18nProps & Route & {};

View File

@ -8,9 +8,9 @@ import type { I18nProps } from '@polkadot/ui-app/types';
import './SideBar.css';
import React from 'react';
import Icon from 'semantic-ui-react/dist/es/elements/Icon';
import Menu from 'semantic-ui-react/dist/es/collections/Menu';
import Divider from 'semantic-ui-react/dist/es/elements/Divider';
import Icon from '@polkadot/ui-app/src/Icon';
import Menu from '@polkadot/ui-app/src/Menu';
import routing from '../routing';
import translate from '../translate';
@ -40,14 +40,14 @@ function SideBar ({ className, style, t }: Props): React$Node {
/>
)
: (
<Divider
<Menu.Divider
hidden
key={index}
/>
)
))
}
<Divider hidden />
<Menu.Divider hidden />
<Menu.Item className='apps--SideBar-Item'>
<a
className='apps--SideBar-Item-NavLink'

View File

@ -0,0 +1,11 @@
/* Copyright 2017-2018 Jaco Greeff
/* This software may be modified and distributed under the terms
/* of the ISC license. See the LICENSE file for details. */
.ui--Button-Group {
text-align: right;
}
.ui--Button-Group:not(:first-child) {
margin-top: 0.75rem;
}

View File

@ -0,0 +1,21 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { BareProps } from '../types';
import React from 'react';
type Props = BareProps;
function ButtonDivider ({ className, style }: Props): React$Node {
return (
<div
className={['ui button compact mini basic', className].join(' ')}
style={style}
/>
);
}
export default ButtonDivider;

View File

@ -0,0 +1,32 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { BareProps } from '../types';
import React from 'react';
import SUIButton from 'semantic-ui-react/dist/es/elements/Button';
import Divider from './Divider';
type Props = BareProps & {
children?: React$Node
};
function ButtonGroup ({ children, className, style }: Props): React$Node {
return (
<div
className={['ui--Button-Group', className].join(' ')}
style={style}
>
<SUIButton.Group>
{children}
</SUIButton.Group>
</div>
);
}
ButtonGroup.Divider = Divider;
export default ButtonGroup;

View File

@ -0,0 +1,31 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { I18nProps } from '../types';
import React from 'react';
import SUIButton from 'semantic-ui-react/dist/es/elements/Button';
import isUndefined from '@polkadot/util/is/undefined';
import translate from '../translate';
type Props = I18nProps & {
text?: string
};
function ButtonOr ({ className, style, t, text }: Props): React$Node {
return (
<SUIButton.Or text={
isUndefined(text)
? t('button.or', {
defaultValue: 'or'
})
: text
} />
);
}
export default translate(ButtonOr);

View File

@ -0,0 +1,67 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { BareProps } from '../types';
import './Button.css';
import React from 'react';
import SUIButton from 'semantic-ui-react/dist/es/elements/Button';
import isUndefined from '@polkadot/util/is/undefined';
import Divider from './Divider';
import Group from './Group';
import Or from './Or';
export type Button$Sizes = 'mini' | 'tiny' | 'small' | 'medium' | 'large' | 'big' | 'huge' | 'massive';
type Props = BareProps & {
children?: React$Node,
floated?: 'left' | 'right',
icon?: string,
isBasic?: boolean,
isCircular?: boolean,
isDisabled?: boolean,
isNegative?: boolean,
isPrimary?: boolean,
onClick?: () => void | Promise<void>,
size?: Button$Sizes,
// flowlint-next-line unclear-type:off
text?: any
};
function Button ({ children, className, floated, icon, isBasic = false, isCircular = false, isDisabled = false, isNegative = false, isPrimary = false, onClick, size, style, text }: Props): React$Node {
const props = {
basic: isBasic,
circular: isCircular,
className,
disabled: isDisabled,
floated,
icon,
negative: isNegative,
onClick,
primary: isPrimary,
size,
secondary: isBasic && !(isPrimary || isNegative),
style
};
return isUndefined(text) && isUndefined(children)
? (
<SUIButton {...props} />
)
: (
<SUIButton {...props}>
{text}{children}
</SUIButton>
);
}
Button.Divider = Divider;
Button.Group = Group;
Button.Or = Or;
export default Button;

View File

@ -3,28 +3,30 @@
// of the ISC license. See the LICENSE file for details.
// @flow
import type { Button$Sizes } from './Button';
import type { BareProps } from './types';
import React from 'react';
import CopyToClipboard from 'react-copy-to-clipboard';
import Button from 'semantic-ui-react/dist/es/elements/Button';
type Button$Sizes = 'mini' | 'tiny' | 'small' | 'medium' | 'large' | 'big' | 'huge' | 'massive';
import Button from './Button';
type Props = BareProps & {
icon?: string,
isCircular?: boolean,
isPrimary?: boolean,
size?: Button$Sizes,
value?: string
}
export default function CopyButton ({ className, icon = 'copy', isPrimary = true, size = 'tiny', style, value }: Props): React$Node {
export default function CopyButton ({ className, icon = 'copy', isCircular = true, isPrimary = true, size = 'tiny', style, value }: Props): React$Node {
return (
<CopyToClipboard text={value}>
<Button
className={className}
icon={icon}
primary={isPrimary}
isCircular={isCircular}
isPrimary={isPrimary}
size={size}
style={style}
/>

View File

@ -0,0 +1,10 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import SUIIcon from 'semantic-ui-react/dist/es/elements/Icon';
const Icon = SUIIcon;
export default Icon;

View File

@ -21,7 +21,6 @@ type Props = BareProps & {
label?: React$Node,
max?: mixed,
min?: mixed,
name?: string,
// flowlint-next-line unclear-type:off
onChange: (value: any) => void,
placeholder?: string,
@ -34,9 +33,20 @@ type SUIEvent = {
value: any
};
export default class Input extends React.PureComponent<Props> {
type State = {
name: string;
}
let counter = 0;
export default class Input extends React.PureComponent<Props, State> {
state: State = {
name: `in_${counter++}_at_${Date.now()}`
};
render (): React$Node {
const { children, className, defaultValue, isAction = false, isDisabled = false, isError = false, label, max, min, name, placeholder, style, type = 'text', value } = this.props;
const { children, className, defaultValue, isAction = false, isDisabled = false, isError = false, label, max, min, placeholder, style, type = 'text', value } = this.props;
const { name } = this.state;
return (
<Labelled

View File

@ -85,10 +85,12 @@ export default class InputAddress extends React.Component<Props, State> {
const { isInput = true } = this.props;
const queryLower = query.toLowerCase();
const matches = filteredOptions.filter((item) => {
if (!item.value) {
// $FlowFixMe yes, this is how we check for Element (??!)
if (!item || !item.value) {
return true;
}
// $FLowFixMe we should now have value elements
const { name, value } = item;
const hasMatch = name.toLowerCase().indexOf(queryLower) !== -1 ||
value.toLowerCase().indexOf(queryLower) !== -1;
@ -96,6 +98,7 @@ export default class InputAddress extends React.Component<Props, State> {
return hasMatch;
});
// $FlowFixMe yes, this is how we check for Element
const valueMatches = matches.filter((item) => item.value);
// see if we should add a new item, i.e. no valid address found
@ -116,8 +119,17 @@ export default class InputAddress extends React.Component<Props, State> {
}
return matches.filter((item, index) => {
// it is a value entry or header followed by a value entry
if (item.value || (index !== matches.length - 1 && matches[index + 1].value)) {
if (!item) {
return false;
}
const isLast = index === matches.length - 1;
const nextItem = matches[index + 1];
// $FlowFixMe yes, this is how we check for Element
const hasNext = nextItem && nextItem.value;
// $FlowFixMe yes, this is how we check for Element
if (item.value || (!isLast && hasNext)) {
return true;
}

View File

@ -26,17 +26,17 @@
}
.ui--DropdownLinked-Item-call {
flex: 1;
font-family: monospace;
margin-left: 1rem;
opacity: 0.5;
overflow: hidden;
text-align: right;
flex: 1 0;
margin-right: 1rem;
text-align: left;
text-overflow: ellipsis;
}
.ui--DropdownLinked-Item-text {
flex: 1 0;
flex: 1;
opacity: 0.5;
text-align: right;
text-overflow: ellipsis;
}
.ui--DropdownLinked-Sections {}

View File

@ -30,17 +30,17 @@ export default function createOptions (sectionName: any, type: 'private' | 'publ
className: 'ui--DropdownLinked-Item',
key: `${sectionName}_${name}`,
text: [
<div
className='ui--DropdownLinked-Item-text'
key={`${sectionName}_${name}:text`}
>
{description || name}
</div>,
<div
className='ui--DropdownLinked-Item-call'
key={`${sectionName}_${name}:call`}
>
{name}({inputs})
</div>,
<div
className='ui--DropdownLinked-Item-text'
key={`${sectionName}_${name}:text`}
>
{description || name}
</div>
],
value: name

View File

@ -33,17 +33,17 @@ export default function createOptions (sectionName: any): Array<*> {
className: 'ui--DropdownLinked-Item',
key: `${sectionName}_${name}`,
text: [
<div
className='ui--DropdownLinked-Item-text'
key={`${sectionName}_${name}:text`}
>
{description || name}
</div>,
<div
className='ui--DropdownLinked-Item-call'
key={`${sectionName}_${name}:call`}
>
{name}({inputs})
</div>,
<div
className='ui--DropdownLinked-Item-text'
key={`${sectionName}_${name}:text`}
>
{description || name}
</div>
],
value: name

View File

@ -0,0 +1,18 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import SUIDivider from 'semantic-ui-react/dist/es/elements/Divider';
import SUIMenu from 'semantic-ui-react/dist/es/collections/Menu';
type MenuDef = typeof SUIMenu & {
Divider: typeof SUIDivider
};
// $FlowFixMe we areally want to do this, yes
const Menu: MenuDef = SUIMenu;
Menu.Divider = SUIDivider;
export default Menu;

View File

@ -0,0 +1,10 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import SUIModal from 'semantic-ui-react/dist/es/modules/Modal';
const Modal = SUIModal;
export default Modal;

View File

@ -6,8 +6,8 @@
import type { BareProps } from './types';
import React from 'react';
import Button from 'semantic-ui-react/dist/es/elements/Button';
import Button from './Button';
import Input from './Input';
type Props = BareProps & {
@ -33,9 +33,6 @@ export default class Password extends React.PureComponent<Props, State> {
render (): React$Node {
const { children, className, defaultValue, isDisabled, isError, label, name, onChange, style, value } = this.props;
const { isVisible } = this.state;
const type = isVisible
? 'text'
: 'password';
return (
<Input
@ -48,12 +45,20 @@ export default class Password extends React.PureComponent<Props, State> {
name={name}
onChange={onChange}
style={style}
type={type}
type={
isVisible
? 'text'
: 'password'
}
value={value}
>
<Button
icon='eye'
primary
icon={
isVisible
? 'hide'
: 'unhide'
}
isPrimary
onClick={this.onToggleVisible}
/>
{children}

View File

@ -76,13 +76,3 @@
.ui--row > div.thirty3 {
padding: 0 0.25rem;
}
.ui--row-buttons {
margin: 1em 0;
text-align: right;
}
.ui--row-buttons .button {
margin: 0 0.25rem;
text-align: left;
}

View File

@ -46,9 +46,9 @@
text-align: right;
}
.ui.modal > .actions .button {
margin: 0 0.25rem;
text-align: left;
.ui.modal > .header {
border-bottom: none;
padding-bottom: 0;
}
.ui.page.modals.transition.visible {

View File

@ -3,18 +3,13 @@
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringOption } from '../types';
import React from 'react';
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
// import React from 'react';
// import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
export default function createHeader (text: string): $Shape<KeyringOption> {
// HACK We add our own header and make it look like SUI, the below type renders more than once when searching through
// <Dropdown.Header>Addresses</Dropdown.Header>
return {
className: 'ui--KeyPair-header',
disabled: true,
key: `header-${text.toLowerCase()}`,
content: text
};
export default function createHeader (text: string): React$Element<*> {
return (
<Dropdown.Header key={`header-${text.toLowerCase()}`}>
{text}
</Dropdown.Header>
);
}

View File

@ -26,7 +26,7 @@ export type KeyringOption = KeyringOption$Data & {
value: string
};
export type KeyringOptions = Array<KeyringOption>;
export type KeyringOptions = Array<KeyringOption | React$Element<*>>;
export type KeyringJson$Meta = {
isRecent?: boolean,