@transferwise/components 45.17.0 → 45.18.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 (80) hide show
  1. package/build/i18n/en.json +1 -0
  2. package/build/index.esm.js +391 -350
  3. package/build/index.esm.js.map +1 -1
  4. package/build/index.js +391 -349
  5. package/build/index.js.map +1 -1
  6. package/build/main.css +1 -1
  7. package/build/styles/common/Option/Option.css +1 -1
  8. package/build/styles/inputs/SelectInput.css +1 -1
  9. package/build/styles/instructionsList/InstructionsList.css +1 -1
  10. package/build/styles/main.css +1 -1
  11. package/build/styles/stepper/Stepper.css +1 -1
  12. package/build/styles/tooltip/Tooltip.css +1 -1
  13. package/build/types/accordion/AccordionItem/AccordionItem.d.ts.map +1 -1
  14. package/build/types/button/Button.d.ts.map +1 -1
  15. package/build/types/button/Button.messages.d.ts +9 -0
  16. package/build/types/button/Button.messages.d.ts.map +1 -0
  17. package/build/types/common/index.d.ts +1 -0
  18. package/build/types/common/polymorphicWithOverrides/PolymorphicWithOverrides.d.ts +13 -0
  19. package/build/types/common/polymorphicWithOverrides/PolymorphicWithOverrides.d.ts.map +1 -0
  20. package/build/types/common/randomId.d.ts +13 -0
  21. package/build/types/common/randomId.d.ts.map +1 -0
  22. package/build/types/index.d.ts +1 -1
  23. package/build/types/index.d.ts.map +1 -1
  24. package/build/types/inputs/SelectInput.d.ts +16 -6
  25. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  26. package/build/types/instructionsList/InstructionsList.d.ts +10 -3
  27. package/build/types/instructionsList/InstructionsList.d.ts.map +1 -1
  28. package/build/types/processIndicator/ProcessIndicator.d.ts +1 -1
  29. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  30. package/build/types/select/Select.d.ts.map +1 -1
  31. package/build/types/select/searchBox/SearchBox.d.ts.map +1 -1
  32. package/build/types/tooltip/Tooltip.d.ts +2 -1
  33. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  34. package/package.json +4 -3
  35. package/src/accordion/AccordionItem/AccordionItem.spec.js +1 -0
  36. package/src/accordion/AccordionItem/AccordionItem.tsx +19 -11
  37. package/src/accordion/AccordionItem/__snapshots__/AccordionItem.spec.js.snap +18 -4
  38. package/src/button/Button.messages.js +9 -0
  39. package/src/button/Button.spec.js +1 -2
  40. package/src/button/Button.story.tsx +6 -0
  41. package/src/button/Button.tsx +17 -2
  42. package/src/button/__snapshots__/Button.spec.js.snap +22 -15
  43. package/src/common/Option/Option.css +1 -1
  44. package/src/common/Option/Option.less +0 -5
  45. package/src/common/index.js +1 -0
  46. package/src/common/polymorphicWithOverrides/PolymorphicWithOverrides.tsx +19 -0
  47. package/src/common/randomId.ts +14 -0
  48. package/src/dateInput/DateInput.story.tsx +0 -3
  49. package/src/i18n/en.json +1 -0
  50. package/src/index.ts +3 -0
  51. package/src/inputs/SelectInput.css +1 -1
  52. package/src/inputs/SelectInput.less +8 -2
  53. package/src/inputs/SelectInput.story.tsx +52 -5
  54. package/src/inputs/SelectInput.tsx +165 -104
  55. package/src/inputs/_Popover.less +1 -1
  56. package/src/instructionsList/InstructionList.story.tsx +39 -0
  57. package/src/instructionsList/InstructionsList.css +1 -1
  58. package/src/instructionsList/InstructionsList.less +3 -15
  59. package/src/instructionsList/InstructionsList.spec.tsx +35 -0
  60. package/src/instructionsList/InstructionsList.tsx +40 -25
  61. package/src/main.css +1 -1
  62. package/src/moneyInput/MoneyInput.story.tsx +0 -3
  63. package/src/phoneNumberInput/PhoneNumberInput.story.js +0 -3
  64. package/src/processIndicator/ProcessIndicator.js +2 -2
  65. package/src/promoCard/PromoCard.tsx +1 -16
  66. package/src/select/Select.js +2 -0
  67. package/src/select/Select.story.js +0 -6
  68. package/src/select/searchBox/SearchBox.spec.js +3 -7
  69. package/src/select/searchBox/SearchBox.tsx +2 -0
  70. package/src/stepper/Stepper.css +1 -1
  71. package/src/stepper/Stepper.less +1 -1
  72. package/src/tooltip/Tooltip.css +1 -1
  73. package/src/tooltip/Tooltip.less +13 -0
  74. package/src/tooltip/Tooltip.spec.tsx +97 -29
  75. package/src/tooltip/Tooltip.tsx +24 -31
  76. package/src/tooltip/__snapshots__/Tooltip.spec.tsx.snap +31 -0
  77. package/src/upload/Upload.spec.js +2 -0
  78. package/src/instructionsList/InstructionList.story.js +0 -27
  79. package/src/instructionsList/InstructionsList.spec.js +0 -29
  80. package/src/select/searchBox/__snapshots__/SearchBox.spec.js.snap +0 -46
@@ -1,7 +1,8 @@
1
1
  import classNames from 'classnames';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
- import React__default, { forwardRef, cloneElement, useState, useRef, useMemo, useEffect, useCallback, useLayoutEffect, createContext, useContext, PureComponent, createRef, Component, Children, Fragment as Fragment$1 } from 'react';
4
+ import React__default, { forwardRef, cloneElement, useState, useRef, useMemo, useEffect, useCallback, useLayoutEffect, createContext, useContext, Component, PureComponent, createRef, Children, Fragment as Fragment$1 } from 'react';
5
+ import { useId } from '@radix-ui/react-id';
5
6
  import { ChevronUp, CrossCircleFill, Cross, NavigateAway, Check, Info as Info$1, Alert as Alert$2, ClockBorderless, CheckCircle, InfoCircle, Warning, CrossCircle, Clock, Briefcase, Person, ArrowLeft, QuestionMarkCircle, AlertCircle, Search, ChevronDown, CheckCircleFill, ArrowRight, Download, ClockFill, Upload as Upload$2, Document, Plus, PlusCircle, AlertCircleFill } from '@transferwise/icons';
