KeyValueArray.tsx 4.2 KB

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