@verma-consulting/design-library 0.1.43 → 0.1.45

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/index.js CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.tsx
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
+ CountrySelect: () => CountrySelect_default,
34
35
  EmptyState: () => EmptyState_default,
35
36
  FormDialog: () => FormDialog_default,
36
37
  FormDrawer: () => FormDrawer_default,
@@ -48,11 +49,11 @@ __export(index_exports, {
48
49
  StatusPill: () => StatusPill_default,
49
50
  TabPanel: () => TabPanel_default,
50
51
  TablePagination: () => TablePagination_default,
51
- ThemeProvider: () => import_styles17.ThemeProvider,
52
- createTheme: () => import_styles17.createTheme,
53
- makeStyles: () => import_styles18.makeStyles,
54
- styled: () => import_styles17.styled,
55
- useTheme: () => import_styles17.useTheme
52
+ ThemeProvider: () => import_styles19.ThemeProvider,
53
+ createTheme: () => import_styles19.createTheme,
54
+ makeStyles: () => import_styles20.makeStyles,
55
+ styled: () => import_styles19.styled,
56
+ useTheme: () => import_styles19.useTheme
56
57
  });
57
58
  module.exports = __toCommonJS(index_exports);
58
59
  __reExport(index_exports, require("@mui/material"), module.exports);
