react-phone-number-input
Version:
Telephone number input React component
162 lines (141 loc) • 7.85 kB
JavaScript
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { getInitialPhoneDigits, getCountryForPartialE164Number, parsePhoneNumber } from './phoneInputHelpers';
import { isCountrySupportedWithError, getSupportedCountries } from './countries';
export default function getPhoneInputWithCountryStateUpdateFromNewProps(props, prevProps, state) {
var metadata = props.metadata,
countries = props.countries,
newDefaultCountry = props.defaultCountry,
newValue = props.value,
newReset = props.reset,
international = props.international,
displayInitialValueAsLocalNumber = props.displayInitialValueAsLocalNumber,
initialValueFormat = props.initialValueFormat;
var prevDefaultCountry = prevProps.defaultCountry,
prevValue = prevProps.value,
prevReset = prevProps.reset;
var country = state.country,
value = state.value,
hasUserSelectedACountry = state.hasUserSelectedACountry;
var _getInitialPhoneDigits = function _getInitialPhoneDigits(parameters) {
return getInitialPhoneDigits(_objectSpread({}, parameters, {
international: international,
useNationalFormat: displayInitialValueAsLocalNumber || initialValueFormat === 'national',
metadata: metadata
}));
}; // Some users requested a way to reset the component
// (both number `<input/>` and country `<select/>`).
// Whenever `reset` property changes both number `<input/>`
// and country `<select/>` are reset.
// It's not implemented as some instance `.reset()` method
// because `ref` is forwarded to `<input/>`.
// It's also not replaced with just resetting `country` on
// external `value` reset, because a user could select a country
// and then not input any `value`, and so the selected country
// would be "stuck", if not using this `reset` property.
// https://github.com/catamphetamine/react-phone-number-input/issues/300
if (newReset !== prevReset) {
return {
phoneDigits: _getInitialPhoneDigits({
value: undefined,
defaultCountry: newDefaultCountry
}),
value: undefined,
country: newDefaultCountry,
hasUserSelectedACountry: undefined
};
} // `value` is the value currently shown in the component:
// it's stored in the component's `state`, and it's not the `value` property.
// `prevValue` is "previous `value` property".
// `newValue` is "new `value` property".
// If the default country changed
// (e.g. in case of ajax GeoIP detection after page loaded)
// then select it, but only if the user hasn't already manually
// selected a country, and no phone number has been manually entered so far.
// Because if the user has already started inputting a phone number
// then they're okay with no country being selected at all ("International")
// and they don't want to be disturbed, don't want their input to be screwed, etc.
if (newDefaultCountry !== prevDefaultCountry) {
var isNewDefaultCountrySupported = !newDefaultCountry || isCountrySupportedWithError(newDefaultCountry, metadata);
var noValueHasBeenEnteredByTheUser = // By default, "no value has been entered" means `value` is `undefined`.
!value || // When `international` is `true`, and some country has been pre-selected,
// then the `<input/>` contains a pre-filled value of `+${countryCallingCode}${leadingDigits}`,
// so in case of `international` being `true`, "the user hasn't entered anything" situation
// doesn't just mean `value` is `undefined`, but could also mean `value` is `+${countryCallingCode}`.
international && value === _getInitialPhoneDigits({
value: undefined,
defaultCountry: prevDefaultCountry
}); // Only update the `defaultCountry` property if no phone number
// has been entered by the user or pre-set by the application.
var noValueHasBeenEntered = !newValue && noValueHasBeenEnteredByTheUser;
if (!hasUserSelectedACountry && isNewDefaultCountrySupported && noValueHasBeenEntered) {
return {
country: newDefaultCountry,
// If `phoneDigits` is empty, then automatically select the new `country`
// and set `phoneDigits` to `+{getCountryCallingCode(newCountry)}`.
// The code assumes that "no phone number has been entered by the user",
// and no `value` property has been passed, so the `phoneNumber` parameter
// of `_getInitialPhoneDigits({ value, phoneNumber, ... })` is `undefined`.
phoneDigits: _getInitialPhoneDigits({
value: undefined,
defaultCountry: newDefaultCountry
}),
// `value` is `undefined` and it stays so.
value: undefined
};
}
} // If a new `value` is set externally.
// (e.g. as a result of an ajax API request
// to get user's phone after page loaded)
// The first part — `newValue !== prevValue` —
// is basically `props.value !== prevProps.value`
// so it means "if value property was changed externally".
// The second part — `newValue !== value` —
// is for ignoring the `getDerivedStateFromProps()` call
// which happens in `this.onChange()` right after `this.setState()`.
// If this `getDerivedStateFromProps()` call isn't ignored
// then the country flag would reset on each input.
if (newValue !== prevValue && newValue !== value) {
var phoneNumber;
var parsedCountry;
if (newValue) {
phoneNumber = parsePhoneNumber(newValue, metadata);
var supportedCountries = getSupportedCountries(countries, metadata);
if (phoneNumber && phoneNumber.country) {
// Ignore `else` because all countries are supported in metadata.
/* istanbul ignore next */
if (!supportedCountries || supportedCountries.indexOf(phoneNumber.country) >= 0) {
parsedCountry = phoneNumber.country;
}
} else {
parsedCountry = getCountryForPartialE164Number(newValue, {
country: undefined,
countries: supportedCountries,
metadata: metadata
});
}
}
var hasUserSelectedACountryUpdate;
if (!newValue) {
// Reset `hasUserSelectedACountry` flag in `state`.
hasUserSelectedACountryUpdate = {
hasUserSelectedACountry: undefined
};
}
return _objectSpread({}, hasUserSelectedACountryUpdate, {
phoneDigits: _getInitialPhoneDigits({
phoneNumber: phoneNumber,
value: newValue,
defaultCountry: newDefaultCountry
}),
value: newValue,
country: newValue ? parsedCountry : newDefaultCountry
});
} // `defaultCountry` didn't change.
// `value` didn't change.
// `phoneDigits` didn't change, because `value` didn't change.
//
// So no need to update state.
}
//# sourceMappingURL=getPhoneInputWithCountryStateUpdateFromNewProps.js.map