@transferwise/components 46.10.0 → 46.11.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 (67) hide show
  1. package/README.md +14 -1
  2. package/build/i18n/de.json +1 -0
  3. package/build/i18n/en.json +1 -0
  4. package/build/i18n/es.json +1 -0
  5. package/build/i18n/fr.json +1 -0
  6. package/build/i18n/hu.json +1 -0
  7. package/build/i18n/id.json +1 -0
  8. package/build/i18n/it.json +1 -0
  9. package/build/i18n/ja.json +1 -0
  10. package/build/i18n/pl.json +1 -0
  11. package/build/i18n/pt.json +1 -0
  12. package/build/i18n/ro.json +1 -0
  13. package/build/i18n/ru.json +1 -0
  14. package/build/i18n/th.json +1 -0
  15. package/build/i18n/tr.json +1 -0
  16. package/build/i18n/zh-CN.json +1 -0
  17. package/build/i18n/zh-HK.json +1 -0
  18. package/build/index.esm.js +56 -33
  19. package/build/index.esm.js.map +1 -1
  20. package/build/index.js +56 -33
  21. package/build/index.js.map +1 -1
  22. package/build/main.css +6 -0
  23. package/build/mocks.esm.js +40 -0
  24. package/build/mocks.esm.js.map +1 -0
  25. package/build/mocks.js +43 -0
  26. package/build/mocks.js.map +1 -0
  27. package/build/styles/drawer/Drawer.css +3 -0
  28. package/build/styles/main.css +6 -0
  29. package/build/styles/modal/Modal.css +3 -0
  30. package/build/types/mocks.d.ts +9 -0
  31. package/build/types/mocks.d.ts.map +1 -0
  32. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  33. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts +8 -0
  34. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts.map +1 -0
  35. package/build/types/test-utils/window-mock.d.ts.map +1 -1
  36. package/package.json +22 -6
  37. package/src/dimmer/Dimmer.spec.js +0 -4
  38. package/src/drawer/Drawer.css +3 -0
  39. package/src/drawer/Drawer.less +4 -0
  40. package/src/i18n/de.json +1 -0
  41. package/src/i18n/en.json +1 -0
  42. package/src/i18n/es.json +1 -0
  43. package/src/i18n/fr.json +1 -0
  44. package/src/i18n/hu.json +1 -0
  45. package/src/i18n/id.json +1 -0
  46. package/src/i18n/it.json +1 -0
  47. package/src/i18n/ja.json +1 -0
  48. package/src/i18n/pl.json +1 -0
  49. package/src/i18n/pt.json +1 -0
  50. package/src/i18n/ro.json +1 -0
  51. package/src/i18n/ru.json +1 -0
  52. package/src/i18n/th.json +1 -0
  53. package/src/i18n/tr.json +1 -0
  54. package/src/i18n/zh-CN.json +1 -0
  55. package/src/i18n/zh-HK.json +1 -0
  56. package/src/inputs/SelectInput.story.tsx +221 -315
  57. package/src/main.css +6 -0
  58. package/src/mocks.ts +48 -0
  59. package/src/modal/Modal.css +3 -0
  60. package/src/modal/Modal.less +4 -0
  61. package/src/modal/Modal.story.tsx +55 -21
  62. package/src/phoneNumberInput/PhoneNumberInput.messages.ts +8 -0
  63. package/src/phoneNumberInput/PhoneNumberInput.spec.js +12 -7
  64. package/src/phoneNumberInput/PhoneNumberInput.tsx +3 -2
  65. package/src/snackbar/Snackbar.spec.js +0 -4
  66. package/src/test-utils/window-mock.ts +7 -23
  67. package/src/withNextPortal/withNextPortal.spec.js +0 -4
@@ -1,10 +1,11 @@
1
1
  import { action } from '@storybook/addon-actions';
2
2
  import { Meta, StoryObj } from '@storybook/react';
