@transferwise/components 46.40.0 → 46.41.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.
Files changed (37) hide show
  1. package/build/index.js +68 -74
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +69 -75
  4. package/build/index.mjs.map +1 -1
  5. package/build/main.css +69 -14
  6. package/build/styles/main.css +69 -14
  7. package/build/styles/statusIcon/StatusIcon.css +4 -2
  8. package/build/styles/uploadInput/UploadInput.css +18 -1
  9. package/build/styles/uploadInput/uploadButton/UploadButton.css +4 -0
  10. package/build/styles/uploadInput/uploadItem/UploadItem.css +43 -11
  11. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  12. package/build/types/field/Field.d.ts +6 -1
  13. package/build/types/field/Field.d.ts.map +1 -1
  14. package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
  15. package/package.json +4 -4
  16. package/src/dateInput/DateInput.spec.tsx +220 -0
  17. package/src/dateInput/DateInput.story.tsx +3 -76
  18. package/src/dateInput/DateInput.tests.story.tsx +238 -0
  19. package/src/dateInput/DateInput.tsx +50 -53
  20. package/src/field/Field.story.tsx +17 -36
  21. package/src/field/Field.tests.story.tsx +33 -0
  22. package/src/field/Field.tsx +23 -13
  23. package/src/inlineAlert/InlineAlert.story.tsx +13 -5
  24. package/src/inlineAlert/InlineAlert.tsx +13 -6
  25. package/src/main.css +69 -14
  26. package/src/statusIcon/StatusIcon.css +4 -2
  27. package/src/statusIcon/StatusIcon.less +4 -2
  28. package/src/statusIcon/StatusIcon.tsx +1 -1
  29. package/src/uploadInput/UploadInput.css +18 -1
  30. package/src/uploadInput/UploadInput.less +17 -1
  31. package/src/uploadInput/UploadInput.tests.story.tsx +13 -2
  32. package/src/uploadInput/uploadButton/UploadButton.css +4 -0
  33. package/src/uploadInput/uploadButton/UploadButton.less +5 -0
  34. package/src/uploadInput/uploadItem/UploadItem.css +43 -11
  35. package/src/uploadInput/uploadItem/UploadItem.less +61 -17
  36. package/src/dateInput/DateInput.rtl.spec.tsx +0 -17
  37. package/src/dateInput/DateInput.spec.js +0 -477
