glide-design-system
Version:
Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.
223 lines (201 loc) • 6.04 kB
JavaScript
import React, { useState, useEffect, useRef } from "react";
import styles from "./PhoneNumber.module.css";
function PhoneNumberInput({
style,
id,
name,
value,
setCountryCode,
className,
onChange,
label,required
}) {
const [phoneNumbers, setPhoneNumbers] = useState();
const [showCode, setShowCode] = useState(false);
const [hovered, setHovered] = useState(null);
const countryCodeRef = useRef(null);
const [code, setCode] = useState('');
const [phoneNumber, setPhoneNumber] = useState(value ? value :'');
const [updateValue, setValue] = useState(value ? value : "");
const codeStyle = {
fontSize: "16px",
cursor: "pointer",
...style,
};
const options = [
{ code: "+44", name: "+44 United Kingdom" },
{ code: "+91", name: "+91 India" },
{ code: "+1", name: "+1 United States " },
];
useEffect(() => {
setPhoneNumber(value);
if (value) {
const valueString = value.toString();
if (valueString.startsWith("+91")) {
setCountryCode("+91");
setCode("+91");
setPhoneNumbers(valueString.slice(3));
} else if (valueString.startsWith("+1")) {
setCountryCode("+1");
setCode("+1");
setPhoneNumbers(valueString.slice(2));
} else if (valueString.startsWith("+44")) {
setCountryCode("+44");
setCode("+44");
setPhoneNumbers(valueString.slice(3));
} else {
setCountryCode(code);
setCode(code);
setPhoneNumbers(valueString);
}
} else {
setCountryCode("");
setPhoneNumbers("");
}
if (!value) {
setCountryCode(code ? code : "+1");
setPhoneNumbers("");
setCode(code ? code : "+1");
}
function handleClickOutside(event) {
if (
countryCodeRef.current &&
!countryCodeRef.current.contains(event.target)
) {
setShowCode(false);
}
}
document.addEventListener("click", handleClickOutside);
return () => {
document.removeEventListener("click", handleClickOutside);
};
}, []);
useEffect(() => {
setValue(value);
}, [value]);
const selectCountryCode = (e) => {
setCountryCode(e.target.value);
setCode(e.target.value);
};
const showPhoneNumber = (e) => {
e.stopPropagation();
setShowCode(!showCode);
};
const selectCode = (data) => {
setCountryCode(data);
setCode(data);
setShowCode(false);
};
const valueHandler = (e) => {
setValue(e.target.value);
setPhoneNumber(e.target.value);
if (onChange) onChange(e);
};
const handlePhoneNumberKeyPress = (event) => {
const keyCode = event.keyCode || event.which;
const keyValue = String.fromCharCode(keyCode);
// Allow only numbers (digits) and backspace
const numericRegex = /^[0-9\b]+$/;
// Limit the input to only five characters
if (event.target.value.length >= 10 && event.key !== "Backspace") {
event.preventDefault();
return;
}
if (!numericRegex.test(keyValue)) {
event.preventDefault();
}
};
return (
<div>
<p className={styles.headers}>
{label ? label : "Phone Number"}
{required && (
<span className={styles.required}>
*
</span>
)}
</p>
<div style={{ display: "flex" }} id={id ? id : ""}>
<div
onChange={selectCountryCode}
style={codeStyle}
className={`${styles.countryCodeParentInput} ${
className ? className : ""
}`}
onClick={showPhoneNumber}>
<input
type="text"
value={code}
readOnly
ref={countryCodeRef}
className={`${styles.inputField} ${styles.countryCodeField}`}
/>
{!showCode ? (
<span
onClick={showPhoneNumber}
className="material-symbols-outlined">
expand_more
</span>
) : (
<span
onClick={showPhoneNumber}
className="material-symbols-outlined">
expand_less
</span>
)}
</div>
<br />
<div className={styles.phNoParentInput}>
<input
name={name}
placeholder="Enter Phone Number"
type="text"
className={styles.inputField}
onChange={(e) => valueHandler(e)}
onKeyPress={handlePhoneNumberKeyPress}
value={
phoneNumber===undefined?'':
phoneNumber?.toString().startsWith("+91")
? phoneNumber?.toString()?.slice(3)
: phoneNumber?.toString().startsWith("+44")
? phoneNumber?.toString()?.slice(3)
: phoneNumber?.toString()?.startsWith("+1")
? phoneNumber?.toString()?.slice(2)
: phoneNumber
}
/>
</div>
<br />
</div>
{showCode && (
<div
className={styles.countryCodeContainer}
style={{ border: "1px solid #A9A9A9", position: "absolute" }}>
{options.map((option, index) => (
<div key={index} value={option.code}>
<div
className={`${styles.countryCodeContainer} ${
hovered === index
? styles.optionColorHover
: styles.optionColorNotHover
} `}
onMouseEnter={() => setHovered(index)}
onMouseLeave={() => setHovered(null)}>
<div
onClick={() => selectCode(option.code)}
className={
option?.code === code
? styles?.optionsListSelected
: styles.optionsListUnselected
}>
{option?.name}
</div>
</div>
</div>
))}
</div>
)}
</div>
);
}
export default PhoneNumberInput;