react-simple-phone-input 1.1.8-beta → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1355,36 +1355,6 @@ function requireReactJsxRuntime_development () {
1355
1355
  }
1356
1356
  } (jsxRuntime));
1357
1357
 
1358
- function styleInject(css, ref) {
1359
- if ( ref === void 0 ) ref = {};
1360
- var insertAt = ref.insertAt;
1361
-
1362
- if (!css || typeof document === 'undefined') { return; }
1363
-
1364
- var head = document.head || document.getElementsByTagName('head')[0];
1365
- var style = document.createElement('style');
1366
- style.type = 'text/css';
1367
-
1368
- if (insertAt === 'top') {
1369
- if (head.firstChild) {
1370
- head.insertBefore(style, head.firstChild);
1371
- } else {
1372
- head.appendChild(style);
1373
- }
1374
- } else {
1375
- head.appendChild(style);
1376
- }
1377
-
1378
- if (style.styleSheet) {
1379
- style.styleSheet.cssText = css;
1380
- } else {
1381
- style.appendChild(document.createTextNode(css));
1382
- }
1383
- }
1384
-
1385
- var css_248z = ".simple-phone-input-sri198-container {\r\n position: relative;\r\n}\r\n\r\n.simple-phone-input-sri198-main {\r\n display: flex;\r\n border: 1px solid rgba(0, 0, 0, 0.295);\r\n user-select: none;\r\n border-radius: 3px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-container {\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n background: rgba(0, 0, 0, 0.144);\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-container img {\r\n margin-right: 6px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown {\r\n background: white;\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n position: absolute;\r\n top: 100%;\r\n left: 0;\r\n right: 0;\r\n height: 250px;\r\n overflow-y: auto;\r\n box-shadow: 0 0 20px rgb(180, 180, 180);\r\n display: none;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-container-button {\r\n display: flex;\r\n flex: 1;\r\n width: 92px;\r\n padding: 5px 2px 5px 7px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-container-button.dial {\r\n width: unset;\r\n padding: 8px 3px 8px 8px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown.active {\r\n display: block;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown li {\r\n margin: 3px 0;\r\n padding: 3px 8px;\r\n display: flex;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown li.active {\r\n background: rgba(0, 0, 0, 0.116);\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown li img {\r\n margin-right: 6px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-text {\r\n font-size: 15px;\r\n flex: 1;\r\n margin-top: 3px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-country-code {\r\n opacity: 0.6;\r\n margin-top: 3px;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-icon svg {\r\n transition: 0.3s ease;\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown-icon.active svg {\r\n transform: rotate(-180deg)\r\n}\r\n\r\n.simple-phone-input-sri198-dropdown li:hover {\r\n background: rgba(0, 0, 0, 0.116);\r\n}\r\n\r\n.simple-phone-input-sri198-selected-code {\r\n flex: 1;\r\n font-size: 14px;\r\n margin-top: 3px;\r\n}\r\n\r\n.simple-phone-input-sri198-input {\r\n width: 100%;\r\n border: none;\r\n padding: 0 10px;\r\n}\r\n\r\n.simple-phone-input-sri198-input:focus {\r\n outline: none;\r\n}\r\n\r\n.simple-phone-input-sri198-search-container {\r\n padding: 5px;\r\n position: relative;\r\n}\r\n\r\n.simple-phone-input-sri198-search-container input {\r\n border: 1px solid rgba(0, 0, 0, 0.116);\r\n padding: 8px 10px;\r\n width: 100%;\r\n font-size: 15px;\r\n border-radius: 2px;\r\n}\r\n\r\n.simple-phone-input-sri198-search-icon {\r\n position: absolute;\r\n right: 10px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n display: flex;\r\n pointer-events: none;\r\n}\r\n\r\n.simple-phone-input-sri198-not-found {\r\n text-align: center;\r\n margin-top: 10px;\r\n font-size: 15px;\r\n color: red;\r\n}\r\n\r\n.simple-phone-input-sri198-search-icon svg {\r\n font-size: 20px;\r\n}\r\n\r\n.simple-phone-input-sri198-search-container input:focus {\r\n outline: none;\r\n}";
1386
- styleInject(css_248z);
1387
-
1388
1358
  const countryData = [
1389
1359
  {
1390
1360
  country: "Afghanistan",
@@ -2568,17 +2538,19 @@ const countryData = [
2568
2538
  }
2569
2539
  ];
2570
2540
 
2541
+ //Get default country function
2571
2542
  const getDefaultCountry = (code) => {
2572
2543
  const result = countryData.find((item) => item.countryCode === code);
2573
2544
  return result;
2574
2545
  };
2546
+ //Get country data by search
2575
2547
  const getBySearch = (search, onlyCountry, excludeCountry) => {
2576
- var countries = [];
2548
+ let countries = [];
2577
2549
  if (excludeCountry && excludeCountry.length > 0) {
2578
- countries = countryData.filter((item) => excludeCountry?.indexOf(item.countryCode) === -1);
2550
+ countries = countryData.filter((item) => !excludeCountry?.includes(item.countryCode));
2579
2551
  }
2580
2552
  else if (onlyCountry && onlyCountry?.length > 0) {
2581
- countries = countryData.filter((item) => onlyCountry?.indexOf(item.countryCode) !== -1);
2553
+ countries = countryData.filter((item) => onlyCountry?.includes(item.countryCode));
2582
2554
  }
2583
2555
  else {
2584
2556
  countries = countryData;
@@ -2590,22 +2562,24 @@ const getBySearch = (search, onlyCountry, excludeCountry) => {
2590
2562
  });
2591
2563
  return result;
2592
2564
  };
2565
+ //Get country data by filter
2593
2566
  const getCountryByFilter = (onlyCountry, excludeCountry, preferredCountry) => {
2594
- var countries = [];
2567
+ let countries = [];
2595
2568
  if (excludeCountry && excludeCountry.length > 0) {
2596
- countries = countryData.filter((item) => excludeCountry?.indexOf(item.countryCode) === -1);
2569
+ countries = countryData.filter((item) => !excludeCountry?.includes(item.countryCode));
2597
2570
  }
2598
2571
  else if (onlyCountry && onlyCountry?.length > 0) {
2599
- countries = countryData.filter((item) => onlyCountry?.indexOf(item.countryCode) !== -1);
2572
+ countries = countryData.filter((item) => onlyCountry?.includes(item.countryCode));
2600
2573
  }
2601
2574
  else {
2602
2575
  countries = countryData;
2603
2576
  }
2604
- const result = countries.sort((a, b) => (Number(preferredCountry?.indexOf(b.countryCode)) - Number(preferredCountry?.indexOf(a.countryCode)))
2577
+ const result = countries.sort((a, b) => (Number(preferredCountry?.includes(b.countryCode)) - Number(preferredCountry?.includes(a.countryCode)))
2605
2578
  || (preferredCountry?.indexOf(a.countryCode) - preferredCountry?.indexOf(b.countryCode)));
2606
2579
  return result;
2607
2580
  };
2608
2581
 
2582
+ //Click out side hook
2609
2583
  function useOnClickOutside(ref, handler) {
2610
2584
  React.useEffect(() => {
2611
2585
  const listener = (event) => {
@@ -2623,12 +2597,21 @@ function useOnClickOutside(ref, handler) {
2623
2597
  }, [ref, handler]);
2624
2598
  }
2625
2599
 
2600
+ //Component
2626
2601
  const PhoneInput = ({ placeholder, country, onChange, value, iconComponent, inputProps, onlyCountries, excludeCountries, preferredCountries, showDropdownIcon = true, dialCodeInputField = false, search = true, searchPlaceholder = "Search country", showSearchIcon = true, searchIconComponent, searchProps, searchNotFound = "Not found" }) => {
2602
+ //State
2627
2603
  const [selected, setSelected] = React.useState({});
2628
2604
  const [isDropdown, setDropdown] = React.useState(false);
2629
2605
  const [inputValue, setInputValue] = React.useState(value || "");
2630
2606
  const [countryDataInfo, setCountryData] = React.useState(countryData);
2607
+ const [cursor, setCursor] = React.useState(0);
2608
+ //Ref
2609
+ const dropdownRef = React.useRef(null);
2610
+ const listRef = React.useRef(null);
2611
+ //Custom Hook Call
2612
+ useOnClickOutside(dropdownRef, () => setDropdown(false));
2631
2613
  //Handler
2614
+ //---Input Onchange Handler//
2632
2615
  const handleChange = (e) => {
2633
2616
  const onlyNumber = e.target.value.replace(/\D/g, '');
2634
2617
  if (dialCodeInputField) {
@@ -2640,13 +2623,13 @@ const PhoneInput = ({ placeholder, country, onChange, value, iconComponent, inpu
2640
2623
  onChange(selected.callingCode + onlyNumber);
2641
2624
  }
2642
2625
  };
2643
- //
2626
+ //---Search Input Onchange Handler//
2644
2627
  const onSearchHandler = (e) => {
2645
2628
  const search = e.target.value;
2646
2629
  setCountryData(getBySearch(search, onlyCountries, excludeCountries));
2647
2630
  };
2648
- //
2649
- const handleSelected = (item) => {
2631
+ //---Set Selected Handler//
2632
+ const handleSelected = (item, i) => {
2650
2633
  if (dialCodeInputField) {
2651
2634
  const result = inputValue?.replace(selected.callingCode, item.callingCode);
2652
2635
  setInputValue(result.length > 0 ? result : item.callingCode);
@@ -2657,11 +2640,54 @@ const PhoneInput = ({ placeholder, country, onChange, value, iconComponent, inpu
2657
2640
  }
2658
2641
  setSelected(item);
2659
2642
  setDropdown(false);
2643
+ setCursor(i);
2644
+ };
2645
+ //---Scroll To View Handler//
2646
+ const scrollIntoView = (position) => {
2647
+ if (search) {
2648
+ if (countryDataInfo.length > 0) {
2649
+ listRef.current?.scrollTo({
2650
+ top: position,
2651
+ behavior: "smooth"
2652
+ });
2653
+ }
2654
+ }
2655
+ };
2656
+ //---Keyboard Navigation//
2657
+ const keyBoardNav = (e) => {
2658
+ if (isDropdown) {
2659
+ if (e.key === "ArrowDown") {
2660
+ e.preventDefault();
2661
+ setCursor(c => (c < countryDataInfo.length - 1 ? c + 1 : c));
2662
+ }
2663
+ if (e.key === "ArrowUp") {
2664
+ e.preventDefault();
2665
+ setCursor(c => (c > 0 ? c - 1 : 0));
2666
+ }
2667
+ if (e.key === "Escape") {
2668
+ setDropdown(false);
2669
+ }
2670
+ if (e.key === "Enter" && cursor >= 0) {
2671
+ setSelected(countryDataInfo[cursor]);
2672
+ setDropdown(false);
2673
+ }
2674
+ }
2660
2675
  };
2661
- //Custom Hook
2662
- const ref = React.useRef();
2663
- useOnClickOutside(ref, () => setDropdown(false));
2664
- //Effects
2676
+ //React Hook
2677
+ //---Scroll to view hook//
2678
+ React.useEffect(() => {
2679
+ if (cursor < 0 || cursor > countryDataInfo.length || !listRef) {
2680
+ return () => {
2681
+ };
2682
+ }
2683
+ if (isDropdown && listRef) {
2684
+ if (countryDataInfo.length > 0) {
2685
+ let listItems = Array.from(listRef.current?.children);
2686
+ listItems[cursor] && scrollIntoView(listItems[cursor].offsetTop - 65);
2687
+ }
2688
+ }
2689
+ }, [cursor]);
2690
+ //---Dial Code Field Effect//
2665
2691
  React.useMemo(() => {
2666
2692
  if (dialCodeInputField) {
2667
2693
  const result = inputValue?.replace(selected.callingCode, getDefaultCountry(country).callingCode);
@@ -2670,16 +2696,16 @@ const PhoneInput = ({ placeholder, country, onChange, value, iconComponent, inpu
2670
2696
  }
2671
2697
  setSelected(getDefaultCountry(country));
2672
2698
  }, [country, dialCodeInputField]);
2673
- //
2699
+ //---Country search hook//
2674
2700
  React.useMemo(() => {
2675
2701
  setCountryData(getCountryByFilter(onlyCountries, excludeCountries, preferredCountries));
2676
2702
  }, [onlyCountries, excludeCountries, preferredCountries]);
2677
- return (jsxRuntime.exports.jsx("div", { className: "simple-phone-input-sri198-container", children: jsxRuntime.exports.jsxs("div", { className: "simple-phone-input-sri198-main", children: [jsxRuntime.exports.jsxs("div", { className: "simple-phone-input-sri198-dropdown-container", ref: ref, children: [jsxRuntime.exports.jsxs("div", { onClick: () => setDropdown(!isDropdown), className: dialCodeInputField ? "simple-phone-input-sri198-dropdown-container-button dial" : "simple-phone-input-sri198-dropdown-container-button", children: [jsxRuntime.exports.jsx("img", { src: "https://cdn.jsdelivr.net/gh/siamahnaf198/country-flags@main/img/" + selected.countryCode + ".svg", alt: selected.country, width: "20px" }), !dialCodeInputField &&
2703
+ return (jsxRuntime.exports.jsx("div", { className: "simple-phone-input-sri198-container", onKeyDown: (e) => keyBoardNav(e), tabIndex: -1, children: jsxRuntime.exports.jsxs("div", { className: "simple-phone-input-sri198-main", children: [jsxRuntime.exports.jsxs("div", { className: "simple-phone-input-sri198-dropdown-container", ref: dropdownRef, children: [jsxRuntime.exports.jsxs("div", { onClick: () => setDropdown(!isDropdown), className: dialCodeInputField ? "simple-phone-input-sri198-dropdown-container-button dial" : "simple-phone-input-sri198-dropdown-container-button", children: [jsxRuntime.exports.jsx("img", { src: "https://cdn.jsdelivr.net/gh/siamahnaf198/country-flags@main/img/" + selected.countryCode + ".svg", alt: selected.country, width: "20px" }), !dialCodeInputField &&
2678
2704
  jsxRuntime.exports.jsx("span", { className: "simple-phone-input-sri198-selected-code", children: selected.callingCode }), showDropdownIcon &&
2679
- jsxRuntime.exports.jsx("div", { className: isDropdown ? "simple-phone-input-sri198-dropdown-icon" : "simple-phone-input-sri198-dropdown-icon active", children: iconComponent ? iconComponent : (jsxRuntime.exports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", preserveAspectRatio: "xMidYMid meet", viewBox: "0 0 24 24", children: jsxRuntime.exports.jsx("path", { fill: "currentColor", d: "m7 10l5 5l5-5z" }) })) })] }), jsxRuntime.exports.jsxs("ul", { className: isDropdown ? "simple-phone-input-sri198-dropdown active" : "simple-phone-input-sri198-dropdown", children: [search &&
2705
+ jsxRuntime.exports.jsx("div", { className: isDropdown ? "simple-phone-input-sri198-dropdown-icon" : "simple-phone-input-sri198-dropdown-icon active", children: iconComponent ? iconComponent : (jsxRuntime.exports.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", preserveAspectRatio: "xMidYMid meet", viewBox: "0 0 24 24", children: jsxRuntime.exports.jsx("path", { fill: "currentColor", d: "m7 10l5 5l5-5z" }) })) })] }), jsxRuntime.exports.jsxs("ul", { className: isDropdown ? "simple-phone-input-sri198-dropdown active" : "simple-phone-input-sri198-dropdown", ref: listRef, children: [search &&
2680
2706
  jsxRuntime.exports.jsxs("div", { className: "simple-phone-input-sri198-search-container", children: [jsxRuntime.exports.jsx("input", { placeholder: searchPlaceholder, ...searchProps, onChange: onSearchHandler }), showSearchIcon &&
2681
2707
  jsxRuntime.exports.jsx("div", { className: "simple-phone-input-sri198-search-icon", children: searchIconComponent ?? (jsxRuntime.exports.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", preserveAspectRatio: "xMidYMid meet", viewBox: "0 0 48 48", children: [jsxRuntime.exports.jsxs("g", { fill: "#616161", children: [jsxRuntime.exports.jsx("path", { d: "m29.175 31.99l2.828-2.827l12.019 12.019l-2.828 2.827z" }), jsxRuntime.exports.jsx("circle", { cx: "20", cy: "20", r: "16" })] }), jsxRuntime.exports.jsx("path", { fill: "#37474F", d: "m32.45 35.34l2.827-2.828l8.696 8.696l-2.828 2.828z" }), jsxRuntime.exports.jsx("circle", { cx: "20", cy: "20", r: "13", fill: "#64B5F6" }), jsxRuntime.exports.jsx("path", { fill: "#BBDEFB", d: "M26.9 14.2c-1.7-2-4.2-3.2-6.9-3.2s-5.2 1.2-6.9 3.2c-.4.4-.3 1.1.1 1.4c.4.4 1.1.3 1.4-.1C16 13.9 17.9 13 20 13s4 .9 5.4 2.5c.2.2.5.4.8.4c.2 0 .5-.1.6-.2c.4-.4.4-1.1.1-1.5z" })] })) })] }), countryDataInfo.length === 0 &&
2682
- jsxRuntime.exports.jsx("div", { className: "simple-phone-input-sri198-not-found", children: searchNotFound }), countryDataInfo.map((item, i) => (jsxRuntime.exports.jsxs("li", { onClick: () => handleSelected(item), className: item.countryCode === selected.countryCode ? "active" : "", children: [jsxRuntime.exports.jsx("img", { src: "https://cdn.jsdelivr.net/gh/siamahnaf198/country-flags@main/img/" + item.countryCode + ".svg", alt: item.country, width: "20px" }), jsxRuntime.exports.jsx("span", { className: "simple-phone-input-sri198-dropdown-text", children: item.country }), jsxRuntime.exports.jsx("span", { className: "simple-phone-input-sri198-dropdown-country-code", children: item.callingCode })] }, i)))] })] }), jsxRuntime.exports.jsx("input", { className: "simple-phone-input-sri198-input", placeholder: placeholder, onChange: handleChange, type: "tel", onInput: (e) => {
2708
+ jsxRuntime.exports.jsx("div", { className: "simple-phone-input-sri198-not-found", children: searchNotFound }), countryDataInfo.map((item, i) => (jsxRuntime.exports.jsxs("li", { onClick: () => handleSelected(item, i), className: i === cursor ? "active" : "", children: [jsxRuntime.exports.jsx("img", { src: "https://cdn.jsdelivr.net/gh/siamahnaf198/country-flags@main/img/" + item.countryCode + ".svg", alt: item.country, width: "20px" }), jsxRuntime.exports.jsx("span", { className: "simple-phone-input-sri198-dropdown-text", children: item.country }), jsxRuntime.exports.jsx("span", { className: "simple-phone-input-sri198-dropdown-country-code", children: item.callingCode })] }, i)))] })] }), jsxRuntime.exports.jsx("input", { className: "simple-phone-input-sri198-input", placeholder: placeholder, onChange: handleChange, type: "tel", onInput: (e) => {
2683
2709
  if (dialCodeInputField) {
2684
2710
  const oldVal = inputValue.slice(selected.callingCode.length);
2685
2711
  if (e.target.value.startsWith(selected.callingCode)) {
@@ -2689,7 +2715,7 @@ const PhoneInput = ({ placeholder, country, onChange, value, iconComponent, inpu
2689
2715
  e.target.value = selected.callingCode + oldVal;
2690
2716
  }
2691
2717
  }
2692
- }, value: inputValue, ...inputProps })] }) }));
2718
+ }, onKeyDown: (e) => keyBoardNav(e), value: inputValue, ...inputProps })] }) }));
2693
2719
  };
2694
2720
 
2695
2721
  export { PhoneInput };