/ common / components / AddressFieldFactory / AddressFieldFactory.tsx
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 };