theluyuan 38ba663466
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
init
2025-09-02 14:49:16 +08:00

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);