@transferwise/components 45.14.2 → 45.15.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 (88) hide show
  1. package/build/index.esm.js +680 -50
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +683 -50
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +1 -1
  6. package/build/styles/common/closeButton/CloseButton.css +1 -1
  7. package/build/styles/inputs/Input.css +1 -1
  8. package/build/styles/inputs/InputGroup.css +1 -1
  9. package/build/styles/inputs/SelectInput.css +1 -0
  10. package/build/styles/inputs/TextArea.css +1 -1
  11. package/build/styles/main.css +1 -1
  12. package/build/styles/promoCard/PromoCard.css +1 -1
  13. package/build/styles/stepper/Stepper.css +1 -1
  14. package/build/types/common/hooks/useMedia.d.ts +2 -0
  15. package/build/types/common/hooks/useMedia.d.ts.map +1 -0
  16. package/build/types/common/hooks/useScreenSize.d.ts +3 -0
  17. package/build/types/common/hooks/useScreenSize.d.ts.map +1 -0
  18. package/build/types/common/preventScroll/PreventScroll.d.ts +2 -0
  19. package/build/types/common/preventScroll/PreventScroll.d.ts.map +1 -0
  20. package/build/types/dateLookup/dateTrigger/DateTrigger.messages.d.ts +7 -7
  21. package/build/types/dateLookup/dateTrigger/DateTrigger.messages.d.ts.map +1 -1
  22. package/build/types/index.d.ts +4 -0
  23. package/build/types/index.d.ts.map +1 -1
  24. package/build/types/inputs/Input.d.ts +1 -0
  25. package/build/types/inputs/Input.d.ts.map +1 -1
  26. package/build/types/inputs/SearchInput.d.ts +10 -0
  27. package/build/types/inputs/SearchInput.d.ts.map +1 -0
  28. package/build/types/inputs/SelectInput.d.ts +41 -0
  29. package/build/types/inputs/SelectInput.d.ts.map +1 -0
  30. package/build/types/inputs/_BottomSheet.d.ts +17 -0
  31. package/build/types/inputs/_BottomSheet.d.ts.map +1 -0
  32. package/build/types/inputs/_ButtonInput.d.ts +6 -0
  33. package/build/types/inputs/_ButtonInput.d.ts.map +1 -0
  34. package/build/types/inputs/_Popover.d.ts +18 -0
  35. package/build/types/inputs/_Popover.d.ts.map +1 -0
  36. package/build/types/inputs/_common.d.ts.map +1 -1
  37. package/build/types/logo/Logo.d.ts.map +1 -1
  38. package/build/types/stepper/Stepper.d.ts.map +1 -1
  39. package/build/types/tile/Tile.d.ts.map +1 -1
  40. package/build/types/utilities/wrapInFragment.d.ts +3 -0
  41. package/build/types/utilities/wrapInFragment.d.ts.map +1 -0
  42. package/package.json +26 -20
  43. package/src/common/closeButton/CloseButton.css +1 -1
  44. package/src/common/hooks/useMedia.spec.ts +39 -0
  45. package/src/common/hooks/useMedia.ts +15 -0
  46. package/src/common/hooks/useScreenSize.ts +7 -0
  47. package/src/common/preventScroll/PreventScroll.tsx +6 -0
  48. package/src/decision/Decision.story.js +11 -11
  49. package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +12 -12
  50. package/src/i18n/en.json +1 -0
  51. package/src/index.ts +8 -0
  52. package/src/inputs/Input.css +1 -1
  53. package/src/inputs/Input.less +14 -0
  54. package/src/inputs/Input.tsx +6 -2
  55. package/src/inputs/InputGroup.css +1 -1
  56. package/src/inputs/InputGroup.less +5 -0
  57. package/src/inputs/SearchInput.story.tsx +40 -0
  58. package/src/inputs/SearchInput.tsx +35 -0
  59. package/src/inputs/SelectInput.css +1 -0
  60. package/src/inputs/SelectInput.less +183 -0
  61. package/src/inputs/SelectInput.spec.tsx +120 -0
  62. package/src/inputs/SelectInput.story.tsx +259 -0
  63. package/src/inputs/SelectInput.tsx +565 -0
  64. package/src/inputs/TextArea.css +1 -1
  65. package/src/inputs/TextArea.less +5 -0
  66. package/src/inputs/_BottomSheet.less +107 -0
  67. package/src/inputs/_BottomSheet.tsx +128 -0
  68. package/src/inputs/_ButtonInput.less +7 -0
  69. package/src/inputs/_ButtonInput.tsx +27 -0
  70. package/src/inputs/_Popover.less +38 -0
  71. package/src/inputs/_Popover.tsx +118 -0
  72. package/src/inputs/_common.less +0 -4
  73. package/src/inputs/_common.ts +0 -1
  74. package/src/logo/Logo.js +3 -21
  75. package/src/logo/__snapshots__/Logo.spec.js.snap +78 -30
  76. package/src/main.css +1 -1
  77. package/src/main.less +4 -0
  78. package/src/promoCard/PromoCard.css +1 -1
  79. package/src/select/searchBox/__snapshots__/SearchBox.spec.js.snap +1 -1
  80. package/src/ssr.spec.js +7 -0
  81. package/src/stepper/Stepper.css +1 -1
  82. package/src/stepper/Stepper.less +1 -9
  83. package/src/stepper/Stepper.spec.js +4 -4
  84. package/src/stepper/Stepper.tsx +2 -5
  85. package/src/tile/Tile.js +5 -11
  86. package/src/tile/__snapshots__/Tile.spec.js.snap +7 -9
  87. package/src/utilities/wrapInFragment.tsx +3 -0
  88. /package/src/dateLookup/dateTrigger/{DateTrigger.messages.js → DateTrigger.messages.ts} +0 -0