6
7
  import PropTypes from 'prop-types';
7
8
  import { defineMessages, useIntl, injectIntl, IntlProvider } from 'react-intl';
@@ -15,7 +16,7 @@ import mergeRefs from 'react-merge-refs';
15
16
  import { isUndefined, isKey, isNumber, isEmpty, isNull, isArray } from '@transferwise/neptune-validation';
16
17
  import { usePopper } from 'react-popper';
17
18
  import { Transition, Listbox } from '@headlessui/react';
18
- import { useId } from '@radix-ui/react-id';
19
+ import mergeProps from 'merge-props';
19
20
  import { useSyncExternalStore } from 'use-sync-external-store/shim';
20
21
  import { useFloating, useDismiss, useRole, useInteractions, FloatingPortal, FloatingFocusManager, offset, flip, shift, size, autoUpdate } from '@floating-ui/react';
21
22
  import { usePreventScroll } from '@react-aria/overlays';
@@ -457,6 +458,21 @@ function getDirectionFromLocale(locale) {
457
458
  }
458
459
  }
459
460
 
461
+ /**
462
+ * generateRandomId() function
463
+ *
464
+ * This function generates a random string of characters that can be used as
465
+ * an ID.
466
+ *
467
+ * @returns {string} A random string of characters.
468
+ * @example
469
+ * const id = generateRandomId();
470
+ * // id will be a random string of characters, such as "id-4711".
471
+ */
472
+ const generateRandomId = () => {
473
+ return `id-${Math.random().toString(36).slice(7)}`;
474
+ };
475
+
460
476
  const DEFAULT_TYPE$1 = Typography.TITLE_GROUP;
461
477
  const titleTypeMapping = {
462
478
  [Typography.TITLE_SCREEN]: 'h1',
@@ -640,8 +656,10 @@ const AccordionItem = ({
640
656
  const iconElement = icon ? /*#__PURE__*/cloneElement(icon, {
641
657
  size: 24
642
658
  }) : null;
659
+ const fallbackId = useId();
660
+ const accordionId = id ?? fallbackId;
643
661
  return /*#__PURE__*/jsxs("div", {
644
- id: id,
662
+ id: accordionId,
645
663
  className: classNames('np-accordion-item', iconElement ? 'np-accordion-item--with-icon' : null, {
646
664
  'np-accordion-item--open': open
647
665
  }),
@@ -655,14 +673,22 @@ const AccordionItem = ({
655
673
  size: Size.MEDIUM
656
674
  }),
657
675
  inverseMediaCircle: false,
676
+ "aria-expanded": open,
677
+ "aria-controls": `${accordionId}-section`,
678
+ id: `${accordionId}-control`,
658
679
  onClick: onClick
659
- }), open && /*#__PURE__*/jsx(Body, {
660
- as: "span",
661
- type: Typography.BODY_LARGE,
662
- className: classNames('np-accordion-item__content', 'd-block', {
663
- 'has-icon': icon
664
- }),
665
- children: content
680
+ }), open && /*#__PURE__*/jsx("div", {
681
+ id: `${accordionId}-section`,
682
+ role: "region",
683
+ "aria-labelledby": `${accordionId}-control`,
684
+ children: /*#__PURE__*/jsx(Body, {
685
+ as: "span",
686
+ type: Typography.BODY_LARGE,
687
+ className: classNames('np-accordion-item__content', 'd-block', {
688
+ 'has-icon': icon
689
+ }),
690
+ children: content
691
+ })
666
692
  })]
667
693
  });
668
694
  };
@@ -763,7 +789,7 @@ const ActionOption = ({
763
789
  });
764
790
  };
765
791
 
