@transferwise/components 46.32.0 → 46.34.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 (38) hide show
  1. package/build/index.js +71 -39
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +71 -39
  4. package/build/index.mjs.map +1 -1
  5. package/build/types/alert/Alert.d.ts +3 -2
  6. package/build/types/alert/Alert.d.ts.map +1 -1
  7. package/build/types/common/domHelpers/documentIosClick.d.ts +0 -1
  8. package/build/types/common/domHelpers/documentIosClick.d.ts.map +1 -1
  9. package/build/types/common/domHelpers/index.d.ts +1 -1
  10. package/build/types/common/domHelpers/index.d.ts.map +1 -1
  11. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  12. package/build/types/moneyInput/MoneyInput.d.ts +4 -2
  13. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  14. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts +1 -1
  15. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  16. package/build/types/select/Select.d.ts +7 -7
  17. package/build/types/select/Select.d.ts.map +1 -1
  18. package/build/types/typeahead/Typeahead.d.ts +4 -55
  19. package/build/types/typeahead/Typeahead.d.ts.map +1 -1
  20. package/package.json +3 -3
  21. package/src/alert/Alert.spec.tsx +12 -0
  22. package/src/alert/Alert.story.tsx +11 -1
  23. package/src/alert/Alert.tsx +33 -14
  24. package/src/common/domHelpers/documentIosClick.ts +0 -5
  25. package/src/common/domHelpers/index.ts +0 -1
  26. package/src/dateLookup/DateLookup.rtl.spec.tsx +2 -3
  27. package/src/dateLookup/DateLookup.tsx +1 -3
  28. package/src/inputs/SelectInput.spec.tsx +1 -1
  29. package/src/moneyInput/MoneyInput.rtl.spec.tsx +10 -0
  30. package/src/moneyInput/MoneyInput.spec.js +10 -5
  31. package/src/moneyInput/MoneyInput.tsx +21 -14
  32. package/src/phoneNumberInput/PhoneNumberInput.rtl.spec.tsx +10 -0
  33. package/src/phoneNumberInput/PhoneNumberInput.tsx +11 -2
  34. package/src/select/Select.js +18 -15
  35. package/src/select/Select.rtl.spec.tsx +17 -0
  36. package/src/select/Select.spec.js +2 -7
  37. package/src/typeahead/Typeahead.rtl.spec.tsx +16 -0
  38. package/src/typeahead/Typeahead.tsx +21 -7
package/build/index.mjs CHANGED
@@ -136,10 +136,6 @@ function stopPropagation$1(event) {
136
136
  event.nativeEvent.stopImmediatePropagation();
137
137
  }
138
138
  }
139
- function getSimpleRandomId(prefix) {
140
- const random = Math.ceil(Math.random() * 999999);
141
- return `${prefix}${random}`;
142
- }
143
139
 
144
140
  /**
145
141
  * Defined in `Dimmer.less`
@@ -954,7 +950,7 @@ function Alert({
954
950
  "data-testid": "alert",
955
951
  onTouchStart: () => setShouldFire(true),
956
952
  onTouchEnd: event => {
957
- if (shouldFire && action &&
953
+ if (shouldFire && action?.href &&
958
954
  // Check if current event is triggered from closeButton
959
955
  event.target instanceof Node && closeButtonReference.current && !closeButtonReference.current.contains(event.target)) {
960
956
  if (action.target === '_blank') {
@@ -991,13 +987,8 @@ function Alert({
991
987
  children: message
992
988
  })
993
989
  })]
994
- }), action && /*#__PURE__*/jsx(Link, {
995
- href: action.href,
996
- className: "m-t-1",
997
- "aria-label": action['aria-label'],
998
- target: action.target,
999
- type: Typography.LINK_LARGE,
1000
- children: action.text
990
+ }), action && /*#__PURE__*/jsx(Action, {
991
+ action: action
1001
992
  })]
1002
993
  })]
