UNPKG

@automattic/form-components

Version:
160 lines (136 loc) 4.01 kB
/** * External dependencies */ import React from 'react'; import PropTypes from 'prop-types'; import { localize } from 'i18n-calypso'; import { identity, noop, find } from 'lodash'; import classnames from 'classnames'; /** * Internal dependencies */ import FormLabel from 'components/forms/form-label'; import FormTelInput from 'components/forms/form-tel-input'; import FormFieldset from 'components/forms/form-fieldset'; import CountrySelect from 'components/forms/form-country-select'; import phoneValidation from 'lib/phone-validation'; const CLEAN_REGEX = /^0|[\s.\-()]+/g; export class FormPhoneInput extends React.Component { static propTypes = { initialCountryCode: PropTypes.string, initialPhoneNumber: PropTypes.string, countriesList: PropTypes.object.isRequired, isDisabled: PropTypes.bool, countrySelectProps: PropTypes.object, phoneInputProps: PropTypes.object, onChange: PropTypes.func, translate: PropTypes.func, }; static defaultProps = { isDisabled: false, countrySelectProps: {}, phoneInputProps: {}, onChange: noop, translate: identity, }; state = { countryCode: this.props.initialCountryCode || '', phoneNumber: this.props.initialPhoneNumber || '', }; componentWillMount() { this._maybeSetCountryStateFromList(); } componentDidUpdate() { this._maybeSetCountryStateFromList(); } render() { var countryValueLink = { value: this.state.countryCode, requestChange: this._handleCountryChange, }, phoneValueLink = { value: this.state.phoneNumber, requestChange: this._handlePhoneChange, }; return ( <div className={ classnames( this.props.className, 'form-phone-input' ) }> <FormFieldset className="form-fieldset__country"> <FormLabel htmlFor="country_code"> { this.props.translate( 'Country Code', { context: 'The country code for the phone for the user.', } ) } </FormLabel> <CountrySelect { ...this.props.countrySelectProps } countriesList={ this.props.countriesList } disabled={ this.props.isDisabled } name="country_code" ref="countryCode" valueLink={ countryValueLink } /> </FormFieldset> <FormFieldset className="form-fieldset__phone-number"> <FormLabel htmlFor="phone_number"> { this.props.translate( 'Phone Number' ) } </FormLabel> <FormTelInput { ...this.props.phoneInputProps } disabled={ this.props.isDisabled } name="phone_number" valueLink={ phoneValueLink } /> </FormFieldset> </div> ); } _getCountryData = () => { // TODO: move this to country-list or CountrySelect return find( this.props.countriesList.get(), { code: this.state.countryCode, } ); }; _handleCountryChange = newValue => { this.setState( { countryCode: newValue }, this._triggerOnChange ); }; _handlePhoneChange = newValue => { this.setState( { phoneNumber: newValue }, this._triggerOnChange ); }; _triggerOnChange = () => { this.props.onChange( this.getValue() ); }; _cleanNumber = number => { return number.replace( CLEAN_REGEX, '' ); }; // Set the default state of the country code selector, if not already set _maybeSetCountryStateFromList = () => { var countries; if ( this.state.countryCode ) { return; } countries = this.props.countriesList.get(); if ( ! countries.length ) { return; } this.setState( { countryCode: countries[ 0 ].code, } ); }; _validate = number => { return phoneValidation( number ); }; getValue = () => { var countryData = this._getCountryData(), numberClean = this._cleanNumber( this.state.phoneNumber ), countryNumericCode = countryData ? countryData.numeric_code : '', numberFull = countryNumericCode + numberClean, isValid = this._validate( numberFull ); return { isValid: ! isValid.error, validation: isValid, countryData: countryData, phoneNumber: numberClean, phoneNumberFull: numberFull, }; }; } export default localize( FormPhoneInput );