ghost-portal/packages/react-params/src/Param/Tuple.tsx
Jaco Greeff e6ca2db884
Rename ui-* -> react-* (#1495)
* Rename ui-* -> react-*

* Rename actual folders

* react-app -> react-components

* CSS links
2019-08-12 13:12:05 +02:00

104 lines
2.8 KiB
TypeScript

// 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 { Codec, TypeDef } from '@polkadot/types/types';
import { Props, RawParam } from '../types';
import React from 'react';
import { isUndefined } from '@polkadot/util';
import Bare from './Bare';
import findComponent from './findComponent';
interface State {
Components: React.ComponentType<Props>[];
sub: string[];
subTypes: TypeDef[];
type?: string;
values: RawParam[];
}
export default class Tuple extends React.PureComponent<Props, State> {
public state: State = {
Components: [],
sub: [],
subTypes: [],
values: []
};
public static getDerivedStateFromProps ({ defaultValue: { value }, type: { sub, type } }: Props, prevState: State): Partial<State> | null {
if (type === prevState.type) {
return null;
}
const subTypes = sub && Array.isArray(sub)
? sub
: [];
const values = (value as any[]).map((value): { isValid: boolean; value: Codec } =>
isUndefined(value) || isUndefined(value.isValid)
? {
isValid: !isUndefined(value),
value
}
: value
);
return {
Components: subTypes.map((type): React.ComponentType<Props> => findComponent(type)),
sub: subTypes.map(({ type }): string => type),
subTypes,
type,
values
};
}
public render (): React.ReactNode {
const { className, isDisabled, onEnter, style, withLabel } = this.props;
const { Components, sub, subTypes, values } = this.state;
return (
<Bare
className={className}
style={style}
>
{Components.map((Component, index): React.ReactNode => (
<Component
defaultValue={values[index] || {}}
isDisabled={isDisabled}
key={index}
label={sub[index]}
onChange={this.onChange(index)}
onEnter={onEnter}
type={subTypes[index]}
withLabel={withLabel}
/>
))}
</Bare>
);
}
private onChange = (index: number): (value: RawParam) => void => {
return (value: RawParam): void => {
this.setState(
({ values }: State): State => ({
values: values.map((svalue, sindex): RawParam =>
(sindex === index)
? value
: svalue
)
} as unknown as State),
(): void => {
const { values } = this.state;
const { onChange } = this.props;
onChange && onChange({
isValid: values.reduce((result: boolean, { isValid }): boolean => result && isValid, true),
value: values.map(({ value }): any => value)
});
}
);
};
}
}