Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
import React, { useEffect, useRef, useState } from 'react';
|
|
import { connect } from 'react-redux';
|
|
import { makeStyles } from 'tss-react/mui';
|
|
|
|
import { IReduxState } from '../../../../app/types';
|
|
import Popover from '../../../../base/popover/components/Popover.web';
|
|
import { setDialOutCountry, setDialOutNumber } from '../../../actions.web';
|
|
import { getDialOutCountry, getDialOutNumber } from '../../../functions';
|
|
import { getCountryFromDialCodeText } from '../../../utils';
|
|
|
|
import CountryDropDown from './CountryDropdown';
|
|
import CountrySelector from './CountrySelector';
|
|
|
|
const PREFIX_REG = /^(00)|\+/;
|
|
|
|
interface IProps {
|
|
|
|
/**
|
|
* The country to dial out to.
|
|
*/
|
|
dialOutCountry: { code: string; dialCode: string; name: string; };
|
|
|
|
/**
|
|
* The number to dial out to.
|
|
*/
|
|
dialOutNumber: string;
|
|
|
|
/**
|
|
* Handler used when user presses 'Enter'.
|
|
*/
|
|
onSubmit: Function;
|
|
|
|
/**
|
|
* Sets the dial out country.
|
|
*/
|
|
setDialOutCountry: Function;
|
|
|
|
/**
|
|
* Sets the dial out number.
|
|
*/
|
|
setDialOutNumber: Function;
|
|
}
|
|
|
|
const useStyles = makeStyles()(theme => {
|
|
return {
|
|
container: {
|
|
border: 0,
|
|
borderRadius: theme.shape.borderRadius,
|
|
display: 'flex',
|
|
backgroundColor: theme.palette.ui03
|
|
},
|
|
|
|
input: {
|
|
padding: '0 4px',
|
|
margin: 0,
|
|
border: 0,
|
|
background: 'transparent',
|
|
color: theme.palette.text01,
|
|
flexGrow: 1,
|
|
...theme.typography.bodyShortRegular
|
|
}
|
|
};
|
|
});
|
|
|
|
const CountryPicker = (props: IProps) => {
|
|
const [ isOpen, setIsOpen ] = useState(false);
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const { classes } = useStyles();
|
|
|
|
useEffect(() => {
|
|
inputRef.current?.focus();
|
|
}, []);
|
|
|
|
const onChange = ({ target: { value: newValue } }: React.ChangeEvent<HTMLInputElement>) => {
|
|
if (PREFIX_REG.test(newValue)) {
|
|
const textWithDialCode = newValue.replace(PREFIX_REG, '');
|
|
|
|
if (textWithDialCode.length >= 4) {
|
|
const country = getCountryFromDialCodeText(textWithDialCode);
|
|
|
|
if (country) {
|
|
const rest = textWithDialCode.replace(country.dialCode, '');
|
|
|
|
props.setDialOutCountry(country);
|
|
props.setDialOutNumber(rest);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
props.setDialOutNumber(newValue);
|
|
};
|
|
|
|
const onCountrySelectorClick = () => {
|
|
setIsOpen(open => !open);
|
|
};
|
|
|
|
const onDropdownClose = () => {
|
|
setIsOpen(false);
|
|
};
|
|
|
|
const onEntryClick = (country: { code: string; dialCode: string; name: string; }) => {
|
|
props.setDialOutCountry(country);
|
|
onDropdownClose();
|
|
};
|
|
|
|
const onKeyPress = (e: React.KeyboardEvent) => {
|
|
if (e.key === ' ' || e.key === 'Enter') {
|
|
e.preventDefault();
|
|
props.onSubmit();
|
|
}
|
|
};
|
|
|
|
return (
|
|
/* eslint-disable react/jsx-no-bind */
|
|
<Popover
|
|
content = { <CountryDropDown onEntryClick = { onEntryClick } /> }
|
|
onPopoverClose = { onDropdownClose }
|
|
position = 'bottom'
|
|
trigger = 'click'
|
|
visible = { isOpen }>
|
|
<div className = { classes.container }>
|
|
<CountrySelector
|
|
country = { props.dialOutCountry }
|
|
onClick = { onCountrySelectorClick } />
|
|
<input
|
|
className = { classes.input }
|
|
onChange = { onChange }
|
|
onKeyPress = { onKeyPress }
|
|
ref = { inputRef }
|
|
value = { props.dialOutNumber } />
|
|
</div>
|
|
</Popover>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Maps (parts of) the redux state to the React {@code Component} props.
|
|
*
|
|
* @param {Object} state - The redux state.
|
|
* @returns {IProps}
|
|
*/
|
|
function mapStateToProps(state: IReduxState) {
|
|
return {
|
|
dialOutCountry: getDialOutCountry(state),
|
|
dialOutNumber: getDialOutNumber(state)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Maps redux actions to the props of the component.
|
|
*
|
|
* @type {{
|
|
* setDialOutCountry: Function,
|
|
* setDialOutNumber: Function
|
|
* }}
|
|
*/
|
|
const mapDispatchToProps = {
|
|
setDialOutCountry,
|
|
setDialOutNumber
|
|
};
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(CountryPicker);
|