import React, { Component } from 'react';
import { connect } from 'react-redux';
import ExpandIcon from '@atlaskit/icon/glyph/expand';
import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
import { translate } from '../../base/i18n';
import CountryIcon from './CountryIcon';
import { updateDialOutCodes } from '../actions';
/**
* The expand icon of the dropdown menu.
*
* @type {XML}
*/
const EXPAND_ICON = ;
/**
* The default value of the country if the fetch service is unavailable.
*
* @type {{name: string, dialCode: string, code: string}}
*/
const DEFAULT_COUNTRY = {
name: 'United States',
dialCode: '+1',
code: 'US'
};
/**
* React {@code Component} responsible for fetching and displaying dial-out
* country codes, as well as dialing a phone number.
*
* @extends Component
*/
class DialOutNumbersForm extends Component {
/**
* {@code DialOutNumbersForm}'s property types.
*
* @static
*/
static propTypes = {
/**
* The redux state representing the list of dial-out codes.
*/
_dialOutCodes: React.PropTypes.array,
/**
* The function called on every dial input change.
*/
onChange: React.PropTypes.func,
/**
* Invoked to obtain translated strings.
*/
t: React.PropTypes.func,
/**
* Invoked to send an ajax request for dial-out codes.
*/
updateDialOutCodes: React.PropTypes.func
};
/**
* Initializes a new {@code DialOutNumbersForm} instance.
*
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props) {
super(props);
this.state = {
dialInput: '',
/**
* Whether or not the dropdown should be open.
*
* @type {boolean}
*/
isDropdownOpen: false,
/**
* The selected country.
*
* @type {Object}
*/
selectedCountry: DEFAULT_COUNTRY
};
/**
* The internal reference to the DOM/HTML element backing the React
* {@code Component} text input.
*
* @private
* @type {HTMLInputElement}
*/
this._dialInputElem = null;
// Bind event handlers so they are only bound once for every instance.
this._onInputChange = this._onInputChange.bind(this);
this._onOpenChange = this._onOpenChange.bind(this);
this._onSelect = this._onSelect.bind(this);
this._setDialInputElement = this._setDialInputElement.bind(this);
}
/**
* Dispatches a request for dial out codes if not already present in the
* redux store. If dial out codes are present, sets a default code to
* display in the dropdown trigger.
*
* @inheritdoc
* returns {void}
*/
componentDidMount() {
const dialOutCodes = this.props._dialOutCodes;
if (dialOutCodes) {
this._setDefaultCode(dialOutCodes);
} else {
this.props.updateDialOutCodes();
}
}
/**
* Monitors for dial out code updates and sets a default code to display in
* the dropdown trigger if not already set.
*
* @inheritdoc
* returns {void}
*/
componentWillReceiveProps(nextProps) {
if (!this.state.selectedCountry && nextProps._dialOutCodes) {
this._setDefaultCode(nextProps._dialOutCodes);
}
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { t, _dialOutCodes } = this.props;
const items
= _dialOutCodes ? this._formatCountryCodes(_dialOutCodes) : [];
return (
{ this._createDropdownMenu(items) }
);
}
/**
* Creates a {@code StatelessDropdownMenu} instance.
*
* @param {Array} items - The content to display within the dropdown.
* @returns {ReactElement}
*/
_createDropdownMenu(items) {
const { code, dialCode } = this.state.selectedCountry;
return (
{ this._createDropdownTrigger(dialCode, code) }
);
}
/**
* Creates a React {@code Component} with a readonly HTMLInputElement as a
* trigger for displaying the dropdown menu. The {@code Component} will also
* display the currently selected number.
*
* @param {string} dialCode - The +xx dial code.
* @param {string} countryCode - The country 2 letter code.
* @private
* @returns {ReactElement}
*/
_createDropdownTrigger(dialCode, countryCode) {
return (
{ EXPAND_ICON }
);
}
/**
* Transforms the passed in numbers object into an array of objects that can
* be parsed by {@code StatelessDropdownMenu}.
*
* @param {Object} countryCodes - The list of country codes.
* @private
* @returns {Array