@@ -1,477 +0,0 @@
1
- import { shallow, mount } from 'enzyme';
2
- import { useIntl } from 'react-intl';
3
-
4
- import { DateInput } from '..';
5
- import { mockMatchMedia, mockResizeObserver } from '../test-utils';
6
-
7
- const LOCALES = {
8
- jp: 'ja-JP',
9
- us: 'en-US',
10
- };
11
- const DEFAULT_LOCALE = 'en-GB';
12
- const FEBRUARY_INDEX = 1;
13
- const AUGUST_INDEX = 7;
14
-
15
- const DAY_SELECTOR = 'ForwardRef(Input)[name="day"]';
16
- const MONTH_SELECTOR = 'SelectInput';
17
- const YEAR_SELECTOR = 'ForwardRef(Input)[name="year"]';
18
-
19
- jest.mock('./DateInput.messages', () => ({
20
- monthLabel: {
21
- id: 'neptune.DateInput.month.label',
22
- defaultMessage: 'Month',
23
- },
24
- dayLabel: {
25
- id: 'neptune.DateInput.day.label',
26
- defaultMessage: 'Day',
27
- },
28
- yearLabel: {
29
- id: 'neptune.DateInput.year.label',
30
- defaultMessage: 'Year',
31
- },
32
- dayPlaceholder: {
33
- id: 'neptune.DateInput.day.placeholder',
34
- defaultMessage: 'DD',
35
- description: 'Placeholder for 2-digit day values within an input.',
36
- },
37
- yearPlaceholder: {
38
- id: 'neptune.DateInput.year.placeholder',
39
- defaultMessage: 'YYYY',
40
- description: 'Placeholder for 4-digit year values within an input.',
41
- },
42
- }));
43
-
44
- jest.mock('react-intl');
45
-
46
- describe('Date Input Component', () => {
47
- let selectMonth;
48
- let inputDay;
49
- let inputYear;
50
- let component;
51
- const props = { onChange: jest.fn() };
52
-
53
- beforeEach(() => {
54
- mockMatchMedia();
55
- mockResizeObserver();
56
- useIntl.mockReturnValue({
57
- locale: DEFAULT_LOCALE,
58
- formatMessage: (message) => message.defaultMessage,
59
- });
60
- component = shallow(<DateInput {...props} />);
61
-
62
- selectMonth = component.find(MONTH_SELECTOR);
63
- inputDay = component.find(DAY_SELECTOR);
64
- inputYear = component.find(YEAR_SELECTOR);
65
- });
66
-
67
- afterEach(() => {
68
- jest.resetAllMocks();
69
- });
70
-
71
- describe('when initialised without a model', () => {
72
- it('sets day field to empty', () => {
73
- expect(inputDay.prop('value')).toBe('');
74
- });
75
-
76
- it('sets month field to 0', () => {
77
- expect(selectMonth.props().value).toBeNull();
78
- });
79
-
80
- it('sets year field to empty', () => {
81
- expect(inputYear.prop('value')).toBe('');
82
- });
83
-
84
- it('allows 0 prefixed day values', () => {
85
- inputDay.simulate('change', { target: { value: '0' } });
86
- setTimeout(() => {
87
- expect(inputDay.prop('value')).toBe('0');
88
- });
89
- });
90
-
91
- it('does not allow 00 as a day value', () => {
92
- inputDay.simulate('change', { target: { value: '00' } });
93
- setTimeout(() => {
94
- expect(inputDay.prop('value')).toBe('1');
95
- });
96
- });
97
- });
98
-
99
- describe('when initialised with a model', () => {
100
- describe('as a valid Date instance', () => {
101
- it(`sets values correctly`, () => {
102
- component = shallow(<DateInput {...props} value="1971-02-01" />);
103
-
104
- selectMonth = component.find(MONTH_SELECTOR);
105
- inputDay = component.find(DAY_SELECTOR);
106
- inputYear = component.find(YEAR_SELECTOR);
107
-
108
- expect(inputDay.prop('value')).toBe(1);
109
- expect(selectMonth.prop('value')).toBe(FEBRUARY_INDEX);
110
- expect(inputYear.prop('value')).toBe(1971);
111
- });
112
- });
113
-
114
- describe('as a valid short ISO8601 string', () => {
115
- it('sets values correctly', () => {
116
- component = shallow(<DateInput {...props} value="1990-08-22" />);
117
-
118
- selectMonth = component.find(MONTH_SELECTOR);
119
- inputDay = component.find(DAY_SELECTOR);
120
- inputYear = component.find(YEAR_SELECTOR);
121
-
122
- expect(inputDay.prop('value')).toBe(22);
123
- expect(selectMonth.prop('value')).toBe(AUGUST_INDEX);
124
- expect(inputYear.prop('value')).toBe(1990);
125
- });
126
- });
127
-
128
- describe('as a valid short ISO8601 string with year and month only', () => {
129
- it('sets values correctly', () => {
130
- component = shallow(<DateInput {...props} value="1990-08" />);
131
-
132
- selectMonth = component.find(MONTH_SELECTOR);
133
- inputDay = component.find(DAY_SELECTOR);
134
- inputYear = component.find(YEAR_SELECTOR);
135
-
136
- expect(inputDay.prop('value')).toBe('');
137
- expect(selectMonth.prop('value')).toBe(AUGUST_INDEX);
138
- expect(inputYear.prop('value')).toBe(1990);
139
- });
140
- });
141
-
142
- describe('as a valid long ISO8601 string', () => {
143
- it('sets values correctly', () => {
144
- component = shallow(<DateInput {...props} value="1990-02-28T00:00:00.000Z" />);
145
-
146
- selectMonth = component.find(MONTH_SELECTOR);
147
- inputDay = component.find(DAY_SELECTOR);
148
- inputYear = component.find(YEAR_SELECTOR);
149
-
150
- expect(inputDay.prop('value')).toBe(28);
151
- expect(selectMonth.prop('value')).toBe(FEBRUARY_INDEX);
152
- expect(inputYear.prop('value')).toBe(1990);
153
- });
154
- });
155
-
156
- describe('when disabled is set to true', () => {
157
- it('sets values to disabled', () => {
158
- component = shallow(<DateInput {...props} disabled />);
159
-
160
- selectMonth = component.find(MONTH_SELECTOR);
161
- inputDay = component.find(DAY_SELECTOR);
162
- inputYear = component.find(YEAR_SELECTOR);
163
-
164
- expect(inputDay.prop('disabled')).toBe(true);
165
- expect(selectMonth.prop('disabled')).toBe(true);
166
- expect(inputYear.prop('disabled')).toBe(true);
167
- });
168
- });
169
-
170
- describe('when disabled is set to false', () => {
171
- it("doesn't sets values to disabled", () => {
172
- component = shallow(<DateInput {...props} />);
173
-
174
- selectMonth = component.find(MONTH_SELECTOR);
175
- inputDay = component.find(DAY_SELECTOR);
176
- inputYear = component.find(YEAR_SELECTOR);
177
-
178
- expect(inputDay.prop('disabled')).toBe(false);
179
- expect(selectMonth.prop('disabled')).toBe(false);
180
- expect(inputYear.prop('disabled')).toBe(false);
181
- });
182
- });
183
- });
184
-
185
- describe('when locale is provided', () => {
186
- it('shows day before month if locale is GB', () => {
187
- useIntl.mockReturnValue({
188
- locale: DEFAULT_LOCALE,
189
- formatMessage: (message) => message.defaultMessage,
190
- });
191
-
192
- component = shallow(<DateInput {...props} />);
193
-
194
- expect(component.find('span').at(0).text()).toBe('Day');
195
- expect(component.find('span').at(1).text()).toBe('Month');
196
- expect(component.find('span').at(2).text()).toBe('Year');
197
- });
198
-
199
- it('shows month before day if locale is US', () => {
200
- useIntl.mockReturnValue({
201
- locale: LOCALES.us,
202
- formatMessage: (message) => message.defaultMessage,
203
- });
204
-
205
- component = shallow(<DateInput {...props} />);
206
-
207
- expect(component.find('span').at(0).text()).toBe('Month');
208
- expect(component.find('span').at(1).text()).toBe('Day');
209
- expect(component.find('span').at(2).text()).toBe('Year');
210
- });
211
-
212
- it('shows year, month, day if locale is JP', () => {
213
- useIntl.mockReturnValue({
214
- locale: LOCALES.jp,
215
- formatMessage: (message) => message.defaultMessage,
216
- });
217
-
218
- component = shallow(<DateInput {...props} />);
219
-
220
- expect(component.find('span').at(0).text()).toBe('Year');
221
- expect(component.find('span').at(1).text()).toBe('Month');
222
- expect(component.find('span').at(2).text()).toBe('Day');
223
- });
224
- });
225
-
226
- describe('when initialised', () => {
227
- describe('without an initial value', () => {
228
- it(`doesn't call the onChange callback`, () => {
229
- component = mount(<DateInput {...props} />);
230
-
231
- expect(props.onChange).not.toHaveBeenCalled();
232
- });
233
- });
234
-
235
- describe('with an initial value', () => {
236
- it(`doesn't call the onChange callback`, () => {
237
- component = mount(<DateInput {...props} value="1990-08" />);
238
-
239
- expect(props.onChange).not.toHaveBeenCalled();
240
- });
241
- });
242
-
243
- describe('with placeholders set', () => {
244
- it(`doesn't override placeholders`, () => {
245
- const placeholders = {
246
- day: 'DayPlaceholder',
247
- month: 'MonthPlaceholder',
248
- year: 'YearPlaceholder',
249
- };
250
- component = mount(<DateInput {...props} placeholders={placeholders} />);
251
-
252
- expect(component.find(DAY_SELECTOR).props().placeholder).toStrictEqual('DayPlaceholder');
253
- expect(component.find(MONTH_SELECTOR).props().placeholder).toStrictEqual(
254
- 'MonthPlaceholder',
255
- );
256
- expect(component.find(YEAR_SELECTOR).props().placeholder).toStrictEqual('YearPlaceholder');
257
- });
258
- });
259
-
260
- describe('with placeholders not set', () => {
261
- it('uses localized defaults', () => {
262
- component = mount(<DateInput {...props} />);
263
-
264
- expect(component.find(DAY_SELECTOR).props().placeholder).toStrictEqual('DD');
265
- expect(component.find(MONTH_SELECTOR).props().placeholder).toStrictEqual('Month');
266
- expect(component.find(YEAR_SELECTOR).props().placeholder).toStrictEqual('YYYY');
267
- });
268
- });
269
-
270
- describe('with labels set', () => {
271
- it(`doesn't override placeholders`, () => {
272
- component = mount(
273
- <DateInput
274
- {...props}
275
- dayLabel="dayLabel"
276
- monthLabel="monthLabel"
277
- yearLabel="yearLabel"
278
- />,
279
- );
280
-
281
- expect(component.find({ children: 'dayLabel', type: 'span' })).toBeTruthy();
282
- expect(component.find({ children: 'monthLabel', type: 'span' })).toBeTruthy();
283
- expect(component.find({ children: 'yearLabel', type: 'span' })).toBeTruthy();
284
- });
285
- });
286
-
287
- describe('with labels not set', () => {
288
- it('uses localized defaults', () => {
289
- component = mount(<DateInput {...props} />);
290
-
291
- expect(component.find({ children: 'Day', type: 'span' })).toBeTruthy();
292
- expect(component.find({ children: 'Month', type: 'span' })).toBeTruthy();
293
- expect(component.find({ children: 'Year', type: 'span' })).toBeTruthy();
294
- });
295
- });
296
- });
297
-
298
- describe('when user interacts', () => {
299
- describe('with an empty date input', () => {
300
- it('calls onChange with null if month is not selected', () => {
301
- component = mount(<DateInput {...props} />);
302
-
303
- inputDay = component.find(DAY_SELECTOR);
304
-
305
- inputDay.simulate('change', { target: { value: '12' } });
306
-
307
- inputYear = component.find(YEAR_SELECTOR);
308
-
309
- inputYear.simulate('change', { target: { value: '1990' } });
310
-
311
- expect(props.onChange).toHaveBeenLastCalledWith(null);
312
- });
313
- });
314
-
315
- describe('with day input', () => {
316
- it('returns correct value for correct input', () => {
317
- component = mount(<DateInput {...props} value="2001-02-11" />);
318
-
319
- inputDay = component.find(DAY_SELECTOR);
320
-
321
- inputDay.simulate('change', { target: { value: '12' } });
322
-
323
- expect(props.onChange).toHaveBeenCalledWith('2001-02-12');
324
- });
325
-
326
- it('returns null for invalid input', () => {
327
- component = mount(<DateInput {...props} value="2001-01-01" />);
328
-
329
- inputDay = component.find(DAY_SELECTOR);
330
-
331
- inputDay.simulate('change', { target: { value: 'aa' } });
332
-
333
- expect(props.onChange).toHaveBeenCalledWith(null);
334
- });
335
-
336
- it('returns null when day input is cleared', () => {
337
- component = mount(<DateInput {...props} value="2001-01-01" />);
338
-
339
- inputDay = component.find(DAY_SELECTOR);
340
-
341
- inputDay.simulate('change', { target: { value: '' } });
342
-
343
- expect(props.onChange).toHaveBeenLastCalledWith(null);
344
- });
345
- });
346
-
347
- describe('with year input', () => {
348
- it('returns correct value for correct input', () => {
349
- component = mount(<DateInput {...props} value="2001-01-01" />);
350
- inputYear = component.find(YEAR_SELECTOR);
351
-
352
- inputYear.simulate('change', { target: { value: '1990' } });
353
-
354
- expect(props.onChange).toHaveBeenCalledWith('1990-01-01');
355
- });
356
- });
357
- });
358
-
359
- describe('with day input and year input', () => {
360
- describe('when switching from day input to year input', () => {
361
- it('does not call onBlur nor onFocus', () => {
362
- const onFocus = jest.fn();
363
- const onBlur = jest.fn();
364
-
365
- component = mount(<DateInput {...props} onFocus={onFocus} onBlur={onBlur} />);
366
-
367
- inputDay = component.find(DAY_SELECTOR);
368
- inputYear = component.find(YEAR_SELECTOR);
369
-
370
- inputDay.simulate('focus');
371
-
372
- inputDay.simulate('blur', { relatedTarget: inputYear.getDOMNode() });
373
- inputYear.simulate('focus', { relatedTarget: inputDay.getDOMNode() });
374
- inputYear.simulate('blur');
375
-
376
- expect(onFocus).toHaveBeenCalledTimes(1);
377
- expect(onBlur).toHaveBeenCalledTimes(1);
378
-
379
- jest.useRealTimers();
380
- });
381
-
382
- it('does not call onBlur on IE11 either', () => {
383
- const onBlur = jest.fn();
384
-
385
- component = mount(<DateInput {...props} onBlur={onBlur} />);
386
-
387
- inputDay = component.find(DAY_SELECTOR);
388
- inputYear = component.find(YEAR_SELECTOR);
389
-
390
- inputDay.simulate('focus');
391
-
392
- Object.defineProperty(document, 'activeElement', {
393
- value: inputYear.getDOMNode(),
394
- });
395
-
396
- inputDay.simulate('blur', { relatedTarget: null });
397
- inputYear.simulate('focus', { relatedTarget: inputDay.getDOMNode() });
398
-
399
- expect(onBlur).not.toHaveBeenCalled();
400
-
401
- jest.useRealTimers();
402
- });
403
- });
404
- });
405
-
406
- describe('when user selects invalid dates', () => {
407
- it('corrects days in lap years February', () => {
408
- component = mount(<DateInput {...props} value="2000-02-29" />);
409
-
410
- expect(component.find(DAY_SELECTOR).prop('value')).toBe(29);
411
-
412
- inputYear = component.find(YEAR_SELECTOR);
413
- inputYear.simulate('change', { target: { value: 1999 } });
414
-
415
- expect(component.find(DAY_SELECTOR).prop('value')).toBe(28);
416
- });
417
-
418
- it('lowers days if value entered too high', () => {
419
- const comp = shallow(<DateInput {...props} />);
420
-
421
- inputDay = comp.find(DAY_SELECTOR);
422
-
423
- inputDay.simulate('change', { target: { value: 32 } });
424
-
425
- expect(comp.find(DAY_SELECTOR).prop('value')).toBe(31);
426
- });
427
-
428
- it('highers days if value entered too low', () => {
429
- const comp = shallow(<DateInput {...props} />);
430
-
431
- inputDay = comp.find(DAY_SELECTOR);
432
-
433
- inputDay.simulate('change', { target: { value: -1 } });
434
-
435
- expect(comp.find(DAY_SELECTOR).prop('value')).toBe(1);
436
- });
437
- });
438
-
439
- describe('when in mode month and year only', () => {
440
- beforeEach(() => {
441
- const extraProps = {
442
- mode: 'month-year',
443
- value: '2001-01-01',
444
- };
445
- component = mount(<DateInput {...{ ...props, ...extraProps }} />);
446
- });
447
-
448
- it('should only display month and year inputs', () => {
449
- expect(component.exists(YEAR_SELECTOR)).toBe(true);
450
- expect(component.exists(MONTH_SELECTOR)).toBe(true);
451
- expect(component.exists(DAY_SELECTOR)).toBe(false);
452
- });
453
- });
454
-
455
- describe('when selectProps is provided', () => {
456
- beforeEach(() => {
457
- component = shallow(
458
- <DateInput
459
- selectProps={{
460
- buttonProps: {
461
- 'aria-label': 'mock-button-label',
462
- },
463
- }}
464
- {...props}
465
- />,
466
- );
467
- });
468
-
469
- it('renders Select component with expected props', () => {
470
- const select = component.find(MONTH_SELECTOR);
471
-
472
- expect(select.prop('buttonProps')).toStrictEqual({
473
- 'aria-label': 'mock-button-label',
474
- });
475
- });
476
- });
477
- });