import React, { Component } from 'react'; import { Form, Input, Button, Row, Col } from 'antd'; import omit from 'omit.js'; import styles from './index.less'; import ItemMap from './map'; import LoginContext, { ILoginContext } from './LoginContext'; import { FormComponentProps } from 'antd/lib/form'; type Omit = Pick>; export type WrappedLoginItemProps = Omit; export type LoginItemKeyType = keyof typeof ItemMap; export type LoginItemType = { [K in keyof typeof ItemMap]: React.FC }; export interface LoginItemProps { name?: string; rules?: any[]; style?: React.CSSProperties; onGetCaptcha?: (event?: MouseEvent) => void | Promise | false; placeholder?: string; buttonText?: React.ReactNode; onPressEnter?: (e: any) => void; countDown?: number; getCaptchaButtonText?: string; getCaptchaSecondText?: string; updateActive?: ILoginContext['updateActive']; type?: string; defaultValue?: string; form?: FormComponentProps['form']; customProps?: { [key: string]: any }; onChange?: (e: any) => void; } interface LoginItemState { count: number; } const FormItem = Form.Item; class WrapFormItem extends Component { static defaultProps = { getCaptchaButtonText: 'captcha', getCaptchaSecondText: 'second', }; constructor(props: LoginItemProps) { super(props); this.state = { count: 0, }; } interval: number | undefined; componentDidMount() { const { updateActive, name = '' } = this.props; if (updateActive) { updateActive(name); } } componentWillUnmount() { clearInterval(this.interval); } onGetCaptcha = () => { const { onGetCaptcha } = this.props; const result = onGetCaptcha ? onGetCaptcha() : null; if (result === false) { return; } if (result instanceof Promise) { result.then(this.runGetCaptchaCountDown); } else { this.runGetCaptchaCountDown(); } }; getFormItemOptions = ({ onChange, defaultValue, customProps = {}, rules }: LoginItemProps) => { const options: { rules?: Array; onChange?: LoginItemProps['onChange']; initialValue?: LoginItemProps['defaultValue']; } = { rules: rules || customProps.rules, }; if (onChange) { options.onChange = onChange; } if (defaultValue) { options.initialValue = defaultValue; } return options; }; runGetCaptchaCountDown = () => { const { countDown } = this.props; let count = countDown || 59; this.setState({ count }); this.interval = window.setInterval(() => { count -= 1; this.setState({ count }); if (count === 0) { clearInterval(this.interval); } }, 1000); }; render() { const { count } = this.state; // 这么写是为了防止restProps中 带入 onChange, defaultValue, rules props const { onChange, customProps, defaultValue, rules, name, getCaptchaButtonText, getCaptchaSecondText, updateActive, type, form, ...restProps } = this.props; if (!name) { console.warn('name is required!'); return null; } if (!form) { return null; } const { getFieldDecorator } = form; // get getFieldDecorator props const options = this.getFormItemOptions(this.props); const otherProps = restProps || {}; if (type === 'Captcha') { const inputProps = omit(otherProps, ['onGetCaptcha', 'countDown']); return ( {getFieldDecorator(name, options)()} ); } return ( {getFieldDecorator(name, options)()} ); } } const LoginItem: Partial = {}; Object.keys(ItemMap).forEach(key => { const item = ItemMap[key]; LoginItem[key] = (props: LoginItemProps) => ( {context => { console.log(context); return ( ); }} ); }); export default LoginItem as LoginItemType;