1003
994
  }), onDismiss && /*#__PURE__*/jsx(CloseButton, {
@@ -1024,6 +1015,28 @@ function alertArrowClassNames(arrow) {
1024
1015
  return 'arrow';
1025
1016
  }
1026
1017
  }
1018
+ function Action({
1019
+ action
1020
+ }) {
1021
+ if ('href' in action) {
1022
+ return /*#__PURE__*/jsx(Link, {
1023
+ href: action.href,
1024
+ className: "m-t-1",
1025
+ "aria-label": action['aria-label'],
1026
+ target: action.target,
1027
+ type: Typography.LINK_LARGE,
1028
+ onClick: action.onClick,
1029
+ children: action.text
1030
+ });
1031
+ }
1032
+ return /*#__PURE__*/jsx("button", {
1033
+ type: "button",
1034
+ "aria-label": action['aria-label'],
1035
+ className: "btn-unstyled np-text-link-large m-t-1",
1036
+ onClick: action.onClick,
1037
+ children: action.text
1038
+ });
1039
+ }
1027
1040
 
1028
1041
  // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
1029
1042
  var AvatarType;
@@ -7430,9 +7443,8 @@ const formatAmountIfSet = ({
7430
7443
  }) => {
7431
7444
  if (maxLengthOverride) {
7432
7445
  return amount != null ? String(amount) : '';
7433
- } else {
7434
- return typeof amount === 'number' ? formatAmount(amount, currency, locale) : '';
7435
7446
  }
7447
+ return typeof amount === 'number' ? formatAmount(amount, currency, locale) : '';
7436
7448
  };
7437
7449
  const parseNumber = ({
7438
7450
  amount,
@@ -7490,7 +7502,7 @@ class MoneyInput extends Component {
7490
7502
  key,
7491
7503
  ctrlKey
7492
7504
  } = event;
7493
- const isNumberKey = isNumber(parseInt(key, 10));
7505
+ const isNumberKey = isNumber(Number.parseInt(key, 10));
7494
7506
  return isNumberKey || metaKey || ctrlKey || allowedInputKeys.has(key);
7495
7507
  };
7496
7508
  handleKeyDown = event => {
@@ -7506,7 +7518,7 @@ class MoneyInput extends Component {
7506
7518
  const parsed = isEmpty(paste) ? null : parseNumber({
7507
7519
  amount: paste,
7508
7520
  currency: this.props.selectedCurrency.currency,
7509
- locale: locale,
7521
+ locale,
7510
7522
  maxLengthOverride: this.props.maxLengthOverride
7511
7523
  });
7512
7524
  if (isNumberOrNull(parsed)) {
@@ -7514,7 +7526,7 @@ class MoneyInput extends Component {
7514
7526
  formattedAmount: formatAmountIfSet({
7515
7527
  amount: parsed,
7516
7528
  currency: this.props.selectedCurrency.currency,
7517
- locale: locale,
7529
+ locale,
7518
7530
  maxLengthOverride: this.props.maxLengthOverride
7519
7531
  })
7520
7532
  });
@@ -7611,15 +7623,17 @@ class MoneyInput extends Component {
7611
7623
  style = className => this.props.classNames[className] || className;
7612
7624
  render() {
7613
7625
  const {
7626
+ inputAttributes,
7627
+ id: amountInputId,
7628
+ 'aria-labelledby': ariaLabelledByProp,
7614
7629
  selectedCurrency,
7615
7630
  onCurrencyChange,
7616
7631
  size,
7617
7632
  addon,
7618
- id,
7619
- 'aria-labelledby': ariaLabelledBy,
7620
7633
  selectProps,
7621
7634
  maxLengthOverride
7622
7635
  } = this.props;
7636
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes?.['aria-labelledby'];
7623
7637
  const selectOptions = this.getSelectOptions();
7624
7638
  const hasSingleCurrency = () => {
7625
7639
  if (selectOptions.length !== 0) {
@@ -7640,10 +7654,12 @@ class MoneyInput extends Component {
7640
7654
  const isFixedCurrency = !this.state.searchQuery && hasSingleCurrency() || !onCurrencyChange;
7641
7655
  const disabled = !this.props.onAmountChange;
7642
7656
  return /*#__PURE__*/jsxs("div", {
7657
+ role: "group",
7658
+ ...inputAttributes,
7643
7659
  "aria-labelledby": ariaLabelledBy,
7644
7660
  className: classNames(this.style('tw-money-input'), this.style('input-group'), this.style(`input-group-${size}`)),
7645
7661
  children: [/*#__PURE__*/jsx(Input, {
7646
- id: id,
7662
+ id: amountInputId,
7647
7663
  value: this.state.formattedAmount,
7648
7664
  inputMode: "decimal",
7649
7665
  disabled: disabled,
@@ -7744,7 +7760,7 @@ function currencyOptionFitsQuery(option, query) {
7744
7760
  return contains(option.label, query) || contains(option.searchable, query) || contains(option.note, query);
7745
7761
  }
7746
7762
  function contains(property, query) {
7747
- return property && property.toLowerCase().includes(query.toLowerCase());
7763
+ return property?.toLowerCase().includes(query.toLowerCase());
7748
7764
  }
7749
7765
  function sortOptionsLabelsToFirst(options, query) {
7750
7766
  return [...options].sort((first, second) => {
@@ -7762,7 +7778,9 @@ function sortOptionsLabelsToFirst(options, query) {
7762
7778
  return 0;
7763
7779
  });
7764
7780
  }
7765
- var MoneyInput$1 = injectIntl(MoneyInput);
7781
+ var MoneyInput$1 = injectIntl(withInputAttributes(MoneyInput, {
7782
+ nonLabelable: true
7783
+ }));
7766
7784
 
7767
7785
  const NavigationOptionList = ({
7768
7786
  children
@@ -9283,7 +9301,7 @@ const defaultSelectProps = {};
9283
9301
  const defaultDisabledCountries = [];
9284
9302
  const PhoneNumberInput = ({
9285
9303
  id,
9286
- 'aria-labelledby': ariaLabelledBy,
9304
+ 'aria-labelledby': ariaLabelledByProp,
9287
9305
  required,
9288
9306
  disabled,
9289
9307
  initialValue,
@@ -9297,6 +9315,10 @@ const PhoneNumberInput = ({
9297
9315
  selectProps = defaultSelectProps,
9298
9316
  disabledCountries = defaultDisabledCountries
9299
9317
  }) => {
9318
+ const inputAttributes = useInputAttributes({
9319
+ nonLabelable: true
9320
+ });
9321
+ const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];
9300
9322
  const {
9301
9323
  locale,
9302
9324
  formatMessage
@@ -9353,6 +9375,8 @@ const PhoneNumberInput = ({
9353
9375
  setBroadcastedValue(internalValue);
9354
9376
  }, [onChange, broadcastedValue, internalValue]);
9355
9377
  return /*#__PURE__*/jsxs("div", {
9378
+ role: "group",
9379
+ ...inputAttributes,
9356
9380
  "aria-labelledby": ariaLabelledBy,
9357
9381
  className: "tw-telephone",
9358
9382
  children: [/*#__PURE__*/jsx("div", {
@@ -10085,6 +10109,7 @@ function Select({
10085
10109
  dropdownProps,
10086
10110
  buttonProps
10087
10111
  }) {
10112
+ const inputAttributes = useInputAttributes();
10088
10113
  const {
10089
10114
  formatMessage
10090
10115
  } = useIntl();
@@ -10104,7 +10129,6 @@ function Select({
10104
10129
  const optionsListReference = useRef(null);
10105
10130
  const isSearchEnabled = !!onSearchChange || !!search;
10106
10131
  const isDropdownAutoWidth = dropdownWidth == null;
10107
- const fallbackButtonId = useMemo(() => getSimpleRandomId('np-select-'), []);
10108
10132
  const options = useMemo(() => {
10109
10133
  if (!search || !searchValue) {
10110
10134
  return defaultOptions;
@@ -10112,14 +10136,14 @@ function Select({
10112
10136
  return defaultOptions.filter(isSearchableOption).filter(option => {
10113
10137
  if (typeof search === 'function') {
10114
10138
  return search(option, searchValue);
10115
- } else {
10116
- return defaultFilterFunction(option, searchValue);
10117
10139
  }
10140
+ return defaultFilterFunction(option, searchValue);
10118
10141
  });
10119
10142
  }, [defaultOptions, search, searchValue]);
10120
10143
  const selectableOptions = useMemo(() => options.filter(isActionableOption), [options]);
10121
10144
  const focusedOption = selectableOptions[keyboardFocusedOptionIndex];
10122
- const computedId = id || fallbackButtonId;
10145
+ const fallbackButtonId = useId();
10146
+ const computedId = id || inputAttributes.id || fallbackButtonId;
10123
10147
  const listboxId = `${computedId}-listbox`;
10124
10148
  const searchBoxId = `${computedId}-searchbox`;
10125
10149
  const {
@@ -10250,7 +10274,7 @@ function Select({
10250
10274
  useEffect(() => {
10251
10275
  if (open) {
10252
10276
  if (!isMobile || searchValue) {
10253
- if (isSearchEnabled && !!searchBoxReference.current) {
10277
+ if (isSearchEnabled && searchBoxReference.current) {
10254
10278
  searchBoxReference.current.focus();
10255
10279
  }
10256
10280
  if (!isSearchEnabled && optionsListReference.current && (previousKeyboardFocusedOptionIndex.current == null || Number.isNaN(previousKeyboardFocusedOptionIndex.current))) {
@@ -10436,6 +10460,7 @@ function Select({
10436
10460
  onBlur: handleOnBlur,
10437
10461
  children: [/*#__PURE__*/jsxs(Button, {
10438
10462
  ref: dropdownButtonReference,
10463
+ ...inputAttributes,
10439
10464
  id: computedId,
10440
10465
  block: block,
10441
10466
  size: size,
@@ -10511,9 +10536,6 @@ Select.propTypes = {
10511
10536
  * if `function` you can define your own search function to implement custom search experience. This search function used while filtering the options array. The custom search function takes two parameters. First is the option the second is the keyword.
10512
10537
  */
10513
10538
  search: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
10514
- onChange: PropTypes.func.isRequired,
10515
- onFocus: PropTypes.func,
10516
- onBlur: PropTypes.func,
10517
10539
  options: PropTypes.arrayOf(PropTypes.shape({
10518
10540
  value: PropTypes.any,
10519
10541
  label: PropTypes.node,
@@ -10526,17 +10548,20 @@ Select.propTypes = {
10526
10548
  disabled: PropTypes.bool,
10527
10549
  searchStrings: PropTypes.arrayOf(PropTypes.string)
10528
10550
  })).isRequired,
10529
- /**
10530
- * To have full control of your search value and response use `onSearchChange` function combined with `searchValue` and custom filtering on the options array.
10531
- * DO NOT USE TOGETHER WITH `search` PROPERTY
10532
- */
10533
- onSearchChange: PropTypes.func,
10534
10551
  searchValue: PropTypes.string,
10535
10552
  searchPlaceholder: PropTypes.string,
10536
10553
  classNames: PropTypes.objectOf(PropTypes.string),
10537
10554
  dropdownUp: PropTypes.bool,
10538
10555
  buttonProps: PropTypes.object,
10539
- dropdownProps: PropTypes.object
10556
+ dropdownProps: PropTypes.object,
10557
+ onChange: PropTypes.func.isRequired,
10558
+ onFocus: PropTypes.func,
10559
+ onBlur: PropTypes.func,
10560
+ /**
10561
+ * To have full control of your search value and response use `onSearchChange` function combined with `searchValue` and custom filtering on the options array.
10562
+ * DO NOT USE TOGETHER WITH `search` PROPERTY
10563
+ */
10564
+ onSearchChange: PropTypes.func
10540
10565
  };
10541
10566
  Select.defaultProps = {
10542
10567
  id: undefined,
@@ -12132,7 +12157,8 @@ class Typeahead extends Component {
12132
12157
  };
12133
12158
  render() {
12134
12159
  const {
12135
- id,
12160
+ inputAttributes,
12161
+ id: idProp,
12136
12162
  placeholder,
12137
12163
  multiple,
12138
12164
  size,
@@ -12150,6 +12176,7 @@ class Typeahead extends Component {
12150
12176
  alert,
12151
12177
  inputAutoComplete
12152
12178
  } = this.props;
12179
+ const id = idProp ?? inputAttributes?.id;
12153
12180
  const {
12154
12181
  errorState,
12155
12182
  query,
@@ -12175,6 +12202,8 @@ class Typeahead extends Component {
12175
12202
  const hasWarning = displayAlert && alertType === Sentiment.WARNING;
12176
12203
  const hasInfo = displayAlert && alertType === Sentiment.NEUTRAL;
12177
12204
  return /*#__PURE__*/jsx("div", {
12205
+ role: "group",
12206
+ ...inputAttributes,
12178
12207
  id: id,
12179
12208
  className: classNames('typeahead', `typeahead-${size}`, {
12180
12209
  'typeahead--has-value': selected.length > 0,
@@ -12230,6 +12259,9 @@ class Typeahead extends Component {
12230
12259
  });
12231
12260
  }
12232
12261
  }
12262
+ var Typeahead$1 = withInputAttributes(Typeahead, {
12263
+ nonLabelable: true
12264
+ });
12233
12265
 
12234
12266
  // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
12235
12267
  var UploadStep;
@@ -14758,5 +14790,5 @@ const translations = {
14758
14790
  'zh-HK': zhHK
14759
14791
  };
14760
14792
 
14761
- export { Accordion, ActionButton, ActionOption, Alert, AlertArrowPosition, Avatar, AvatarType, AvatarWrapper, Badge, Card$2 as BaseCard, Body, BottomSheet$1 as BottomSheet, Breakpoint, Button, Card$1 as Card, Carousel, Checkbox, CheckboxButton$1 as CheckboxButton, CheckboxOption, Chevron, Chip, Chips, CircularButton, ControlType, CriticalCommsBanner, DEFAULT_LANG, DEFAULT_LOCALE, DateInput, DateLookup$1 as DateLookup, DateMode, Decision, DecisionPresentation, DecisionType, DefinitionList$1 as DefinitionList, Dimmer$1 as Dimmer, Direction, DirectionProvider, Display, Drawer$1 as Drawer, DropFade, Emphasis, Field, FileType, FlowNavigation, Header, Image, Info, InfoPresentation, InlineAlert, Input, InputGroup, InputWithDisplayFormat, InstructionsList, Label, LanguageProvider, Layout, Link, ListItem$1 as ListItem, Loader, Logo$1 as Logo, LogoType, Markdown, MarkdownNodeType, Modal, Money, MoneyInput$1 as MoneyInput, MonthFormat, NavigationOption, NavigationOptionList as NavigationOptionsList, Nudge, Option$2 as Option, OverlayHeader$1 as OverlayHeader, PhoneNumberInput, Popover$1 as Popover, Position, Priority, ProcessIndicator$1 as ProcessIndicator, ProfileType, Progress, ProgressBar, PromoCard$1 as PromoCard, PromoCardGroup$1 as PromoCardGroup, Provider, RTL_LANGUAGES, Radio, RadioGroup, RadioOption, SUPPORTED_LANGUAGES, Scroll, SearchInput, Section, SegmentedControl, Select, SelectInput, SelectInputOptionContent, SelectInputTriggerButton, Sentiment, Size, SlidingPanel, SnackbarConsumer, SnackbarContext, SnackbarPortal, SnackbarProvider, Status, StatusIcon, Stepper, Sticky, Summary, Switch, SwitchOption, Tabs$1 as Tabs, TextArea, TextareaWithDisplayFormat, Theme, Title, Tooltip, Type, Typeahead, Typography, Upload$1 as Upload, UploadInput, UploadStep, Variant, Width, adjustLocale, getCountryFromLocale, getDirectionFromLocale, getLangFromLocale, isBrowser, isServerSide, translations, useDirection, useLayout, useScreenSize, useSnackbar };
14793
+ export { Accordion, ActionButton, ActionOption, Alert, AlertArrowPosition, Avatar, AvatarType, AvatarWrapper, Badge, Card$2 as BaseCard, Body, BottomSheet$1 as BottomSheet, Breakpoint, Button, Card$1 as Card, Carousel, Checkbox, CheckboxButton$1 as CheckboxButton, CheckboxOption, Chevron, Chip, Chips, CircularButton, ControlType, CriticalCommsBanner, DEFAULT_LANG, DEFAULT_LOCALE, DateInput, DateLookup$1 as DateLookup, DateMode, Decision, DecisionPresentation, DecisionType, DefinitionList$1 as DefinitionList, Dimmer$1 as Dimmer, Direction, DirectionProvider, Display, Drawer$1 as Drawer, DropFade, Emphasis, Field, FileType, FlowNavigation, Header, Image, Info, InfoPresentation, InlineAlert, Input, InputGroup, InputWithDisplayFormat, InstructionsList, Label, LanguageProvider, Layout, Link, ListItem$1 as ListItem, Loader, Logo$1 as Logo, LogoType, Markdown, MarkdownNodeType, Modal, Money, MoneyInput$1 as MoneyInput, MonthFormat, NavigationOption, NavigationOptionList as NavigationOptionsList, Nudge, Option$2 as Option, OverlayHeader$1 as OverlayHeader, PhoneNumberInput, Popover$1 as Popover, Position, Priority, ProcessIndicator$1 as ProcessIndicator, ProfileType, Progress, ProgressBar, PromoCard$1 as PromoCard, PromoCardGroup$1 as PromoCardGroup, Provider, RTL_LANGUAGES, Radio, RadioGroup, RadioOption, SUPPORTED_LANGUAGES, Scroll, SearchInput, Section, SegmentedControl, Select, SelectInput, SelectInputOptionContent, SelectInputTriggerButton, Sentiment, Size, SlidingPanel, SnackbarConsumer, SnackbarContext, SnackbarPortal, SnackbarProvider, Status, StatusIcon, Stepper, Sticky, Summary, Switch, SwitchOption, Tabs$1 as Tabs, TextArea, TextareaWithDisplayFormat, Theme, Title, Tooltip, Type, Typeahead$1 as Typeahead, Typography, Upload$1 as Upload, UploadInput, UploadStep, Variant, Width, adjustLocale, getCountryFromLocale, getDirectionFromLocale, getLangFromLocale, isBrowser, isServerSide, translations, useDirection, useLayout, useScreenSize, useSnackbar };
14762
14794
  //# sourceMappingURL=index.mjs.map