Fix Tuple rendering (in same vein as Struct) (#1737)

This commit is contained in:
Jaco Greeff 2019-10-17 17:26:08 +02:00 committed by GitHub
parent c810053a7f
commit 6ffc1653db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 63 deletions

View File

@ -4,7 +4,7 @@
import { Props as BaseProps, Size } from '../types';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { Compact } from '@polkadot/types';
import { Input } from '@polkadot/react-components';
import { hexToU8a, isHex, u8aToHex } from '@polkadot/util';
@ -44,13 +44,18 @@ function convertInput (value: string): [boolean, Uint8Array] {
export default function BaseBytes ({ asHex, children, className, defaultValue: { value }, isDisabled, isError, label, length = -1, onChange, onEnter, size = 'full', style, validate = defaultValidate, withLabel, withLength }: Props): React.ReactElement<Props> {
const [isValid, setIsValid] = useState(false);
const defaultValue = value
? (
isHex(value)
? value
: u8aToHex(value as Uint8Array, isDisabled ? 256 : -1)
)
: undefined;
useEffect((): void => {
const [isValid, converted] = convertInput(value);
setIsValid(
isValid && validate(converted) && (
length !== -1
? converted.length === length
: true
)
);
}, [length, value]);
const _onChange = (hex: string): void => {
let [isValid, value] = convertInput(hex);
@ -75,6 +80,14 @@ export default function BaseBytes ({ asHex, children, className, defaultValue: {
setIsValid(isValid);
};
const defaultValue = value
? (
isHex(value)
? value
: u8aToHex(value as Uint8Array, isDisabled ? 256 : -1)
)
: undefined;
return (
<Bare
className={className}

View File

@ -8,7 +8,7 @@ import React from 'react';
import BaseBytes from './BaseBytes';
export default function Hash ({ className, defaultValue, isDisabled, isError, label, name, onChange, onEnter, style, type, withLabel }: Props): React.ReactElement<Props> {
export default function Hash256 ({ className, defaultValue, isDisabled, isError, label, name, onChange, onEnter, style, type, withLabel }: Props): React.ReactElement<Props> {
return (
<BaseBytes
className={className}

View File

@ -0,0 +1,28 @@
// Copyright 2017-2019 @polkadot/react-components authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Props } from '../types';
import React from 'react';
import BaseBytes from './BaseBytes';
export default function Hash512 ({ className, defaultValue, isDisabled, isError, label, name, onChange, onEnter, style, type, withLabel }: Props): React.ReactElement<Props> {
return (
<BaseBytes
className={className}
defaultValue={defaultValue}
isDisabled={isDisabled}
isError={isError}
label={label}
length={64}
name={name}
onChange={onChange}
onEnter={onEnter}
style={style}
type={type}
withLabel={withLabel}
/>
);
}

View File

@ -2,72 +2,50 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Codec, TypeDef } from '@polkadot/types/types';
import { Props, RawParam } from '../types';
import { TypeDef } from '@polkadot/types/types';
import { ParamDef, Props, RawParam } from '../types';
import React, { useEffect, useState } from 'react';
import { isUndefined } from '@polkadot/util';
import { createType, getTypeDef } from '@polkadot/types';
import Bare from './Bare';
import findComponent from './findComponent';
import Params from '../';
import Base from './Base';
import Static from './Static';
export default function Tuple ({ className, defaultValue, isDisabled, onChange, onEnter, style, type, withLabel }: Props): React.ReactElement<Props> {
const [{ Components, subTypes }, setComponents] = useState<{ Components: React.ComponentType<Props>[]; subTypes: TypeDef[] }>({ Components: [], subTypes: [] });
const [values, setValues] = useState<RawParam[]>([]);
export default function Tuple (props: Props): React.ReactElement<Props> {
const [params, setParams] = useState<ParamDef[]>([]);
const { className, isDisabled, label, onChange, style, type, withLabel } = props;
useEffect((): void => {
const subTypes: TypeDef[] = type.sub && Array.isArray(type.sub)
? type.sub
: [];
const rawType = createType(type.type as any).toRawType();
const typeDef = getTypeDef(rawType);
setComponents({
Components: subTypes.map((type): React.ComponentType<Props> => findComponent(type)),
subTypes
});
setParams((typeDef.sub as TypeDef[]).map((type): ParamDef => ({ name: type.name, type })));
}, [type]);
useEffect((): void => {
setValues(
(((defaultValue && defaultValue.value) || []) as any[]).map((value): { isValid: boolean; value: Codec } =>
isUndefined(value) || isUndefined(value.isValid)
? { isValid: !isUndefined(value), value }
: value
)
);
}, [defaultValue]);
if (isDisabled) {
return <Static {...props} />;
}
useEffect((): void => {
const _onChangeParams = (values: RawParam[]): void => {
onChange && onChange({
isValid: values.reduce((result: boolean, { isValid }): boolean => result && isValid, true),
isValid: values.reduce((result, { isValid }): boolean => result && isValid, true as boolean),
value: values.map(({ value }): any => value)
});
}, [values]);
const _onChange = (index: number): (value: RawParam) => void =>
(value: RawParam): void =>
setValues(values.map((prev, prevIndex): RawParam =>
(prevIndex === index)
? value
: prev
));
};
return (
<Bare
className={className}
style={style}
>
{Components.map((Component, index): React.ReactNode => (
<Component
defaultValue={values[index] || {}}
isDisabled={isDisabled}
key={index}
label={subTypes[index].type}
onChange={_onChange(index)}
onEnter={onEnter}
type={subTypes[index]}
withLabel={withLabel}
/>
))}
</Bare>
<div className='ui--Params-Tuple'>
<Base
className={className}
label={label}
style={style}
withLabel={withLabel}
/>
<Params
onChange={_onChangeParams}
params={params}
/>
</div>
);
}

View File

@ -16,7 +16,8 @@ import Bytes from './Bytes';
import Code from './Code';
import Data from './Data';
import Enum from './Enum';
import Hash from './Hash';
import Hash256 from './Hash256';
import Hash512 from './Hash512';
import Moment from './Moment';
import Proposal from './Proposal';
import KeyValue from './KeyValue';
@ -45,7 +46,8 @@ const components: ComponentMap = ([
{ c: Code, t: ['Code'] },
{ c: Data, t: ['Data', 'Keys'] },
{ c: Enum, t: ['Enum'] },
{ c: Hash, t: ['CodeHash', 'Hash', 'H256', 'H512', 'SeedOf', 'Signature'] },
{ c: Hash256, t: ['CodeHash', 'Hash', 'H256', 'SeedOf'] },
{ c: Hash512, t: ['H512', 'Signature'] },
{ c: KeyValue, t: ['KeyValue'] },
{ c: KeyValueArray, t: ['Vec<KeyValue>'] },
{ c: Moment, t: ['Moment', 'MomentOf'] },