FormInput.js 11 KB

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