@@ -267,8 +268,8 @@ var TablePagination = React.forwardRef(function TablePagination2(props, ref) {
267
268
  var TablePagination_default = TablePagination;
268
269
 
269
270
  // src/index.tsx
270
- var import_styles17 = require("@mui/material/styles");
271
- var import_styles18 = require("@mui/styles");
271
+ var import_styles19 = require("@mui/material/styles");
272
+ var import_styles20 = require("@mui/styles");
272
273
 
273
274
  // src/Logo.tsx
274
275
  var import_react = require("react");
@@ -393,7 +394,10 @@ var import_icons_material = require("@mui/icons-material");
393
394
  var import_jsx_runtime4 = require("react/jsx-runtime");
394
395
  var BootstrapDialog = (0, import_styles2.styled)(import_material3.Dialog)(({ theme }) => ({
395
396
  "& .MuiDialog-paper": {
396
- borderRadius: 24
397
+ borderRadius: 24,
398
+ [theme.breakpoints.down("md")]: {
399
+ borderRadius: 0
400
+ }
397
401
  },
398
402
  "& .MuiDialogContent-root": {
399
403
  padding: theme.spacing(4)
@@ -616,6 +620,17 @@ var import_material5 = require("@mui/material");
616
620
  var import_styles6 = require("@mui/material/styles");
617
621
  var import_icons_material3 = require("@mui/icons-material");
618
622
  var import_jsx_runtime6 = require("react/jsx-runtime");
623
+ var DEFAULT_ACCEPT = "image/jpeg,image/png,image/gif,image/webp,image/avif,image/bmp,image/svg+xml,image/heic,image/heif";
624
+ function isValidImageFile(file) {
625
+ const type = file.type.trim().toLowerCase();
626
+ if (type.startsWith("image/")) {
627
+ return true;
628
+ }
629
+ if (!type && /\.(jpe?g|png|gif|webp|avif|bmp|svg|heic|heif)$/i.test(file.name)) {
630
+ return true;
631
+ }
632
+ return false;
633
+ }
619
634
  var HiddenInput = (0, import_styles6.styled)("input")({
620
635
  position: "absolute",
621
636
  width: 1,
@@ -685,7 +700,7 @@ var ImageUploadAvatar = ({
685
700
  onChange,
686
701
  size = 128,
687
702
  variant = "rounded",
688
- accept = "image/*",
703
+ accept = DEFAULT_ACCEPT,
689
704
  disabled,
690
705
  allowClear = true
691
706
  }) => {
@@ -707,7 +722,12 @@ var ImageUploadAvatar = ({
707
722
  }, [internalSrc]);
708
723
  const handlePick = (e) => {
709
724
  var _a2, _b;
710
- const selected = (_b = (_a2 = e.target.files) == null ? void 0 : _a2[0]) != null ? _b : null;
725
+ const raw = (_b = (_a2 = e.target.files) == null ? void 0 : _a2[0]) != null ? _b : null;
726
+ if (raw && !isValidImageFile(raw)) {
727
+ if (inputRef.current) inputRef.current.value = "";
728
+ return;
729
+ }
730
+ const selected = raw;
711
731
  if (internalSrc == null ? void 0 : internalSrc.startsWith("blob:")) {
712
732
  URL.revokeObjectURL(internalSrc);
713
733
  }
@@ -1285,39 +1305,6 @@ var useStyles2 = (0, import_styles14.makeStyles)((theme) => ({
1285
1305
  whiteSpace: "pre-wrap"
1286
1306
  }
1287
1307
  }));
1288
- function createSearchableSelectPopperOptions() {
1289
- return {
1290
- modifiers: [
1291
- {
1292
- name: "searchableSelectViewportMaxHeight",
1293
- enabled: true,
1294
- phase: "beforeWrite",
1295
- requires: ["computeStyles"],
1296
- fn({ state }) {
1297
- if (typeof window === "undefined") return;
1298
- const padding = 12;
1299
- const vh = window.innerHeight;
1300
- const ref = state.rects.reference;
1301
- const refBottom = ref.y + ref.height;
1302
- const spaceBelow = vh - refBottom - padding;
1303
- const spaceAbove = ref.y - padding;
1304
- const placement = state.placement || "bottom-start";
1305
- const isTop = placement.startsWith("top");
1306
- const available = Math.max(0, isTop ? spaceAbove : spaceBelow);
1307
- const maxH = Math.min(available, vh * 0.7);
1308
- state.styles.popper = state.styles.popper || {};
1309
- Object.assign(state.styles.popper, {
1310
- display: "flex",
1311
- flexDirection: "column",
1312
- minHeight: 0,
1313
- maxHeight: `${maxH}px`,
1314
- overflow: "hidden"
1315
- });
1316
- }
1317
- }
1318
- ]
1319
- };
1320
- }
1321
1308
  var SearchableSelect = import_react6.default.memo(
1322
1309
  ({
1323
1310
  name,
@@ -1387,10 +1374,6 @@ var SearchableSelect = import_react6.default.memo(
1387
1374
  }, [selected, multiple]);
1388
1375
  const isValueEmpty = !value.trim();
1389
1376
  const showClear = onClear != null;
1390
- const searchableSelectPopperOptions = (0, import_react6.useMemo)(
1391
- () => createSearchableSelectPopperOptions(),
1392
- []
1393
- );
1394
1377
  return editMode ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material13.FormControl, { fullWidth: true, style, disabled, size, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1395
1378
  import_material13.Autocomplete,
1396
1379
  {
@@ -1448,36 +1431,12 @@ var SearchableSelect = import_react6.default.memo(
1448
1431
  }
1449
1432
  },
1450
1433
  slotProps: {
1451
- popper: {
1452
- // Align with field width; only flip vertically (never left/right like placement "auto").
1453
- placement: "bottom-start",
1454
- modifiers: [
1455
- {
1456
- name: "flip",
1457
- options: {
1458
- fallbackPlacements: [
1459
- "top-start",
1460
- "top",
1461
- "bottom-start",
1462
- "bottom"
1463
- ]
1464
- }
1465
- }
1466
- ],
1467
- popperOptions: searchableSelectPopperOptions
1468
- },
1469
1434
  paper: {
1470
1435
  sx: {
1471
1436
  background: glassBackground,
1472
1437
  backdropFilter: "blur(12px) saturate(150%)",
1473
1438
  border: `1px solid ${(0, import_styles13.alpha)("#FFFFFF", theme.palette.mode === "dark" ? 0.16 : 0.55)}`,
1474
1439
  boxShadow: theme.palette.mode === "dark" ? "rgba(0, 0, 0, 0.34) 0px 10px 26px" : "rgba(15, 23, 42, 0.16) 0px 8px 24px",
1475
- flex: 1,
1476
- minHeight: 0,
1477
- maxHeight: "100%",
1478
- overflow: "hidden",
1479
- display: "flex",
1480
- flexDirection: "column",
1481
1440
  "& .MuiAutocomplete-option": {
1482
1441
  "&[aria-selected='true']": {
1483
1442
  backgroundColor: (0, import_styles13.alpha)(
@@ -1495,18 +1454,6 @@ var SearchableSelect = import_react6.default.memo(
1495
1454
  }
1496
1455
  }
1497
1456
  },
1498
- ListboxProps: {
1499
- sx: {
1500
- // Override MUI default maxHeight: 40vh so the panel height comes from the Popper modifier only.
1501
- maxHeight: "none",
1502
- flex: "1 1 auto",
1503
- minHeight: 0,
1504
- overflowY: "auto",
1505
- WebkitOverflowScrolling: "touch",
1506
- overscrollBehavior: "contain",
1507
- touchAction: "pan-y"
1508
- }
1509
- },
1510
1457
  renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1511
1458
  import_material13.TextField,
1512
1459
  {
@@ -1623,11 +1570,11 @@ var FormDrawer = ({
1623
1570
  onClose: () => setOpen(false),
1624
1571
  sx: {
1625
1572
  "& .MuiDrawer-paper": {
1626
- width: mdMatches ? "100%" : "64%",
1573
+ width: mdMatches ? "100%" : "72%",
1627
1574
  height: "100%",
1628
1575
  display: "flex",
1629
1576
  flexDirection: "column",
1630
- borderRadius: mdMatches ? "24px 24px 0 0" : "24px 0 0 24px"
1577
+ borderRadius: mdMatches ? 0 : "24px 0 0 24px"
1631
1578
  }
1632
1579
  },
1633
1580
  children: [
@@ -1681,9 +1628,129 @@ var FormDrawer_default = FormDrawer;
1681
1628
  // src/PhoneNumberField.tsx
1682
1629
  var import_react7 = require("react");
1683
1630
  var import_material15 = require("@mui/material");
1631
+ var import_Autocomplete = require("@mui/material/Autocomplete");
1684
1632
  var import_styles16 = require("@mui/material/styles");
1685
1633
  var import_common_library3 = require("@verma-consulting/common-library");
1686
1634
  var import_jsx_runtime17 = require("react/jsx-runtime");
1635
+ var import_react8 = require("react");
1636
+ var EXT_MAX_LEN = 20;
1637
+ var filterCountryOptions = (0, import_Autocomplete.createFilterOptions)({
1638
+ stringify: (option) => `${option.label} ${option.code} ${option.phone}`
1639
+ });
1640
+ function extractExtensionFromMain(main) {
1641
+ let m = main.trim();
1642
+ let extFromMeta = "";
1643
+ const semi = m.match(/;ext=(\d+)/i);
1644
+ if (semi) {
1645
+ extFromMeta = semi[1];
1646
+ m = m.replace(/;ext=\d+/gi, "");
1647
+ }
1648
+ const extWord = m.match(/\bext\.?\s*(\d+)/i);
1649
+ if (extWord) {
1650
+ extFromMeta = extFromMeta || extWord[1];
1651
+ m = m.replace(/\bext\.?\s*\d+/i, "");
1652
+ }
1653
+ return { main: m, extFromMeta };
1654
+ }
1655
+ function parsePhoneValue(raw, countries, defaultCountry) {
1656
+ var _a2, _b, _c, _d;
1657
+ const s = String(raw != null ? raw : "").trim();
1658
+ if (!s) return { dial: "", local: "", extension: "" };
1659
+ const defaultDial = (_b = (_a2 = countries.find((c) => c.code === defaultCountry)) == null ? void 0 : _a2.phone) != null ? _b : "1";
1660
+ let ext = "";
1661
+ let mainPart = s;
1662
+ const xSplit = s.split(/\s*[xX]\s*/);
1663
+ if (xSplit.length > 1) {
1664
+ mainPart = (_c = xSplit[0]) != null ? _c : "";
1665
+ ext = xSplit.slice(1).join("").replace(/\D/g, "").slice(0, EXT_MAX_LEN);
1666
+ }
1667
+ const meta = extractExtensionFromMain(mainPart);
1668
+ mainPart = meta.main;
1669
+ if (meta.extFromMeta) {
1670
+ ext = (ext || meta.extFromMeta).replace(/\D/g, "").slice(0, EXT_MAX_LEN);
1671
+ }
1672
+ const digitsOnly = mainPart.replace(/\D/g, "");
1673
+ if (!digitsOnly) return { dial: "", local: "", extension: ext };
1674
+ const sorted = [...countries].sort(
1675
+ (a, b) => b.phone.length - a.phone.length
1676
+ );
1677
+ if (mainPart.trim().startsWith("+")) {
1678
+ const found2 = sorted.find((c) => digitsOnly.startsWith(c.phone));
1679
+ if (found2) {
1680
+ const rest = digitsOnly.slice(found2.phone.length);
1681
+ const local = found2.phone === "1" ? rest.slice(-10) : rest.slice(-10);
1682
+ return {
1683
+ dial: found2.phone,
1684
+ local,
1685
+ extension: ext
1686
+ };
1687
+ }
1688
+ }
1689
+ const foundDefault = countries.find((c) => c.code === defaultCountry);
1690
+ const dial = (_d = foundDefault == null ? void 0 : foundDefault.phone) != null ? _d : defaultDial;
1691
+ if (dial === "1") {
1692
+ if (digitsOnly.length === 11 && digitsOnly.startsWith("1")) {
1693
+ return {
1694
+ dial: "1",
1695
+ local: digitsOnly.slice(1, 11),
1696
+ extension: ext
1697
+ };
1698
+ }
1699
+ if (digitsOnly.length <= 10) {
1700
+ return {
1701
+ dial: "1",
1702
+ local: digitsOnly.slice(-10),
1703
+ extension: ext
1704
+ };
1705
+ }
1706
+ if (digitsOnly.length > 10) {
1707
+ return {
1708
+ dial: "1",
1709
+ local: digitsOnly.slice(-10),
1710
+ extension: ext
1711
+ };
1712
+ }
1713
+ }
1714
+ const found = sorted.find((c) => digitsOnly.startsWith(c.phone));
1715
+ if (found) {
1716
+ const rest = digitsOnly.slice(found.phone.length);
1717
+ return {
1718
+ dial: found.phone,
1719
+ local: rest.slice(-10),
1720
+ extension: ext
1721
+ };
1722
+ }
1723
+ return {
1724
+ dial,
1725
+ local: digitsOnly.slice(-10),
1726
+ extension: ext
1727
+ };
1728
+ }
1729
+ function buildStoredValue(dial, local, extension) {
1730
+ if (!dial || !local) return "";
1731
+ const core = `+${dial}${local}`;
1732
+ if (extension) return `${core}x${extension}`;
1733
+ return core;
1734
+ }
1735
+ function formatNanpNational(digits) {
1736
+ const d = digits.replace(/\D/g, "").slice(0, 10);
1737
+ if (!d.length) return "";
1738
+ if (d.length <= 3) return d;
1739
+ if (d.length <= 6) return `${d.slice(0, 3)}-${d.slice(3)}`;
1740
+ return `${d.slice(0, 3)}-${d.slice(3, 6)}-${d.slice(6, 10)}`;
1741
+ }
1742
+ function formatOtherNational(local) {
1743
+ const d = local.replace(/\D/g, "").slice(0, 15);
1744
+ if (!d.length) return "";
1745
+ return d.replace(/(\d{3,4})(?=\d)/g, "$1 ").trim();
1746
+ }
1747
+ function formatLineDisplay(dial, localNumber, extension) {
1748
+ if (!localNumber && !extension) return "";
1749
+ const main = dial === "1" ? formatNanpNational(localNumber) : formatOtherNational(localNumber);
1750
+ if (!extension) return main;
1751
+ if (!main) return `x${extension}`;
1752
+ return `${main} x${extension}`;
1753
+ }
1687
1754
  var PhoneNumberField = ({
1688
1755
  value = "",
1689
1756
  onChange,
@@ -1694,6 +1761,7 @@ var PhoneNumberField = ({
1694
1761
  autoFocus = false,
1695
1762
  onBlur
1696
1763
  }) => {
1764
+ var _a2, _b;
1697
1765
  const theme = (0, import_material15.useTheme)();
1698
1766
  const smMatches = (0, import_material15.useMediaQuery)(theme.breakpoints.down("sm"));
1699
1767
  const countries = import_common_library3.constants.COUNTRIES || [];
@@ -1708,65 +1776,67 @@ var PhoneNumberField = ({
1708
1776
  };
1709
1777
  const [country, setCountry] = (0, import_react7.useState)(defaultCountry);
1710
1778
  const [localNumber, setLocalNumber] = (0, import_react7.useState)("");
1779
+ const [extension, setExtension] = (0, import_react7.useState)("");
1711
1780
  const [isFocused, setIsFocused] = (0, import_react7.useState)(false);
1712
1781
  const [selectOpen, setSelectOpen] = (0, import_react7.useState)(false);
1713
1782
  const [ignoreNextOutsideClick, setIgnoreNextOutsideClick] = (0, import_react7.useState)(false);
1783
+ const [bareExtensionX, setBareExtensionX] = (0, import_react7.useState)(false);
1714
1784
  const wrapperRef = (0, import_react7.useRef)(null);
1715
- const parseE164 = (0, import_react7.useCallback)(
1785
+ const applyParsedFromValue = (0, import_react7.useCallback)(
1716
1786
  (val) => {
1717
- const cleaned = (val || "").toString().replace(/\D/g, "");
1718
- if (!cleaned) return { dial: "", local: "" };
1719
- const sorted = [...countries].sort(
1720
- (a, b) => b.phone.length - a.phone.length
1721
- );
1722
- const found = sorted.find((c) => cleaned.startsWith(c.phone));
1723
- if (found) {
1724
- const dial = found.phone;
1725
- const local = cleaned.slice(dial.length);
1726
- return { dial, local: local.slice(-10) };
1787
+ setBareExtensionX(false);
1788
+ const parsed = parsePhoneValue(val, countries, defaultCountry);
1789
+ if (parsed.dial) {
1790
+ const found = countries.find((c) => c.phone === parsed.dial);
1791
+ if (found) setCountry(found.code);
1727
1792
  }
1728
- return { dial: "", local: cleaned.slice(-10) };
1793
+ setLocalNumber(parsed.local);
1794
+ setExtension(parsed.extension);
1729
1795
  },
1730
- [countries]
1796
+ [countries, defaultCountry]
1731
1797
  );
1732
1798
  (0, import_react7.useEffect)(() => {
1733
1799
  if (isFocused) return;
1734
1800
  if (!value) {
1735
1801
  setLocalNumber("");
1802
+ setExtension("");
1803
+ setBareExtensionX(false);
1736
1804
  return;
1737
1805
  }
1738
- const { dial, local } = parseE164(String(value));
1739
- if (dial) {
1740
- const found = countries.find((c) => c.phone === dial);
1741
- if (found) setCountry(found.code);
1742
- }
1743
- setLocalNumber(local);
1744
- }, [value, parseE164, countries, isFocused]);
1745
- const formatLocalNumber = (digits) => {
1746
- const cleaned = digits.replace(/\D/g, "").slice(0, 10);
1747
- let formatted = "";
1748
- if (cleaned.length > 0) formatted += cleaned.slice(0, 3);
1749
- if (cleaned.length > 3) formatted += "-" + cleaned.slice(3, 6);
1750
- if (cleaned.length > 6) formatted += "-" + cleaned.slice(6, 10);
1751
- return formatted;
1752
- };
1806
+ applyParsedFromValue(String(value));
1807
+ }, [value, isFocused, applyParsedFromValue]);
1753
1808
  const commitValue = (0, import_react7.useCallback)(() => {
1754
- var _a2;
1809
+ var _a3;
1810
+ const sel = countries.find((c) => c.code === country);
1811
+ const dial = (_a3 = sel == null ? void 0 : sel.phone) != null ? _a3 : "";
1812
+ onChange(buildStoredValue(dial, localNumber, extension));
1813
+ }, [countries, country, localNumber, extension, onChange]);
1814
+ const handleLocalChange = (e) => {
1815
+ var _a3, _b2;
1816
+ const raw = e.target.value;
1817
+ const parts = raw.split(/\s*[xX]\s*/);
1818
+ const mainRaw = (_a3 = parts[0]) != null ? _a3 : "";
1819
+ const extDigits = parts.slice(1).join("").replace(/\D/g, "").slice(0, EXT_MAX_LEN);
1755
1820
  const sel = countries.find((c) => c.code === country);
1756
- const dial = (_a2 = sel == null ? void 0 : sel.phone) != null ? _a2 : "";
1757
- if (dial && localNumber) {
1758
- onChange(`+${dial}${localNumber}`);
1821
+ const dial = (_b2 = sel == null ? void 0 : sel.phone) != null ? _b2 : "1";
1822
+ const maxLocal = dial === "1" ? 10 : 15;
1823
+ let mainDigits = mainRaw.replace(/\D/g, "");
1824
+ if (dial === "1") {
1825
+ if (mainDigits.length === 11 && mainDigits.startsWith("1")) {
1826
+ mainDigits = mainDigits.slice(1);
1827
+ }
1828
+ mainDigits = mainDigits.slice(0, 10);
1759
1829
  } else {
1760
- onChange("");
1830
+ mainDigits = mainDigits.slice(0, maxLocal);
1761
1831
  }
1762
- }, [countries, country, localNumber, onChange]);
1763
- const handleLocalChange = (e) => {
1764
- const digits = e.target.value.replace(/\D/g, "").slice(0, 10);
1765
- setLocalNumber(digits);
1766
- };
1767
- const handleCountryChange = (e) => {
1768
- setCountry(e.target.value);
1832
+ setLocalNumber(mainDigits);
1833
+ setExtension(extDigits);
1834
+ setBareExtensionX(
1835
+ /[xX]/.test(raw) && extDigits.length === 0
1836
+ );
1769
1837
  };
1838
+ const dialForDisplay = (_b = (_a2 = countries.find((c) => c.code === country)) == null ? void 0 : _a2.phone) != null ? _b : "";
1839
+ const displayLocal = formatLineDisplay(dialForDisplay, localNumber, extension) + (bareExtensionX ? localNumber ? " x" : "x" : "");
1770
1840
  (0, import_react7.useEffect)(() => {
1771
1841
  const onDocMouseDown = (ev) => {
1772
1842
  if (!wrapperRef.current) return;
@@ -1794,6 +1864,7 @@ var PhoneNumberField = ({
1794
1864
  onBlur == null ? void 0 : onBlur();
1795
1865
  }
1796
1866
  };
1867
+ const selectedCountry = countries.find((c) => c.code === country);
1797
1868
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1798
1869
  import_material15.Box,
1799
1870
  {
@@ -1810,52 +1881,77 @@ var PhoneNumberField = ({
1810
1881
  sx: { width: "100%" },
1811
1882
  children: [
1812
1883
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1813
- import_material15.TextField,
1884
+ import_material15.Autocomplete,
1814
1885
  {
1815
- select: true,
1816
- value: country,
1817
- onChange: handleCountryChange,
1818
1886
  disabled,
1887
+ options: countries,
1888
+ value: selectedCountry != null ? selectedCountry : null,
1889
+ onChange: (_, newValue) => {
1890
+ if (newValue) setCountry(newValue.code);
1891
+ },
1892
+ getOptionLabel: (option) => `(+${option.phone})`,
1893
+ filterOptions: filterCountryOptions,
1894
+ isOptionEqualToValue: (a, b) => a.code === b.code,
1895
+ disableClearable: true,
1819
1896
  size,
1897
+ onOpen: () => {
1898
+ setSelectOpen(true);
1899
+ setIgnoreNextOutsideClick(true);
1900
+ },
1901
+ onClose: () => setSelectOpen(false),
1820
1902
  sx: {
1821
- width: 140,
1903
+ width: smMatches ? 64 : 108,
1904
+ minWidth: smMatches ? 64 : 108,
1905
+ maxWidth: smMatches ? 64 : 108,
1906
+ flexShrink: 0,
1822
1907
  "& .MuiOutlinedInput-root": {
1823
1908
  borderTopRightRadius: 0,
1824
1909
  borderBottomRightRadius: 0,
1825
1910
  ...glassInputSx
1826
- }
1827
- },
1828
- SelectProps: {
1829
- renderValue: (val) => {
1830
- const code = typeof val === "string" ? val : defaultCountry.toUpperCase();
1831
- const c = countries.find((x) => x.code === code);
1832
- return c ? `${c.code} (+${c.phone})` : code;
1833
1911
  },
1834
- onOpen: () => {
1835
- setSelectOpen(true);
1836
- setIgnoreNextOutsideClick(true);
1837
- },
1838
- onClose: () => setSelectOpen(false)
1912
+ "& .MuiInputBase-input": {
1913
+ overflow: "hidden",
1914
+ textOverflow: "ellipsis",
1915
+ whiteSpace: "nowrap"
1916
+ }
1839
1917
  },
1840
- children: countries.map((option) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material15.MenuItem, { value: option.code, children: [
1841
- option.code,
1842
- " (+",
1843
- option.phone,
1844
- ")"
1845
- ] }, option.code))
1918
+ renderOption: (props, option) => /* @__PURE__ */ (0, import_react8.createElement)(import_material15.Box, { component: "li", ...props, key: option.code }, /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1919
+ import_material15.Box,
1920
+ {
1921
+ component: "img",
1922
+ loading: "lazy",
1923
+ width: 20,
1924
+ alt: "",
1925
+ src: `https://flagcdn.com/w20/${option.code.toLowerCase()}.png`,
1926
+ srcSet: `https://flagcdn.com/w40/${option.code.toLowerCase()}.png 2x`,
1927
+ sx: { mr: 1, flexShrink: 0 }
1928
+ }
1929
+ ), option.code, " (+", option.phone, ")"),
1930
+ renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1931
+ import_material15.TextField,
1932
+ {
1933
+ ...params,
1934
+ variant: "outlined",
1935
+ size,
1936
+ inputProps: {
1937
+ ...params.inputProps,
1938
+ autoComplete: "tel-country"
1939
+ }
1940
+ }
1941
+ )
1846
1942
  }
1847
1943
  ),
1848
1944
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1849
1945
  import_material15.TextField,
1850
1946
  {
1851
1947
  label,
1852
- value: localNumber ? formatLocalNumber(localNumber) : "",
1948
+ value: displayLocal,
1853
1949
  onChange: handleLocalChange,
1854
- placeholder: " - - ",
1950
+ placeholder: "415-555-0100 x123",
1855
1951
  inputProps: {
1856
- inputMode: "numeric",
1857
- pattern: "[0-9]*",
1858
- maxLength: 12
1952
+ inputMode: "text",
1953
+ autoComplete: "tel-national",
1954
+ "aria-label": label
1859
1955
  },
1860
1956
  disabled,
1861
1957
  size,
@@ -1877,8 +1973,207 @@ var PhoneNumberField = ({
1877
1973
  );
1878
1974
  };
1879
1975
  var PhoneNumberField_default = PhoneNumberField;
1976
+
1977
+ // src/CountrySelect.tsx
1978
+ var import_react9 = require("react");
1979
+ var import_material16 = require("@mui/material");
1980
+ var import_styles17 = require("@mui/material/styles");
1981
+ var import_styles18 = require("@mui/styles");
1982
+ var import_common_library4 = require("@verma-consulting/common-library");
1983
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1984
+ var import_react10 = require("react");
1985
+ var useStyles3 = (0, import_styles18.makeStyles)((theme) => ({
1986
+ defaultMode: {
1987
+ margin: "4px",
1988
+ paddingTop: 14,
1989
+ paddingBottom: 14,
1990
+ paddingLeft: 8,
1991
+ paddingRight: 8,
1992
+ cursor: "pointer",
1993
+ borderRadius: 8,
1994
+ border: `1px solid ${(0, import_styles17.alpha)("#FFFFFF", theme.palette.mode === "dark" ? 0.16 : 0.55)}`,
1995
+ backdropFilter: "blur(14px) saturate(150%)",
1996
+ background: theme.palette.mode === "dark" ? "linear-gradient(160deg, rgba(31,41,55,0.78), rgba(17,24,39,0.68))" : "linear-gradient(160deg, rgba(255,255,255,0.9), rgba(245,249,255,0.72))",
1997
+ "&:hover": {
1998
+ boxShadow: theme.palette.mode === "dark" ? "rgba(0, 0, 0, 0.34) 0px 10px 26px" : "rgba(15, 23, 42, 0.16) 0px 8px 24px"
1999
+ }
2000
+ },
2001
+ formLabel: {
2002
+ cursor: "pointer"
2003
+ },
2004
+ formValue: {
2005
+ cursor: "pointer",
2006
+ wordBreak: "break-word",
2007
+ whiteSpace: "pre-wrap"
2008
+ }
2009
+ }));
2010
+ var COUNTRIES = import_common_library4.constants.COUNTRIES;
2011
+ var CountrySelect = ({
2012
+ value,
2013
+ onChange,
2014
+ label = "Country",
2015
+ size = "small",
2016
+ disabled = false,
2017
+ style = {}
2018
+ }) => {
2019
+ const theme = (0, import_styles17.useTheme)();
2020
+ const classes = useStyles3();
2021
+ const [editMode, setEditMode] = (0, import_react9.useState)(false);
2022
+ const glassBackground = theme.palette.mode === "dark" ? "linear-gradient(160deg, rgba(31,41,55,0.78), rgba(17,24,39,0.68))" : "linear-gradient(160deg, rgba(255,255,255,0.9), rgba(245,249,255,0.72))";
2023
+ const handleBlur = () => {
2024
+ setTimeout(() => setEditMode(false), 15);
2025
+ };
2026
+ const selectedOption = COUNTRIES.find((country) => country.code === value);
2027
+ if (!editMode) {
2028
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2029
+ "div",
2030
+ {
2031
+ onClick: () => !disabled && setEditMode(true),
2032
+ className: classes.defaultMode,
2033
+ style,
2034
+ children: [
2035
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.FormLabel, { className: classes.formLabel, children: label }),
2036
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2037
+ import_material16.Box,
2038
+ {
2039
+ sx: {
2040
+ display: "flex",
2041
+ alignItems: "center",
2042
+ gap: 1,
2043
+ mt: 0.25
2044
+ },
2045
+ children: [
2046
+ selectedOption ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2047
+ import_material16.Box,
2048
+ {
2049
+ component: "img",
2050
+ loading: "lazy",
2051
+ width: 20,
2052
+ alt: "",
2053
+ src: `https://flagcdn.com/w20/${selectedOption.code.toLowerCase()}.png`,
2054
+ srcSet: `https://flagcdn.com/w40/${selectedOption.code.toLowerCase()}.png 2x`,
2055
+ sx: { flexShrink: 0 }
2056
+ }
2057
+ ) : null,
2058
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Typography, { className: classes.formValue, component: "span", children: (selectedOption == null ? void 0 : selectedOption.label) || "\u2013" })
2059
+ ]
2060
+ }
2061
+ )
2062
+ ]
2063
+ }
2064
+ );
2065
+ }
2066
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2067
+ import_material16.Autocomplete,
2068
+ {
2069
+ disabled,
2070
+ options: COUNTRIES,
2071
+ getOptionLabel: (option) => option.label,
2072
+ autoHighlight: true,
2073
+ openOnFocus: true,
2074
+ disableClearable: true,
2075
+ value: selectedOption != null ? selectedOption : void 0,
2076
+ onChange: (_, newValue) => {
2077
+ if (newValue != null) onChange(newValue);
2078
+ },
2079
+ onBlur: handleBlur,
2080
+ sx: style,
2081
+ size,
2082
+ componentsProps: {
2083
+ paper: {
2084
+ sx: {
2085
+ background: glassBackground,
2086
+ backdropFilter: "blur(12px) saturate(150%)",
2087
+ border: `1px solid ${(0, import_styles17.alpha)("#FFFFFF", theme.palette.mode === "dark" ? 0.16 : 0.55)}`,
2088
+ boxShadow: theme.palette.mode === "dark" ? "rgba(0, 0, 0, 0.34) 0px 10px 26px" : "rgba(15, 23, 42, 0.16) 0px 8px 24px",
2089
+ "& .MuiAutocomplete-option": {
2090
+ "&[aria-selected='true']": {
2091
+ backgroundColor: (0, import_styles17.alpha)(
2092
+ theme.palette.primary.main,
2093
+ theme.palette.mode === "dark" ? 0.28 : 0.14
2094
+ )
2095
+ },
2096
+ "&.Mui-focused": {
2097
+ backgroundColor: (0, import_styles17.alpha)(
2098
+ theme.palette.primary.main,
2099
+ theme.palette.mode === "dark" ? 0.2 : 0.1
2100
+ )
2101
+ }
2102
+ }
2103
+ }
2104
+ }
2105
+ },
2106
+ renderOption: (props, option) => /* @__PURE__ */ (0, import_react10.createElement)(import_material16.Box, { component: "li", ...props, key: option.code }, /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2107
+ "img",
2108
+ {
2109
+ loading: "lazy",
2110
+ width: "20",
2111
+ src: `https://flagcdn.com/w20/${option.code.toLowerCase()}.png`,
2112
+ srcSet: `https://flagcdn.com/w40/${option.code.toLowerCase()}.png 2x`,
2113
+ alt: "",
2114
+ style: { marginRight: 8, flexShrink: 0 }
2115
+ }
2116
+ ), option.label, " (", option.code, ")"),
2117
+ renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2118
+ import_material16.TextField,
2119
+ {
2120
+ ...params,
2121
+ label,
2122
+ variant: "outlined",
2123
+ size,
2124
+ inputProps: {
2125
+ ...params.inputProps,
2126
+ autoComplete: "new-password"
2127
+ },
2128
+ InputProps: {
2129
+ ...params.InputProps,
2130
+ startAdornment: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
2131
+ selectedOption ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2132
+ import_material16.Box,
2133
+ {
2134
+ component: "img",
2135
+ loading: "lazy",
2136
+ width: 20,
2137
+ alt: "",
2138
+ src: `https://flagcdn.com/w20/${selectedOption.code.toLowerCase()}.png`,
2139
+ srcSet: `https://flagcdn.com/w40/${selectedOption.code.toLowerCase()}.png 2x`,
2140
+ sx: { mr: 1, flexShrink: 0, alignSelf: "center" }
2141
+ }
2142
+ ) : null,
2143
+ params.InputProps.startAdornment
2144
+ ] }),
2145
+ sx: {
2146
+ borderRadius: 2,
2147
+ backdropFilter: "blur(10px)",
2148
+ background: glassBackground,
2149
+ color: "text.primary",
2150
+ "&.Mui-focused": {
2151
+ background: glassBackground
2152
+ },
2153
+ "&:hover": {
2154
+ background: glassBackground
2155
+ },
2156
+ "& .MuiInputBase-input": {
2157
+ color: "text.primary",
2158
+ WebkitTextFillColor: "currentColor"
2159
+ },
2160
+ "& .MuiOutlinedInput-notchedOutline": {
2161
+ borderColor: (0, import_styles17.alpha)(
2162
+ "#FFFFFF",
2163
+ theme.palette.mode === "dark" ? 0.18 : 0.6
2164
+ )
2165
+ }
2166
+ }
2167
+ }
2168
+ }
2169
+ )
2170
+ }
2171
+ );
2172
+ };
2173
+ var CountrySelect_default = CountrySelect;
1880
2174
  // Annotate the CommonJS export names for ESM import in node:
1881
2175
  0 && (module.exports = {
2176
+ CountrySelect,
1882
2177
  EmptyState,
1883
2178
  FormDialog,
1884
2179
  FormDrawer,