@transferwise/components 46.39.0 → 46.41.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.
- package/build/index.js +244 -493
- package/build/index.js.map +1 -1
- package/build/index.mjs +245 -494
- package/build/index.mjs.map +1 -1
- package/build/main.css +4 -2
- package/build/styles/main.css +4 -2
- package/build/styles/statusIcon/StatusIcon.css +4 -2
- package/build/types/dateInput/DateInput.d.ts.map +1 -1
- package/build/types/field/Field.d.ts +6 -1
- package/build/types/field/Field.d.ts.map +1 -1
- package/build/types/index.d.ts +2 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inlineAlert/InlineAlert.d.ts +2 -2
- package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
- package/build/types/processIndicator/ProcessIndicator.d.ts +1 -1
- package/build/types/processIndicator/ProcessIndicator.d.ts.map +1 -1
- package/build/types/upload/Upload.d.ts +91 -55
- package/build/types/upload/Upload.d.ts.map +1 -1
- package/build/types/upload/Upload.messages.d.ts +42 -60
- package/build/types/upload/Upload.messages.d.ts.map +1 -1
- package/build/types/upload/index.d.ts +2 -2
- package/build/types/upload/index.d.ts.map +1 -1
- package/build/types/upload/steps/completeStep/completeStep.d.ts +11 -18
- package/build/types/upload/steps/completeStep/completeStep.d.ts.map +1 -1
- package/build/types/upload/steps/completeStep/index.d.ts +2 -1
- package/build/types/upload/steps/completeStep/index.d.ts.map +1 -1
- package/build/types/upload/steps/index.d.ts +3 -4
- package/build/types/upload/steps/index.d.ts.map +1 -1
- package/build/types/upload/steps/processingStep/index.d.ts +2 -1
- package/build/types/upload/steps/processingStep/index.d.ts.map +1 -1
- package/build/types/upload/steps/processingStep/processingStep.d.ts +11 -13
- package/build/types/upload/steps/processingStep/processingStep.d.ts.map +1 -1
- package/build/types/upload/steps/uploadImageStep/index.d.ts +2 -1
- package/build/types/upload/steps/uploadImageStep/index.d.ts.map +1 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts +14 -18
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
- package/build/types/upload/utils/asyncFileRead/asyncFileRead.d.ts +1 -1
- package/build/types/upload/utils/asyncFileRead/asyncFileRead.d.ts.map +1 -1
- package/build/types/upload/utils/asyncFileRead/index.d.ts +1 -1
- package/build/types/upload/utils/asyncFileRead/index.d.ts.map +1 -1
- package/build/types/upload/utils/getFileType/getFileType.d.ts +1 -1
- package/build/types/upload/utils/getFileType/getFileType.d.ts.map +1 -1
- package/build/types/upload/utils/getFileType/index.d.ts +1 -1
- package/build/types/upload/utils/getFileType/index.d.ts.map +1 -1
- package/build/types/upload/utils/index.d.ts +5 -7
- package/build/types/upload/utils/index.d.ts.map +1 -1
- package/build/types/upload/utils/isSizeValid/index.d.ts +1 -1
- package/build/types/upload/utils/isSizeValid/index.d.ts.map +1 -1
- package/build/types/upload/utils/isSizeValid/isSizeValid.d.ts +1 -1
- package/build/types/upload/utils/isSizeValid/isSizeValid.d.ts.map +1 -1
- package/build/types/upload/utils/isTypeValid/index.d.ts +1 -1
- package/build/types/upload/utils/isTypeValid/index.d.ts.map +1 -1
- package/build/types/upload/utils/isTypeValid/isTypeValid.d.ts +1 -1
- package/build/types/upload/utils/isTypeValid/isTypeValid.d.ts.map +1 -1
- package/build/types/upload/utils/postData/index.d.ts +1 -1
- package/build/types/upload/utils/postData/index.d.ts.map +1 -1
- package/build/types/upload/utils/postData/postData.d.ts +11 -1
- package/build/types/upload/utils/postData/postData.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/dateInput/DateInput.spec.tsx +220 -0
- package/src/dateInput/DateInput.story.tsx +3 -76
- package/src/dateInput/DateInput.tests.story.tsx +238 -0
- package/src/dateInput/DateInput.tsx +50 -53
- package/src/field/Field.story.tsx +17 -36
- package/src/field/Field.tests.story.tsx +33 -0
- package/src/field/Field.tsx +23 -13
- package/src/index.ts +2 -1
- package/src/inlineAlert/InlineAlert.story.tsx +13 -5
- package/src/inlineAlert/InlineAlert.tsx +14 -7
- package/src/main.css +4 -2
- package/src/processIndicator/ProcessIndicator.tsx +1 -1
- package/src/statusIcon/StatusIcon.css +4 -2
- package/src/statusIcon/StatusIcon.less +4 -2
- package/src/statusIcon/StatusIcon.tsx +1 -1
- package/src/upload/Upload.spec.js +3 -14
- package/src/upload/Upload.story.tsx +37 -0
- package/src/upload/{Upload.js → Upload.tsx} +164 -169
- package/src/upload/index.ts +2 -0
- package/src/upload/steps/completeStep/completeStep.spec.js +3 -2
- package/src/upload/steps/completeStep/completeStep.tsx +74 -0
- package/src/upload/steps/completeStep/index.ts +2 -0
- package/src/upload/steps/{index.js → index.ts} +0 -1
- package/src/upload/steps/processingStep/index.ts +2 -0
- package/src/upload/steps/processingStep/processingStep.tsx +53 -0
- package/src/upload/steps/uploadImageStep/index.ts +2 -0
- package/src/upload/steps/uploadImageStep/{uploadImageStep.js → uploadImageStep.tsx} +17 -23
- package/src/upload/utils/asyncFileRead/asyncFileRead.spec.ts +14 -0
- package/src/upload/utils/asyncFileRead/asyncFileRead.ts +12 -0
- package/src/upload/utils/getFileType/getFileType.spec.ts +22 -0
- package/src/upload/utils/getFileType/getFileType.ts +16 -0
- package/src/upload/utils/{index.js → index.ts} +0 -2
- package/src/upload/utils/isSizeValid/{isSizeValid.spec.js → isSizeValid.spec.ts} +3 -3
- package/src/upload/utils/isSizeValid/isSizeValid.ts +3 -0
- package/src/upload/utils/isTypeValid/isTypeValid.spec.ts +62 -0
- package/src/upload/utils/isTypeValid/isTypeValid.ts +19 -0
- package/src/upload/utils/postData/postData.spec.ts +65 -0
- package/src/upload/utils/postData/postData.ts +36 -0
- package/src/uploadInput/UploadInput.tsx +1 -1
- package/build/types/upload/steps/mediaUploadStep/index.d.ts +0 -2
- package/build/types/upload/steps/mediaUploadStep/index.d.ts.map +0 -1
- package/build/types/upload/steps/mediaUploadStep/mediaUploadStep.d.ts +0 -24
- package/build/types/upload/steps/mediaUploadStep/mediaUploadStep.d.ts.map +0 -1
- package/build/types/upload/uploadSteps.d.ts +0 -5
- package/build/types/upload/uploadSteps.d.ts.map +0 -1
- package/build/types/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.d.ts +0 -2
- package/build/types/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.d.ts.map +0 -1
- package/build/types/upload/utils/getSupportedSpotMimeTypes/index.d.ts +0 -2
- package/build/types/upload/utils/getSupportedSpotMimeTypes/index.d.ts.map +0 -1
- package/build/types/upload/utils/requestMedia/index.d.ts +0 -2
- package/build/types/upload/utils/requestMedia/index.d.ts.map +0 -1
- package/build/types/upload/utils/requestMedia/requestMedia.d.ts +0 -2
- package/build/types/upload/utils/requestMedia/requestMedia.d.ts.map +0 -1
- package/src/dateInput/DateInput.rtl.spec.tsx +0 -17
- package/src/dateInput/DateInput.spec.js +0 -477
- package/src/upload/Upload.story.js +0 -36
- package/src/upload/index.js +0 -2
- package/src/upload/steps/completeStep/completeStep.js +0 -98
- package/src/upload/steps/completeStep/index.js +0 -1
- package/src/upload/steps/mediaUploadStep/index.js +0 -1
- package/src/upload/steps/mediaUploadStep/mediaUploadStep.js +0 -80
- package/src/upload/steps/mediaUploadStep/mediaUploadStep.spec.js +0 -77
- package/src/upload/steps/processingStep/index.js +0 -1
- package/src/upload/steps/processingStep/processingStep.js +0 -73
- package/src/upload/steps/uploadImageStep/index.js +0 -1
- package/src/upload/uploadSteps.ts +0 -5
- package/src/upload/utils/asyncFileRead/asyncFileRead.js +0 -11
- package/src/upload/utils/asyncFileRead/asyncFileRead.spec.js +0 -17
- package/src/upload/utils/getFileType/getFileType.js +0 -19
- package/src/upload/utils/getFileType/getFileType.spec.js +0 -33
- package/src/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.js +0 -18
- package/src/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.spec.js +0 -22
- package/src/upload/utils/getSupportedSpotMimeTypes/index.js +0 -1
- package/src/upload/utils/isSizeValid/isSizeValid.js +0 -1
- package/src/upload/utils/isTypeValid/isTypeValid.js +0 -26
- package/src/upload/utils/isTypeValid/isTypeValid.spec.js +0 -68
- package/src/upload/utils/postData/postData.js +0 -18
- package/src/upload/utils/postData/postData.spec.js +0 -109
- package/src/upload/utils/requestMedia/index.js +0 -1
- package/src/upload/utils/requestMedia/requestMedia.js +0 -26
- package/src/upload/utils/requestMedia/requestMedia.spec.js +0 -44
- /package/src/upload/{Upload.messages.js → Upload.messages.ts} +0 -0
- /package/src/upload/utils/asyncFileRead/{index.js → index.ts} +0 -0
- /package/src/upload/utils/getFileType/{index.js → index.ts} +0 -0
- /package/src/upload/utils/isSizeValid/{index.js → index.ts} +0 -0
- /package/src/upload/utils/isTypeValid/{index.js → index.ts} +0 -0
- /package/src/upload/utils/postData/{index.js → index.ts} +0 -0
|
@@ -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
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { action } from '@storybook/addon-actions';
|
|
2
|
-
import { boolean, number, select, text } from '@storybook/addon-knobs';
|
|
3
|
-
|
|
4
|
-
import Upload from '.';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
component: Upload,
|
|
8
|
-
title: 'Forms/Upload',
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const Basic = () => {
|
|
12
|
-
const size = select('size', ['sm', 'md', 'lg'], 'md');
|
|
13
|
-
const maxSize = number('max file size', 4000000);
|
|
14
|
-
const usAccept = text('accepted format', '*');
|
|
15
|
-
const usDisabled = boolean('disabled', false);
|
|
16
|
-
const psButtonDisabled = boolean('psButtonDisabled', false);
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<Upload
|
|
20
|
-
maxSize={maxSize}
|
|
21
|
-
size={size}
|
|
22
|
-
usAccept={usAccept}
|
|
23
|
-
usLabel="Front of your ID document"
|
|
24
|
-
usDisabled={usDisabled}
|
|
25
|
-
psButtonDisabled={psButtonDisabled}
|
|
26
|
-
httpOptions={{
|
|
27
|
-
url: 'https://httpbin.org/post',
|
|
28
|
-
method: 'POST',
|
|
29
|
-
}}
|
|
30
|
-
onStart={(file) => action('onStart', file)}
|
|
31
|
-
onSuccess={(httpResponse, fileName) => action('onSuccess', httpResponse, fileName)}
|
|
32
|
-
onFailure={(httpResponse) => action('onFailure', httpResponse)}
|
|
33
|
-
onCancel={() => action('onCancel')}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
};
|
package/src/upload/index.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { AlertCircle as AlertCircleIcon, Document as DocumentIcon } from '@transferwise/icons';
|
|
2
|
-
import { useTheme } from '@wise/components-theming';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
|
|
6
|
-
import { Priority, Typography } from '../../..';
|
|
7
|
-
import Body from '../../../body';
|
|
8
|
-
import Button from '../../../button';
|
|
9
|
-
import { Sentiment, Size } from '../../../common';
|
|
10
|
-
import StatusIcon from '../../../statusIcon';
|
|
11
|
-
import Title from '../../../title';
|
|
12
|
-
|
|
13
|
-
const CompleteStep = (props) => {
|
|
14
|
-
const { isModern } = useTheme();
|
|
15
|
-
const {
|
|
16
|
-
csButtonText,
|
|
17
|
-
csFailureText,
|
|
18
|
-
csSuccessText,
|
|
19
|
-
fileName,
|
|
20
|
-
isComplete,
|
|
21
|
-
isError,
|
|
22
|
-
isImage,
|
|
23
|
-
onClear,
|
|
24
|
-
uploadedImage,
|
|
25
|
-
} = props;
|
|
26
|
-
return (
|
|
27
|
-
<div className="droppable-complete-card droppable-card" aria-hidden={!isComplete}>
|
|
28
|
-
<div className="droppable-card-content">
|
|
29
|
-
<div
|
|
30
|
-
className="droppable-card-content d-flex flex-column align-items-center"
|
|
31
|
-
aria-live="polite"
|
|
32
|
-
>
|
|
33
|
-
{isError ? (
|
|
34
|
-
<>
|
|
35
|
-
{isModern ? (
|
|
36
|
-
<StatusIcon size={Size.LARGE} sentiment={Sentiment.NEGATIVE} />
|
|
37
|
-
) : (
|
|
38
|
-
<AlertCircleIcon size={24} className="text-negative" />
|
|
39
|
-
)}
|
|
40
|
-
{csFailureText && (
|
|
41
|
-
<p className={classNames('m-t-2', { 'm-b-0': isModern })}>{csFailureText}</p>
|
|
42
|
-
)}
|
|
43
|
-
</>
|
|
44
|
-
) : (
|
|
45
|
-
<>
|
|
46
|
-
{isImage && uploadedImage ? (
|
|
47
|
-
<img src={uploadedImage} alt="OK" className="thumbnail " />
|
|
48
|
-
) : (
|
|
49
|
-
<DocumentIcon />
|
|
50
|
-
)}
|
|
51
|
-
|
|
52
|
-
{fileName && (
|
|
53
|
-
<Body as="p" className="m-b-0">
|
|
54
|
-
{fileName}
|
|
55
|
-
</Body>
|
|
56
|
-
)}
|
|
57
|
-
{csSuccessText && (
|
|
58
|
-
<Title className="caption m-t-1" type={Typography.TITLE_BODY}>
|
|
59
|
-
{csSuccessText}
|
|
60
|
-
</Title>
|
|
61
|
-
)}
|
|
62
|
-
</>
|
|
63
|
-
)}
|
|
64
|
-
</div>
|
|
65
|
-
{csButtonText && (
|
|
66
|
-
<Button
|
|
67
|
-
priority={isModern ? Priority.PRIMARY : Priority.SECONDARY}
|
|
68
|
-
className={classNames({
|
|
69
|
-
'm-t-1': isModern && !isError,
|
|
70
|
-
'm-t-2': isModern && isError,
|
|
71
|
-
'm-t-3': !isModern,
|
|
72
|
-
})}
|
|
73
|
-
onClick={(event) => onClear(event)}
|
|
74
|
-
>
|
|
75
|
-
{csButtonText}
|
|
76
|
-
</Button>
|
|
77
|
-
)}
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
CompleteStep.propTypes = {
|
|
84
|
-
csButtonText: PropTypes.string.isRequired,
|
|
85
|
-
csSuccessText: PropTypes.string.isRequired,
|
|
86
|
-
csFailureText: PropTypes.string.isRequired,
|
|
87
|
-
fileName: PropTypes.string.isRequired,
|
|
88
|
-
isComplete: PropTypes.bool.isRequired,
|
|
89
|
-
isError: PropTypes.bool.isRequired,
|
|
90
|
-
isImage: PropTypes.bool.isRequired,
|
|
91
|
-
onClear: PropTypes.func.isRequired,
|
|
92
|
-
uploadedImage: PropTypes.string,
|
|
93
|
-
};
|
|
94
|
-
CompleteStep.defaultProps = {
|
|
95
|
-
uploadedImage: null,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
export default CompleteStep;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './completeStep';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './mediaUploadStep';
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { Upload as UploadIcon } from '@transferwise/icons';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
|
|
4
|
-
import Body from '../../../body';
|
|
5
|
-
import Button from '../../../button/Button';
|
|
6
|
-
import { Typography } from '../../../common';
|
|
7
|
-
import Title from '../../../title';
|
|
8
|
-
import { getSupportedSpotMimeTypes, requestMedia } from '../../utils';
|
|
9
|
-
|
|
10
|
-
const MediaUploadStep = ({
|
|
11
|
-
isComplete,
|
|
12
|
-
usAccept,
|
|
13
|
-
usButtonText,
|
|
14
|
-
usDisabled,
|
|
15
|
-
usHelpImage,
|
|
16
|
-
usLabel,
|
|
17
|
-
usPlaceholder,
|
|
18
|
-
fileDropped,
|
|
19
|
-
}) => {
|
|
20
|
-
const getMediaFile = () => {
|
|
21
|
-
const allowedMimeTypes = getSupportedSpotMimeTypes(usAccept);
|
|
22
|
-
|
|
23
|
-
if (allowedMimeTypes.length === 0) {
|
|
24
|
-
throw new Error('provided mimeTypes not supported');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const mediaRequest = { allowedMimeTypes };
|
|
28
|
-
requestMedia(mediaRequest).then((file) => fileDropped(file));
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const getImage = () => {
|
|
32
|
-
if (!usHelpImage) {
|
|
33
|
-
return (
|
|
34
|
-
<div className="circle circle-sm circle-inverse p-t-1">
|
|
35
|
-
<UploadIcon size={24} />
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (typeof usHelpImage === 'string') {
|
|
41
|
-
return <img src={usHelpImage} alt={usLabel} className="thumbnail text-xs-center" />;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return usHelpImage;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return (
|
|
48
|
-
<div>
|
|
49
|
-
<div className="droppable-default-card" aria-hidden={isComplete}>
|
|
50
|
-
<div className="droppable-card-content">
|
|
51
|
-
<div className="m-b-3">{getImage()}</div>
|
|
52
|
-
{usLabel && (
|
|
53
|
-
<Title type={Typography.TITLE_BODY} className="m-b-1">
|
|
54
|
-
{usLabel}
|
|
55
|
-
</Title>
|
|
56
|
-
)}
|
|
57
|
-
{usPlaceholder && (
|
|
58
|
-
<Body as="p" type={Typography.BODY_LARGE} className="m-b-3">{`${usPlaceholder}`}</Body>
|
|
59
|
-
)}
|
|
60
|
-
<Button disabled={usDisabled} onClick={getMediaFile}>
|
|
61
|
-
{usButtonText || <UploadIcon size={24} className="m-r-0" />}
|
|
62
|
-
</Button>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
MediaUploadStep.propTypes = {
|
|
70
|
-
fileDropped: PropTypes.func.isRequired,
|
|
71
|
-
isComplete: PropTypes.bool.isRequired,
|
|
72
|
-
usAccept: PropTypes.string.isRequired,
|
|
73
|
-
usButtonText: PropTypes.string.isRequired,
|
|
74
|
-
usDisabled: PropTypes.bool.isRequired,
|
|
75
|
-
usHelpImage: PropTypes.node.isRequired,
|
|
76
|
-
usLabel: PropTypes.string.isRequired,
|
|
77
|
-
usPlaceholder: PropTypes.string.isRequired,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export default MediaUploadStep;
|