@transferwise/components 46.6.0 → 46.7.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.
Files changed (133) hide show
  1. package/build/index.esm.js +186 -342
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +185 -341
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +6 -17
  6. package/build/styles/inputs/Input.css +0 -4
  7. package/build/styles/inputs/SelectInput.css +6 -1
  8. package/build/styles/inputs/TextArea.css +0 -4
  9. package/build/styles/main.css +6 -17
  10. package/build/styles/select/Select.css +0 -4
  11. package/build/types/common/locale/index.d.ts +26 -43
  12. package/build/types/common/locale/index.d.ts.map +1 -1
  13. package/build/types/index.d.ts +1 -0
  14. package/build/types/index.d.ts.map +1 -1
  15. package/build/types/inputs/SelectInput.d.ts +6 -5
  16. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  17. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +22 -27
  18. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  19. package/build/types/phoneNumberInput/data/countries.d.ts +5 -10
  20. package/build/types/phoneNumberInput/data/countries.d.ts.map +1 -1
  21. package/build/types/phoneNumberInput/index.d.ts +1 -1
  22. package/build/types/phoneNumberInput/index.d.ts.map +1 -1
  23. package/build/types/phoneNumberInput/utils/cleanNumber/cleanNumber.d.ts +1 -1
  24. package/build/types/phoneNumberInput/utils/cleanNumber/cleanNumber.d.ts.map +1 -1
  25. package/build/types/phoneNumberInput/utils/cleanNumber/index.d.ts +1 -1
  26. package/build/types/phoneNumberInput/utils/cleanNumber/index.d.ts.map +1 -1
  27. package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts +8 -1
  28. package/build/types/phoneNumberInput/utils/excludeCountries/excludeCountries.d.ts.map +1 -1
  29. package/build/types/phoneNumberInput/utils/excludeCountries/index.d.ts +1 -1
  30. package/build/types/phoneNumberInput/utils/excludeCountries/index.d.ts.map +1 -1
  31. package/build/types/phoneNumberInput/utils/explodeNumberModel/index.d.ts +8 -4
  32. package/build/types/phoneNumberInput/utils/explodeNumberModel/index.d.ts.map +1 -1
  33. package/build/types/phoneNumberInput/utils/findCountryByCode/index.d.ts +1 -1
  34. package/build/types/phoneNumberInput/utils/findCountryByCode/index.d.ts.map +1 -1
  35. package/build/types/phoneNumberInput/utils/findCountryByPrefix/index.d.ts +1 -1
  36. package/build/types/phoneNumberInput/utils/findCountryByPrefix/index.d.ts.map +1 -1
  37. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts +2 -1
  38. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.d.ts.map +1 -1
  39. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/index.d.ts +1 -1
  40. package/build/types/phoneNumberInput/utils/groupCountriesByPrefix/index.d.ts.map +1 -1
  41. package/build/types/phoneNumberInput/utils/index.d.ts +11 -13
  42. package/build/types/phoneNumberInput/utils/index.d.ts.map +1 -1
  43. package/build/types/phoneNumberInput/utils/isStringNumeric/index.d.ts +1 -1
  44. package/build/types/phoneNumberInput/utils/isStringNumeric/index.d.ts.map +1 -1
  45. package/build/types/phoneNumberInput/utils/isStringNumeric/isStringNumeric.d.ts +1 -1
  46. package/build/types/phoneNumberInput/utils/isStringNumeric/isStringNumeric.d.ts.map +1 -1
  47. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/index.d.ts +1 -1
  48. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/index.d.ts.map +1 -1
  49. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.d.ts +6 -1
  50. package/build/types/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.d.ts.map +1 -1
  51. package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts +2 -1
  52. package/build/types/phoneNumberInput/utils/longestMatchingPrefix/index.d.ts.map +1 -1
  53. package/build/types/phoneNumberInput/utils/setDefaultPrefix/index.d.ts +7 -1
  54. package/build/types/phoneNumberInput/utils/setDefaultPrefix/index.d.ts.map +1 -1
  55. package/build/types/phoneNumberInput/utils/sortArrayByProperty/index.d.ts +1 -1
  56. package/build/types/phoneNumberInput/utils/sortArrayByProperty/index.d.ts.map +1 -1
  57. package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts +1 -1
  58. package/build/types/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.d.ts.map +1 -1
  59. package/package.json +3 -4
  60. package/src/common/locale/{index.spec.js → index.spec.ts} +4 -4
  61. package/src/common/locale/index.ts +96 -0
  62. package/src/index.ts +1 -0
  63. package/src/inputs/Input.css +0 -4
  64. package/src/inputs/SelectInput.css +6 -1
  65. package/src/inputs/SelectInput.less +8 -1
  66. package/src/inputs/SelectInput.spec.tsx +26 -0
  67. package/src/inputs/SelectInput.story.tsx +73 -1
  68. package/src/inputs/SelectInput.tsx +104 -85
  69. package/src/inputs/TextArea.css +0 -4
  70. package/src/main.css +6 -17
  71. package/src/phoneNumberInput/PhoneNumberInput.spec.js +18 -22
  72. package/src/phoneNumberInput/PhoneNumberInput.tsx +193 -0
  73. package/src/phoneNumberInput/data/{countries.js → countries.ts} +9 -1
  74. package/src/phoneNumberInput/utils/cleanNumber/cleanNumber.ts +3 -0
  75. package/src/phoneNumberInput/utils/excludeCountries/{excludeCountries.spec.js → excludeCountries.spec.ts} +1 -1
  76. package/src/phoneNumberInput/utils/excludeCountries/{excludeCountries.js → excludeCountries.ts} +6 -5
  77. package/src/phoneNumberInput/utils/explodeNumberModel/{explodeNumberModel.spec.js → explodeNumberModel.spec.ts} +1 -1
  78. package/src/phoneNumberInput/utils/explodeNumberModel/index.ts +24 -0
  79. package/src/phoneNumberInput/utils/findCountryByCode/{findCountryByCode.spec.js → findCountryByCode.spec.ts} +0 -1
  80. package/src/phoneNumberInput/utils/findCountryByCode/index.ts +12 -0
  81. package/src/phoneNumberInput/utils/findCountryByPrefix/index.ts +12 -0
  82. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.spec.ts +102 -0
  83. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.ts +12 -0
  84. package/src/phoneNumberInput/utils/{index.js → index.ts} +0 -2
  85. package/src/phoneNumberInput/utils/isStringNumeric/{isStringNumeric.spec.js → isStringNumeric.spec.ts} +0 -1
  86. package/src/phoneNumberInput/utils/isStringNumeric/isStringNumeric.ts +1 -0
  87. package/src/phoneNumberInput/utils/isValidPhoneNumber/{isValidPhoneNumber.spec.js → isValidPhoneNumber.spec.ts} +1 -1
  88. package/src/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.ts +7 -0
  89. package/src/phoneNumberInput/utils/longestMatchingPrefix/index.ts +4 -0
  90. package/src/phoneNumberInput/utils/setDefaultPrefix/index.ts +20 -0
  91. package/src/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.ts +6 -0
  92. package/src/select/Select.css +0 -4
  93. package/build/types/phoneNumberInput/utils/filterOptionsForQuery/index.d.ts +0 -2
  94. package/build/types/phoneNumberInput/utils/filterOptionsForQuery/index.d.ts.map +0 -1
  95. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/index.d.ts +0 -2
  96. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/index.d.ts.map +0 -1
  97. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.d.ts +0 -3
  98. package/build/types/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.d.ts.map +0 -1
  99. package/build/types/utilities/wrapInFragment.d.ts +0 -3
  100. package/build/types/utilities/wrapInFragment.d.ts.map +0 -1
  101. package/src/common/locale/index.js +0 -139
  102. package/src/phoneNumberInput/PhoneNumberInput.js +0 -210
  103. package/src/phoneNumberInput/data/countries.spec.js +0 -12
  104. package/src/phoneNumberInput/utils/cleanNumber/cleanNumber.js +0 -4
  105. package/src/phoneNumberInput/utils/explodeNumberModel/index.js +0 -27
  106. package/src/phoneNumberInput/utils/filterOptionsForQuery/filterOptionsForQuery.spec.js +0 -36
  107. package/src/phoneNumberInput/utils/filterOptionsForQuery/index.js +0 -11
  108. package/src/phoneNumberInput/utils/findCountryByCode/index.js +0 -10
  109. package/src/phoneNumberInput/utils/findCountryByPrefix/index.js +0 -11
  110. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.js +0 -26
  111. package/src/phoneNumberInput/utils/groupCountriesByPrefix/groupCountriesByPrefix.spec.js +0 -67
  112. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/index.js +0 -1
  113. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.js +0 -25
  114. package/src/phoneNumberInput/utils/isOptionAndFitsQuery/isOptionAndFitsQuery.spec.js +0 -66
  115. package/src/phoneNumberInput/utils/isStringNumeric/isStringNumeric.js +0 -1
  116. package/src/phoneNumberInput/utils/isValidPhoneNumber/isValidPhoneNumber.js +0 -10
  117. package/src/phoneNumberInput/utils/longestMatchingPrefix/index.js +0 -2
  118. package/src/phoneNumberInput/utils/setDefaultPrefix/index.js +0 -25
  119. package/src/phoneNumberInput/utils/sortArrayByProperty/sortArrayByProperty.js +0 -3
  120. package/src/utilities/wrapInFragment.tsx +0 -3
  121. /package/src/phoneNumberInput/{PhoneNumberInput.story.js → PhoneNumberInput.story.tsx} +0 -0
  122. /package/src/phoneNumberInput/{index.js → index.ts} +0 -0
  123. /package/src/phoneNumberInput/utils/cleanNumber/{cleanNumber.spec.js → cleanNumber.spec.ts} +0 -0
  124. /package/src/phoneNumberInput/utils/cleanNumber/{index.js → index.ts} +0 -0
  125. /package/src/phoneNumberInput/utils/excludeCountries/{index.js → index.ts} +0 -0
  126. /package/src/phoneNumberInput/utils/findCountryByPrefix/{findCountryByPrefix.spec.js → findCountryByPrefix.spec.ts} +0 -0
  127. /package/src/phoneNumberInput/utils/groupCountriesByPrefix/{index.js → index.ts} +0 -0
  128. /package/src/phoneNumberInput/utils/isStringNumeric/{index.js → index.ts} +0 -0
  129. /package/src/phoneNumberInput/utils/isValidPhoneNumber/{index.js → index.ts} +0 -0
  130. /package/src/phoneNumberInput/utils/longestMatchingPrefix/{longestMatchingPrefix.spec.js → longestMatchingPrefix.spec.ts} +0 -0
  131. /package/src/phoneNumberInput/utils/setDefaultPrefix/{setDefaultPrefix.spec.js → setDefaultPrefix.spec.ts} +0 -0
  132. /package/src/phoneNumberInput/utils/sortArrayByProperty/{index.js → index.ts} +0 -0
  133. /package/src/phoneNumberInput/utils/sortArrayByProperty/{sortArrayByProperty.spec.js → sortArrayByProperty.spec.ts} +0 -0