3
+ import { ScreenMode, ThemeProvider } from '@wise/components-theming';
3
4
  import { useState } from 'react';
4
5
 
5
- import { Button, Modal } from '..';
6
- import { Scroll } from '../common';
7
- import { lorem10, lorem1000, storyConfig } from '../test-utils';
6
+ import { Button, Modal, ModalProps } from '..';
7
+ import { CommonProps, Scroll } from '../common';
8
+ import { lorem10, lorem100, lorem1000, storyConfig } from '../test-utils';
8
9
 
9
10
  export default {
10
11
  component: Modal,
@@ -23,6 +24,39 @@ export default {
23
24
 
24
25
  type Story = StoryObj<typeof Modal>;
25
26
 
27
+ export interface StoryContentProps {
28
+ args: CommonProps & ModalProps;
29
+ screenMode?: ScreenMode;
30
+ }
31
+
32
+ const StoryContent = ({ args, screenMode }: StoryContentProps) => {
33
+ // eslint-disable-next-line react-hooks/rules-of-hooks
34
+ const [open, setOpen] = useState(args.open);
35
+ return (
36
+ <>
37
+ <Button onClick={() => setOpen(true)}>Open Modal</Button>
38
+ <Modal
39
+ {...args}
40
+ body={
41
+ !screenMode ? (
42
+ args.body
43
+ ) : (
44
+ <ThemeProvider theme="personal" screenMode={screenMode}>
45
+ {lorem100}
46
+ </ThemeProvider>
47
+ )
48
+ }
49
+ open={open}
50
+ disableDimmerClickToClose={args.disableDimmerClickToClose}
51
+ onClose={() => {
52
+ setOpen(false);
53
+ action('Modal closed')();
54
+ }}
55
+ />
56
+ </>
57
+ );
58
+ };
59
+
26
60
  export const Basic: Story = {
27
61
  args: {
28
62
  title: 'Title',
@@ -30,24 +64,7 @@ export const Basic: Story = {
30
64
  scroll: Scroll.VIEWPORT,
31
65
  footer: <Button block>Action</Button>,
32
66
  },
33
- render: (args) => {
34
- // eslint-disable-next-line react-hooks/rules-of-hooks
35
- const [open, setOpen] = useState(args.open);
36
- return (
37
- <>
38
- <Button onClick={() => setOpen(true)}>Open Modal</Button>
39
- <Modal
40
- {...args}
41
- open={open}
42
- disableDimmerClickToClose={args.disableDimmerClickToClose}
43
- onClose={() => {
44
- setOpen(false);
45
- action('Modal closed')();
46
- }}
47
- />
48
- </>
49
- );
50
- },
67
+ render: (args) => <StoryContent args={args} />,
51
68
  };
52
69
 
53
70
  export const BasicMobile: Story = storyConfig(Basic, { variants: ['mobile'] });
@@ -80,3 +97,20 @@ export const WithoutTitle: Story = {
80
97
  };
81
98
 
82
99
  export const WithoutTitleMobile: Story = storyConfig(WithoutTitle, { variants: ['mobile'] });
100
+
101
+ export const WithThemeProviderInContent: Story = {
102
+ args: {
103
+ title: lorem10,
104
+ body: lorem100,
105
+ scroll: Scroll.VIEWPORT,
106
+ footer: <Button block>Action</Button>,
107
+ },
108
+ render: (args, { globals: { screenMode } }) => (
109
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
110
+ <StoryContent args={args} screenMode={screenMode} />
111
+ ),
112
+ };
113
+
114
+ export const WithThemeProviderInContentMobile: Story = storyConfig(WithThemeProviderInContent, {
115
+ variants: ['mobile'],
116
+ });
@@ -0,0 +1,8 @@
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ export default defineMessages({
4
+ selectInputPlaceholder: {
5
+ id: 'neptune.PhoneNumberInput.SelectInput.placeholder',
6
+ defaultMessage: 'Select an option...',
7
+ },
8
+ });
@@ -5,7 +5,12 @@ import { mockMatchMedia, mockResizeObserver } from '../test-utils';
5
5
 
6
6
  import PhoneNumberInput from '.';
7
7
 
8
- jest.mock('react-intl');
8
+ const locale = 'en-GB';
9
+ const formatMessage = (message) => message.defaultMessage;
10
+ jest.mock('react-intl', () => ({
11
+ ...jest.requireActual('react-intl'),
12
+ useIntl: jest.fn(() => ({ locale, formatMessage })),
13
+ }));
9
14
 
10
15
  mockMatchMedia();
11
16
  mockResizeObserver();
@@ -22,7 +27,7 @@ describe('Given a telephone number component', () => {
22
27
  const NUMBER_SELECTOR = 'input[name="phoneNumber"]';
23
28
 
24
29
  beforeEach(() => {
25
- useIntl.mockReturnValue({ locale: 'en-GB' });
30
+ useIntl.mockReturnValue({ locale, formatMessage });
26
31
  });
27
32
 
28
33
  afterEach(() => {
@@ -210,7 +215,7 @@ describe('Given a telephone number component', () => {
210
215
 
211
216
  describe('when supplied with a placeholder', () => {
212
217
  beforeEach(() => {
213
- useIntl.mockReturnValue({ locale: 'es-ES' });
218
+ useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
214
219
  component = shallow(
215
220
  <PhoneNumberInput {...props} initialValue="+12345678" placeholder="placeholder" />,
216
221
  );
@@ -224,7 +229,7 @@ describe('Given a telephone number component', () => {
224
229
 
225
230
  describe('when supplied with a search placeholder', () => {
226
231
  beforeEach(() => {
227
- useIntl.mockReturnValue({ locale: 'es-ES' });
232
+ useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
228
233
  component = shallow(
229
234
  <PhoneNumberInput
230
235
  {...props}
@@ -243,7 +248,7 @@ describe('Given a telephone number component', () => {
243
248
  describe('when supplied with a locale', () => {
244
249
  describe('and a value', () => {
245
250
  beforeEach(() => {
246
- useIntl.mockReturnValue({ locale: 'es-ES' });
251
+ useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
247
252
  component = shallow(<PhoneNumberInput {...props} initialValue="+12345678" />);
248
253
  select = component.find(PREFIX_SELECT_SELECTOR);
249
254
  input = component.find(NUMBER_SELECTOR);
@@ -257,7 +262,7 @@ describe('Given a telephone number component', () => {
257
262
  describe('and no value', () => {
258
263
  describe('and no country code', () => {
259
264
  beforeEach(() => {
260
- useIntl.mockReturnValue({ locale: 'es' });
265
+ useIntl.mockReturnValue({ locale: 'es', formatMessage });
261
266
  component = shallow(<PhoneNumberInput {...props} />);
262
267
  select = component.find(PREFIX_SELECT_SELECTOR);
263
268
  input = component.find(NUMBER_SELECTOR);
@@ -270,7 +275,7 @@ describe('Given a telephone number component', () => {
270
275
 
271
276
  describe('and country code', () => {
272
277
  beforeEach(() => {
273
- useIntl.mockReturnValue({ locale: 'es-ES' });
278
+ useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
274
279
  component = shallow(<PhoneNumberInput {...props} countryCode="US" />);
275
280
  select = component.find(PREFIX_SELECT_SELECTOR);
276
281
  input = component.find(NUMBER_SELECTOR);
@@ -4,6 +4,7 @@ import { useIntl } from 'react-intl';
4
4
  import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
5
5
  import { SelectInput, SelectInputOptionContent, SelectInputProps } from '../inputs/SelectInput';
6
6
 
7
+ import messages from './PhoneNumberInput.messages';
7
8
  import countries from './data/countries';
8
9
  import {
9
10
  explodeNumberModel,
@@ -54,7 +55,7 @@ const PhoneNumberInput = ({
54
55
  selectProps = defaultSelectProps,
55
56
  disabledCountries = defaultDisabledCountries,
56
57
  }: PhoneNumberInputProps) => {
57
- const { locale } = useIntl();
58
+ const { locale, formatMessage } = useIntl();
58
59
 
59
60
  const [internalValue, setInternalValue] = useState<PhoneNumber>(() => {
60
61
  const cleanValue = initialValue ? cleanNumber(initialValue) : null;
@@ -132,7 +133,7 @@ const PhoneNumberInput = ({
132
133
  <div className="tw-telephone">
133
134
  <div className="tw-telephone__country-select">
134
135
  <SelectInput
135
- placeholder="Select an option…"
136
+ placeholder={formatMessage(messages.selectInputPlaceholder)}
136
137
  items={[...countriesByPrefix].map(([prefix, countries]) => ({
137
138
  type: 'option',
138
139
  value: prefix,
@@ -45,10 +45,6 @@ describe('Snackbar', () => {
45
45
  mount(<SnackbarAppendingToBody {...props} />);
46
46
 
47
47
  expect(createPortal).toHaveBeenCalledTimes(1);
48
- /** Using toBeCalledWith was not matching properly */
49
- const [comp, body] = ReactDOM.createPortal.mock.calls[0];
50
- expect(comp).toMatchObject(snackbar());
51
- expect(body).toMatchObject(document.body);
52
48
  jest.clearAllMocks();
53
49
  });
54
50
 
@@ -1,30 +1,14 @@
1
+ import {
2
+ mockMatchMedia as baseMockMatchMedia,
3
+ mockResizeObserver as baseMockResizeObserver,
4
+ } from '../mocks';
5
+
1
6
  export function mockMatchMedia() {
2
- Object.defineProperty(window, 'matchMedia', {
3
- writable: true,
4
- value: jest.fn().mockImplementation((query: string) => {
5
- const matches = /^\(min-width: ([0-9]+)px\)$/.exec(query);
6
- const minWidth = matches != null ? Number(matches[1]) : undefined;
7
- return {
8
- matches: minWidth != null ? window.innerWidth >= minWidth : false,
9
- media: query,
10
- onchange: null,
11
- addListener: jest.fn(), // deprecated
12
- removeListener: jest.fn(), // deprecated
13
- addEventListener: jest.fn(),
14
- removeEventListener: jest.fn(),
15
- dispatchEvent: jest.fn(),
16
- };
17
- }),
18
- });
7
+ baseMockMatchMedia(jest);
19
8
  }
20
9
 
21
10
  export function mockResizeObserver() {
22
11
  // mock ResizeObserver because it's not implemented in jsdoc lib
23
12
  // https://github.com/jsdom/jsdom/issues/3368
24
- // eslint-disable-next-line compat/compat
25
- window.ResizeObserver = class ResizeObserver {
26
- observe = jest.fn();
27
- unobserve = jest.fn();
28
- disconnect = jest.fn();
29
- };
13
+ baseMockResizeObserver(jest);
30
14
  }
@@ -14,12 +14,8 @@ describe('withNextPortal', () => {
14
14
  ReactDOM.createPortal.mockImplementation(() => null);
15
15
  const props = {};
16
16
  const Component = withNextPortal(AnyComponent);
17
- const expected = mount(<AnyComponent {...props} />);
18
17
  mount(<Component {...props} />);
19
18
  expect(ReactDOM.createPortal).toHaveBeenCalledTimes(1);
20
- const [comp, body] = ReactDOM.createPortal.mock.calls[0];
21
- expect(comp).toMatchObject(expected);
22
- expect(body).toMatchObject(document.body);
23
19
  });
24
20
 
25
21
  const AnyComponent = () => <div>Test div</div>;