FormInput.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. import * as WebBrowser from "expo-web-browser";
  2. import * as React from "react";
  3. import { View, StyleSheet, TouchableWithoutFeedback } from "react-native";
  4. import {
  5. Layout,
  6. Input,
  7. Button,
  8. useTheme,
  9. Icon,
  10. Text,
  11. SelectItem,
  12. } from "@ui-kitten/components";
  13. import { Cascader, BottomModal } from "beeshell";
  14. import variables from "../constants/customTheme";
  15. import { useModel } from "flooks";
  16. import OpenTime from "./OpenTime";
  17. import Datepicker from "./Datepicker";
  18. import UpLoadImage from "./UpLoadImage";
  19. import moment from "moment";
  20. import Actionsheet from "./Actionsheet";
  21. const AlertIcon = props => <Icon {...props} name='alert-circle-outline' />;
  22. function* flattenSelect(array, key) {
  23. for (const item of array) {
  24. let _array = key ? item[key] : item;
  25. if (Array.isArray(_array) && _array.length > 0) {
  26. yield* flattenSelect(_array, key);
  27. } else {
  28. yield item;
  29. }
  30. }
  31. }
  32. const FormInput = React.memo(props => {
  33. const { appearance } = props;
  34. const [secureTextEntry, setSecureTextEntry] = React.useState(true);
  35. const { cancel, confirm } = useModel("wordsModel");
  36. const toggleSecureEntry = () => {
  37. setSecureTextEntry(!secureTextEntry);
  38. };
  39. const renderIcon = props => (
  40. <TouchableWithoutFeedback onPress={toggleSecureEntry}>
  41. <Icon {...props} name={secureTextEntry ? "eye-off" : "eye"} />
  42. </TouchableWithoutFeedback>
  43. );
  44. function getInputProps(props) {
  45. let _props = {
  46. value: props.value || "",
  47. placeholder: props.placeholder,
  48. };
  49. if (props.type === "phone") {
  50. _props = {
  51. ..._props,
  52. dataDetectorTypes: "phoneNumber",
  53. maxLength: 11,
  54. keyboardType: "phone-pad",
  55. };
  56. } else if (props.type === "password") {
  57. _props = {
  58. ..._props,
  59. accessoryRight: ImageProps => renderIcon(ImageProps),
  60. secureTextEntry: secureTextEntry,
  61. };
  62. } else if (props.type == "code") {
  63. _props = {
  64. ..._props,
  65. maxLength: 6,
  66. keyboardType: "numeric",
  67. };
  68. } else if (props.type == "amount" || props.type == "money") {
  69. _props = {
  70. ..._props,
  71. keyboardType: "numeric",
  72. };
  73. }
  74. if (props.onChange) {
  75. _props = {
  76. ..._props,
  77. onChangeText: nextValue => props.onChange(nextValue),
  78. };
  79. }
  80. return _props;
  81. }
  82. const inputProps = getInputProps(props);
  83. // const myInput = () => {
  84. // if (inputProps != null) {
  85. // return;
  86. // }
  87. // };
  88. const Label = props => {
  89. return (
  90. <View
  91. style={[
  92. appearance === "inner" ? styles.labelleft : styles.label,
  93. props.type === "img" ? { alignSelf: "flex-start" } : {},
  94. props.labelStyle || {},
  95. ]}
  96. >
  97. <Text
  98. category='c1'
  99. style={{
  100. textAlign: appearance != "inner" ? "right" : "left",
  101. }}
  102. >
  103. {props.label}
  104. </Text>
  105. </View>
  106. );
  107. };
  108. const ForwardIcon = props => <Icon {...props} name='arrow-ios-forward' />;
  109. const selectList = props.selectList ? props.selectList : [];
  110. const [bottomModalX, changeBottomModalx] = React.useState("");
  111. const [selectVal, setSelectVal] = React.useState("");
  112. const selectInfo = React.useMemo(() => {
  113. if (props.type === "select" && props.value && selectList.length > 0) {
  114. const childrens = [...flattenSelect(selectList, "children")];
  115. return (
  116. childrens.find(item => {
  117. return item.id == props.value;
  118. }) || { name: " " }
  119. );
  120. } else {
  121. return { name: " " };
  122. }
  123. }, [props.value, props.type, selectList]);
  124. const [open, ChangeOpen] = React.useState(false);
  125. function submitEvent(val) {
  126. console.log(val);
  127. }
  128. const Btn = ({ btnText }) => (
  129. <Button
  130. appearance='ghost'
  131. size='tiny'
  132. style={{ paddingVertical: 8, marginLeft: 5 }}
  133. >
  134. {btnText}
  135. </Button>
  136. );
  137. const theme = useTheme();
  138. function getMain(type, props) {
  139. if (type == "select") {
  140. return (
  141. <>
  142. <SelectItem
  143. appearance='form'
  144. style={{ flex: 1 }}
  145. accessoryRight={ForwardIcon}
  146. title={selectInfo.name}
  147. onPress={() => {
  148. bottomModalX.open();
  149. }}
  150. />
  151. <BottomModal
  152. ref={c => {
  153. changeBottomModalx(c);
  154. }}
  155. title={props.selectTitle}
  156. titleStyle={styles.titleStyle}
  157. cancelable={true}
  158. leftLabelText={cancel}
  159. leftLabelTextStyle={styles.leftLabelTextStyle}
  160. rightLabelText={confirm}
  161. rightLabelTextStyle={styles.rightLabelTextStyle}
  162. rightCallback={() => {
  163. props.onChange(selectVal);
  164. }}
  165. >
  166. <Cascader
  167. style={{
  168. width: "100%",
  169. height: 200,
  170. marginBottom: 50,
  171. minHeight: 200,
  172. }}
  173. data={selectList}
  174. fieldKeys={{
  175. labelKey: "name",
  176. idKey: "id",
  177. activeKey: "choose",
  178. }}
  179. onChange={(value, info) => {
  180. setSelectVal(value[0]);
  181. }}
  182. />
  183. </BottomModal>
  184. </>
  185. );
  186. } else if (type == "openTime") {
  187. return (
  188. <OpenTime
  189. open={open}
  190. submit={(start, end, week) => {
  191. ChangeOpen(false);
  192. props.onChange(
  193. week.join(","),
  194. moment(start, "HH:mm").format("HH:mm:ss"),
  195. moment(end, "HH:mm").format("HH:mm:ss")
  196. );
  197. console.log(
  198. moment(start, "HH:mm").format("HH:mm:ss"),
  199. moment(end, "HH:mm").format("HH:mm:ss"),
  200. week
  201. );
  202. }}
  203. cancelEvent={() => {
  204. ChangeOpen(false);
  205. }}
  206. openModal={() => {
  207. ChangeOpen(true);
  208. }}
  209. defaultValue={props.defaultValue}
  210. />
  211. );
  212. } else if (type == "date") {
  213. return (
  214. <Datepicker chooseDate={props.onChange} value={props.value} />
  215. );
  216. } else if (type == "url") {
  217. return (
  218. <SelectItem
  219. appearance='form'
  220. style={{ flex: 1 }}
  221. accessoryRight={ForwardIcon}
  222. title={props.value || " "}
  223. onPress={props.changePath}
  224. />
  225. );
  226. } else if (type == "actionSheet") {
  227. return (
  228. <>
  229. <Actionsheet
  230. list={props.list}
  231. value={props.value}
  232. onChange={props.onChange}
  233. />
  234. </>
  235. );
  236. } else if (type == "img") {
  237. return (
  238. <UpLoadImage
  239. style={styles.upload}
  240. value={props.value}
  241. changeIcon={props.onChange}
  242. />
  243. );
  244. } else if (appearance == "inner" && props.type == "code") {
  245. return (
  246. <Input
  247. {...inputProps}
  248. accessoryLeft={leftprops => (
  249. <Label {...props} {...leftprops} />
  250. )}
  251. accessoryRight={() => <Btn btnText={props.btnText} />}
  252. size='small'
  253. style={styles.input}
  254. appearance='innerCode'
  255. />
  256. );
  257. } else if (appearance == "inner") {
  258. return (
  259. <Input
  260. {...inputProps}
  261. accessoryLeft={leftprops => (
  262. <Label {...props} {...leftprops} />
  263. )}
  264. size='small'
  265. style={styles.input}
  266. appearance='inner'
  267. />
  268. );
  269. } else {
  270. return <Input {...inputProps} size='small' style={styles.input} />;
  271. }
  272. }
  273. return (
  274. <Layout
  275. level='1'
  276. style={[
  277. styles.inputContainer,
  278. { ...props.style },
  279. props.type === "img" ? { flexDirection: "column" } : {},
  280. { paddingVertical: appearance == "inner" ? 0 : 10 },
  281. ]}
  282. >
  283. {appearance !== "inner" && <Label {...props} />}
  284. {(!props.value || props.value == " ") && (
  285. <Text category='c1' style={styles.sub}>
  286. {props.sub}
  287. </Text>
  288. )}
  289. {getMain(props.type, props)}
  290. {appearance !== "inner" && props.type == "code" && Btn(props)}
  291. </Layout>
  292. );
  293. });
  294. function ChnageTime(sendNum, isSend, changeSend_Num) {
  295. let num = sendNum - 1;
  296. console.log(num);
  297. changeSend_Num(true, num);
  298. setTimeout(() => {
  299. ChnageTime(num, isSend, changeSend_Num);
  300. }, 1000);
  301. }
  302. const styles = StyleSheet.create({
  303. inputContainer: {
  304. flexDirection: "row",
  305. alignItems: "center",
  306. paddingVertical: 10,
  307. paddingHorizontal: 4,
  308. },
  309. input: {
  310. flex: 1,
  311. },
  312. label: {
  313. width: 80,
  314. marginRight: 19,
  315. flexShrink: 0,
  316. },
  317. labelleft: {
  318. width: 73,
  319. flexShrink: 0,
  320. },
  321. right: {
  322. flexDirection: "row",
  323. },
  324. code: {
  325. paddingHorizontal: 5,
  326. marginLeft: 5,
  327. },
  328. selectContent: {
  329. backgroundColor: "#F0F0F0",
  330. },
  331. titleStyle: {
  332. fontSize: 15,
  333. },
  334. leftLabelTextStyle: {
  335. fontSize: 13,
  336. },
  337. rightLabelTextStyle: {
  338. fontSize: 13,
  339. },
  340. sub: {
  341. color: "#787878",
  342. position: "absolute",
  343. left: 90,
  344. zIndex: 2,
  345. },
  346. upload: {
  347. marginTop: 20,
  348. width: 67,
  349. height: 67,
  350. },
  351. });
  352. export default FormInput;