@transferwise/components 46.135.1 → 46.135.3

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 (59) hide show
  1. package/build/avatarWrapper/AvatarWrapper.js.map +1 -1
  2. package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
  3. package/build/common/panel/Panel.js +49 -54
  4. package/build/common/panel/Panel.js.map +1 -1
  5. package/build/common/panel/Panel.mjs +54 -59
  6. package/build/common/panel/Panel.mjs.map +1 -1
  7. package/build/listItem/ListItem.js +2 -2
  8. package/build/listItem/ListItem.js.map +1 -1
  9. package/build/listItem/ListItem.mjs +2 -2
  10. package/build/listItem/ListItem.mjs.map +1 -1
  11. package/build/main.css +4 -3
  12. package/build/select/Select.js +1 -1
  13. package/build/select/Select.js.map +1 -1
  14. package/build/select/Select.mjs +1 -1
  15. package/build/select/Select.mjs.map +1 -1
  16. package/build/styles/main.css +4 -3
  17. package/build/styles/modal/Modal.css +2 -2
  18. package/build/styles/select/Select.css +2 -1
  19. package/build/tooltip/Tooltip.js +29 -50
  20. package/build/tooltip/Tooltip.js.map +1 -1
  21. package/build/tooltip/Tooltip.mjs +30 -51
  22. package/build/tooltip/Tooltip.mjs.map +1 -1
  23. package/build/types/common/panel/Panel.d.ts.map +1 -1
  24. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  25. package/package.json +9 -11
  26. package/src/actionButton/ActionButton.story.tsx +4 -4
  27. package/src/actionButton/ActionButton.test.story.tsx +4 -4
  28. package/src/avatarWrapper/AvatarWrapper.tsx +3 -3
  29. package/src/common/circle/Circle.story.tsx +3 -3
  30. package/src/common/panel/Panel.tsx +56 -49
  31. package/src/iconButton/IconButton.story.tsx +5 -6
  32. package/src/iconButton/IconButton.test.story.tsx +8 -8
  33. package/src/icons/Icons.story.tsx +381 -0
  34. package/src/listItem/ListItem.test.tsx +24 -0
  35. package/src/listItem/ListItem.tsx +2 -2
  36. package/src/listItem/_stories/ListItem.context.test.story.tsx +63 -0
  37. package/src/listItem/_stories/ListItem.scenarios.story.tsx +3 -3
  38. package/src/main.css +4 -3
  39. package/src/modal/Modal.css +2 -2
  40. package/src/modal/Modal.less +1 -1
  41. package/src/moneyInput/MoneyInput.story.tsx +2 -2
  42. package/src/navigationOption/NavigationOption.story.tsx +3 -3
  43. package/src/overlayHeader/OverlayHeader.story.tsx +2 -2
  44. package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +3 -3
  45. package/src/prompt/ActionPrompt/ActionPrompt.test.story.tsx +3 -3
  46. package/src/prompt/InfoPrompt/InfoPrompt.accessibility.docs.mdx +1 -1
  47. package/src/prompt/InfoPrompt/InfoPrompt.story.tsx +3 -3
  48. package/src/prompt/InlinePrompt/InlinePrompt.accessibility.docs.mdx +1 -1
  49. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +5 -5
  50. package/src/prompt/InlinePrompt/InlinePrompt.test.story.tsx +2 -2
  51. package/src/select/Select.css +2 -1
  52. package/src/select/Select.less +6 -5
  53. package/src/select/Select.story.tsx +3 -3
  54. package/src/select/Select.test.story.tsx +59 -0
  55. package/src/select/Select.tsx +1 -1
  56. package/src/select/option/Option.test.tsx +3 -3
  57. package/src/summary/Summary.story.tsx +5 -5
  58. package/src/summary/Summary.test.story.tsx +2 -2
  59. package/src/tooltip/Tooltip.tsx +26 -45
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "46.135.1",
3
+ "version": "46.135.3",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -49,11 +49,11 @@
49
49
  "@rollup/plugin-node-resolve": "^16.0.3",
50
50
  "@rollup/plugin-typescript": "^12.3.0",
51
51
  "@rollup/plugin-url": "^8.0.2",
