InputArray.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import React, { Component } from "react";
  2. import styled from "styled-components";
  3. type PropsType = {
  4. label?: string;
  5. values: string[];
  6. setValues: (x: string[]) => void;
  7. width?: string;
  8. disabled?: boolean;
  9. };
  10. type StateType = {};
  11. export default class InputArray extends Component<PropsType, StateType> {
  12. dict2arr = (dict: Record<string, any>) => {
  13. let arr = [];
  14. for (let key in dict) {
  15. arr.push(`${key}: ${dict[key]}`);
  16. }
  17. return arr;
  18. };
  19. renderDeleteButton = (values: string[], i: number) => {
  20. if (!this.props.disabled) {
  21. return (
  22. <DeleteButton
  23. onClick={() => {
  24. let v = [...values];
  25. v.splice(i, 1);
  26. this.props.setValues(v);
  27. }}
  28. >
  29. <i className="material-icons">cancel</i>
  30. </DeleteButton>
  31. );
  32. }
  33. };
  34. renderInputList = (values: string[]) => {
  35. return (
  36. <>
  37. {values.map((value: string, i: number) => {
  38. return (
  39. <InputWrapper>
  40. <Input
  41. placeholder=""
  42. width="270px"
  43. value={value}
  44. onChange={(e: any) => {
  45. let v = [...values];
  46. v[i] = e.target.value;
  47. this.props.setValues(v);
  48. }}
  49. disabled={this.props.disabled}
  50. />
  51. {this.renderDeleteButton(values, i)}
  52. </InputWrapper>
  53. );
  54. })}
  55. </>
  56. );
  57. };
  58. render() {
  59. let { values } = this.props;
  60. if (!Array.isArray(values)) {
  61. values = this.dict2arr(values);
  62. }
  63. return (
  64. <StyledInputArray>
  65. <Label>{this.props.label}</Label>
  66. {values.length === 0 ? <></> : this.renderInputList(values)}
  67. <AddRowButton
  68. onClick={() => {
  69. let v = [...values];
  70. v.push("");
  71. this.props.setValues(v);
  72. }}
  73. >
  74. <i className="material-icons">add</i> Add Row
  75. </AddRowButton>
  76. </StyledInputArray>
  77. );
  78. }
  79. }
  80. const AddRowButton = styled.div`
  81. display: flex;
  82. align-items: center;
  83. margin-top: 5px;
  84. width: 270px;
  85. font-size: 13px;
  86. color: #aaaabb;
  87. height: 30px;
  88. border-radius: 3px;
  89. cursor: pointer;
  90. background: #ffffff11;
  91. :hover {
  92. background: #ffffff22;
  93. }
  94. > i {
  95. color: #ffffff44;
  96. font-size: 16px;
  97. margin-left: 8px;
  98. margin-right: 10px;
  99. display: flex;
  100. align-items: center;
  101. justify-content: center;
  102. }
  103. `;
  104. const DeleteButton = styled.div`
  105. width: 15px;
  106. height: 15px;
  107. display: flex;
  108. align-items: center;
  109. margin-left: 8px;
  110. margin-top: -3px;
  111. justify-content: center;
  112. > i {
  113. font-size: 17px;
  114. color: #ffffff44;
  115. display: flex;
  116. align-items: center;
  117. justify-content: center;
  118. cursor: pointer;
  119. :hover {
  120. color: #ffffff88;
  121. }
  122. }
  123. `;
  124. const InputWrapper = styled.div`
  125. display: flex;
  126. align-items: center;
  127. `;
  128. const Input = styled.input`
  129. outline: none;
  130. border: none;
  131. margin-bottom: 5px;
  132. font-size: 13px;
  133. background: #ffffff11;
  134. border: 1px solid #ffffff55;
  135. border-radius: 3px;
  136. width: ${(props: { disabled?: boolean; width: string }) =>
  137. props.width ? props.width : "270px"};
  138. color: ${(props: { disabled?: boolean; width: string }) =>
  139. props.disabled ? "#ffffff44" : "white"};
  140. padding: 5px 10px;
  141. height: 35px;
  142. `;
  143. const Label = styled.div`
  144. color: #ffffff;
  145. margin-bottom: 10px;
  146. `;
  147. const StyledInputArray = styled.div`
  148. margin-bottom: 15px;
  149. margin-top: 22px;
  150. `;