ArrayInput.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import React from "react";
  2. import styled from "styled-components";
  3. import { ArrayInputField, ArrayInputFieldState } from "../types";
  4. import useFormField from "../hooks/useFormField";
  5. const ArrayInput: React.FC<ArrayInputField> = (props) => {
  6. const { state, variables, setVars } = useFormField<ArrayInputFieldState>(
  7. props.id,
  8. {
  9. initVars: {
  10. [props.variable]: [],
  11. },
  12. }
  13. );
  14. if (state == undefined) return <></>;
  15. const renderDeleteButton = (values: string[], i: number) => {
  16. if (!props.isReadOnly) {
  17. return (
  18. <DeleteButton
  19. onClick={() => {
  20. setVars((prev) => {
  21. return {
  22. [props.variable]: prev[props.variable]
  23. .slice(0, i)
  24. .concat(prev[props.variable].slice(i + 1)),
  25. };
  26. });
  27. }}
  28. >
  29. <i className="material-icons">cancel</i>
  30. </DeleteButton>
  31. );
  32. }
  33. };
  34. const 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. e.persist();
  46. setVars((prev) => {
  47. return {
  48. [props.variable]: prev[props.variable].map(
  49. (t: string, j: number) => {
  50. return i == j ? e.target.value : t;
  51. }
  52. ),
  53. };
  54. });
  55. }}
  56. disabled={props.isReadOnly}
  57. />
  58. {renderDeleteButton(values, i)}
  59. </InputWrapper>
  60. );
  61. })}
  62. </>
  63. );
  64. };
  65. return (
  66. <StyledInputArray>
  67. <Label>{props.label}</Label>
  68. {variables[props.variable] === 0 ? (
  69. <></>
  70. ) : (
  71. renderInputList(variables[props.variable])
  72. )}
  73. <AddRowButton
  74. onClick={() => {
  75. setVars((prev) => {
  76. return {
  77. [props.variable]: [...prev[props.variable], ""],
  78. };
  79. });
  80. }}
  81. >
  82. <i className="material-icons">add</i> Add Row
  83. </AddRowButton>
  84. </StyledInputArray>
  85. );
  86. };
  87. export default ArrayInput;
  88. const AddRowButton = styled.div`
  89. display: flex;
  90. align-items: center;
  91. margin-top: 5px;
  92. width: 270px;
  93. font-size: 13px;
  94. color: #aaaabb;
  95. height: 30px;
  96. border-radius: 3px;
  97. cursor: pointer;
  98. background: #ffffff11;
  99. :hover {
  100. background: #ffffff22;
  101. }
  102. > i {
  103. color: #ffffff44;
  104. font-size: 16px;
  105. margin-left: 8px;
  106. margin-right: 10px;
  107. display: flex;
  108. align-items: center;
  109. justify-content: center;
  110. }
  111. `;
  112. const DeleteButton = styled.div`
  113. width: 15px;
  114. height: 15px;
  115. display: flex;
  116. align-items: center;
  117. margin-left: 8px;
  118. margin-top: -3px;
  119. justify-content: center;
  120. > i {
  121. font-size: 17px;
  122. color: #ffffff44;
  123. display: flex;
  124. align-items: center;
  125. justify-content: center;
  126. cursor: pointer;
  127. :hover {
  128. color: #ffffff88;
  129. }
  130. }
  131. `;
  132. const InputWrapper = styled.div`
  133. display: flex;
  134. align-items: center;
  135. `;
  136. const Input = styled.input`
  137. outline: none;
  138. border: none;
  139. margin-bottom: 5px;
  140. font-size: 13px;
  141. background: #ffffff11;
  142. border: 1px solid #ffffff55;
  143. border-radius: 3px;
  144. width: ${(props: { disabled?: boolean; width: string }) =>
  145. props.width ? props.width : "270px"};
  146. color: ${(props: { disabled?: boolean; width: string }) =>
  147. props.disabled ? "#ffffff44" : "white"};
  148. padding: 5px 10px;
  149. height: 35px;
  150. `;
  151. const Label = styled.div`
  152. color: #ffffff;
  153. margin-bottom: 10px;
  154. `;
  155. const StyledInputArray = styled.div`
  156. margin-bottom: 15px;
  157. margin-top: 22px;
  158. `;