@transferwise/components 46.29.0 → 46.29.1

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.
@@ -1,4 +1,3 @@
1
- export { useClientWidth } from "./useClientWidth/useClientWidth";
2
1
  export { default as useConditionalListener } from "./useConditionalListener";
3
2
  export { default as useDirection } from "./useDirection";
4
3
  export { default as useHasIntersected } from "./useHasIntersected";
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- import { Step } from '../stepper/Stepper';
1
+ /// <reference types="react" />
2
+ import { type Step } from '../stepper/Stepper';
3
3
  export interface FlowNavigationProps {
4
4
  activeStep?: number;
5
5
  avatar?: React.ReactNode;
@@ -12,6 +12,6 @@ export interface FlowNavigationProps {
12
12
  /** Steps to be displayed in stepper. If you don't need the stepper, please use OverlayHeader instead */
13
13
  steps: readonly Step[];
14
14
  }
15
- declare const FlowNavigation: ({ activeStep, avatar, logo, done, onClose, onGoBack, steps, }: FlowNavigationProps) => React.JSX.Element;
15
+ declare const FlowNavigation: ({ activeStep, avatar, logo, done, onClose, onGoBack, steps, }: FlowNavigationProps) => import("react").JSX.Element;
16
16
  export default FlowNavigation;
17
17
  //# sourceMappingURL=FlowNavigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FlowNavigation.d.ts","sourceRoot":"","sources":["../../../src/flowNavigation/FlowNavigation.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAgB,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAMnD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sIAAsI;IACtI,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wGAAwG;IACxG,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACxB;AAED,QAAA,MAAM,cAAc,kEAQjB,mBAAmB,sBA+ErB,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"FlowNavigation.d.ts","sourceRoot":"","sources":["../../../src/flowNavigation/FlowNavigation.tsx"],"names":[],"mappings":";AAQA,OAAgB,EAAE,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAOxD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sIAAsI;IACtI,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wGAAwG;IACxG,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;CACxB;AAED,QAAA,MAAM,cAAc,kEAQjB,mBAAmB,gCAmErB,CAAC;AAEF,eAAe,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "46.29.0",
3
+ "version": "46.29.1",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -55,6 +55,10 @@
55
55
  "@storybook/addon-interactions": "^7.6.17",
56
56
  "@storybook/addon-knobs": "^7.0.2",
57
57
  "@storybook/addon-viewport": "^7.6.17",
58
+ "@storybook/addons": "^7.6.17",
59
+ "@storybook/api": "^7.6.17",
60
+ "@storybook/components": "^7.6.17",
61
+ "@storybook/core-events": "^7.6.17",
58
62
  "@storybook/manager-api": "^7.6.17",
59
63
  "@storybook/react": "^7.6.17",
60
64
  "@storybook/react-webpack5": "^7.6.17",
@@ -67,7 +71,7 @@
67
71
  "@testing-library/react-hooks": "^8.0.0",
68
72
  "@testing-library/user-event": "^13.2.1",
69
73
  "@transferwise/icons": "^3.7.0",
70
- "@transferwise/neptune-tokens": "^8.8.1",
74
+ "@transferwise/neptune-tokens": "^8.9.2",
71
75
  "@tsconfig/recommended": "^1.0.2",
72
76
  "@types/babel__core": "^7.20.1",
73
77
  "@types/commonmark": "^0.27.9",
@@ -75,7 +79,6 @@
75
79
  "@types/lodash": "4.14.202",
76
80
  "@types/lodash.clamp": "^4.0.9",
77
81
  "@types/lodash.debounce": "^4.0.9",
78
- "@types/lodash.throttle": "^4.1.7",
79
82
  "@types/node": "^14.14.31",
80
83
  "@types/react": "^17.0.65",
81
84
  "@types/react-dom": "^17.0.20",
@@ -95,8 +98,8 @@
95
98
  "rollup": "^3.28.1",
96
99
  "storybook": "^7.6.17",
97
100
  "@transferwise/less-config": "3.1.0",
98
- "@transferwise/neptune-css": "14.9.6",
99
- "@wise/components-theming": "1.1.0"
101
+ "@transferwise/neptune-css": "14.10.0",
102
+ "@wise/components-theming": "1.2.0"
100
103
  },