package/build/index.js CHANGED
@@ -376,131 +376,76 @@ const Key = {
376
376
  COMMA: ','
377
377
  };
378
378
 
379
- /**
380
- * Default language
381
- *
382
- * @type {string}
383
- */
384
379
  const DEFAULT_LANG = 'en';
385
-
386
- /**
387
- * Default locale
388
- *
389
- * @type {string}
390
- */
391
380
  const DEFAULT_LOCALE = 'en-GB';
392
-
393
381
  /**
394
- * Array of languages that are written from the right to the left
395
- *
396
- * @type {string[]}
382
+ * Languages written right-to-left.
397
383
  */
398
384
  const RTL_LANGUAGES = ['ar', 'he'];
399
-
400
385
  /**
401
386
  * @deprecated The source of truth for supported languages lives in Crab.
402
- * @type {string[]}
403
387
  */
404
388
  const SUPPORTED_LANGUAGES = [DEFAULT_LANG, 'de', 'es', 'fr', 'hu', 'id', 'it', 'ja', 'pl', 'pt', 'ro', 'ru', 'th', 'tr', 'uk', 'zh'];
405
-
406
389
  /**
407
- * Verifies and adjusts locale (replace `_` with `-`)
408
- * Returns null if locale is unrecognized by {Intl.Locale}
390
+ * Verifies and adjusts locale, replacing `_` with `-`.
409
391
  *
410
- * @param {string} locale (`es`, `es_ES`, `en-GB`, `en`, `ja`, `ja-JP` etc)
411
- * @returns {string|null}
392
+ * @param locale `es`, `es_ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
393
+ * @returns `null` if locale is unrecognized by `Intl.Locale`.
412
394
  */