package/build/index.js CHANGED
@@ -14,6 +14,11 @@ var reactDom = require('react-dom');
14
14
  var neptuneValidation = require('@transferwise/neptune-validation');
15
15
  var mergeRefs = require('react-merge-refs');
16
16
  var reactPopper = require('react-popper');
17
+ var react$1 = require('@headlessui/react');
18
+ var reactId = require('@radix-ui/react-id');
19
+ var shim = require('use-sync-external-store/shim');
20
+ var react = require('@floating-ui/react');
21
+ var overlays = require('@react-aria/overlays');
17
22
  var art = require('@wise/art');
18
23
  var clamp$2 = require('lodash.clamp');
19
24
  var debounce = require('lodash.debounce');
@@ -2013,7 +2018,7 @@ const MOVE_OFFSET_THRESHOLD = 50;
2013
2018
  * Neptune Web: https://transferwise.github.io/neptune-web/components/overlays/BottomSheet
2014
2019
  *
2015
2020
  */
2016
- const BottomSheet = props => {
2021
+ const BottomSheet$1 = props => {
2017
2022
  const bottomSheetReference = React.useRef(null);
2018
2023
  const topBarReference = React.useRef(null);
2019
2024
  const contentReference = React.useRef(null);
@@ -2167,7 +2172,7 @@ const BottomSheet = props => {
2167
2172
  })
2168
2173
  });
2169
2174
  };
2170
- var BottomSheet$1 = BottomSheet;
2175
+ var BottomSheet$2 = BottomSheet$1;
2171
2176
 