52
- "@storybook/addon-a11y": "^10.3.4",
53
- "@storybook/addon-docs": "^10.3.4",
52
+ "@storybook/addon-a11y": "^10.3.5",
53
+ "@storybook/addon-docs": "^10.3.5",
54
54
  "@storybook/addon-mcp": "^0.4.1",
55
55
  "@storybook/addon-webpack5-compiler-babel": "^4.0.1",
56
- "@storybook/react-webpack5": "^10.3.4",
56
+ "@storybook/react-webpack5": "^10.3.5",
57
57
  "@testing-library/dom": "^10.4.1",
58
58
  "@testing-library/jest-dom": "^6.9.1",
59
59
  "@testing-library/react": "^16.3.2",
@@ -73,7 +73,7 @@
73
73
  "@wise/eslint-config": "^13.3.0",
74
74
  "babel-plugin-formatjs": "^10.5.41",
75
75
  "eslint": "^9.39.4",
76
- "eslint-plugin-storybook": "^10.3.4",
76
+ "eslint-plugin-storybook": "^10.3.5",
77
77
  "gulp": "^5.0.1",
78
78
  "jest": "^30.3.0",
79
79
  "jest-environment-jsdom": "^29.7.0",
@@ -83,7 +83,7 @@
83
83
  "react-intl": "^7.1.14",
84
84
  "rollup": "^4.60.1",
85
85
  "rollup-preserve-directives": "^1.1.3",
86
- "storybook": "^10.3.4",
86
+ "storybook": "^10.3.5",
87
87
  "storybook-addon-tag-badges": "^3.1.0",
88
88
  "storybook-addon-test-codegen": "^3.0.1",
89
89
  "@transferwise/less-config": "3.1.2",
@@ -103,11 +103,11 @@
103
103
  "dependencies": {
104
104
  "@babel/runtime": "^7.29.2",
105
105
  "@floating-ui/react": "^0.27.19",
106
- "@headlessui/react": "^2.2.9",
107
- "@popperjs/core": "^2.11.8",
106
+ "@headlessui/react": "^2.2.10",
108
107
  "@react-aria/focus": "^3.21.5",
109
108
  "@react-aria/overlays": "^3.31.2",
110
109
  "@transferwise/formatting": "^2.14.0",
110
+ "@transferwise/neptune-tokens": "^8.21.0",
111
111
  "@transferwise/neptune-validation": "^3.3.3",
112
112
  "clsx": "^2.1.1",
113
113
  "commonmark": "^0.31.2",
@@ -116,10 +116,8 @@
116
116
  "lodash.clamp": "^4.0.3",
117
117
  "lodash.debounce": "^4.0.8",
118
118
  "merge-props": "^6.0.0",
119
- "react-popper": "^2.3.0",
120
119
  "react-transition-group": "^4.4.5",
121
- "virtua": "^0.48.8",
122
- "@transferwise/neptune-tokens": "^8.21.0"
120
+ "virtua": "^0.48.8"
123
121
  },