101
104
  "peerDependencies": {
102
105
  "@transferwise/icons": "^3.7.0",
@@ -124,7 +127,6 @@
124
127
  "core-js": "^3.8.0",
125
128
  "lodash.clamp": "^4.0.3",
126
129
  "lodash.debounce": "^4.0.8",
127
- "lodash.throttle": "^4.1.1",
128
130
  "lodash.topairs": "^4.3.0",
129
131
  "merge-props": "^6.0.0",
130
132
  "prop-types": "^15.7.2",
@@ -1,4 +1,3 @@
1
- export { useClientWidth } from './useClientWidth/useClientWidth';
2
1
  export { default as useConditionalListener } from './useConditionalListener';
3
2
  export { default as useDirection } from './useDirection';
4
3
  export { default as useHasIntersected } from './useHasIntersected';
@@ -7,7 +7,6 @@ import { render, fireEvent, screen } from '../test-utils';
7
7
 
8
8
  import Decision, { DecisionPresentation, DecisionType } from '.';
9
9
 
10
- jest.mock('lodash.throttle', () => jest.fn((fn) => fn));
11
10
  mockMatchMedia(jest);
12
11
 
13
12
  describe('Decision', () => {
@@ -2,11 +2,11 @@ import '@testing-library/jest-dom';
2
2
 
3
3
  import Avatar, { AvatarType } from '../avatar';
4
4
  import { Breakpoint, Size } from '../common';
5
- import { render, screen } from '../test-utils';
5
+ import { mockMatchMedia, render, screen } from '../test-utils';
6
6
 
7
7
  import FlowNavigation from './FlowNavigation';
8
8
 
9
- jest.mock('lodash.throttle', () => jest.fn((fn) => fn));
9
+ mockMatchMedia();
10
10
 
11
11
  jest.mock('./animatedLabel', () => {
12
12
  return function ({ className, activeLabel }) {
@@ -24,23 +24,8 @@ jest.mock('./backButton', () => {
24
24
  });
25
25
 
26
26
  describe('FlowNavigation', () => {
27
- const resetClientWidth = (width) => {
28
- Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
29
- configurable: true,
30
- value: width,
31
- });
32
- };
33
27
  beforeEach(() => {
34
- resetClientWidth(Breakpoint.LARGE + 1);
35
- });
36
-
37
- afterAll(() => {
38
- const originalClientWidth = Object.getOwnPropertyDescriptor(
39
- HTMLElement.prototype,
40
- 'clientWidth',
41
- );
42
-
43
- Object.defineProperty(HTMLElement.prototype, 'clientWidth', originalClientWidth);
28
+ window.innerWidth = Breakpoint.LARGE + 1;
44
29
  });
45
30
 
46
31
  const props = {
@@ -117,21 +102,21 @@ describe('FlowNavigation', () => {
117
102
  });
118
103
 
119
104
  it(`renders xs-max class`, () => {
120
- resetClientWidth(Breakpoint.SMALL - 1);
105
+ window.innerWidth = Breakpoint.SMALL - 1;
121
106
  const { container } = render(<FlowNavigation {...props} onClose={null} />);
122
107
 
123
108
  expect(container.querySelector('.np-flow-navigation--xs-max')).toBeInTheDocument();
124
109
  });
125
110
 
126
111
  it(`renders sm class`, () => {
127
- resetClientWidth(Breakpoint.SMALL);
112
+ window.innerWidth = Breakpoint.SMALL;
128
113
  const { container } = render(<FlowNavigation {...props} onClose={null} />);
129
114
 
130
115
  expect(container.querySelector('.np-flow-navigation--sm')).toBeInTheDocument();
131
116
  });
132
117
 
133
118
  it(`renders lg class`, () => {
134
- resetClientWidth(Breakpoint.LARGE);
119
+ window.innerWidth = Breakpoint.LARGE;
135
120
  const { container } = render(<FlowNavigation {...props} onClose={null} />);
136
121
 
137
122
  expect(container.querySelector('.np-flow-navigation--lg')).toBeInTheDocument();
@@ -139,7 +124,7 @@ describe('FlowNavigation', () => {
139
124
 
140
125
  describe('on mobile', () => {
141
126
  beforeEach(() => {
142
- resetClientWidth(Breakpoint.SMALL - 1);
127
+ window.innerWidth = Breakpoint.SMALL - 1;
143
128
  });
144
129
 
145
130
  it('renders as expected', () => {
@@ -1,18 +1,17 @@
1
1
  import classNames from 'classnames';
2
2
  import { useRef } from 'react';
3
- import React from 'react';
4
3
  import { useIntl } from 'react-intl';
5
4
 
6
5
  import { Breakpoint, Layout } from '../common';
7
6
  import { CloseButton } from '../common/closeButton';
8
7
  import FlowHeader from '../common/flowHeader/FlowHeader';
9
- import { useClientWidth } from '../common/hooks';
10
8
  import Logo from '../logo';
11
- import Stepper, { Step } from '../stepper/Stepper';
9
+ import Stepper, { type Step } from '../stepper/Stepper';
12
10
 
13
11
  import messages from './FlowNavigation.messages';
14
12
  import AnimatedLabel from './animatedLabel';
15
13
  import BackButton from './backButton';
14
+ import { useScreenSize } from '../common/hooks/useScreenSize';
16
15
 
17
16
  export interface FlowNavigationProps {
18
17
  activeStep?: number;
@@ -36,13 +35,12 @@ const FlowNavigation = ({
36
35
  onGoBack,
37
36
  steps,
38
37
  }: FlowNavigationProps) => {
39
- const reference = useRef<HTMLDivElement>(null);
40
38
  const intl = useIntl();
41
39
 
42
- const [clientWidth] = useClientWidth({ ref: reference });
43
40
  const closeButton = onClose != null && <CloseButton size="lg" onClick={onClose} />;
44
- const isSmall = clientWidth != null && clientWidth < Breakpoint.SMALL;
45
- const isLarge = clientWidth != null && clientWidth >= Breakpoint.LARGE;
41
+
42
+ const screenSm = useScreenSize(Breakpoint.SMALL);
43
+ const screenLg = useScreenSize(Breakpoint.LARGE);
46
44
 
47
45
  const newAvatar = done ? null : avatar;
48
46
 
@@ -50,28 +48,31 @@ const FlowNavigation = ({
50
48
 
51
49
  return (
52
50
  <div
53
- ref={reference}
54
51
  className={classNames(
55
52
  'np-flow-navigation d-flex align-items-center justify-content-center p-y-3',
56
53
  { 'np-flow-navigation--border-bottom': !done },
57
54
  )}
58
55
  >
59
56
  <FlowHeader
60
- className={classNames('np-flow-navigation__content p-x-3', {
61
- 'np-flow-navigation--hidden': !clientWidth,
62
- 'np-flow-navigation--xs-max': isSmall,
63
- // Size switches on parent container which may or may not have the same size as the window.
64
- 'np-flow-navigation--sm': clientWidth != null && clientWidth >= Breakpoint.SMALL,
65
- 'np-flow-navigation--lg': isLarge,
66
- })}
57
+ className={classNames(
58
+ 'np-flow-navigation__content p-x-3',
59
+ screenSm == null
60
+ ? 'np-flow-navigation--hidden'
61
+ : {
62
+ 'np-flow-navigation--xs-max': !screenSm,
63
+ // Size switches on parent container which may or may not have the same size as the window.
64
+ 'np-flow-navigation--sm': screenSm,
65
+ 'np-flow-navigation--lg': screenLg,
66
+ },
67
+ )}
67
68
  leftContent={
68
69
  <>
69
- {isSmall && displayGoBack ? (
70
+ {!screenSm && displayGoBack ? (
70
71
  <BackButton aria-label={intl.formatMessage(messages.back)} onClick={onGoBack} />
71
72
  ) : (
72
73
  <div className="np-flow-header__left">{logo}</div>
73
74
  )}
74
- {isSmall && (
75
+ {!screenSm && (
75
76
  <AnimatedLabel
76
77
  className="m-x-1"
77
78
  labels={steps.map((step) => step.label)}
@@ -81,17 +82,7 @@ const FlowNavigation = ({
81
82
  </>
82
83
  }
83
84
  rightContent={
84
- <div
85
- className={classNames(
86
- 'np-flow-header__right',
87
- 'd-flex',
88
- 'align-items-center',
89
- 'justify-content-end',
90
- {
91
- 'order-2': isLarge,
92
- },
93
- )}
94
- >
85
+ <div className="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg">
95
86
  {newAvatar}
96
87
  {newAvatar && closeButton && <span className="m-x-1" />}
97
88
  {closeButton}
@@ -106,11 +97,7 @@ const FlowNavigation = ({
106
97
  />
107
98
  )
108
99
  }
109
- layout={
110
- clientWidth != null && clientWidth < Breakpoint.LARGE
111
- ? Layout.VERTICAL
112
- : Layout.HORIZONTAL
113
- }
100
+ layout={!screenLg ? Layout.VERTICAL : Layout.HORIZONTAL}
114
101
  />
115
102
  </div>
116
103
  );
@@ -18,7 +18,7 @@ exports[`FlowNavigation on mobile renders as expected 1`] = `
18
18
  AnimatedLabel
19
19
  </div>
20
20
  <div
21
- class="np-flow-header__right d-flex align-items-center justify-content-end"
21
+ class="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg"
22
22
  >
23
23
  <div
24
24
  class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
@@ -134,7 +134,7 @@ exports[`FlowNavigation renders as expected 1`] = `
134
134
  />
135
135
  </div>
136
136
  <div
137
- class="np-flow-header__right d-flex align-items-center justify-content-end order-2"
137
+ class="np-flow-header__right d-flex align-items-center justify-content-end order-2--lg"
138
138
  >
139
139
  <div
140
140
  class="tw-avatar tw-avatar--48 tw-avatar--initials np-text-title-body"
package/src/i18n/hu.json CHANGED
@@ -35,7 +35,7 @@
35
35
  "neptune.Upload.psProcessingText": "Feltöltés...",
36
36
  "neptune.Upload.usButtonText": "Vagy válaszd ki a fájlt",
37
37
  "neptune.Upload.usDropMessage": "Húzd ide a fájlokat a feltöltéshez",
38
- "neptune.Upload.usPlaceholder": "Húzz ide egy legfeljebb {maxSize} MB méretű fájlt",
38
+ "neptune.Upload.usPlaceholder": "Húzz ide egy legfeljebb {maxSize}MB méretű fájlt",
39
39
  "neptune.UploadButton.allFileTypes": "Összes fájltípus",
40
40
  "neptune.UploadButton.dropFiles": "Húzd a fájlokat ide a feltöltéshez",
41
41
  "neptune.UploadButton.instructions": "{fileTypes}, legfeljebb {size}MB",
@@ -0,0 +1,21 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { ThemeProvider } from '@wise/components-theming';
3
+
4
+ import Button from '../../button';
5
+
6
+ export default {
7
+ component: ThemeProvider,
8
+ title: 'Other/ThemeProvider',
9
+ } satisfies Meta<typeof ThemeProvider>;
10
+
11
+ type Story = StoryObj<typeof ThemeProvider>;
12
+
13
+ export const PlatformTheme: Story = {
14
+ render: () => (
15
+ <>
16
+ <ThemeProvider theme="platform">
17
+ <Button>Button</Button>
18
+ </ThemeProvider>
19
+ </>
20
+ ),
21
+ };
@@ -1,11 +0,0 @@
1
- /// <reference types="react" />
2
- type FlowNavigationProps = {
3
- ref: React.RefObject<HTMLElement> | Window | undefined;
4
- throttleMs?: number;
5
- };
6
- export declare const useClientWidth: {
7
- ({ ref, throttleMs }: FlowNavigationProps): (number | null)[];
8
- THROTTLE_MS: number;
9
- };
10
- export {};
11
- //# sourceMappingURL=useClientWidth.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useClientWidth.d.ts","sourceRoot":"","sources":["../../../../../src/common/hooks/useClientWidth/useClientWidth.tsx"],"names":[],"mappings":";AAOA,KAAK,mBAAmB,GAAG;IACzB,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,cAAc;0BAAuC,mBAAmB;;CAgCpF,CAAC"}
@@ -1,77 +0,0 @@
1
- import { act, renderHook } from '@testing-library/react-hooks';
2
-
3
- import { fireEvent } from '../../../test-utils';
4
-
5
- import { useClientWidth } from './useClientWidth';
6
-
7
- jest.mock('lodash.throttle', () => jest.fn((fn) => fn));
8
-
9
- describe('useClientWidth', () => {
10
- describe('when invalid ref is provided', () => {
11
- it('returns 0', () => {
12
- const reference = { invalid: true };
13
- const {
14
- result: { current },
15
- } = renderHook(() => useClientWidth({ ref: reference }));
16
-
17
- expect(current).toStrictEqual([null]);
18
- });
19
- });
20
-
21
- describe('when valid ref is provided', () => {
22
- it('returns initial ref width', () => {
23
- const reference = { current: { clientWidth: 500 } };
24
- const {
25
- result: { current },
26
- } = renderHook(() => useClientWidth({ ref: reference }));
27
-
28
- expect(current).toStrictEqual([500]);
29
- });
30
-
31
- it('updates the ref width on window resize', () => {
32
- const reference = { current: { clientWidth: 500 } };
33
- const { result } = renderHook(() => useClientWidth({ ref: reference }));
34
-
35
- expect(result.current).toStrictEqual([500]);
36
-
37
- act(() => {
38
- reference.current.clientWidth = 700;
39
- fireEvent(window, new Event('resize'));
40
- });
41
- expect(result.current).toStrictEqual([700]);
42
-
43
- act(() => {
44
- reference.current.clientWidth = 800;
45
- fireEvent(window, new Event('resize'));
46
- });
47
- expect(result.current).toStrictEqual([800]);
48
- });
49
- });
50
-
51
- describe('when window ref is provided', () => {
52
- it('returns window innerWidth', () => {
53
- window.innerWidth = 600;
54
- const {
55
- result: { current },
56
- } = renderHook(() => useClientWidth({ ref: window }));
57
-
58
- expect(current).toStrictEqual([600]);
59
- });
60
- });
61
-
62
- describe('when cleanup runs the event is not longer attached to window', () => {
63
- it('returns window innerWidth', () => {
64
- const reference = { current: { clientWidth: 500 } };
65
- const { result, unmount } = renderHook(() => useClientWidth({ ref: reference }));
66
-
67
- unmount();
68
-
69
- act(() => {
70
- reference.current.clientWidth = 700;
71
- fireEvent(window, new Event('resize'));
72
- });
73
-
74
- expect(result.current).toStrictEqual([500]);
75
- });
76
- });
77
- });
@@ -1,47 +0,0 @@
1
- import throttle from 'lodash.throttle';
2
- import { useLayoutEffect, useState, useEffect, RefObject } from 'react';
3
-
4
- const THROTTLE_MS = 100;
5
-
6
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
7
-
8
- type FlowNavigationProps = {
9
- ref: React.RefObject<HTMLElement> | Window | undefined;
10
- throttleMs?: number;
11
- };
12
-
13
- export const useClientWidth = ({ ref, throttleMs = THROTTLE_MS }: FlowNavigationProps) => {
14
- const [clientWidth, setClientWidth] = useState<number | null>(null);
15
-
16
- useIsomorphicLayoutEffect(() => {
17
- // eslint-disable-next-line unicorn/consistent-function-scoping
18
- const updateClientWidth = () => {
19
- if (ref) {
20
- // when `ref` is a window
21
- if ('innerWidth' in ref) {
22
- setClientWidth(ref.innerWidth);
23
- }
24
- // when `ref` is an element
25
- else if (ref.current) {
26
- setClientWidth(ref.current.clientWidth);
27
- }
28
- }
29
- };
30
- // This assignment saves a reference to the function so it will be the same passed to both addEventListener removeEventListener.
31
- // If throttle gets passed directly to both add and removeEventListenet the results will be that the event
32
- // won't get removed even if the component is unmounted.
33
- const attachedFunction = throttle(updateClientWidth, throttleMs);
34
-
35
- window.addEventListener('resize', attachedFunction, true);
36
-
37
- // using requestAnimationFrame to perform the calculation before the next repaint
38
- // getting width earlier causes issues in animations when used with react-transition-group
39
- window.requestAnimationFrame(updateClientWidth);
40
-
41
- return () => window.removeEventListener('resize', attachedFunction, true);
42
- }, []);
43
-
44
- return [clientWidth];
45
- };
46
-
47
- useClientWidth.THROTTLE_MS = THROTTLE_MS;