2172
2177
  const typeClassMap$1 = {
2173
2178
  [exports.ControlType.ACCENT]: 'btn-accent',
@@ -3194,7 +3199,7 @@ const ResponsivePanel = /*#__PURE__*/React.forwardRef(({
3194
3199
  isMobile
3195
3200
  } = useLayout();
3196
3201
  if (isMobile) {
3197
- return /*#__PURE__*/jsxRuntime.jsx(BottomSheet$1, {
3202
+ return /*#__PURE__*/jsxRuntime.jsx(BottomSheet$2, {
3198
3203
  open: open,
3199
3204
  className: className,
3200
3205
  onClose: onClose,
@@ -4275,21 +4280,14 @@ const Tile = ({
4275
4280
  title
4276
4281
  }) => {
4277
4282
  const isSmall = size === exports.Size.SMALL;
4278
- const {
4279
- isModern
4280
- } = componentsTheming.useTheme();
4281
4283
  const Element = href ? 'a' : 'button';
4282
4284
  return /*#__PURE__*/jsxRuntime.jsxs(Element, {
4283
4285
  className: classNames__default.default('decision', 'flex-column', 'np-tile', 'text-no-decoration', 'text-xs-center', className, {
4284
- 'p-a-3': !isSmall && isModern,
4285
- 'p-y-5 p-x-4': !isSmall && !isModern,
4286
- 'p-a-2': isSmall,
4287
- 'np-tile--small': isSmall,
4288
- disabled
4289
- }),
4286
+ 'p-a-3': !isSmall,
4287
+ 'p-a-2 np-tile--small': isSmall
4288
+ }, disabled && 'disabled'),
4290
4289
  href: href,
4291
4290
  target: target,
4292
- "aria-label": title,
4293
4291
  onClick: disabled ? null : onClick,
4294
4292
  onKeyDown: disabled ? null : ({
4295
4293
  key
@@ -4305,15 +4303,12 @@ const Tile = ({
4305
4303
  type: exports.Typography.TITLE_SUBSECTION,
4306
4304
  className: classNames__default.default(isSmall ? 'm-t-1' : 'm-t-2'),
4307
4305
  children: title
4308
- }), isModern && description && /*#__PURE__*/jsxRuntime.jsx(Body, {
4306
+ }), description ? /*#__PURE__*/jsxRuntime.jsx(Body, {
4309
4307
  as: "span",
4310
4308
  type: exports.Typography.BODY_DEFAULT,
4311
4309
  className: "m-t-1",
4312
4310
  children: description
4313
- }), !isModern && description && /*#__PURE__*/jsxRuntime.jsx("div", {
4314
- className: "np-tile__description",
4315
- children: description
4316
- })]
4311
+ }) : null]
4317
4312
  });
4318
4313
  };
4319
4314
  Tile.propTypes = {
@@ -5326,14 +5321,6 @@ LogoWise.defaultProps = {
5326
5321
  height: "24",
5327
5322
  fill: "none"
5328
5323
  };
5329
- const baseUrl = 'https://wise.com/public-resources/assets/logos/wise/';
5330
- const logoPaths = {
5331
- WISE: 'brand_logo.svg',
5332
- WISE_BUSINESS: 'brand_logo_business.svg',
5333
- WISE_INVERSE: 'brand_logo_inverse.svg',
5334
- WISE_BUSINESS_INVERSE: 'brand_logo_business_inverse.svg',
5335
- WISE_FLAG: 'brand_flag.svg'
5336
- };
5337
5324
  const svgPaths = {
5338
5325
  WISE: LogoWise,
5339
5326
  WISE_BUSINESS: LogoWise,
@@ -5347,21 +5334,14 @@ const Logo = ({
5347
5334
  inverse,
5348
5335
  type
5349
5336
  }) => {
5350
- const {
5351
- isModern
5352
- } = componentsTheming.useTheme();
5353
5337
  const [clientWidth] = useClientWidth({
5354
5338
  ref: isServerSide() ? undefined : window
5355
5339
  });
5356
5340
  const isSmall = clientWidth < exports.Breakpoint.SMALL;
5357
- const path = isSmall ? logoPaths['WISE_FLAG'] : logoPaths[`${type}${inverse ? '_INVERSE' : ''}`];
5358
5341
  const LogoSvg = isSmall ? svgPaths[`WISE_FLAG${inverse ? '_INVERSE' : ''}`] : svgPaths[`${type}${inverse ? '_INVERSE' : ''}`];
5359
- return isModern ? /*#__PURE__*/jsxRuntime.jsx(LogoSvg, {
5360
- className: "np-logo-svg"
5361
- }) : /*#__PURE__*/jsxRuntime.jsx("img", {
5362
- className: classNames__default.default('np-logo', className),
5363
- alt: type === exports.LogoType.WISE ? 'Wise' : 'Wise business',
5364
- src: `${baseUrl}${path}`
5342
+ return /*#__PURE__*/jsxRuntime.jsx(LogoSvg, {
5343
+ className: classNames__default.default('np-logo-svg', className),
5344
+ alt: type === exports.LogoType.WISE ? 'Wise' : 'Wise business'
5365
5345
  });
5366
5346
  };
5367
5347
  Logo.propTypes = {
@@ -5533,13 +5513,12 @@ const Stepper = ({
5533
5513
  children: /*#__PURE__*/jsxRuntime.jsx("small", {
5534
5514
  children: step.label
5535
5515
  })
5536
- }) : /*#__PURE__*/jsxRuntime.jsx(Body, {
5537
- as: "span",
5538
- className: "tw-stepper__step-label small",
5516
+ }) : /*#__PURE__*/jsxRuntime.jsx("span", {
5517
+ className: "tw-stepper__step-label",
5539
5518
  children: step.label
5540
5519
  });
5541
5520
  return /*#__PURE__*/jsxRuntime.jsx("li", {
5542
- className: classNames__default.default('hidden-xs', 'tw-stepper__step', active && 'tw-stepper__step--active', clickable && 'tw-stepper__step--clickable', step.hoverLabel && 'tw-stepper__step--has-tooltip'),
5521
+ className: classNames__default.default('hidden-xs', 'tw-stepper__step', active ? 'np-text-body-default-bold tw-stepper__step--active' : 'np-text-body-default', clickable && 'tw-stepper__step--clickable', step.hoverLabel && 'tw-stepper__step--has-tooltip'),
5543
5522
  style: isRTL ? {
5544
5523
  right: `${index * stepPercentage * 100}%`
5545
5524
  } : {
@@ -5872,7 +5851,7 @@ const Modal = ({
5872
5851
  });
5873
5852
  };
5874
5853
 
5875
- const Popover = ({
5854
+ const Popover$1 = ({
5876
5855
  children,
5877
5856
  className,
5878
5857
  content,
@@ -5926,12 +5905,12 @@ const logActionRequired = ({
5926
5905
  }) => {
5927
5906
  logActionRequiredIf(`Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${deprecatedPlacements[preferredPlacement]} instead.`, deprecatedPlacements[preferredPlacement]);
5928
5907
  };
5929
- Popover.defaultProps = {
5908
+ Popover$1.defaultProps = {
5930
5909
  className: undefined,
5931
5910
  preferredPlacement: exports.Position.RIGHT,
5932
5911
  title: undefined
5933
5912
  };
5934
- Popover.propTypes = {
5913
+ Popover$1.propTypes = {
5935
5914
  children: PropTypes__default.default.node.isRequired,
5936
5915
  className: PropTypes__default.default.string,
5937
5916
  content: PropTypes__default.default.node.isRequired,
@@ -5948,7 +5927,7 @@ const deprecatedPlacements = {
5948
5927
  [exports.Position.LEFT_TOP]: exports.Position.TOP,
5949
5928
  [exports.Position.RIGHT_TOP]: exports.Position.TOP
5950
5929
  };
5951
- var Popover$1 = Popover;
5930
+ var Popover$2 = Popover$1;
5952
5931
 
5953
5932
  const Info = ({
5954
5933
  className = undefined,
@@ -5990,7 +5969,7 @@ const Info = ({
5990
5969
  title: title,
5991
5970
  onClose: () => setOpen(false)
5992
5971
  })]
5993
- }) : /*#__PURE__*/jsxRuntime.jsx(Popover$1, {
5972
+ }) : /*#__PURE__*/jsxRuntime.jsx(Popover$2, {
5994
5973
  content: content,
5995
5974
  preferredPlacement: exports.Position.BOTTOM,
5996
5975
  title: title,
@@ -6179,11 +6158,12 @@ function formControlClassNameBase({
6179
6158
  'np-form-control--size-sm np-text-body-default': size === 'sm',
6180
6159
  'np-form-control--size-md np-text-body-large': size === 'md',
6181
6160
  'np-form-control--size-lg np-text-title-subsection': size === 'lg'
6182
- }, 'np-form-control--shape-rectangle');
6161
+ });
6183
6162
  }
6184
6163
 
6185
6164
  const Input = /*#__PURE__*/React.forwardRef(function Input({
6186
6165
  size = 'auto',
6166
+ shape = 'rectangle',
6187
6167
  className,
6188
6168
  ...restProps
6189
6169
  }, reference) {
@@ -6192,7 +6172,10 @@ const Input = /*#__PURE__*/React.forwardRef(function Input({
6192
6172
  ref: reference,
6193
6173
  className: classNames__default.default(className, formControlClassNameBase({
6194
6174
  size
6195
- }))
6175
+ }), 'np-input', {
6176
+ 'np-input--shape-rectangle': shape === 'rectangle',
6177
+ 'np-input--shape-pill': shape === 'pill'
6178
+ })
6196
6179
  // eslint-disable-next-line react/forbid-dom-props
6197
6180
  ,
6198
6181
  style: inputPaddings,
@@ -6200,6 +6183,653 @@ const Input = /*#__PURE__*/React.forwardRef(function Input({
6200
6183
  });
6201
6184
  });
6202
6185
 
6186
+ const SearchInput = /*#__PURE__*/React.forwardRef(function SearchInput({
6187
+ shape = 'pill',
6188
+ disabled,
6189
+ className,
6190
+ ...restProps
6191
+ }, ref) {
6192
+ return /*#__PURE__*/jsxRuntime.jsx(InputGroup, {
6193
+ addonStart: {
6194
+ content: /*#__PURE__*/jsxRuntime.jsx(icons.Search, {
6195
+ size: 24
6196
+ }),
6197
+ initialContentWidth: 24
6198
+ },
6199
+ disabled: disabled,
6200
+ className: className,
6201
+ children: /*#__PURE__*/jsxRuntime.jsx(Input, {
6202
+ ref: ref,
6203
+ role: "searchbox",
6204
+ inputMode: "search",
6205
+ shape: shape,
6206
+ ...restProps
6207
+ })
6208
+ });
6209
+ });
6210
+
6211
+ function useMedia(query) {
6212
+ return shim.useSyncExternalStore(onStoreChange => {
6213
+ const mediaQueryList = window.matchMedia(query);
6214
+ mediaQueryList.addEventListener('change', onStoreChange);
6215
+ return () => {
6216
+ mediaQueryList.removeEventListener('change', onStoreChange);
6217
+ };
6218
+ }, () => typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined, () => undefined);
6219
+ }
6220
+
6221
+ function useScreenSize(size) {
6222
+ return useMedia(`(min-width: ${size}px)`);
6223
+ }
6224
+
6225
+ function wrapInFragment(value) {
6226
+ return /*#__PURE__*/jsxRuntime.jsx(jsxRuntime.Fragment, {
6227
+ children: value
6228
+ });
6229
+ }
6230
+
6231
+ function PreventScroll() {
6232
+ overlays.usePreventScroll();
6233
+ return null;
6234
+ }
6235
+
6236
+ function BottomSheet({
6237
+ open,
6238
+ renderTrigger,
6239
+ title,
6240
+ initialFocusRef,
6241
+ padding = 'md',
6242
+ children,
6243
+ onClose
6244
+ }) {
6245
+ const {
6246
+ refs,
6247
+ context
6248
+ } = react.useFloating({
6249
+ open,
6250
+ onOpenChange: value => {
6251
+ if (!value) {
6252
+ onClose?.();
6253
+ }
6254
+ }
6255
+ });
6256
+ const dismiss = react.useDismiss(context, {
6257
+ outsidePressEvent: 'mousedown'
6258
+ });
6259
+ const role = react.useRole(context);
6260
+ const {
6261
+ getReferenceProps,
6262
+ getFloatingProps
6263
+ } = react.useInteractions([dismiss, role]);
6264
+ const [floatingKey, setFloatingKey] = React.useState(0);
6265
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
6266
+ children: [open ? /*#__PURE__*/jsxRuntime.jsx(PreventScroll, {}) : null, renderTrigger?.({
6267
+ ref: refs.setReference,
6268
+ getInteractionProps: getReferenceProps
6269
+ }), /*#__PURE__*/jsxRuntime.jsx(react.FloatingPortal, {
6270
+ children: /*#__PURE__*/jsxRuntime.jsxs(react$1.Transition, {
6271
+ show: open,
6272
+ className: "np-bottom-sheet-v2-container",
6273
+ beforeEnter: () => {
6274
+ setFloatingKey(prev => prev + 1);
6275
+ },
6276
+ children: [/*#__PURE__*/jsxRuntime.jsx(react$1.Transition.Child, {
6277
+ enter: "np-bottom-sheet-v2-backdrop-container--enter",
6278
+ enterFrom: "np-bottom-sheet-v2-backdrop-container--enter-from",
6279
+ leave: "np-bottom-sheet-v2-backdrop-container--leave",
6280
+ leaveTo: "np-bottom-sheet-v2-backdrop-container--leave-to",
6281
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
6282
+ className: "np-bottom-sheet-v2-backdrop"
6283
+ })
6284
+ }), /*#__PURE__*/jsxRuntime.jsx(react.FloatingFocusManager, {
6285
+ context: context,
6286
+ initialFocus: initialFocusRef,
6287
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
6288
+ className: "np-bottom-sheet-v2",
6289
+ children: /*#__PURE__*/jsxRuntime.jsx(react$1.Transition.Child, {
6290
+ className: "np-bottom-sheet-v2-content",
6291
+ enter: "np-bottom-sheet-v2-content--enter",
6292
+ enterFrom: "np-bottom-sheet-v2-content--enter-from",
6293
+ leave: "np-bottom-sheet-v2-content--leave",
6294
+ leaveTo: "np-bottom-sheet-v2-content--leave-to",
6295
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
6296
+ // Force inner state invalidation on open
6297
+ ref: refs.setFloating,
6298
+ className: "np-bottom-sheet-v2-content-inner-container",
6299
+ ...getFloatingProps(),
6300
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
6301
+ className: "np-bottom-sheet-v2-header",
6302
+ children: /*#__PURE__*/jsxRuntime.jsx(CloseButton, {
6303
+ size: exports.Size.SMALL,
6304
+ onClick: () => {
6305
+ onClose?.();
6306
+ }
6307
+ })
6308
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
6309
+ className: classNames__default.default('np-bottom-sheet-v2-content-inner', title && 'np-bottom-sheet-v2-content-inner--has-title', {
6310
+ 'np-bottom-sheet-v2-content-inner--padding-md': padding === 'md'
6311
+ }),
6312
+ children: [title ? /*#__PURE__*/jsxRuntime.jsx("h2", {
6313
+ className: "np-bottom-sheet-v2-title np-text-title-body",
6314
+ children: title
6315
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("div", {
6316
+ className: "np-bottom-sheet-v2-body np-text-body-default",
6317
+ children: children
6318
+ })]
6319
+ })]
6320
+ }, floatingKey)
6321
+ })
6322
+ })
6323
+ })]
6324
+ })
6325
+ })]
6326
+ });
6327
+ }
6328
+
6329
+ const ButtonInput = /*#__PURE__*/React.forwardRef(function ButtonInput({
6330
+ size = 'md',
6331
+ className,
6332
+ style,
6333
+ ...restProps
6334
+ }, ref) {
6335
+ const inputPaddings = useInputPaddings();
6336
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
6337
+ ref: ref,
6338
+ type: "button",
6339
+ className: classNames__default.default(className, formControlClassNameBase({
6340
+ size
6341
+ }), 'np-button-input')
6342
+ // eslint-disable-next-line react/forbid-dom-props
6343
+ ,
6344
+ style: {
6345
+ ...inputPaddings,
6346
+ ...style
6347
+ },
6348
+ ...restProps
6349
+ });
6350
+ });
6351
+
6352
+ const floatingPadding = 16;
6353
+ function Popover({
6354
+ placement,
6355
+ open,
6356
+ renderTrigger,
6357
+ title,
6358
+ padding = 'md',
6359
+ children,
6360
+ onClose
6361
+ }) {
6362
+ const {
6363
+ refs,
6364
+ floatingStyles,
6365
+ context
6366
+ } = react.useFloating({
6367
+ placement,
6368
+ middleware: [react.offset(8), react.flip({
6369
+ padding: floatingPadding,
6370
+ crossAxis: false
6371
+ }), react.shift(), react.size({
6372
+ padding: floatingPadding,
6373
+ apply: ({
6374
+ elements,
6375
+ rects,
6376
+ availableHeight
6377
+ }) => {
6378
+ elements.floating.style.setProperty('--max-height', `${availableHeight}px`);
6379
+ elements.floating.style.setProperty('--width', `${rects.reference.width}px`);
6380
+ }
6381
+ })],
6382
+ whileElementsMounted: react.autoUpdate,
6383
+ open,
6384
+ onOpenChange: value => {
6385
+ if (!value) {
6386
+ onClose?.();
6387
+ }
6388
+ }
6389
+ });
6390
+ const dismiss = react.useDismiss(context, {
6391
+ outsidePressEvent: 'mousedown'
6392
+ });
6393
+ const role = react.useRole(context);
6394
+ const {
6395
+ getReferenceProps,
6396
+ getFloatingProps
6397
+ } = react.useInteractions([role, dismiss]);
6398
+ const [floatingKey, setFloatingKey] = React.useState(0);
6399
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
6400
+ children: [open ? /*#__PURE__*/jsxRuntime.jsx(PreventScroll, {}) : null, renderTrigger({
6401
+ ref: refs.setReference,
6402
+ getInteractionProps: getReferenceProps
6403
+ }), /*#__PURE__*/jsxRuntime.jsx(react.FloatingPortal, {
6404
+ children: /*#__PURE__*/jsxRuntime.jsx(react.FloatingFocusManager, {
6405
+ context: context,
6406
+ children: /*#__PURE__*/jsxRuntime.jsx(react$1.Transition, {
6407
+ show: open,
6408
+ leave: "transition-opacity",
6409
+ leaveTo: "opacity-0",
6410
+ beforeEnter: () => {
6411
+ setFloatingKey(prev => prev + 1);
6412
+ },
6413
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
6414
+ // Force inner state invalidation on open
6415
+ ref: refs.setFloating,
6416
+ className: "np-popover-v2-container"
6417
+ // eslint-disable-next-line react/forbid-dom-props
6418
+ ,
6419
+ style: floatingStyles,
6420
+ ...getFloatingProps(),
6421
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
6422
+ className: classNames__default.default('np-popover-v2', title && 'np-popover-v2--has-title', {
6423
+ 'np-popover-v2--padding-md': padding === 'md'
6424
+ }),
6425
+ children: [title ? /*#__PURE__*/jsxRuntime.jsx("h2", {
6426
+ className: "np-popover-v2-title np-text-title-body",
6427
+ children: title
6428
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("div", {
6429
+ className: "np-popover-v2-content np-text-body-default",
6430
+ children: children
6431
+ })]
6432
+ })
6433
+ }, floatingKey)
6434
+ })
6435
+ })
6436
+ })]
6437
+ });
6438
+ }
6439
+
6440
+ function searchableString(value) {
6441
+ return value.trim().replace(/\s+/gu, ' ').toLowerCase();
6442
+ }
6443
+ function inferSearchableStrings(value) {
6444
+ if (typeof value === 'string') {
6445
+ return [searchableString(value)];
6446
+ }
6447
+ if (typeof value === 'object' && value != null) {
6448
+ return Object.values(value).filter(innerValue => typeof innerValue === 'string').map(innerValue => searchableString(innerValue));
6449
+ }
6450
+ return [];
6451
+ }
6452
+ const SelectInputHasValueContext = /*#__PURE__*/React.createContext(false);
6453
+ const SelectInputOptionContentCompactContext = /*#__PURE__*/React.createContext(false);
6454
+ function dedupeSelectInputOptionItem(item, existingValues) {
6455
+ if (existingValues.has(item.value)) {
6456
+ return {
6457
+ ...item,
6458
+ value: undefined
6459
+ };
6460
+ }
6461
+ existingValues.add(item.value);
6462
+ return item;
6463
+ }
6464
+ function dedupeSelectInputItems(items) {
6465
+ const existingValues = new Set();
6466
+ return items.map(item => {
6467
+ switch (item.type) {
6468
+ case 'option':
6469
+ {
6470
+ return dedupeSelectInputOptionItem(item, existingValues);
6471
+ }
6472
+ case 'group':
6473
+ {
6474
+ return {
6475
+ ...item,
6476
+ options: item.options.map(option => dedupeSelectInputOptionItem(option, existingValues))
6477
+ };
6478
+ }
6479
+ }
6480
+ return item;
6481
+ });
6482
+ }
6483
+ function SelectInput({
6484
+ name,
6485
+ placeholder,
6486
+ items,
6487
+ defaultValue,
6488
+ value: controlledValue,
6489
+ renderValue = wrapInFragment,
6490
+ compareValues,
6491
+ filterable,
6492
+ filterPlaceholder,
6493
+ disabled,
6494
+ className,
6495
+ onChange,
6496
+ onClear
6497
+ }) {
6498
+ const intl = reactIntl.useIntl();
6499
+ const [open, setOpen] = React.useState(false);
6500
+ const triggerRef = React.useRef(null);
6501
+ const screenSm = useScreenSize(exports.Breakpoint.SMALL);
6502
+ const OptionsOverlay = screenSm ? Popover : BottomSheet;
6503
+ const searchInputRef = React.useRef(null);
6504
+ const listboxRef = React.useRef(null);
6505
+ const controllerRef = filterable ? searchInputRef : listboxRef;
6506
+ return /*#__PURE__*/jsxRuntime.jsx(react$1.Listbox, {
6507
+ name: name,
6508
+ defaultValue: defaultValue,
6509
+ value: controlledValue
6510
+ // TODO: Remove assertion when upgrading TypeScript to v5
6511
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
6512
+ ,
6513
+ by: compareValues,
6514
+ disabled: disabled,
6515
+ onChange: value => {
6516
+ setOpen(false);
6517
+ onChange?.(value);
6518
+ },
6519
+ children: ({
6520
+ disabled: uiDisabled,
6521
+ value
6522
+ }) => /*#__PURE__*/jsxRuntime.jsx(SelectInputHasValueContext.Provider, {
6523
+ value: value != null,
6524
+ children: /*#__PURE__*/jsxRuntime.jsx(InputGroup, {
6525
+ addonEnd: {
6526
+ content: /*#__PURE__*/jsxRuntime.jsxs("span", {
6527
+ className: classNames__default.default('np-select-input-addon-container', uiDisabled && 'disabled'),
6528
+ children: [onClear != null && value != null ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
6529
+ children: [/*#__PURE__*/jsxRuntime.jsx("button", {
6530
+ type: "button",
6531
+ "aria-label": intl.formatMessage(messages$4.ariaLabel),
6532
+ disabled: uiDisabled,
6533
+ className: "np-select-input-addon np-select-input-addon--interactive",
6534
+ onClick: event => {
6535
+ event.preventDefault();
6536
+ onClear();
6537
+ triggerRef.current?.focus({
6538
+ preventScroll: true
6539
+ });
6540
+ },
6541
+ children: /*#__PURE__*/jsxRuntime.jsx(icons.Cross, {
6542
+ size: 16
6543
+ })
6544
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
6545
+ className: "np-select-input-addon-separator"
6546
+ })]
6547
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("span", {
6548
+ className: "np-select-input-addon",
6549
+ children: /*#__PURE__*/jsxRuntime.jsx(icons.ChevronDown, {
6550
+ size: 16
6551
+ })
6552
+ })]
6553
+ }),
6554
+ padding: 'sm'
6555
+ },
6556
+ className: className,
6557
+ children: /*#__PURE__*/jsxRuntime.jsx(OptionsOverlay, {
6558
+ open: open,
6559
+ renderTrigger: ({
6560
+ ref,
6561
+ getInteractionProps
6562
+ }) => /*#__PURE__*/jsxRuntime.jsx(react$1.Listbox.Button, {
6563
+ ref: mergeRefs__default.default([ref, triggerRef]),
6564
+ as: SelectInputButton,
6565
+ overrides: getInteractionProps(),
6566
+ onClick: () => {
6567
+ setOpen(prev => !prev);
6568
+ },
6569
+ children: value != null ? /*#__PURE__*/jsxRuntime.jsx(SelectInputOptionContentCompactContext.Provider, {
6570
+ value: true,
6571
+ children: renderValue(value, true)
6572
+ }) : /*#__PURE__*/jsxRuntime.jsx("span", {
6573
+ className: "np-select-input-placeholder",
6574
+ children: placeholder
6575
+ })
6576
+ }),
6577
+ initialFocusRef: controllerRef,
6578
+ padding: "none",
6579
+ onClose: () => {
6580
+ setOpen(false);
6581
+ },
6582
+ children: /*#__PURE__*/jsxRuntime.jsx(SelectInputOptions, {
6583
+ items: items,
6584
+ renderValue: renderValue,
6585
+ filterable: filterable,
6586
+ filterPlaceholder: filterPlaceholder,
6587
+ searchInputRef: searchInputRef,
6588
+ listboxRef: listboxRef
6589
+ })
6590
+ })
6591
+ })
6592
+ })
6593
+ });
6594
+ }
6595
+ const SelectInputButton = /*#__PURE__*/React.forwardRef(function SelectInputButton({
6596
+ overrides,
6597
+ ...restProps
6598
+ }, ref) {
6599
+ return /*#__PURE__*/jsxRuntime.jsx(ButtonInput, {
6600
+ ref: ref,
6601
+ ...restProps,
6602
+ ...overrides
6603
+ });
6604
+ });
6605
+ const SelectInputOptionsContainer = /*#__PURE__*/React.forwardRef(function SelectInputOptionsContainer({
6606
+ 'aria-orientation': ariaOrientation,
6607
+ 'aria-activedescendant': ariaActiveDescendant,
6608
+ role,
6609
+ tabIndex,
6610
+ onAriaActiveDescendantChange,
6611
+ onKeyDown,
6612
+ ...restProps
6613
+ }, ref) {
6614
+ const handleAriaActiveDescendantChange = useEffectEvent(onAriaActiveDescendantChange);
6615
+ React.useEffect(() => {
6616
+ handleAriaActiveDescendantChange(ariaActiveDescendant);
6617
+ }, [ariaActiveDescendant, handleAriaActiveDescendantChange]);
6618
+ return (
6619
+ /*#__PURE__*/
6620
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
6621
+ jsxRuntime.jsx("div", {
6622
+ ref: ref,
6623
+ onKeyDown: event => {
6624
+ // Prevent absorbing dismissal requests too early
6625
+ if (event.key !== 'Escape') {
6626
+ onKeyDown?.(event);
6627
+ }
6628
+ },
6629
+ ...restProps
6630
+ })
6631
+ );
6632
+ });
6633
+ function SelectInputOptions({
6634
+ items,
6635
+ renderValue = wrapInFragment,
6636
+ filterable,
6637
+ filterPlaceholder,
6638
+ searchInputRef,
6639
+ listboxRef
6640
+ }) {
6641
+ const [query, setQuery] = React.useState('');
6642
+ const needle = React.useMemo(() => query ? searchableString(query) : null, [query]);
6643
+ const listboxContainerRef = React.useRef(null);
6644
+ React.useEffect(() => {
6645
+ if (listboxContainerRef.current != null) {
6646
+ listboxContainerRef.current.style.setProperty('--initial-height', `${listboxContainerRef.current.offsetHeight}px`);
6647
+ }
6648
+ }, []);
6649
+ const listboxId = reactId.useId();
6650
+ const controllerRef = filterable ? searchInputRef : listboxRef;
6651
+ return /*#__PURE__*/jsxRuntime.jsxs(react$1.Listbox.Options, {
6652
+ as: SelectInputOptionsContainer,
6653
+ static: true,
6654
+ className: "np-select-input-options-container",
6655
+ onAriaActiveDescendantChange: value => {
6656
+ if (controllerRef.current != null) {
6657
+ if (value != null) {
6658
+ controllerRef.current.setAttribute('aria-activedescendant', value);
6659
+ } else {
6660
+ controllerRef.current.removeAttribute('aria-activedescendant');
6661
+ }
6662
+ }
6663
+ },
6664
+ children: [filterable ? /*#__PURE__*/jsxRuntime.jsx("div", {
6665
+ className: "np-select-input-query-container",
6666
+ children: /*#__PURE__*/jsxRuntime.jsx(SearchInput, {
6667
+ ref: searchInputRef,
6668
+ shape: "rectangle",
6669
+ placeholder: filterPlaceholder,
6670
+ value: query,
6671
+ "aria-controls": listboxId,
6672
+ onKeyDown: event => {
6673
+ // Prevent interfering with the matcher of Headless UI
6674
+ // https://mathiasbynens.be/notes/javascript-unicode#regex
6675
+ if (/^.$/u.test(event.key)) {
6676
+ event.stopPropagation();
6677
+ }
6678
+ },
6679
+ onChange: event => {
6680
+ setQuery(event.currentTarget.value);
6681
+ }
6682
+ })
6683
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("div", {
6684
+ ref: listboxContainerRef,
6685
+ className: classNames__default.default('np-select-input-listbox-container', items.some(item => item.type === 'group') && 'np-select-input-listbox-container--has-group'),
6686
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
6687
+ ref: listboxRef,
6688
+ id: listboxId,
6689
+ role: "listbox",
6690
+ "aria-orientation": "vertical",
6691
+ tabIndex: 0,
6692
+ className: "np-select-input-listbox",
6693
+ children: (needle == null ? items : dedupeSelectInputItems(items)).map((item, index) => /*#__PURE__*/jsxRuntime.jsx(SelectInputItemView
6694
+ // eslint-disable-next-line react/no-array-index-key
6695
+ , {
6696
+ item: item,
6697
+ renderValue: renderValue,
6698
+ needle: needle
6699
+ }, index))
6700
+ })
6701
+ })]
6702
+ });
6703
+ }
6704
+ function SelectInputItemView({
6705
+ item,
6706
+ renderValue,
6707
+ needle
6708
+ }) {
6709
+ switch (item.type) {
6710
+ case 'option':
6711
+ {
6712
+ if (item.value != null && (!needle || inferSearchableStrings(item.filterMatchers ?? item.value).some(haystack => haystack.includes(needle)))) {
6713
+ return /*#__PURE__*/jsxRuntime.jsx(SelectInputOption, {
6714
+ value: item.value,
6715
+ disabled: item.disabled,
6716
+ children: renderValue(item.value, false)
6717
+ });
6718
+ }
6719
+ break;
6720
+ }
6721
+ case 'group':
6722
+ {
6723
+ return /*#__PURE__*/jsxRuntime.jsx(SelectInputGroupItemView, {
6724
+ item: item,
6725
+ renderValue: renderValue,
6726
+ needle: needle
6727
+ });
6728
+ }
6729
+ case 'separator':
6730
+ {
6731
+ if (needle == null) {
6732
+ return /*#__PURE__*/jsxRuntime.jsx("hr", {
6733
+ className: "np-select-input-separator-item",
6734
+ "aria-hidden": true
6735
+ });
6736
+ }
6737
+ break;
6738
+ }
6739
+ }
6740
+ return null;
6741
+ }
6742
+ function SelectInputGroupItemView({
6743
+ item,
6744
+ renderValue,
6745
+ needle
6746
+ }) {
6747
+ const headerId = reactId.useId();
6748
+ return (
6749
+ /*#__PURE__*/
6750
+ // An empty container may be rendered when no options match `needle`
6751
+ // However, pre-filtering would result in worse performance overall
6752
+ jsxRuntime.jsxs("section", {
6753
+ role: "group",
6754
+ "aria-labelledby": headerId,
6755
+ className: classNames__default.default(needle == null && 'np-select-input-group-item--without-needle'),
6756
+ children: [needle == null ? /*#__PURE__*/jsxRuntime.jsx("header", {
6757
+ id: headerId,
6758
+ role: "presentation",
6759
+ className: "np-select-input-group-item-header np-text-title-group",
6760
+ children: item.label
6761
+ }) : null, item.options.map((option, index) => /*#__PURE__*/jsxRuntime.jsx(SelectInputItemView
6762
+ // eslint-disable-next-line react/no-array-index-key
6763
+ , {
6764
+ item: option,
6765
+ renderValue: renderValue,
6766
+ needle: needle
6767
+ }, index))]
6768
+ })
6769
+ );
6770
+ }
6771
+ function SelectInputOption({
6772
+ value,
6773
+ disabled,
6774
+ children
6775
+ }) {
6776
+ const parentHasValue = React.useContext(SelectInputHasValueContext);
6777
+ // Avoid flash during exit transition
6778
+ const {
6779
+ current: cachedParentHasValue
6780
+ } = React.useRef(parentHasValue);
6781
+ return /*#__PURE__*/jsxRuntime.jsx(react$1.Listbox.Option, {
6782
+ as: "div",
6783
+ value: value,
6784
+ disabled: disabled,
6785
+ className: ({
6786
+ active,
6787
+ disabled: uiDisabled
6788
+ }) => classNames__default.default('np-select-input-option-container np-text-body-large', active && 'np-select-input-option-container--active', uiDisabled && 'np-select-input-option-container--disabled'),
6789
+ children: ({
6790
+ selected
6791
+ }) => /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
6792
+ children: [cachedParentHasValue ? /*#__PURE__*/jsxRuntime.jsx(icons.Check, {
6793
+ size: 16,
6794
+ className: classNames__default.default(!selected && 'np-select-input-option-check--not-selected')
6795
+ }) : null, /*#__PURE__*/jsxRuntime.jsx("div", {
6796
+ className: "np-select-input-option",
6797
+ children: children
6798
+ })]
6799
+ })
6800
+ });
6801
+ }
6802
+ function SelectInputOptionContent({
6803
+ title,
6804
+ note,
6805
+ description,
6806
+ icon
6807
+ }) {
6808
+ const compact = React.useContext(SelectInputOptionContentCompactContext);
6809
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
6810
+ className: "np-select-input-option-content-container np-text-body-large",
6811
+ children: [icon ? /*#__PURE__*/jsxRuntime.jsx("div", {
6812
+ className: classNames__default.default('np-select-input-option-content-icon', !compact && 'np-select-input-option-content-icon--not-compact'),
6813
+ children: icon
6814
+ }) : null, /*#__PURE__*/jsxRuntime.jsxs("div", {
6815
+ className: "np-select-input-option-content-text",
6816
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
6817
+ className: classNames__default.default('np-select-input-option-content-text-line-1', compact && 'np-select-input-option-content-text-compact'),
6818
+ children: [/*#__PURE__*/jsxRuntime.jsx("h4", {
6819
+ className: "d-inline np-text-body-large",
6820
+ children: title
6821
+ }), note ? /*#__PURE__*/jsxRuntime.jsx("span", {
6822
+ className: "np-select-input-option-content-text-secondary np-text-body-default",
6823
+ children: note
6824
+ }) : null]
6825
+ }), description ? /*#__PURE__*/jsxRuntime.jsx("div", {
6826
+ className: classNames__default.default('np-select-input-option-content-text-secondary np-text-body-default', compact && 'np-select-input-option-content-text-compact'),
6827
+ children: description
6828
+ }) : null]
6829
+ })]
6830
+ });
6831
+ }
6832
+
6203
6833
  const TextArea = /*#__PURE__*/React.forwardRef(function TextArea({
6204
6834
  className,
6205
6835
  ...restProps
@@ -7315,7 +7945,7 @@ function Select({
7315
7945
  headerTitle: searchPlaceholder || formatMessage(messages$3.searchPlaceholder),
7316
7946
  onClose: handleCloseOptions,
7317
7947
  children: renderOptionsList()
7318
- }) : /*#__PURE__*/jsxRuntime.jsx(BottomSheet$1, {
7948
+ }) : /*#__PURE__*/jsxRuntime.jsx(BottomSheet$2, {
7319
7949
  open: open,
7320
7950
  onClose: handleCloseOptions,
7321
7951
  children: renderOptionsList({
@@ -14439,7 +15069,7 @@ exports.AvatarWrapper = AvatarWrapper;
14439
15069
  exports.Badge = Badge;
14440
15070
  exports.BaseCard = Card;
14441
15071
  exports.Body = Body;
14442
- exports.BottomSheet = BottomSheet$1;
15072
+ exports.BottomSheet = BottomSheet$2;
14443
15073
  exports.Button = Button;
14444
15074
  exports.Card = Card$2;
14445
15075
  exports.Checkbox = Checkbox$1;
@@ -14487,7 +15117,7 @@ exports.Nudge = Nudge;
14487
15117
  exports.Option = Option$2;
14488
15118
  exports.OverlayHeader = OverlayHeader$1;
14489
15119
  exports.PhoneNumberInput = PhoneNumberInput$1;
14490
- exports.Popover = Popover$1;
15120
+ exports.Popover = Popover$2;
14491
15121
  exports.ProcessIndicator = ProcessIndicator$1;
14492
15122
  exports.Progress = Progress;
14493
15123
  exports.ProgressBar = ProgressBar;
@@ -14499,8 +15129,11 @@ exports.Radio = Radio$1;
14499
15129
  exports.RadioGroup = RadioGroup$1;
14500
15130
  exports.RadioOption = RadioOption$1;
14501
15131
  exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
15132
+ exports.SearchInput = SearchInput;
14502
15133
  exports.Section = Section;
14503
15134
  exports.Select = Select;
15135
+ exports.SelectInput = SelectInput;
15136
+ exports.SelectInputOptionContent = SelectInputOptionContent;
14504
15137
  exports.SlidingPanel = SlidingPanel$1;
14505
15138
  exports.SnackbarConsumer = SnackbarConsumer;
14506
15139
  exports.SnackbarContext = SnackbarContext;