413
395
  function adjustLocale(locale) {
414
- if (!locale || locale.trim().length === 0) {
415
- return null;
416
- }
417
- try {
418
- const {
419
- baseName
420
- } = new Intl.Locale(locale.trim().replace('_', '-'));
421
- return baseName;
422
- } catch (error) {
423
- // eslint-disable-next-line no-console
424
- console.error(error);
425
- return null;
396
+ const localeTrimmed = locale?.trim();
397
+ if (localeTrimmed) {
398
+ try {
399
+ return new Intl.Locale(localeTrimmed.replace('_', '-')).baseName;
400
+ } catch (error) {
401
+ // eslint-disable-next-line no-console
402
+ console.error(error);
403
+ }
426
404
  }
405
+ return null;
427
406
  }
428
-
429
407
  /**
430
- * Provides corresponding lang (iso2) for provided locale
431
- * if locale is invalid or language is unsupported returns null
408
+ * Provides corresponding lang (iso2) for provided locale.
432
409
  *
433
410
  * @deprecated The use of this function almost always breaks language variants
434
411
  * e.g. Simplified and Traditional Chinese.
435
412
  * There should be no use case for this function.
436
413
  * To select the correct translations from a translations object, pass the
437
414
  * locale directly into Crab's getLocalisedMessages.
438
- * @param {string} locale (`es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP` etc)
439
- * @returns {string|null} two-letter ISO639-1 language
415
+ * @param locale `es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
416
+ * @returns Two-letter ISO 639-1 language code, falling back to `null` if locale is invalid or language is unsupported.
440
417
  */
441
418
  function getLangFromLocale(locale) {
442
419
  const adjustedLocale = adjustLocale(locale);
443
- if (adjustedLocale === null) {
444
- return null;
445
- }
446
- try {
420
+ if (adjustedLocale != null) {
447
421
  const {
448
422
  language
449
423
  } = new Intl.Locale(adjustedLocale);
450
424
  if (SUPPORTED_LANGUAGES.includes(language)) {
451
425
  return language;
452
426
  }
453
- return null;
454
- } catch (error) {
455
- // eslint-disable-next-line no-console
456
- console.error(error);
457
- return null;
458
427
  }
428
+ return null;
459
429
  }
460
-
461
430
  /**
462
- * Provides corresponding country code (iso2) for locales code with explicit region value (`es-ES`, `en-GB`, `ja-JP` etc.)
463
- * if the value is invalid or missing region it returns null
431
+ * Provides corresponding country code (iso2) for locales code with explicit region value.
464
432
  *
465
- * @param {string} locale
466
- * @returns {string|null}
433
+ * @param locale `es-ES`, `en-GB`, `ja-JP`, etc.
434
+ * @returns `null` if the locale is invalid or the region can‘t be identified.
467
435
  */
468
436
  function getCountryFromLocale(locale) {
469
437
  const adjustedLocale = adjustLocale(locale);
470
- if (adjustedLocale === null) {
471
- return null;
472
- }
473
- try {
474
- const {
475
- region
476
- } = new Intl.Locale(adjustedLocale);
477
- return region ?? null;
478
- } catch (error) {
479
- // eslint-disable-next-line no-console
480
- console.error(error);
481
- return null;
482
- }
438
+ return adjustedLocale != null ? new Intl.Locale(adjustedLocale).region ?? null : null;
483
439
  }
484
-
485
440
  /**
486
441
  * Provides the layout direction for a given locale.
487
- * If locale is invalid or language is unsupported returns Direction.LTR
488
442
  *
489
- * @param {string} locale (`es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP` etc)
490
- * @returns {Direction} The layout direction based on the locale
443
+ * @param locale `es`, `es-ES`, `en-GB`, `en`, `ja`, `ja-JP`, etc.
444
+ * @returns The layout direction based on the locale, falling back to `Direction.LTR` if the locale is invalid or unsupported.
491
445
  */
492
446
  function getDirectionFromLocale(locale) {
493
- try {
494
- const adjustedLocale = adjustLocale(locale);
495
- const {
496
- language
497
- } = new Intl.Locale(adjustedLocale);
498
- return RTL_LANGUAGES.includes(language) ? exports.Direction.RTL : exports.Direction.LTR;
499
- } catch (error) {
500
- // eslint-disable-next-line no-console
501
- console.error(error);
502
- return exports.Direction.LTR;
503
- }
447
+ const adjustedLocale = adjustLocale(locale);
448
+ return adjustedLocale != null && RTL_LANGUAGES.includes(new Intl.Locale(adjustedLocale).language) ? exports.Direction.RTL : exports.Direction.LTR;
504
449
  }
505
450
 
506
451
  /**
@@ -6488,12 +6433,6 @@ const PolymorphicWithOverrides = /*#__PURE__*/React.forwardRef(function Polymorp
6488
6433
  });
6489
6434
  });
