Enum.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // Copyright 2017-2020 @polkadot/react-components authors & contributors
  2. // This software may be modified and distributed under the terms
  3. // of the Apache-2.0 license. See the LICENSE file for details.
  4. import { TypeDef } from '@polkadot/types/types';
  5. import { ParamDef, Props, RawParam } from '../types';
  6. import React, { useCallback, useEffect, useState } from 'react';
  7. import { registry } from '@polkadot/react-api';
  8. import { Dropdown } from '@polkadot/react-components';
  9. import { Enum, createType, getTypeDef } from '@polkadot/types';
  10. import Params from '../';
  11. import Bare from './Bare';
  12. import Static from './Static';
  13. interface Option {
  14. text?: string;
  15. value?: string;
  16. }
  17. function EnumParam (props: Props): React.ReactElement<Props> {
  18. const { className, defaultValue, isDisabled, isError, label, onChange, overrides, style, type, withLabel } = props;
  19. const [current, setCurrent] = useState<ParamDef[] | null>(null);
  20. const [initialValue, setInitialValue] = useState<string | null>(null);
  21. const [{ options, subTypes }, setOptions] = useState<{ options: Option[]; subTypes: TypeDef[] }>({ options: [], subTypes: [] });
  22. useEffect((): void => {
  23. const rawType = createType(registry, type.type as any).toRawType();
  24. const typeDef = getTypeDef(rawType);
  25. const subTypes = typeDef.sub as TypeDef[];
  26. setOptions({
  27. options: subTypes.map(({ name }): Option => ({
  28. text: name,
  29. value: name
  30. })),
  31. subTypes
  32. });
  33. setCurrent([{ name: subTypes[0].name, type: subTypes[0] }]);
  34. }, [type]);
  35. useEffect((): void => {
  36. setInitialValue(
  37. defaultValue && defaultValue.value
  38. ? defaultValue.value instanceof Enum
  39. ? defaultValue.value.type
  40. : Object.keys(defaultValue.value)[0]
  41. : null
  42. );
  43. }, [defaultValue]);
  44. const _onChange = useCallback(
  45. (value: string): void => {
  46. const newType = subTypes.find(({ name }): boolean => name === value) || null;
  47. setCurrent(
  48. newType
  49. ? [{ name: newType.name, type: newType }]
  50. : null
  51. );
  52. },
  53. [subTypes]
  54. );
  55. const _onChangeParam = useCallback(
  56. ([{ isValid, value }]: RawParam[]): void => {
  57. current && onChange && onChange({
  58. isValid,
  59. value: { [current[0].name as string]: value }
  60. });
  61. },
  62. [current]
  63. );
  64. if (isDisabled) {
  65. return <Static {...props} />;
  66. }
  67. return (
  68. <Bare
  69. className={className}
  70. style={style}
  71. >
  72. <Dropdown
  73. className='full'
  74. defaultValue={initialValue}
  75. isDisabled={isDisabled}
  76. isError={isError}
  77. label={label}
  78. options={options}
  79. onChange={_onChange}
  80. withEllipsis
  81. withLabel={withLabel}
  82. />
  83. {current && (
  84. <Params
  85. onChange={_onChangeParam}
  86. overrides={overrides}
  87. params={current}
  88. />
  89. )}
  90. </Bare>
  91. );
  92. }
  93. export default React.memo(EnumParam);