124
122
  "publishConfig": {
125
123
  "access": "public",
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
- import { Settings } from '@transferwise/icons';
2
+ import { Cog } from '@transferwise/icons';
3
3
 
4
4
  import ActionButton from './ActionButton';
5
5
  import { withVariantConfig } from '../../.storybook/helpers';
@@ -33,15 +33,15 @@ export const Basic: Story = {
33
33
  </div>
34
34
  <div>
35
35
  <ActionButton priority="primary" {...args}>
36
- <Settings />
36
+ <Cog />
37
37
  Primary label
38
38
  </ActionButton>
39
39
  <ActionButton priority="secondary" {...args}>
40
- <Settings />
40
+ <Cog />
41
41
  Secondary label
42
42
  </ActionButton>
43
43
  <ActionButton priority="tertiary" {...args}>
44
- <Settings />
44
+ <Cog />
45
45
  Tertiary label
46
46
  </ActionButton>
47
47
  </div>
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
- import { Settings } from '@transferwise/icons';
2
+ import { Cog } from '@transferwise/icons';
3
3
  import ActionButton from './ActionButton';
4
4
  import { withVariantConfig } from '../../.storybook/helpers';
5
5
 
@@ -28,15 +28,15 @@ export const DisabledVariants: Story = {
28
28
  </div>
29
29
  <div>
30
30
  <ActionButton priority="primary" {...args}>
31
- <Settings />
31
+ <Cog />
32
32
  Primary label
33
33
  </ActionButton>
34
34
  <ActionButton priority="secondary" {...args}>
35
- <Settings />
35
+ <Cog />
36
36
  Secondary label
37
37
  </ActionButton>
38
38
  <ActionButton priority="tertiary" {...args}>
39
- <Settings />
39
+ <Cog />
40
40
  Tertiary label
41
41
  </ActionButton>
42
42
  </div>
@@ -1,4 +1,4 @@
1
- import { Person as ProfileIcon, Briefcase as BriefcaseIcon } from '@transferwise/icons';
1
+ import { Person, Briefcase as BriefcaseIcon } from '@transferwise/icons';
2
2
  import { useState, useEffect } from 'react';
3
3
 
4
4
  import Avatar, { AvatarProps, AvatarType } from '../avatar';
@@ -112,7 +112,7 @@ const AvatarWrapper = ({
112
112
  if (profileType) {
113
113
  return {
114
114
  type: AvatarType.ICON,
115
- children: isBusinessProfile ? <BriefcaseIcon size="24" /> : <ProfileIcon size="24" />,
115
+ children: isBusinessProfile ? <BriefcaseIcon size="24" /> : <Person size="24" />,
116
116
  ...updatedAvatarProps,
117
117
  };
118
118
  }
@@ -126,7 +126,7 @@ const AvatarWrapper = ({
126
126
  }
127
127
  return {
128
128
  type: AvatarType.ICON,
129
- children: <ProfileIcon size="24" />,
129
+ children: <Person size="24" />,
130
130
  ...updatedAvatarProps,
131
131
  };
132
132
  };
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import Circle from './Circle';
3
- import { Profile } from '@transferwise/icons';
3
+ import { Person } from '@transferwise/icons';
4
4
  import { CircleProps } from '.';
5
5
  import Body from '../../body';
6
6
  import { withVariantConfig } from '../../../.storybook/helpers';
@@ -27,7 +27,7 @@ export const Basic: Story = {
27
27
 
28
28
  export const Sizes: Story = {
29
29
  render: () => {
30
- const content = <Profile size={16} />;
30
+ const content = <Person size={16} />;
31
31
  const sizes: CircleProps['size'][] = [16, 24, 32, 40, 48, 56, 72];
32
32
  return (
33
33
  <div
@@ -52,7 +52,7 @@ export const Sizes: Story = {
52
52
  export const FixedSize: Story = {
53
53
  render: () => {
54
54
  const size = 72;
55
- const content = <Profile size={16} />;
55
+ const content = <Person size={16} />;
56
56
  return (
57
57
  <div
58
58
  style={{
@@ -1,3 +1,13 @@
1
+ import {
2
+ arrow as arrowMiddleware,
3
+ autoUpdate,
4
+ flip as flipMiddleware,
5
+ offset,
6
+ type Placement,
7
+ shift,
8
+ size as sizeMiddleware,
9
+ useFloating,
10
+ } from '@floating-ui/react';
1
11
  import { clsx } from 'clsx';
2
12
  import {
3
13
  CSSProperties,
@@ -7,21 +17,19 @@ import {
7
17
  SyntheticEvent,
8
18
  forwardRef,
9
19
  useContext,
10
- useEffect,
11
- useState,
20
+ useRef,
12
21
  } from 'react';
13
- import { usePopper } from 'react-popper';
14
22
 
15
23
  import { Position, PositionBottom, PositionLeft, PositionRight, PositionTop } from '..';
16
24
  import Dimmer from '../../dimmer';
17
25
  import { OverlayIdContext } from '../../provider/overlay/OverlayIdProvider';
18
26
 
19
- const POPOVER_OFFSET = [0, 16];
27
+ const POPOVER_OFFSET = 16;
20
28
 
21
29
  // By default the flip positioning explores only the opposite alternative. So if left is passed and there's no enough space
22
30
  // the right one gets chosen. If there's no space on both sides popover goes back to the initially chosen one left.
23
31
  // This mapping forces popover to try the four available positions before going back to the initial chosen one.
24
- const fallbackPlacements = {
32
+ const fallbackPlacements: Record<string, Placement[]> = {
25
33
  [Position.TOP]: [Position.BOTTOM, Position.RIGHT, Position.LEFT],
26
34
  [Position.BOTTOM]: [Position.TOP, Position.RIGHT, Position.LEFT],
27
35
  [Position.LEFT]: [Position.RIGHT, Position.TOP, Position.BOTTOM],
@@ -57,56 +65,57 @@ const Panel = forwardRef<HTMLDivElement, PanelProps>(function Panel(
57
65
  }: PanelProps,
58
66
  reference,
59
67
  ) {
60
- const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null);
61
- const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);
68
+ const arrowRef = useRef<HTMLDivElement | null>(null);
69
+
70
+ const middleware = [];
62
71
 
63
- const modifiers = [];
72
+ if (arrow) {
73
+ middleware.push(offset(POPOVER_OFFSET));
74
+ }
75
+
76
+ if (flip && fallbackPlacements[position]) {
77
+ middleware.push(
78
+ flipMiddleware({
79
+ fallbackPlacements: fallbackPlacements[position],
80
+ }),
81
+ );
82
+ }
64
83
 
65
84
  if (altAxis) {
66
- modifiers.push({
67
- // https://popper.js.org/docs/v2/modifiers/prevent-overflow
68
- name: 'preventOverflow',
69
- options: {
70
- altAxis: true,
71
- tether: false,
72
- },
73
- });
85
+ middleware.push(shift());
74
86
  }
75
87
 
76
88
  if (arrow) {
77
- modifiers.push({
78
- name: 'arrow',
79
- options: {
80
- element: arrowElement,
81
- options: {
82
- padding: 8, // 8px from the edges of the popper
83
- },
84
- },
85
- });
86
- // This lets you displace a popper element from its reference element.
87
- modifiers.push({ name: 'offset', options: { offset: POPOVER_OFFSET } });
89
+ middleware.push(arrowMiddleware({ element: arrowRef, padding: 8 }));
88
90
  }
89
- if (flip && fallbackPlacements[position]) {
90
- modifiers.push({
91
- name: 'flip',
92
- options: {
93
- fallbackPlacements: fallbackPlacements[position],
94
- },
95
- });
91
+
92
+ if (considerHeight) {
93
+ middleware.push(
94
+ sizeMiddleware({
95
+ padding: POPOVER_OFFSET,
96
+ apply: ({ elements, availableHeight }) => {
97
+ elements.floating.style.setProperty(
98
+ '--np-panel-available-height',
99
+ `${availableHeight}px`,
100
+ );
101
+ },
102
+ }),
103
+ );
96
104
  }
97
105
 
98
- const { styles, attributes, forceUpdate } = usePopper(anchorRef.current, popperElement, {
106
+ const { refs, floatingStyles, placement, middlewareData } = useFloating({
99
107
  placement: position,
100
- modifiers,
108
+ middleware,
109
+ elements: {
110
+ reference: anchorRef.current,
111
+ },
112
+ whileElementsMounted: open ? autoUpdate : undefined,
101
113
  });
102
114
 
103
- // If the trigger is not visible when the position is calculated, it will be incorrect. Because this can happen repeatedly (on resize for example),
104
- // it is most simple just to always position before opening
105
- useEffect(() => {
106
- if (open && forceUpdate) {
107
- forceUpdate();
108
- }
109
- }, [open]);
115
+ const arrowStyle: CSSProperties = {
116
+ ...(middlewareData.arrow?.x != null ? { left: middlewareData.arrow.x } : {}),
117
+ ...(middlewareData.arrow?.y != null ? { top: middlewareData.arrow.y } : {}),
118
+ };
110
119
 
111
120
  const contentStyle: CSSProperties = {
112
121
  ...(anchorWidth ? { width: anchorRef.current?.clientWidth } : undefined),
@@ -119,18 +128,16 @@ const Panel = forwardRef<HTMLDivElement, PanelProps>(function Panel(
119
128
  <div
120
129
  id={overlayId}
121
130
  {...rest}
122
- ref={setPopperElement}
131
+ ref={refs.setFloating}
123
132
  role="dialog"
124
- style={{ ...styles.popper }}
125
- {...attributes.popper}
133
+ style={floatingStyles}
134
+ data-popper-placement={placement}
126
135
  className={clsx('np-panel', { 'np-panel--open': open }, rest.className)}
127
136
  >
128
137
  <div ref={reference} style={contentStyle} className={clsx('np-panel__content')}>
129
138
  {children}
130
139
  {/* Arrow has to stay inside content to get the same animations as the "dialog" and to get hidden when panel is closed. */}
131
- {arrow && (
132
- <div ref={setArrowElement} className={clsx('np-panel__arrow')} style={styles.arrow} />
133
- )}
140
+ {arrow && <div ref={arrowRef} className={clsx('np-panel__arrow')} style={arrowStyle} />}
134
141
  </div>
135
142
  </div>
136
143
  </Dimmer>
@@ -2,13 +2,12 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import {
3
3
  ArrowLeft,
4
4
  Cross,
5
- Defrost,
6
5
  Edit,
7
6
  Menu,
8
7
  Plus,
9
- Settings,
8
+ Cog,
10
9
  Star,
11
- Travel,
10
+ Suitcase,
12
11
  Briefcase,
13
12
  Bank,
14
13
  Freeze,
@@ -96,7 +95,7 @@ export const Priority: Story = {
96
95
  <Plus />
97
96
  </IconButton>
98
97
  <IconButton priority="secondary" type={args.type} aria-label="Secondary" onClick={fn()}>
99
- <Settings />
98
+ <Cog />
100
99
  </IconButton>
101
100
  <IconButton priority="tertiary" type={args.type} aria-label="Tertiary" onClick={fn()}>
102
101
  <Star />
@@ -363,7 +362,7 @@ export const SentimentAwareness: Story = {
363
362
  type="default"
364
363
  onClick={fn()}
365
364
  >
366
- <Settings />
365
+ <Cog />
367
366
  </IconButton>
368
367
  <IconButton
369
368
  size={args.size}
@@ -381,7 +380,7 @@ export const SentimentAwareness: Story = {
381
380
  type="default"
382
381
  onClick={fn()}
383
382
  >
384
- <Travel />
383
+ <Suitcase />
385
384
  </IconButton>
386
385
  <IconButton
387
386
  size={args.size}
@@ -2,9 +2,9 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import {
3
3
  Menu,
4
4
  Plus,
5
- Settings,
5
+ Cog,
6
6
  Star,
7
- Travel,
7
+ Suitcase,
8
8
  Cross,
9
9
  Edit,
10
10
  Briefcase,
@@ -109,7 +109,7 @@ export const Variants: Story = {
109
109
  type="default"
110
110
  onClick={fn()}
111
111
  >
112
- <Settings />
112
+ <Cog />
113
113
  </IconButton>
114
114
  <IconButton
115
115
  size={size}
@@ -127,7 +127,7 @@ export const Variants: Story = {
127
127
  type="default"
128
128
  onClick={fn()}
129
129
  >
130
- <Travel />
130
+ <Suitcase />
131
131
  </IconButton>
132
132
  <IconButton
133
133
  size={size}
@@ -261,13 +261,13 @@ export const KeyboardInteraction: Story = {
261
261
  type="default"
262
262
  onClick={fn()}
263
263
  >
264
- <Settings />
264
+ <Cog />
265
265
  </IconButton>
266
266
  <IconButton size={48} aria-label="Tertiary" priority="tertiary" type="default" onClick={fn()}>
267
267
  <Star />
268
268
  </IconButton>
269
269
  <IconButton size={48} aria-label="Minimal" priority="minimal" type="default" onClick={fn()}>
270
- <Travel />
270
+ <Suitcase />
271
271
  </IconButton>
272
272
  <IconButton
273
273
  size={48}
@@ -343,13 +343,13 @@ export const Zoom400: Story = {
343
343
  type="default"
344
344
  onClick={fn()}
345
345
  >
346
- <Settings />
346
+ <Cog />
347
347
  </IconButton>
348
348
  <IconButton size={40} aria-label="Tertiary" priority="tertiary" type="default" onClick={fn()}>
349
349
  <Star />
350
350
  </IconButton>
351
351
  <IconButton size={40} aria-label="Minimal" priority="minimal" type="default" onClick={fn()}>
352
- <Travel />
352
+ <Suitcase />
353
353
  </IconButton>
354
354
  <IconButton
355
355
  size={40}