Rework inputs (#26)

This commit is contained in:
Jaco Greeff
2019-05-24 07:52:25 +02:00
committed by GitHub
parent 66f871b7b9
commit a025f5e752
12 changed files with 90 additions and 90 deletions

View File

@@ -5,6 +5,7 @@
import { OnActionFromCtx } from '../../components/types';
import React, { useState } from 'react';
import styled from 'styled-components';
import { ActionBar, Address, Link, withOnAction } from '../../components';
import { editAccount } from '../../messaging';
@@ -18,7 +19,7 @@ type Props = {
function Account ({ address, className, onAction }: Props) {
const [isEditing, setEditing] = useState(false);
const [editedname, setName] = useState(null as string | null);
const [editedname, setName] = useState<string | null>(null);
const toggleEdit = (): void => {
setEditing(!isEditing);
@@ -37,20 +38,17 @@ function Account ({ address, className, onAction }: Props) {
<Address
address={address}
className={className}
name={
isEditing
? (
<Name
address={address}
isFocussed
label={null}
onBlur={saveChanges}
onChange={setName}
/>
)
: undefined
}
>
{isEditing && (
<Name
address={address}
className='edit-name'
isFocussed
label={null}
onBlur={saveChanges}
onChange={setName}
/>
)}
<ActionBar>
<Link onClick={toggleEdit}>Edit</Link>
<Link to={`/account/forget/${address}`}>Forget</Link>
@@ -59,4 +57,11 @@ function Account ({ address, className, onAction }: Props) {
);
}
export default withOnAction(Account);
export default withOnAction(styled(Account)`
.edit-name {
left: 4.75rem;
position: absolute;
right: 0.75rem;
top: -0.5rem;
}
`);

View File

@@ -15,9 +15,9 @@ type Props = {
};
function Create ({ onAction }: Props) {
const [account, setAccount] = useState(null as null | { address: string, seed: string });
const [name, setName] = useState(null as string | null);
const [password, setPassword] = useState(null as string | null);
const [account, setAccount] = useState<null | { address: string, seed: string }>(null);
const [name, setName] = useState<string | null>(null);
const [password, setPassword] = useState<string | null>(null);
useEffect(() => {
createSeed()

View File

@@ -15,9 +15,9 @@ type Props = {
};
function Import ({ onAction }: Props) {
const [account, setAccount] = useState(null as null | { address: string, seed: string });
const [name, setName] = useState(null as string | null);
const [password, setPassword] = useState(null as string | null);
const [account, setAccount] = useState<null | { address: string, seed: string }>(null);
const [name, setName] = useState<string | null>(null);
const [password, setPassword] = useState<string | null>(null);
const onChangeSeed = (seed: string): void => {
validateSeed(seed)

View File

@@ -21,9 +21,9 @@ import Signing from './Signing';
type Props = {};
export default function Popup (props: Props) {
const [accounts, setAccounts] = useState(null as null | Array<KeyringJson>);
const [authRequests, setAuthRequests] = useState(null as null | Array<AuthorizeRequest>);
const [signRequests, setSignRequests] = useState(null as null | Array<SigningRequest>);
const [accounts, setAccounts] = useState<null | Array<KeyringJson>>(null);
const [authRequests, setAuthRequests] = useState<null | Array<AuthorizeRequest>>(null);
const [signRequests, setSignRequests] = useState<null | Array<SigningRequest>>(null);
const onAction = (to?: string): void => {
// loads all accounts & requests (this is passed through to children to trigger changes)

View File

@@ -32,9 +32,7 @@ function Address ({ accounts, address, children, className, isHidden, name, them
return (
<div className={className}>
<Box className='details'>
<div className='name'>
<div className='content'>{name || (account && account.meta.name) || '<unknown>'}</div>
</div>
<div className='name'>{name || (account && account.meta.name) || '<unknown>'}</div>
<div className='address'>{address || '<unknown>'}</div>
<div className='children'>{children}</div>
</Box>
@@ -49,11 +47,11 @@ function Address ({ accounts, address, children, className, isHidden, name, them
}
export default withAccounts(styled(Address)`
position: relative;
box-sizing: border-box;
margin: ${defaults.boxMargin};
padding: ${defaults.boxPadding};
padding-left: 1rem;
position: relative;
.details {
margin: 0;
@@ -70,13 +68,7 @@ export default withAccounts(styled(Address)`
}
.name {
.content {
padding: 0 0 0.5rem 0;
input {
margin: -0.5rem 0;
}
}
padding-bottom: 0.5rem;
}
}

View File

@@ -26,28 +26,20 @@ function Input ({ className, defaultValue, label, isFocussed, isReadOnly, onBlur
onChange && onChange(value.trim());
};
const element = (
<input
autoFocus={isFocussed}
defaultValue={defaultValue || undefined}
readOnly={isReadOnly}
onBlur={onBlur}
onChange={_onChange}
type={type}
value={value}
/>
);
if (!label) {
return <div className={className}>{element}</div>;
}
return (
<Label
className={className}
label={label}
>
{element}
<input
autoFocus={isFocussed}
defaultValue={defaultValue || undefined}
readOnly={isReadOnly}
onBlur={onBlur}
onChange={_onChange}
type={type}
value={value}
/>
</Label>
);
}
@@ -78,7 +70,11 @@ export default styled(Input)`
display: block;
font-family: ${defaults.fontFamily};
font-size: ${defaults.fontSize};
padding: ${defaults.inputPadding};
padding: ${({ label }) =>
label
? defaults.inputPaddingLabel
: defaults.inputPadding
};
width: 100%;
&:read-only {

View File

@@ -10,13 +10,13 @@ import defaults from './defaults';
type Props = {
children: React.ReactNode,
className?: string,
label: string
label?: string | null
};
function Label ({ children, className, label }: Props) {
return (
<div className={className}>
<label>{label}</label>
{label && <label>{label}</label>}
{children}
</div>
);
@@ -30,10 +30,13 @@ export default styled(Label)`
font-size: ${defaults.fontSize};
margin: ${defaults.boxMargin};
padding: ${defaults.boxPadding};
position: relative;
label {
display: block;
font-size: 0.9rem;
margin-bottom: 0.25rem;
font-size: 0.75rem;
left: 1rem;
position: absolute;
top: 0.25rem;
}
`;

View File

@@ -64,7 +64,11 @@ export default styled(TextArea)`
display: block;
font-family: ${defaults.fontFamily};
font-size: ${defaults.fontSize};
padding: ${defaults.inputPadding};
padding: ${({ label }) =>
label
? defaults.inputPaddingLabel
: defaults.inputPadding
};
resize: none;
width: 100%;

View File

@@ -10,10 +10,10 @@ const noop = (to?: string) => {
// do nothing
};
const AccountContext = React.createContext([] as AccountsFromCtx);
const ActionContext = React.createContext(noop as OnActionFromCtx);
const AuthorizeContext = React.createContext([] as AuthRequestsFromCtx);
const SigningContext = React.createContext([] as SignRequestsFromCtx);
const AccountContext = React.createContext<AccountsFromCtx>([]);
const ActionContext = React.createContext<OnActionFromCtx>(noop);
const AuthorizeContext = React.createContext<AuthRequestsFromCtx>([]);
const SigningContext = React.createContext<SignRequestsFromCtx>([]);
export {
AccountContext,

View File

@@ -12,8 +12,8 @@ const defaults: { [index: string]: any } = {
btnBg: TEXT_COLOR, // LINK_COLOR,
btnBgDanger: DANGER_COLOR,
btnBorder: `0 solid `,
btnColor: '#fff',
btnColorDanger: '#fff',
btnColor: '#f5f6f7',
btnColorDanger: '#f5f6f7',
btnPadding: '0.75rem 1rem',
boxBorder: 'none', // '0.25rem solid #e2e1e0',
boxMargin: '0.75rem 0',
@@ -26,6 +26,7 @@ const defaults: { [index: string]: any } = {
hdrColor: LABEL_COLOR,
inputBorder: '#ccc',
inputPadding: '0.5rem 0.75rem',
inputPaddingLabel: '1.25rem 0.75rem 0.5rem',
labelColor: LABEL_COLOR,
lineHeight: '1.25',
linkColor: LINK_COLOR,

View File

@@ -21,5 +21,5 @@ function Back ({ className, to = '/' }: Props) {
}
export default styled(Back)`
padding: 0.5rem;
padding: 0 0.5rem;
`;

View File

@@ -2,13 +2,16 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountsFromCtx } from '../components/types';
import React, { useEffect, useState } from 'react';
import { Input } from '../components';
import { AccountContext } from '../components/contexts';
import { Input, withAccounts } from '../components';
type Props = {
accounts: AccountsFromCtx,
address?: string,
className?: string,
defaultValue?: string | null,
isFocussed?: boolean,
label?: string | null,
@@ -18,38 +21,34 @@ type Props = {
const MIN_LENGTH = 3;
export default function Name ({ address, defaultValue, isFocussed, label = 'a descriptive name for this account', onBlur, onChange }: Props) {
function Name ({ accounts, address, className, defaultValue, isFocussed, label = 'a descriptive name for this account', onBlur, onChange }: Props) {
const [name, setName] = useState('');
const account = accounts.find((account) => account.address === address);
const startValue = (account && account.meta.name) || defaultValue;
const isError = !name && startValue
? false
: (name.length < MIN_LENGTH);
useEffect(() => {
onChange(
(name.length >= MIN_LENGTH)
name && (name.length >= MIN_LENGTH)
? name
: null
);
}, [name]);
return (
<AccountContext.Consumer>
{(accounts) => {
const account = accounts.find((account) => account.address === address);
const startValue = (account && account.meta.name) || defaultValue;
const isError = !name && startValue
? false
: (name.length < MIN_LENGTH);
return (
<Input
defaultValue={startValue}
isError={isError}
isFocussed={isFocussed}
label={label}
onBlur={onBlur}
onChange={setName}
type='text'
/>
);
}}
</AccountContext.Consumer>
<Input
className={className}
defaultValue={startValue}
isError={isError}
isFocussed={isFocussed}
label={label}
onBlur={onBlur}
onChange={setName}
type='text'
/>
);
}
export default withAccounts(Name);