AddressFieldFactory.tsx
1 import React from 'react'; 2 import { connect } from 'react-redux'; 3 4 import { ICurrentTo } from 'features/types'; 5 import { transactionActions } from 'features/transaction'; 6 import { Query } from 'components/renderCbs'; 7 import { AddressInputFactory } from './AddressInputFactory'; 8 import './AddressFieldFactory.scss'; 9 10 interface DispatchProps { 11 setCurrentTo: transactionActions.TSetCurrentTo; 12 } 13 14 interface OwnProps { 15 to: string | null; 16 isSelfAddress?: boolean; 17 showLabelMatch?: boolean; 18 showIdenticon?: boolean; 19 value?: string; 20 dropdownThreshold?: number; 21 withProps(props: CallbackProps): React.ReactElement<any> | null; 22 onChangeOverride?(ev: React.FormEvent<HTMLInputElement>): void; 23 } 24 25 interface State { 26 isFocused: boolean; 27 } 28 29 export interface CallbackProps { 30 isValid: boolean; 31 isLabelEntry: boolean; 32 readOnly: boolean; 33 currentTo: ICurrentTo; 34 onChange(ev: React.FormEvent<HTMLInputElement>): void; 35 onFocus(ev: React.FormEvent<HTMLInputElement>): void; 36 onBlur(ev: React.FormEvent<HTMLInputElement>): void; 37 } 38 39 type Props = DispatchProps & OwnProps; 40 41 class AddressFieldFactoryClass extends React.Component<Props> { 42 public state: State = { 43 isFocused: false 44 }; 45 46 private goingToBlur: number | null = null; 47 48 public componentDidMount() { 49 // this 'to' parameter can be either token or actual field related 50 const { to } = this.props; 51 if (to) { 52 this.props.setCurrentTo(to); 53 } 54 } 55 56 public componentWillUnmount() { 57 if (this.goingToBlur) { 58 window.clearTimeout(this.goingToBlur); 59 } 60 } 61 62 public render() { 63 const { 64 isSelfAddress, 65 showLabelMatch, 66 withProps, 67 showIdenticon, 68 onChangeOverride, 69 value, 70 dropdownThreshold 71 } = this.props; 72 73 return ( 74 <div className="AddressField"> 75 <AddressInputFactory 76 isSelfAddress={isSelfAddress} 77 showLabelMatch={showLabelMatch} 78 withProps={withProps} 79 showIdenticon={showIdenticon} 80 onChangeOverride={onChangeOverride} 81 value={value} 82 dropdownThreshold={dropdownThreshold} 83 isFocused={this.state.isFocused} 84 onChange={this.setAddress} 85 onFocus={this.focus} 86 onBlur={this.setBlurTimeout} 87 /> 88 </div> 89 ); 90 } 91 92 private focus = () => this.setState({ isFocused: true }); 93 94 private blur = () => this.setState({ isFocused: false }); 95 96 private setAddress = (ev: React.FormEvent<HTMLInputElement>) => { 97 const { onChangeOverride, setCurrentTo } = this.props; 98 const { value } = ev.currentTarget; 99 100 onChangeOverride ? onChangeOverride(ev) : setCurrentTo(value); 101 }; 102 103 private setBlurTimeout = () => (this.goingToBlur = window.setTimeout(this.blur, 150)); 104 } 105 106 const AddressFieldFactory = connect(null, { setCurrentTo: transactionActions.setCurrentTo })( 107 AddressFieldFactoryClass 108 ); 109 110 interface DefaultAddressFieldProps { 111 isSelfAddress?: boolean; 112 showLabelMatch?: boolean; 113 showIdenticon?: boolean; 114 value?: string; 115 dropdownThreshold?: number; 116 withProps(props: CallbackProps): React.ReactElement<any> | null; 117 onChangeOverride?(ev: React.FormEvent<HTMLInputElement>): void; 118 } 119 120 const DefaultAddressField: React.SFC<DefaultAddressFieldProps> = ({ 121 isSelfAddress, 122 showLabelMatch, 123 showIdenticon, 124 value, 125 withProps, 126 onChangeOverride, 127 dropdownThreshold 128 }) => ( 129 <Query 130 params={['to']} 131 withQuery={({ to }) => ( 132 <AddressFieldFactory 133 to={to} 134 isSelfAddress={isSelfAddress} 135 showLabelMatch={showLabelMatch} 136 withProps={withProps} 137 showIdenticon={showIdenticon} 138 onChangeOverride={onChangeOverride} 139 value={value} 140 dropdownThreshold={dropdownThreshold} 141 /> 142 )} 143 /> 144 ); 145 146 export { DefaultAddressField as AddressFieldFactory };