766
- var messages$9 = defineMessages({
792
+ var messages$a = defineMessages({
767
793
  ariaLabel: {
768
794
  id: "neptune.CloseButton.ariaLabel"
769
795
  }
@@ -779,7 +805,7 @@ const CloseButton = /*#__PURE__*/forwardRef(function CloseButton({
779
805
  testId
780
806
  }, reference) {
781
807
  const intl = useIntl();
782
- ariaLabel ??= intl.formatMessage(messages$9.ariaLabel);
808
+ ariaLabel ??= intl.formatMessage(messages$a.ariaLabel);
783
809
  const Icon = filled ? CrossCircleFill : Cross;
784
810
  return /*#__PURE__*/jsx("button", {
785
811
  ref: reference,
@@ -799,7 +825,7 @@ const CloseButton = /*#__PURE__*/forwardRef(function CloseButton({
799
825
  });
800
826
  });
801
827
 
802
- var messages$8 = defineMessages({
828
+ var messages$9 = defineMessages({
803
829
  opensInNewTab: {
804
830
  id: "neptune.Link.opensInNewTab"
805
831
  }
@@ -828,7 +854,7 @@ const Link = ({
828
854
  onClick: onClick,
829
855
  ...props,
830
856
  children: [children, " ", isBlank && /*#__PURE__*/jsx(NavigateAway, {
831
- title: formatMessage(messages$8.opensInNewTab)
857
+ title: formatMessage(messages$9.opensInNewTab)
832
858
  })]
833
859
  });
834
860
  };
@@ -2068,6 +2094,135 @@ const BottomSheet$1 = props => {
2068
2094
  };
2069
2095
  var BottomSheet$2 = BottomSheet$1;
2070
2096
 
2097
+ const radius = {
2098
+ xxs: 6,
2099
+ xs: 11,
2100
+ sm: 22,
2101
+ xl: 61
2102
+ };
2103
+ const ANIMATION_DURATION_IN_MS = 1500;
2104
+ class ProcessIndicator extends Component {
2105
+ constructor(props) {
2106
+ super(props);
2107
+ this.state = {
2108
+ status: props.status,
2109
+ size: props.size
2110
+ };
2111
+ this.interval = null;
2112
+ this.timeout = null;
2113
+ }
2114
+
2115
+ /**
2116
+ * Create interval for animation duration (1500ms)
2117
+ * Update state only at the end of every interval
2118
+ * (end of animation loop) if props changed before end of animation
2119
+ */
2120
+ componentDidMount() {
2121
+ this.interval = setInterval(() => {
2122
+ const statusFromState = this.state.status;
2123
+ const sizeFromState = this.state.size;
2124
+ const statusFromProps = this.props.status;
2125
+ const sizeFromProps = this.props.size;
2126
+ if (statusFromState !== statusFromProps) {
2127
+ this.setState({
2128
+ status: statusFromProps
2129
+ }, this.runCallBack(statusFromProps));
2130
+ }
2131
+ if (sizeFromState !== sizeFromProps) {
2132
+ this.setState({
2133
+ size: sizeFromProps
2134
+ });
2135
+ }
2136
+ }, ANIMATION_DURATION_IN_MS);
2137
+ }
2138
+
2139
+ /**
2140
+ * Only trigger render if comopnent's state got
2141
+ * updated from interval callback
2142
+ *
2143
+ * @param nextProps
2144
+ * @param nextState
2145
+ */
2146
+ shouldComponentUpdate(nextProps, nextState) {
2147
+ const isSameStatus = nextProps.status === nextState.status;
2148
+ const isSameSize = nextProps.size === nextState.size;
2149
+ return isSameStatus && isSameSize;
2150
+ }
2151
+
2152
+ // Clear interval before destroying component
2153
+ componentWillUnmount() {
2154
+ clearInterval(this.interval);
2155
+ clearTimeout(this.timeout);
2156
+ }
2157
+ runCallBack = statusFromProps => {
2158
+ const {
2159
+ onAnimationCompleted
2160
+ } = this.props;
2161
+ if (onAnimationCompleted) {
2162
+ this.timeouts = setTimeout(() => {
2163
+ onAnimationCompleted(statusFromProps);
2164
+ }, ANIMATION_DURATION_IN_MS);
2165
+ }
2166
+ };
2167
+ render() {
2168
+ const {
2169
+ className,
2170
+ 'data-testid': dataTestId
2171
+ } = this.props;
2172
+ const {
2173
+ size,
2174
+ status
2175
+ } = this.state;
2176
+ const classes = classNames(`process process-${size}`, className, {
2177
+ [`process-danger`]: status === Status.FAILED,
2178
+ [`process-stopped`]: status === Status.HIDDEN,
2179
+ [`process-success`]: status === Status.SUCCEEDED
2180
+ });
2181
+ return /*#__PURE__*/jsxs("span", {
2182
+ className: classes,
2183
+ "data-testid": dataTestId,
2184
+ children: [/*#__PURE__*/jsxs("span", {
2185
+ className: "process-icon-container",
2186
+ children: [/*#__PURE__*/jsx("span", {
2187
+ className: "process-icon-horizontal"
2188
+ }), /*#__PURE__*/jsx("span", {
2189
+ className: "process-icon-vertical"
2190
+ })]
2191
+ }), /*#__PURE__*/jsx("svg", {
2192
+ xmlns: "http://www.w3.org/2000/svg",
2193
+ children: /*#__PURE__*/jsx("circle", {
2194
+ className: "process-circle",
2195
+ cx: "50%",
2196
+ cy: "50%",
2197
+ r: radius[this.state.size],
2198
+ fillOpacity: "0.0"
2199
+ })
2200
+ })]
2201
+ });
2202
+ }
2203
+ }
2204
+ ProcessIndicator.propTypes = {
2205
+ status: PropTypes.oneOf(['processing', 'failed', 'succeeded', 'hidden']),
2206
+ size: PropTypes.oneOf(['xxs', 'xs', 'sm', 'xl']),
2207
+ onAnimationCompleted: PropTypes.func,
2208
+ className: PropTypes.string,
2209
+ 'data-testid': PropTypes.string
2210
+ };
2211
+ ProcessIndicator.defaultProps = {
2212
+ status: Status.PROCESSING,
2213
+ size: Size.SMALL,
2214
+ onAnimationCompleted: null,
2215
+ className: undefined,
2216
+ 'data-testid': null
2217
+ };
2218
+ var ProcessIndicator$1 = ProcessIndicator;
2219
+
2220
+ var messages$8 = defineMessages({
2221
+ loadingAriaLabel: {
2222
+ id: "neptune.Button.loadingAriaLabel"
2223
+ }
2224
+ });
2225
+
2071
2226
  const typeClassMap$1 = {
2072
2227
  [ControlType.ACCENT]: 'btn-accent',
2073
2228
  [ControlType.POSITIVE]: 'btn-positive',
@@ -2134,6 +2289,7 @@ const Button = /*#__PURE__*/forwardRef(({
2134
2289
  type = ControlType.ACCENT,
2135
2290
  ...rest
2136
2291
  }, reference) => {
2292
+ const intl = useIntl();
2137
2293
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
2138
2294
  logDeprecationNotices({
2139
2295
  size,
@@ -2155,6 +2311,9 @@ const Button = /*#__PURE__*/forwardRef(({
2155
2311
  // @ts-expect-error fix when refactor `typeClassMap` to TypeScript
2156
2312
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
2157
2313
  priorityClassMap[newPriority], className);
2314
+ function processIndicatorSize() {
2315
+ return ['sm', 'xs'].includes(size) ? 'xxs' : 'xs';
2316
+ }
2158
2317
  const Element = component ?? 'button';
2159
2318
  let props;
2160
2319
  if (Element === 'button') {
@@ -2176,10 +2335,11 @@ const Button = /*#__PURE__*/forwardRef(({
2176
2335
  ref: reference,
2177
2336
  className: classes,
2178
2337
  ...props,
2179
- children: [children, loading && /*#__PURE__*/jsx("span", {
2180
- className: classNames('btn-loader', {
2181
- 'm-l-2': !block
2182
- })
2338
+ "aria-live": loading ? 'polite' : 'off',
2339
+ "aria-label": loading ? intl.formatMessage(messages$8.loadingAriaLabel) : undefined,
2340
+ children: [children, loading && /*#__PURE__*/jsx(ProcessIndicator$1, {
2341
+ size: processIndicatorSize(),
2342
+ className: "btn-loader"
2183
2343
  })]
2184
2344
  });
2185
2345
  });
@@ -5327,12 +5487,15 @@ const Tooltip = ({
5327
5487
  position = Position.TOP,
5328
5488
  children = undefined,
5329
5489
  label,
5490
+ id,
5330
5491
  className
5331
5492
  }) => {
5332
5493
  const [open, setOpen] = useState(false);
5333
5494
  const anchorReference = useRef(null);
5334
5495
  const [arrowElement, setArrowElement] = useState(null);
5335
5496
  const [popperElement, setPopperElement] = useState(null);
5497
+ const fallbackId = useId();
5498
+ const tooltipId = id ?? fallbackId;
5336
5499
  const modifiers = [];
5337
5500
  modifiers.push({
5338
5501
  name: 'arrow',
@@ -5371,60 +5534,42 @@ const Tooltip = ({
5371
5534
  forceUpdate();
5372
5535
  }
5373
5536
  }, [open]);
5374
- return /*#__PURE__*/jsxs(Fragment, {
5375
- children: [/*#__PURE__*/jsx("span", {
5537
+ return /*#__PURE__*/jsx(Fragment, {
5538
+ children: /*#__PURE__*/jsxs("span", {
5376
5539
  ref: anchorReference,
5377
- className: "d-inline-block",
5378
- children: children ? /*#__PURE__*/cloneElement(children, {
5379
- /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
5380
- onMouseOver: () => {
5381
- if (children?.props?.onMouseOver) {
5382
- children?.props?.onMouseOver();
5383
- }
5384
- setOpen(true);
5385
- },
5386
- onFocus: () => {
5387
- if (children?.props?.onFocus) {
5388
- children.props.onFocus();
5389
- }
5390
- setOpen(true);
5391
- },
5392
- onMouseOut: () => {
5393
- if (children?.props?.onMouseOver) {
5394
- children.props.onMouseOver();
5395
- }
5396
- setOpen(false);
5540
+ className: "tw-tooltip-container",
5541
+ onMouseOver: () => setOpen(true),
5542
+ onFocus: () => setOpen(true),
5543
+ onMouseOut: () => setOpen(false),
5544
+ onBlur: () => setOpen(false),
5545
+ children: [children ? /*#__PURE__*/cloneElement(children, {
5546
+ 'aria-describedby': `${tooltipId}-tooltip`
5547
+ }) : null, /*#__PURE__*/jsx("div", {
5548
+ // @ts-expect-error
5549
+ ref: setPopperElement,
5550
+ className: classNames('np-tooltip', 'np-panel', open ? `np-panel--open np-tooltip--open` : null, className)
5551
+ // eslint-disable-next-line react/forbid-dom-props
5552
+ ,
5553
+ style: {
5554
+ ...styles.popper
5397
5555
  },
5398
- onBlur: () => {
5399
- if (children?.props?.onBlur) {
5400
- children.props.onBlur();
5401
- }
5402
- setOpen(false);
5403
- }
5404
- /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call */
5405
- }) : null
5406
- }), open ? /*#__PURE__*/jsx("div", {
5407
- // @ts-expect-error
5408
- ref: setPopperElement,
5409
- className: classNames('np-tooltip', 'np-panel', 'np-panel--open', 'bg-screen', className)
5410
- // eslint-disable-next-line react/forbid-dom-props
5411
- ,
5412
- style: {
5413
- ...styles.popper
5414
- },
5415
- ...attributes.popper,
5416
- children: /*#__PURE__*/jsxs("div", {
5417
- className: "np-panel__content tooltip-inner",
5418
- children: [label, /*#__PURE__*/jsx("div", {
5419
- // @ts-expect-error
5420
- ref: setArrowElement,
5421
- className: classNames('np-panel__arrow')
5422
- // eslint-disable-next-line react/forbid-dom-props
5423
- ,
5424
- style: styles.arrow
5425
- })]
5426
- })
5427
- }) : null]
5556
+ ...attributes.popper,
5557
+ "aria-hidden": !open,
5558
+ role: "tooltip",
5559
+ id: `${tooltipId}-tooltip`,
5560
+ children: /*#__PURE__*/jsxs("div", {
5561
+ className: "np-panel__content tooltip-inner",
5562
+ children: [label, /*#__PURE__*/jsx("div", {
5563
+ // @ts-expect-error
5564
+ ref: setArrowElement,
5565
+ className: classNames('np-panel__arrow')
5566
+ // eslint-disable-next-line react/forbid-dom-props
5567
+ ,
5568
+ style: styles.arrow
5569
+ })]
5570
+ })
5571
+ })]
5572
+ })
5428
5573
  });
5429
5574
  };
5430
5575
  var Tooltip$1 = Tooltip;
@@ -6185,6 +6330,20 @@ function useScreenSize(size) {
6185
6330
  return useMedia(`(min-width: ${size}px)`);
6186
6331
  }
6187
6332
 
6333
+ const PolymorphicWithOverrides = /*#__PURE__*/forwardRef(function PolymorphicWithOverrides({
6334
+ __overrides: {
6335
+ as: Element,
6336
+ ...restOverrides
6337
+ },
6338
+ ...restProps
6339
+ }, ref) {
6340
+ return /*#__PURE__*/jsx(Element, {
6341
+ ref: ref,
6342
+ ...restProps,
6343
+ ...restOverrides
6344
+ });
6345
+ });
6346
+
6188
6347
  function wrapInFragment(value) {
6189
6348
  return /*#__PURE__*/jsx(Fragment, {
6190
6349
  children: value
@@ -6431,7 +6590,8 @@ function inferSearchableStrings(value) {
6431
6590
  return [];
6432
6591
  }
6433
6592
  const SelectInputHasValueContext = /*#__PURE__*/createContext(false);
6434
- const SelectInputOptionContentCompactContext = /*#__PURE__*/createContext(false);
6593
+ const SelectInputTriggerButtonPropsContext = /*#__PURE__*/createContext({});
6594
+ const SelectInputOptionContentWithinTriggerContext = /*#__PURE__*/createContext(false);
6435
6595
  function dedupeSelectInputOptionItem(item, existingValues) {
6436
6596
  if (existingValues.has(item.value)) {
6437
6597
  return {
@@ -6461,14 +6621,68 @@ function dedupeSelectInputItems(items) {
6461
6621
  return item;
6462
6622
  });
6463
6623
  }
6624
+ const defaultRenderTrigger = ({
6625
+ content,
6626
+ placeholderShown,
6627
+ clear,
6628
+ disabled,
6629
+ className
6630
+ }) => /*#__PURE__*/jsx(InputGroup, {
6631
+ addonEnd: {
6632
+ content: /*#__PURE__*/jsxs("span", {
6633
+ className: classNames('np-select-input-addon-container', disabled && 'disabled'),
6634
+ children: [clear != null && !placeholderShown ? /*#__PURE__*/jsxs(Fragment, {
6635
+ children: [/*#__PURE__*/jsx(SelectInputClearButton, {
6636
+ onClick: event => {
6637
+ event.preventDefault();
6638
+ clear();
6639
+ }
6640
+ }), /*#__PURE__*/jsx("span", {
6641
+ className: "np-select-input-addon-separator"
6642
+ })]
6643
+ }) : null, /*#__PURE__*/jsx("span", {
6644
+ className: "np-select-input-addon",
6645
+ children: /*#__PURE__*/jsx(ChevronDown, {
6646
+ size: 16
6647
+ })
6648
+ })]
6649
+ }),
6650
+ padding: 'sm'
6651
+ },
6652
+ disabled: disabled,
6653
+ className: className,
6654
+ children: /*#__PURE__*/jsx(SelectInputTriggerButton, {
6655
+ as: ButtonInput,
6656
+ children: placeholderShown ? /*#__PURE__*/jsxs("span", {
6657
+ className: "np-select-input-placeholder",
6658
+ children: [" ", content]
6659
+ }) : content
6660
+ })
6661
+ });
6662
+ function SelectInputClearButton({
6663
+ className,
6664
+ onClick
6665
+ }) {
6666
+ const intl = useIntl();
6667
+ return /*#__PURE__*/jsx("button", {
6668
+ type: "button",
6669
+ "aria-label": intl.formatMessage(messages$5.ariaLabel),
6670
+ className: classNames(className, 'np-select-input-addon np-select-input-addon--interactive'),
6671
+ onClick: onClick,
6672
+ children: /*#__PURE__*/jsx(Cross, {
6673
+ size: 16
6674
+ })
6675
+ });
6676
+ }
6464
6677
  function SelectInput({
6465
6678
  name,
6466
6679
  placeholder,
6467
6680
  items,
6468
6681
  defaultValue,
6469
6682
  value: controlledValue,
6470
- renderValue = wrapInFragment,
6471
6683
  compareValues,
6684
+ renderValue = wrapInFragment,
6685
+ renderTrigger = defaultRenderTrigger,
6472
6686
  filterable,
6473
6687
  filterPlaceholder,
6474
6688
  disabled,
@@ -6476,7 +6690,6 @@ function SelectInput({
6476
6690
  onChange,
6477
6691
  onClear
6478
6692
  }) {
6479
- const intl = useIntl();
6480
6693
  const [open, setOpen] = useState(false);
6481
6694
  const triggerRef = useRef(null);
6482
6695
  const screenSm = useScreenSize(Breakpoint.SMALL);
@@ -6502,87 +6715,75 @@ function SelectInput({
6502
6715
  value
6503
6716
  }) => /*#__PURE__*/jsx(SelectInputHasValueContext.Provider, {
6504
6717
  value: value != null,
6505
- children: /*#__PURE__*/jsx(InputGroup, {
6506
- addonEnd: {
6507
- content: /*#__PURE__*/jsxs("span", {
6508
- className: classNames('np-select-input-addon-container', uiDisabled && 'disabled'),
6509
- children: [onClear != null && value != null ? /*#__PURE__*/jsxs(Fragment, {
6510
- children: [/*#__PURE__*/jsx("button", {
6511
- type: "button",
6512
- "aria-label": intl.formatMessage(messages$5.ariaLabel),
6513
- disabled: uiDisabled,
6514
- className: "np-select-input-addon np-select-input-addon--interactive",
6515
- onClick: event => {
6516
- event.preventDefault();
6517
- onClear();
6518
- triggerRef.current?.focus({
6519
- preventScroll: true
6520
- });
6521
- },
6522
- children: /*#__PURE__*/jsx(Cross, {
6523
- size: 16
6524
- })
6525
- }), /*#__PURE__*/jsx("span", {
6526
- className: "np-select-input-addon-separator"
6527
- })]
6528
- }) : null, /*#__PURE__*/jsx("span", {
6529
- className: "np-select-input-addon",
6530
- children: /*#__PURE__*/jsx(ChevronDown, {
6531
- size: 16
6532
- })
6533
- })]
6534
- }),
6535
- padding: 'sm'
6536
- },
6537
- className: className,
6538
- children: /*#__PURE__*/jsx(OptionsOverlay, {
6539
- open: open,
6540
- renderTrigger: ({
6541
- ref,
6542
- getInteractionProps
6543
- }) => /*#__PURE__*/jsx(Listbox.Button, {
6718
+ children: /*#__PURE__*/jsx(OptionsOverlay, {
6719
+ open: open,
6720
+ renderTrigger: ({
6721
+ ref,
6722
+ getInteractionProps
6723
+ }) => /*#__PURE__*/jsx(SelectInputTriggerButtonPropsContext.Provider, {
6724
+ // eslint-disable-next-line react/jsx-no-constructed-context-values
6725
+ value: {
6544
6726
  ref: mergeRefs([ref, triggerRef]),
6545
- as: SelectInputButton,
6546
- overrides: getInteractionProps(),
6547
- onClick: () => {
6548
- setOpen(prev => !prev);
6549
- },
6550
- children: value != null ? /*#__PURE__*/jsx(SelectInputOptionContentCompactContext.Provider, {
6727
+ ...mergeProps({
6728
+ onClick: () => {
6729
+ setOpen(prev => !prev);
6730
+ }
6731
+ }, getInteractionProps())
6732
+ },
6733
+ children: renderTrigger({
6734
+ content: value != null ? /*#__PURE__*/jsx(SelectInputOptionContentWithinTriggerContext.Provider, {
6551
6735
  value: true,
6552
6736
  children: renderValue(value, true)
6553
- }) : /*#__PURE__*/jsx("span", {
6554
- className: "np-select-input-placeholder",
6555
- children: placeholder
6556
- })
6557
- }),
6558
- initialFocusRef: controllerRef,
6559
- padding: "none",
6560
- onClose: () => {
6561
- setOpen(false);
6562
- },
6563
- children: /*#__PURE__*/jsx(SelectInputOptions, {
6564
- items: items,
6565
- renderValue: renderValue,
6566
- filterable: filterable,
6567
- filterPlaceholder: filterPlaceholder,
6568
- searchInputRef: searchInputRef,
6569
- listboxRef: listboxRef
6737
+ }) : placeholder,
6738
+ placeholderShown: value == null,
6739
+ clear: onClear != null ? () => {
6740
+ onClear();
6741
+ triggerRef.current?.focus({
6742
+ preventScroll: true
6743
+ });
6744
+ } : undefined,
6745
+ disabled: uiDisabled,
6746
+ className: classNames(className, 'np-text-body-large')
6570
6747
  })
6748
+ }),
6749
+ initialFocusRef: controllerRef,
6750
+ padding: "none",
6751
+ onClose: () => {
6752
+ setOpen(false);
6753
+ },
6754
+ children: /*#__PURE__*/jsx(SelectInputOptions, {
6755
+ items: items,
6756
+ renderValue: renderValue,
6757
+ filterable: filterable,
6758
+ filterPlaceholder: filterPlaceholder,
6759
+ searchInputRef: searchInputRef,
6760
+ listboxRef: listboxRef
6571
6761
  })
6572
6762
  })
6573
6763
  })
6574
6764
  });
6575
6765
  }
6576
- const SelectInputButton = /*#__PURE__*/forwardRef(function SelectInputButton({
6577
- overrides,
6766
+ function SelectInputTriggerButton({
6767
+ as = 'button',
6578
6768
  ...restProps
6579
- }, ref) {
6580
- return /*#__PURE__*/jsx(ButtonInput, {
6769
+ }) {
6770
+ const {
6771
+ ref,
6772
+ onClick,
6773
+ ...interactionProps
6774
+ } = useContext(SelectInputTriggerButtonPropsContext);
6775
+ return /*#__PURE__*/jsx(Listbox.Button, {
6581
6776
  ref: ref,
6582
- ...restProps,
6583
- ...overrides
6777
+ as: PolymorphicWithOverrides,
6778
+ __overrides: {
6779
+ as,
6780
+ ...interactionProps
6781
+ },
6782
+ ...mergeProps({
6783
+ onClick
6784
+ }, restProps)
6584
6785
  });
6585
- });
6786
+ }
6586
6787
  const SelectInputOptionsContainer = /*#__PURE__*/forwardRef(function SelectInputOptionsContainer({
6587
6788
  'aria-orientation': ariaOrientation,
6588
6789
  'aria-activedescendant': ariaActiveDescendant,
@@ -6711,8 +6912,7 @@ function SelectInputItemView({
6711
6912
  {
6712
6913
  if (needle == null) {
6713
6914
  return /*#__PURE__*/jsx("hr", {
6714
- className: "np-select-input-separator-item",
6715
- "aria-hidden": true
6915
+ className: "np-select-input-separator-item"
6716
6916
  });
6717
6917
  }
6718
6918
  break;
@@ -6765,18 +6965,19 @@ function SelectInputOption({
6765
6965
  disabled: disabled,
6766
6966
  className: ({
6767
6967
  active,
6968
+ selected,
6768
6969
  disabled: uiDisabled
6769
- }) => classNames('np-select-input-option-container np-text-body-large', active && 'np-select-input-option-container--active', uiDisabled && 'np-select-input-option-container--disabled'),
6970
+ }) => classNames('np-select-input-option-container np-text-body-large', active && 'np-select-input-option-container--active', selected && 'np-select-input-option-container--selected', uiDisabled && 'np-select-input-option-container--disabled'),
6770
6971
  children: ({
6771
6972
  selected
6772
6973
  }) => /*#__PURE__*/jsxs(Fragment, {
6773
- children: [cachedParentHasValue ? /*#__PURE__*/jsx(Check, {
6774
- size: 16,
6775
- className: classNames(!selected && 'np-select-input-option-check--not-selected')
6776
- }) : null, /*#__PURE__*/jsx("div", {
6974
+ children: [/*#__PURE__*/jsx("div", {
6777
6975
  className: "np-select-input-option",
6778
6976
  children: children
6779
- })]
6977
+ }), cachedParentHasValue ? /*#__PURE__*/jsx(Check, {
6978
+ size: 24,
6979
+ className: classNames('np-select-input-option-check', !selected && 'np-select-input-option-check--not-selected')
6980
+ }) : null]
6780
6981
  })
6781
6982
  });
6782
6983
  }
@@ -6786,16 +6987,16 @@ function SelectInputOptionContent({
6786
6987
  description,
6787
6988
  icon
6788
6989
  }) {
6789
- const compact = useContext(SelectInputOptionContentCompactContext);
6990
+ const withinTrigger = useContext(SelectInputOptionContentWithinTriggerContext);
6790
6991
  return /*#__PURE__*/jsxs("div", {
6791
6992
  className: "np-select-input-option-content-container np-text-body-large",
6792
6993
  children: [icon ? /*#__PURE__*/jsx("div", {
6793
- className: classNames('np-select-input-option-content-icon', !compact && 'np-select-input-option-content-icon--not-compact'),
6994
+ className: classNames('np-select-input-option-content-icon', !withinTrigger && 'np-select-input-option-content-icon--not-within-trigger'),
6794
6995
  children: icon
6795
6996
  }) : null, /*#__PURE__*/jsxs("div", {
6796
6997
  className: "np-select-input-option-content-text",
6797
6998
  children: [/*#__PURE__*/jsxs("div", {
6798
- className: classNames('np-select-input-option-content-text-line-1', compact && 'np-select-input-option-content-text-compact'),
6999
+ className: classNames('np-select-input-option-content-text-line-1', withinTrigger && 'np-select-input-option-content-text-within-trigger'),
6799
7000
  children: [/*#__PURE__*/jsx("h4", {
6800
7001
  className: "d-inline np-text-body-large",
6801
7002
  children: title
@@ -6804,7 +7005,7 @@ function SelectInputOptionContent({
6804
7005
  children: note
6805
7006
  }) : null]
6806
7007
  }), description ? /*#__PURE__*/jsx("div", {
6807
- className: classNames('np-select-input-option-content-text-secondary np-text-body-default', compact && 'np-select-input-option-content-text-compact'),
7008
+ className: classNames('np-select-input-option-content-text-secondary np-text-body-default', withinTrigger && 'np-select-input-option-content-text-within-trigger'),
6808
7009
  children: description
6809
7010
  }) : null]
6810
7011
  })]
@@ -7254,47 +7455,48 @@ InputWithDisplayFormat.propTypes = {
7254
7455
  };
7255
7456
  var InputWithDisplayFormat$1 = InputWithDisplayFormat;
7256
7457
 
7257
- const InstructionsList = props => {
7258
- const {
7259
- isModern
7260
- } = useTheme();
7261
- const {
7262
- dos,
7263
- donts
7264
- } = props;
7265
- const DontIcon = isModern ? CrossCircleFill : CrossCircle;
7266
- const DoIcon = isModern ? CheckCircleFill : CheckCircle;
7458
+ const InstructionsList = ({
7459
+ dos,
7460
+ donts
7461
+ }) => {
7267
7462
  return /*#__PURE__*/jsxs("div", {
7268
7463
  className: "tw-instructions",
7269
7464
  children: [dos && dos.map((doThis, index) =>
7270
7465
  /*#__PURE__*/
7271
7466
  // eslint-disable-next-line react/no-array-index-key
7272
- jsxs("div", {
7273
- className: "instruction",
7274
- children: [/*#__PURE__*/jsx(DoIcon, {
7275
- size: 24,
7276
- className: "do"
7277
- }), /*#__PURE__*/jsx(Body, {
7278
- className: "text-primary",
7279
- type: Typography.BODY_LARGE,
7280
- children: doThis
7281
- })]
7467
+ jsx(Instruction, {
7468
+ item: doThis,
7469
+ type: "do"
7282
7470
  }, index)), donts && donts.map((dont, index) =>
7283
7471
  /*#__PURE__*/
7284
7472
  // eslint-disable-next-line react/no-array-index-key
7285
- jsxs("div", {
7286
- className: "instruction",
7287
- children: [/*#__PURE__*/jsx(DontIcon, {
7288
- size: 24,
7289
- className: "dont"
7290
- }), /*#__PURE__*/jsx(Body, {
7291
- className: "text-primary",
7292
- type: Typography.BODY_LARGE,
7293
- children: dont
7294
- })]
7473
+ jsx(Instruction, {
7474
+ item: dont,
7475
+ type: "dont"
7295
7476
  }, index))]
7296
7477
  });
7297
7478
  };
7479
+ function Instruction({
7480
+ item,
7481
+ type
7482
+ }) {
7483
+ const isInstructionNode = typeof item === 'object' && item !== null && 'content' in item && 'aria-label' in item;
7484
+ return /*#__PURE__*/jsxs("div", {
7485
+ className: "instruction",
7486
+ "aria-label": isInstructionNode ? item['aria-label'] : undefined,
7487
+ children: [type === 'do' ? /*#__PURE__*/jsx(CheckCircleFill, {
7488
+ size: 24,
7489
+ className: type
7490
+ }) : /*#__PURE__*/jsx(CrossCircleFill, {
7491
+ size: 24,
7492
+ className: type
7493
+ }), /*#__PURE__*/jsx(Body, {
7494
+ className: "text-primary",
7495
+ type: Typography.BODY_LARGE,
7496
+ children: isInstructionNode ? item.content : item
7497
+ })]
7498
+ });
7499
+ }
7298
7500
  var InstructionsList$1 = InstructionsList;
7299
7501
 
7300
7502
  const Loader = ({
@@ -7460,6 +7662,8 @@ const SearchBox = /*#__PURE__*/forwardRef(({
7460
7662
  }), /*#__PURE__*/jsx(Input, {
7461
7663
  ref: reference,
7462
7664
  id: id,
7665
+ role: "searchbox",
7666
+ inputMode: "search",
7463
7667
  className: classNames(style('np-select-filter')),
7464
7668
  placeholder: placeholder,
7465
7669
  value: value,
@@ -7750,6 +7954,8 @@ function Select({
7750
7954
  ref: optionsListReference,
7751
7955
  id: listboxId,
7752
7956
  role: "listbox",
7957
+ "aria-orientation": "vertical",
7958
+ "aria-activedescendant": getUniqueIdForOption(id, selected),
7753
7959
  tabIndex: "-1",
7754
7960
  className: dropdownClass,
7755
7961
  ...dropdownProps,
@@ -10157,128 +10363,6 @@ PhoneNumberInput.defaultProps = {
10157
10363
  };
10158
10364
  var PhoneNumberInput$1 = PhoneNumberInput;
10159
10365
 
10160
- const radius = {
10161
- xs: 11,
10162
- sm: 22,
10163
- xl: 61
10164
- };
10165
- const ANIMATION_DURATION_IN_MS = 1500;
10166
- class ProcessIndicator extends Component {
10167
- constructor(props) {
10168
- super(props);
10169
- this.state = {
10170
- status: props.status,
10171
- size: props.size
10172
- };
10173
- this.interval = null;
10174
- this.timeout = null;
10175
- }
10176
-
10177
- /**
10178
- * Create interval for animation duration (1500ms)
10179
- * Update state only at the end of every interval
10180
- * (end of animation loop) if props changed before end of animation
10181
- */
10182
- componentDidMount() {
10183
- this.interval = setInterval(() => {
10184
- const statusFromState = this.state.status;
10185
- const sizeFromState = this.state.size;
10186
- const statusFromProps = this.props.status;
10187
- const sizeFromProps = this.props.size;
10188
- if (statusFromState !== statusFromProps) {
10189
- this.setState({
10190
- status: statusFromProps
10191
- }, this.runCallBack(statusFromProps));
10192
- }
10193
- if (sizeFromState !== sizeFromProps) {
10194
- this.setState({
10195
- size: sizeFromProps
10196
- });
10197
- }
10198
- }, ANIMATION_DURATION_IN_MS);
10199
- }
10200
-
10201
- /**
10202
- * Only trigger render if comopnent's state got
10203
- * updated from interval callback
10204
- *
10205
- * @param nextProps
10206
- * @param nextState
10207
- */
10208
- shouldComponentUpdate(nextProps, nextState) {
10209
- const isSameStatus = nextProps.status === nextState.status;
10210
- const isSameSize = nextProps.size === nextState.size;
10211
- return isSameStatus && isSameSize;
10212
- }
10213
-
10214
- // Clear interval before destroying component
10215
- componentWillUnmount() {
10216
- clearInterval(this.interval);
10217
- clearTimeout(this.timeout);
10218
- }
10219
- runCallBack = statusFromProps => {
10220
- const {
10221
- onAnimationCompleted
10222
- } = this.props;
10223
- if (onAnimationCompleted) {
10224
- this.timeouts = setTimeout(() => {
10225
- onAnimationCompleted(statusFromProps);
10226
- }, ANIMATION_DURATION_IN_MS);
10227
- }
10228
- };
10229
- render() {
10230
- const {
10231
- className,
10232
- 'data-testid': dataTestId
10233
- } = this.props;
10234
- const {
10235
- size,
10236
- status
10237
- } = this.state;
10238
- const classes = classNames(`process process-${size}`, className, {
10239
- [`process-danger`]: status === Status.FAILED,
10240
- [`process-stopped`]: status === Status.HIDDEN,
10241
- [`process-success`]: status === Status.SUCCEEDED
10242
- });
10243
- return /*#__PURE__*/jsxs("span", {
10244
- className: classes,
10245
- "data-testid": dataTestId,
10246
- children: [/*#__PURE__*/jsxs("span", {
10247
- className: "process-icon-container",
10248
- children: [/*#__PURE__*/jsx("span", {
10249
- className: "process-icon-horizontal"
10250
- }), /*#__PURE__*/jsx("span", {
10251
- className: "process-icon-vertical"
10252
- })]
10253
- }), /*#__PURE__*/jsx("svg", {
10254
- xmlns: "http://www.w3.org/2000/svg",
10255
- children: /*#__PURE__*/jsx("circle", {
10256
- className: "process-circle",
10257
- cx: "50%",
10258
- cy: "50%",
10259
- r: radius[this.state.size],
10260
- fillOpacity: "0.0"
10261
- })
10262
- })]
10263
- });
10264
- }
10265
- }
10266
- ProcessIndicator.propTypes = {
10267
- status: PropTypes.oneOf(['processing', 'failed', 'succeeded', 'hidden']),
10268
- size: PropTypes.oneOf(['xs', 'sm', 'xl']),
10269
- onAnimationCompleted: PropTypes.func,
10270
- className: PropTypes.string,
10271
- 'data-testid': PropTypes.string
10272
- };
10273
- ProcessIndicator.defaultProps = {
10274
- status: Status.PROCESSING,
10275
- size: Size.SMALL,
10276
- onAnimationCompleted: null,
10277
- className: undefined,
10278
- 'data-testid': null
10279
- };
10280
- var ProcessIndicator$1 = ProcessIndicator;
10281
-
10282
10366
  const Progress = ({
10283
10367
  className,
10284
10368
  id,
@@ -10392,50 +10476,6 @@ const PromoCardIndicator = ({
10392
10476
  });
10393
10477
  };
10394
10478
 
10395
- const generateRandomId = () => {
10396
- return `id-${Math.random().toString(36).slice(7)}`;
10397
- };
10398
- /**
10399
- * PromoCard component.
10400
- *
10401
- * PromoCard is a marketing style component that is used to group marketing
10402
- * product related information (such as choosing Card types). It can be used to
10403
- * display information in a structured way, and can be customized with various
10404
- * props to suit different use cases.
10405
- *
10406
- * @component
10407
- * @param {string} className - Additional class name for the PromoCard.
10408
- * @param {string} description - Description text for the PromoCard.
10409
- * @param {boolean} defaultChecked - Initial checked state for checkboxes and radios.
10410
- * @param {string} download - Download file name for links.
10411
- * @param {string} href - URL for links.
10412
- * @param {string} hrefLang - Language code for linked URL.
10413
- * @param {string} id - ID of the PromoCard.
10414
- * @param {string} imageAlt - Alt text for the image.
10415
- * @param {string} imageSource - Source URL of the image.
10416
- * @param {string} indicatorLabel - Label for the indicator icon.
10417
- * @param {boolean} isChecked - Checked state for checkboxes and radios.
10418
- * @param {boolean} isDisabled - Whether the PromoCard is disabled.
10419
- * @param {Function} onClick - Click event handler for the PromoCard.
10420
- * @param {string} rel - Relationship between the URL and the current page.
10421
- * @param {number} tabIndex - Tab index for keyboard navigation.
10422
- * @param {string} target - Target window for links.
10423
- * @param {string} testId - ID used for testing.
10424
- * @param {string} title - Title text of the PromoCard.
10425
- * @param {('checkbox'|'radio')} type - Type of the PromoCard (checkbox, radio).
10426
- * @param {string} value - Value for checkboxes and radios.
10427
- * @returns {JSX.Element} The rendered PromoCard component.
10428
- * @example
10429
- * <PromoCard
10430
- * title="Example PromoCard"
10431
- * description="This is an example PromoCard with a link variation."
10432
- * href="https://example.com"
10433
- * target="_blank"
10434
- * imageSource="https://example.com/image.png"
10435
- * imageAlt="Example Image"
10436
- * indicatorLabel="Learn More"
10437
- * />
10438
- */
10439
10479
  const PromoCard = /*#__PURE__*/forwardRef(({
10440
10480
  className,
10441
10481
  description,
@@ -10610,6 +10650,7 @@ const LanguageProvider = ({
10610
10650
  };
10611
10651
 
10612
10652
  var en = {
10653
+ "neptune.Button.loadingAriaLabel": "loading",
10613
10654
  "neptune.Chips.ariaLabel": "Clear {choice}",
10614
10655
  "neptune.ClearButton.ariaLabel": "Clear",
10615
10656
  "neptune.CloseButton.ariaLabel": "Close",