6490
6435
 
6491
- function wrapInFragment(value) {
6492
- return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
6493
- children: value
6494
- });
6495
- }
6496
-
6497
6436
  var messages$4 = reactIntl.defineMessages({
6498
6437
  noResultsFound: {
6499
6438
  id: "neptune.SelectInput.noResultsFound"
@@ -6834,10 +6773,10 @@ const defaultRenderTrigger = ({
6834
6773
  children: /*#__PURE__*/jsxRuntime.jsx(SelectInputTriggerButton, {
6835
6774
  as: ButtonInput,
6836
6775
  size: size,
6837
- children: placeholderShown ? /*#__PURE__*/jsxRuntime.jsxs("span", {
6838
- className: "np-select-input-placeholder",
6839
- children: [" ", content]
6840
- }) : content
6776
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
6777
+ className: classNames__default.default('np-select-input-content', placeholderShown && 'np-select-input-placeholder'),
6778
+ children: content
6779
+ })
6841
6780
  })
6842
6781
  });
6843
6782
  function SelectInputClearButton({
@@ -6858,12 +6797,13 @@ function SelectInputClearButton({
6858
6797
  const noop = () => {};
6859
6798
  function SelectInput({
6860
6799
  name,
6800
+ multiple,
6861
6801
  placeholder,
6862
6802
  items,
6863
6803
  defaultValue,
6864
6804
  value: controlledValue,
6865
6805
  compareValues,
6866
- renderValue = wrapInFragment,
6806
+ renderValue = String,
6867
6807
  renderFooter,
6868
6808
  renderTrigger = defaultRenderTrigger,
6869
6809
  filterable,
@@ -6892,6 +6832,7 @@ function SelectInput({
6892
6832
  const controllerRef = filterable ? searchInputRef : listboxRef;
6893
6833
  return /*#__PURE__*/jsxRuntime.jsx(react$1.Listbox, {
6894
6834
  name: name,
6835
+ multiple: multiple,
6895
6836
  defaultValue: defaultValue,
6896
6837
  value: controlledValue
6897
6838
  // TODO: Remove assertion when upgrading TypeScript to v5
@@ -6900,73 +6841,78 @@ function SelectInput({
6900
6841
  by: compareValues,
6901
6842
  disabled: disabled,
6902
6843
  onChange: value => {
6903
- setOpen(false);
6844
+ if (!multiple) {
6845
+ setOpen(false);
6846
+ }
6904
6847
  onChange?.(value);
6905
6848
  },
6906
6849
  children: ({
6907
6850
  disabled: uiDisabled,
6908
6851
  value
6909
- }) => /*#__PURE__*/jsxRuntime.jsx(OptionsOverlay, {
6910
- placement: "bottom-start",
6911
- open: open,
6912
- renderTrigger: ({
6913
- ref,
6914
- getInteractionProps
6915
- }) => /*#__PURE__*/jsxRuntime.jsx(SelectInputTriggerButtonPropsContext.Provider, {
6916
- // eslint-disable-next-line react/jsx-no-constructed-context-values
6917
- value: {
6918
- ref: mergeRefs__default.default([ref, triggerRef]),
6919
- ...mergeProps__default.default({
6920
- onClick: () => {
6921
- setOpen(prev => !prev);
6922
- },
6923
- onKeyDown: event => {
6924
- if (event.key === ' ' || event.key === 'Enter' || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
6852
+ }) => {
6853
+ const placeholderShown = multiple && Array.isArray(value) ? value.length === 0 : value == null;
6854
+ return /*#__PURE__*/jsxRuntime.jsx(OptionsOverlay, {
6855
+ placement: "bottom-start",
6856
+ open: open,
6857
+ renderTrigger: ({
6858
+ ref,
6859
+ getInteractionProps
6860
+ }) => /*#__PURE__*/jsxRuntime.jsx(SelectInputTriggerButtonPropsContext.Provider, {
6861
+ // eslint-disable-next-line react/jsx-no-constructed-context-values
6862
+ value: {
6863
+ ref: mergeRefs__default.default([ref, triggerRef]),
6864
+ ...mergeProps__default.default({
6865
+ onClick: () => {
6925
6866
  setOpen(prev => !prev);
6867
+ },
6868
+ onKeyDown: event => {
6869
+ if (event.key === ' ' || event.key === 'Enter' || event.key === 'ArrowDown' || event.key === 'ArrowUp') {
6870
+ setOpen(prev => !prev);
6871
+ }
6926
6872
  }
6927
- }
6928
- }, getInteractionProps())
6873
+ }, getInteractionProps())
6874
+ },
6875
+ children: renderTrigger({
6876
+ content: !placeholderShown ? /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContentWithinTriggerContext.Provider, {
6877
+ value: true,
6878
+ children: multiple && Array.isArray(value) ? value.map(option => renderValue(option, true)).join(', ') : renderValue(value, true)
6879
+ }) : placeholder,
6880
+ placeholderShown,
6881
+ clear: onClear != null ? () => {
6882
+ onClear();
6883
+ triggerRef.current?.focus({
6884
+ preventScroll: true
6885
+ });
6886
+ } : undefined,
6887
+ disabled: uiDisabled,
6888
+ size,
6889
+ className
6890
+ })
6891
+ }),
6892
+ initialFocusRef: controllerRef,
6893
+ size: filterable ? 'lg' : 'md',
6894
+ padding: "none",
6895
+ onClose: () => {
6896
+ setOpen(false);
6929
6897
  },
6930
- children: renderTrigger({
6931
- content: value != null ? /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContentWithinTriggerContext.Provider, {
6932
- value: true,
6933
- children: renderValue(value, true)
6934
- }) : placeholder,
6935
- placeholderShown: value == null,
6936
- clear: onClear != null ? () => {
6937
- onClear();
6938
- triggerRef.current?.focus({
6939
- preventScroll: true
6940
- });
6941
- } : undefined,
6942
- disabled: uiDisabled,
6943
- size,
6944
- className
6898
+ onCloseEnd: () => {
6899
+ if (filterQuery !== '') {
6900
+ setFilterQuery('');
6901
+ }
6902
+ },
6903
+ children: /*#__PURE__*/jsxRuntime.jsx(SelectInputOptions, {
6904
+ items: items,
6905
+ renderValue: renderValue,
6906
+ renderFooter: renderFooter,
6907
+ filterable: filterable,
6908
+ filterPlaceholder: filterPlaceholder,
6909
+ searchInputRef: searchInputRef,
6910
+ listboxRef: listboxRef,
6911
+ filterQuery: filterQuery,
6912
+ onFilterChange: setFilterQuery
6945
6913
  })
6946
- }),
6947
- initialFocusRef: controllerRef,
6948
- size: filterable ? 'lg' : 'md',
6949
- padding: "none",
6950
- onClose: () => {
6951
- setOpen(false);
6952
- },
6953
- onCloseEnd: () => {
6954
- if (filterQuery !== '') {
6955
- setFilterQuery('');
6956
- }
6957
- },
6958
- children: /*#__PURE__*/jsxRuntime.jsx(SelectInputOptions, {
6959
- items: items,
6960
- renderValue: renderValue,
6961
- renderFooter: renderFooter,
6962
- filterable: filterable,
6963
- filterPlaceholder: filterPlaceholder,
6964
- searchInputRef: searchInputRef,
6965
- listboxRef: listboxRef,
6966
- filterQuery: filterQuery,
6967
- onFilterChange: setFilterQuery
6968
- })
6969
- })
6914
+ });
6915
+ }
6970
6916
  });
6971
6917
  }
6972
6918
  function SelectInputTriggerButton({
@@ -7029,7 +6975,7 @@ const SelectInputOptionsContainer = /*#__PURE__*/React.forwardRef(function Selec
7029
6975
  });
7030
6976
  function SelectInputOptions({
7031
6977
  items,
7032
- renderValue = wrapInFragment,
6978
+ renderValue = String,
7033
6979
  renderFooter,
7034
6980
  filterable = false,
7035
6981
  filterPlaceholder,
@@ -9601,111 +9547,79 @@ const countries = [{
9601
9547
  iso3: 'ZWE',
9602
9548
  phone: '+263'
9603
9549
  }];
9604
- var countries$1 = countries;
9605
9550
 
9606
9551
  const longestMatchingPrefix = matchingCodes => matchingCodes.reduce((a, b) => a.phone.length > b.phone.length ? a : b);
9607
9552
 
9608
9553
  const findCountryByCode = code => {
9609
- let matchingCodes;
9610
- if (code && code.length === 2) {
9611
- matchingCodes = countries$1.filter(country => code.toUpperCase() === country.iso2);
9554
+ if (code.length === 2) {
9555
+ const matchingCodes = countries.filter(country => code.toUpperCase() === country.iso2);
9556
+ if (matchingCodes.length > 0) {
9557
+ return longestMatchingPrefix(matchingCodes);
9558
+ }
9612
9559
  }
9613
- return matchingCodes && matchingCodes.length > 0 ? longestMatchingPrefix(matchingCodes) : null;
9560
+ return null;
9614
9561
  };
9615
9562
 
9616
9563
  /**
9617
9564
  * Default phone code, the UK one `+44`
9618
9565
  */
9619
9566
  const DEFAULT_PHONE_CODE = '+44';
9620
-
9621
9567
  /**
9622
9568
  * Given a valid locale it returns the correspondent prefix if found or +44 otherwise.
9623
9569
  *
9624
- * @param {string} locale - a string that represent the locale ex:'es-ES'
9625
- * @param countryCode
9626
- * @returns {string}
9570
+ * @param locale BCP 47 language tag of locale, e.g. `"es-ES"`.
9571
+ * @param countryCode Two-letter country code (ISO 3166-1 alpha-2).
9627
9572
  */
9628
9573
  const setDefaultPrefix = (locale, countryCode) => {
9629
- const country = findCountryByCode(countryCode) ||
9630
- // when `locale` code has explicit region: `en-GB`, `en-US`, `ar-AE`
9631
- findCountryByCode(getCountryFromLocale(locale)) ||
9632
- // when `locale` code is only two chars value: `fr`, `es`
9633
- findCountryByCode(locale);
9634
- return country?.phone || DEFAULT_PHONE_CODE;
9574
+ const country = (countryCode != null ? findCountryByCode(countryCode) : null) ?? findCountryByCode(getCountryFromLocale(locale) ?? locale);
9575
+ return country?.phone ?? DEFAULT_PHONE_CODE;
9635
9576
  };
9636
9577
 
9637
9578
  /**
9638
9579
  *
9639
9580
  * @param phoneNumber
9640
- * @returns {boolean} - returns true for number that starts with '+' and contains a mix of digits and spaces with
9641
- * at least 4 digits.
9581
+ * @returns True if number that starts with "+" and contains a mix of digits and spaces with at least 4 digits.
9642
9582
  */
9643
- const isValidPhoneNumber = phoneNumber => /^\+[\d-\s]+$/.test(phoneNumber) && phoneNumber.match(/\d+/g) && phoneNumber.match(/\d+/g).join('').length >= 4;
9583
+ const isValidPhoneNumber = phoneNumber => /^\+[\d-\s]+$/.test(phoneNumber) && (phoneNumber.match(/\d+/g)?.join('').length ?? 0) >= 4;
9644
9584
 
9645
9585
  const findCountryByPrefix = number => {
9646
- let matchingCodes = null;
9647
- if (number && number.length > 1) {
9648
- matchingCodes = countries$1.filter(country => number.indexOf(country.phone) === 0);
9586
+ if (number.length > 1) {
9587
+ const matchingCodes = countries.filter(country => number.startsWith(country.phone));
9588
+ if (matchingCodes.length > 0) {
9589
+ return longestMatchingPrefix(matchingCodes);
9590
+ }
9649
9591
  }
9650
- return matchingCodes && matchingCodes.length > 0 ? longestMatchingPrefix(matchingCodes) : null;
9592
+ return null;
9651
9593
  };
9652
9594
 
9653
9595
  /**
9654
- * Given a sting in a valid format ex:'+447573135343' it returns an object of shape
9655
- * {prefix=+44 ,suffix=7573135343}
9656
- *
9657
- * @param {string} number - a string that defines a phone number.
9658
- * @returns {{prefix: (string|*), suffix: string, format: string}}
9596
+ * @param number Phone number in a format like "+447573135343"
9659
9597
  */
9660
9598
  const explodeNumberModel = number => {
9661
- let prefix = '';
9662
- let suffix = '';
9663
- let format = '';
9664
9599
  const country = findCountryByPrefix(number);
9665
- if (country) {
9666
- prefix = country.phone;
9667
- suffix = number.slice(country.phone.length);
9668
- format = country.phoneFormat || '';
9669
- } else {
9670
- prefix = '';
9671
- suffix = number.slice(1);
9672
- format = '';
9673
- }
9674
- return {
9675
- prefix,
9676
- suffix,
9677
- format
9600
+ return country ? {
9601
+ prefix: country.phone,
9602
+ suffix: number.slice(country.phone.length),
9603
+ format: country.phoneFormat
9604
+ } : {
9605
+ prefix: null,
9606
+ suffix: number.slice(1)
9678
9607
  };
9679
9608
  };
9680
9609
 
9681
9610
  const DIGITS_MATCH = /^$|^(\+)|([\d]+)/g;
9682
- const cleanNumber = number => number.match(DIGITS_MATCH) && number.match(DIGITS_MATCH).join('') || '';
9611
+ const cleanNumber = number => number.match(DIGITS_MATCH)?.join('') ?? '';
9683
9612
 
9684
- // Reference fro localeCompare : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
9685
- const sortArrayByProperty = (arrayToSort, property) => [...arrayToSort].sort((a, b) => a[property].localeCompare(b[property]));
9613
+ function sortArrayByProperty(arrayToSort, property) {
9614
+ return [...arrayToSort].sort((a, b) => a[property].localeCompare(b[property]));
9615
+ }
9686
9616
 
9687
9617
  const groupCountriesByPrefix = countries => {
9688
- const groupedArray = countries.reduce((accumulator, country) => {
9689
- const {
9690
- name,
9691
- iso2,
9692
- iso3,
9693
- phone
9694
- } = country;
9695
- if (accumulator[phone]) {
9696
- const previousValue = accumulator[phone];
9697
- accumulator[phone] = {
9698
- ...previousValue,
9699
- name: neptuneValidation.isArray(previousValue.name) ? [...previousValue.name, name] : [previousValue.name, name],
9700
- iso2: neptuneValidation.isArray(previousValue.iso2) ? [...previousValue.iso2, iso2] : [previousValue.iso2, iso2],
9701
- iso3: neptuneValidation.isArray(previousValue.iso3) ? [...previousValue.iso3, iso3] : [previousValue.iso3, iso3]
9702
- };
9703
- } else {
9704
- accumulator[phone] = country;
9705
- }
9706
- return accumulator;
9707
- }, {});
9708
- return Object.values(groupedArray);
9618
+ const countriesByPrefix = new Map();
9619
+ countries.forEach(country => {
9620
+ countriesByPrefix.set(country.phone, [...(countriesByPrefix.get(country.phone) ?? []), country]);
9621
+ });
9622
+ return countriesByPrefix;
9709
9623
  };
9710
9624
 
9711
9625
  // Reference fro localeCompare : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
@@ -9713,41 +9627,38 @@ const filterCountriesByIso3 = (countries, iso3Codes) => {
9713
9627
  const iso3CodesSet = new Set(iso3Codes);
9714
9628
  return countries.filter(country => !iso3CodesSet.has(country.iso3));
9715
9629
  };
9716
-
9717
9630
  /**
9718
9631
  * Removes the countries sepecified in the second param
9719
9632
  *
9720
- * @param {Array} countries: list of country metadata objects
9721
- * @param {Array} disabledCountries: list of iso3 country codes to remove from the list
9722
- * @returns
9633
+ * @param countries list of country metadata objects
9634
+ * @param disabledCountries list of iso3 country codes to remove from the list
9723
9635
  */
9724
9636
  const excludeCountries = (countries, disabledCountries) => {
9725
9637
  return disabledCountries.length > 0 ? filterCountriesByIso3(countries, disabledCountries) : countries;
9726
9638
  };
9727
9639
 
9728
9640
  const ALLOWED_PHONE_CHARS = /^$|^[\d-\s]+$/;
9729
- const PhoneNumberInput = props => {
9730
- const {
9731
- id,
9732
- onChange,
9733
- searchPlaceholder,
9734
- disabled,
9735
- required,
9736
- size,
9737
- placeholder,
9738
- onFocus,
9739
- onBlur,
9740
- countryCode,
9741
- selectProps,
9742
- disabledCountries
9743
- } = props;
9641
+ const defaultSelectProps = {};
9642
+ const defaultDisabledCountries = [];
9643
+ const PhoneNumberInput = ({
9644
+ id,
9645
+ required,
9646
+ disabled,
9647
+ initialValue,
9648
+ onChange,
9649
+ onFocus,
9650
+ onBlur,
9651
+ countryCode,
9652
+ searchPlaceholder = 'Prefix',
9653
+ size = exports.Size.MEDIUM,
9654
+ placeholder,
9655
+ selectProps = defaultSelectProps,
9656
+ disabledCountries = defaultDisabledCountries
9657
+ }) => {
9744
9658
  const {
9745
9659
  locale
9746
9660
  } = reactIntl.useIntl();
9747
- const getInitialValue = () => {
9748
- const {
9749
- initialValue
9750
- } = props;
9661
+ const [internalValue, setInternalValue] = React.useState(() => {
9751
9662
  const cleanValue = initialValue ? cleanNumber(initialValue) : null;
9752
9663
  if (!cleanValue || !isValidPhoneNumber(cleanValue)) {
9753
9664
  return {
@@ -9756,54 +9667,16 @@ const PhoneNumberInput = props => {
9756
9667
  };
9757
9668
  }
9758
9669
  return explodeNumberModel(cleanValue);
9759
- };
9760
- const [internalValue, setInternalValue] = React.useState(getInitialValue());
9670
+ });
9761
9671
  const [broadcastedValue, setBroadcastedValue] = React.useState(null);
9762
- const getSelectOptions = () => {
9763
- const countriesList = excludeCountries(countries$1, disabledCountries);
9764
- const listSortedByISO3 = groupCountriesByPrefix(sortArrayByProperty(countriesList, 'iso3'));
9765
- return listSortedByISO3.map(option => {
9766
- const {
9767
- phone,
9768
- iso3,
9769
- iso2,
9770
- name
9771
- } = option;
9772
- let note = '';
9773
- if (iso3) {
9774
- note = neptuneValidation.isArray(iso3) ? iso3.join(', ') : iso3;
9775
- } else if (iso2) {
9776
- note = neptuneValidation.isArray(iso2) ? iso2.join(', ') : iso2;
9777
- }
9778
- return {
9779
- type: 'option',
9780
- value: {
9781
- value: phone,
9782
- label: phone,
9783
- note: note
9784
- },
9785
- filterMatchers: [phone, note, name]
9786
- };
9787
- });
9788
- };
9789
- const options = getSelectOptions();
9790
- const onPrefixChange = ({
9791
- value
9792
- }) => {
9793
- setInternalValue({
9794
- prefix: value,
9795
- suffix: internalValue.suffix
9796
- });
9797
- };
9672
+ const countriesByPrefix = React.useMemo(() => groupCountriesByPrefix(sortArrayByProperty(excludeCountries(countries, disabledCountries), 'iso3')), [disabledCountries]);
9798
9673
  const onSuffixChange = event => {
9799
- const {
9800
- value = ''
9801
- } = event.target;
9802
- if (ALLOWED_PHONE_CHARS.test(value)) {
9803
- setInternalValue({
9804
- prefix: internalValue.prefix,
9805
- suffix: value
9806
- });
9674
+ const suffix = event.target.value;
9675
+ if (ALLOWED_PHONE_CHARS.test(suffix)) {
9676
+ setInternalValue(prev => ({
9677
+ ...prev,
9678
+ suffix
9679
+ }));
9807
9680
  }
9808
9681
  };
9809
9682
  const onPaste = event => {
@@ -9811,31 +9684,22 @@ const PhoneNumberInput = props => {
9811
9684
  return;
9812
9685
  }
9813
9686
  const pastedValue = (event.nativeEvent.clipboardData.getData('text/plain') || '').replace(/(\s|-)+/g, '');
9814
- const {
9815
- prefix: pastedPrefix,
9816
- suffix: pastedSuffix
9817
- } = explodeNumberModel(pastedValue);
9818
- const selectedPrefix = options.find(({
9819
- value
9820
- }) => value.value === pastedPrefix);
9821
- if (selectedPrefix && ALLOWED_PHONE_CHARS.test(pastedSuffix)) {
9822
- setInternalValue({
9823
- prefix: pastedPrefix,
9824
- suffix: pastedSuffix
9825
- });
9687
+ const pastedNumber = explodeNumberModel(pastedValue);
9688
+ if (pastedNumber.prefix != null && countriesByPrefix.has(pastedNumber.prefix) && ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)) {
9689
+ setInternalValue(pastedNumber);
9826
9690
  }
9827
9691
  };
9828
9692
  React.useEffect(() => {
9829
9693
  if (broadcastedValue === null) {
9830
9694
  return setBroadcastedValue(internalValue);
9831
9695
  }
9832
- const internalPhoneNumber = internalValue.prefix + internalValue.suffix;
9833
- const broadcastedPhoneNumber = broadcastedValue.prefix + broadcastedValue.suffix;
9696
+ const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;
9697
+ const broadcastedPhoneNumber = `${broadcastedValue.prefix ?? ''}${broadcastedValue.suffix}`;
9834
9698
  if (internalPhoneNumber === broadcastedPhoneNumber) {
9835
9699
  return;
9836
9700
  }
9837
9701
  const newValue = isValidPhoneNumber(internalPhoneNumber) ? cleanNumber(internalPhoneNumber) : null;
9838
- onChange(newValue, internalValue.prefix);
9702
+ onChange(newValue, internalValue.prefix ?? '');
9839
9703
  setBroadcastedValue(internalValue);
9840
9704
  }, [onChange, broadcastedValue, internalValue]);
9841
9705
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -9843,18 +9707,29 @@ const PhoneNumberInput = props => {
9843
9707
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
9844
9708
  className: "tw-telephone__country-select",
9845
9709
  children: /*#__PURE__*/jsxRuntime.jsx(SelectInput, {
9846
- placeholder: "Select an option...",
9847
- items: options,
9848
- value: options.find(item => item.value.value === internalValue.prefix)?.value,
9849
- renderValue: (option, withinTrigger) => /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContent, {
9850
- title: option.label,
9851
- note: withinTrigger ? undefined : option.note
9710
+ placeholder: "Select an option\u2026",
9711
+ items: [...countriesByPrefix].map(([prefix, countries]) => ({
9712
+ type: 'option',
9713
+ value: prefix,
9714
+ filterMatchers: [prefix, ...countries.map(country => country.name), ...countries.map(country => country.iso3)]
9715
+ })),
9716
+ value: internalValue.prefix,
9717
+ renderValue: (prefix, withinTrigger) => /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContent, {
9718
+ title: prefix,
9719
+ note: withinTrigger ? undefined : countriesByPrefix.get(prefix)?.map(country => country.iso3).join(', ')
9852
9720
  }),
9853
9721
  filterable: true,
9854
9722
  filterPlaceholder: searchPlaceholder,
9855
9723
  disabled: disabled,
9856
9724
  size: size,
9857
- onChange: onPrefixChange,
9725
+ onChange: prefix => {
9726
+ const country = prefix != null ? findCountryByPrefix(prefix) : null;
9727
+ setInternalValue(prev => ({
9728
+ ...prev,
9729
+ prefix,
9730
+ format: country?.phoneFormat
9731
+ }));
9732
+ },
9858
9733
  ...selectProps
9859
9734
  })
9860
9735
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
@@ -9880,37 +9755,6 @@ const PhoneNumberInput = props => {
9880
9755
  })]
9881
9756
  });
9882
9757
  };
9883
- PhoneNumberInput.propTypes = {
9884
- id: PropTypes__default.default.string,
9885
- required: PropTypes__default.default.bool,
9886
- disabled: PropTypes__default.default.bool,
9887
- initialValue: PropTypes__default.default.string,
9888
- onChange: PropTypes__default.default.func.isRequired,
9889
- onFocus: PropTypes__default.default.func,
9890
- onBlur: PropTypes__default.default.func,
9891
- countryCode: PropTypes__default.default.string,
9892
- searchPlaceholder: PropTypes__default.default.string,
9893
- size: PropTypes__default.default.oneOf(['sm', 'md', 'lg']),
9894
- placeholder: PropTypes__default.default.string,
9895
- selectProps: PropTypes__default.default.object,
9896
- /** List of iso3 codes of countries to remove from the list */
9897
- disabledCountries: PropTypes__default.default.arrayOf(PropTypes__default.default.string)
9898
- };
9899
- PhoneNumberInput.defaultProps = {
9900
- id: null,
9901
- required: false,
9902
- disabled: false,
9903
- initialValue: null,
9904
- onFocus() {},
9905
- onBlur() {},
9906
- countryCode: null,
9907
- searchPlaceholder: 'Prefix',
9908
- size: exports.Size.MEDIUM,
9909
- placeholder: '',
9910
- selectProps: {},
9911
- disabledCountries: []
9912
- };
9913
- var PhoneNumberInput$1 = PhoneNumberInput;
9914
9758
 
9915
9759
  const Progress = ({
9916
9760
  className,
@@ -15687,7 +15531,7 @@ exports.NavigationOptionsList = NavigationOptionList$1;
15687
15531
  exports.Nudge = Nudge;
15688
15532
  exports.Option = Option$2;
15689
15533
  exports.OverlayHeader = OverlayHeader$1;
15690
- exports.PhoneNumberInput = PhoneNumberInput$1;
15534
+ exports.PhoneNumberInput = PhoneNumberInput;
15691
15535
  exports.Popover = Popover$2;
15692
15536
  exports.ProcessIndicator = ProcessIndicator$1;
15693
15537
  exports.Progress = Progress;