@transferwise/components 0.0.0-experimental-be73f56 → 0.0.0-experimental-f304e2c
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/dateLookup/dateTrigger/DateTrigger.js +8 -4
- package/build/dateLookup/dateTrigger/DateTrigger.js.map +1 -1
- package/build/dateLookup/dateTrigger/DateTrigger.mjs +8 -4
- package/build/dateLookup/dateTrigger/DateTrigger.mjs.map +1 -1
- package/build/field/Field.js +13 -3
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.mjs +13 -3
- package/build/field/Field.mjs.map +1 -1
- package/build/i18n/en.json +3 -2
- package/build/i18n/en.json.js +3 -2
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +3 -2
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/inlineAlert/InlineAlert.js +4 -6
- package/build/inlineAlert/InlineAlert.js.map +1 -1
- package/build/inlineAlert/InlineAlert.mjs +4 -6
- package/build/inlineAlert/InlineAlert.mjs.map +1 -1
- package/build/label/Label.js +29 -1
- package/build/label/Label.js.map +1 -1
- package/build/label/Label.messages.js +15 -0
- package/build/label/Label.messages.js.map +1 -0
- package/build/label/Label.messages.mjs +13 -0
- package/build/label/Label.messages.mjs.map +1 -0
- package/build/label/Label.mjs +30 -2
- package/build/label/Label.mjs.map +1 -1
- package/build/main.css +4 -14
- package/build/styles/dateLookup/dateTrigger/DateTrigger.css +0 -8
- package/build/styles/field/Field.css +4 -0
- package/build/styles/main.css +4 -14
- package/build/styles/upload/Upload.css +0 -6
- package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts.map +1 -1
- package/build/types/field/Field.d.ts +4 -2
- package/build/types/field/Field.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
- package/build/types/label/Label.d.ts +10 -1
- package/build/types/label/Label.d.ts.map +1 -1
- package/build/types/label/Label.messages.d.ts +12 -0
- package/build/types/label/Label.messages.d.ts.map +1 -0
- package/build/types/label/index.d.ts +3 -0
- package/build/types/label/index.d.ts.map +1 -0
- package/build/types/upload/Upload.d.ts +0 -1
- package/build/types/upload/Upload.d.ts.map +1 -1
- package/build/types/upload/Upload.messages.d.ts +0 -4
- package/build/types/upload/Upload.messages.d.ts.map +1 -1
- package/build/types/upload/steps/completeStep/completeStep.d.ts +3 -1
- package/build/types/upload/steps/completeStep/completeStep.d.ts.map +1 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts +0 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
- package/build/upload/Upload.js +12 -26
- package/build/upload/Upload.js.map +1 -1
- package/build/upload/Upload.messages.js +0 -3
- package/build/upload/Upload.messages.js.map +1 -1
- package/build/upload/Upload.messages.mjs +0 -3
- package/build/upload/Upload.messages.mjs.map +1 -1
- package/build/upload/Upload.mjs +12 -26
- package/build/upload/Upload.mjs.map +1 -1
- package/build/upload/steps/completeStep/completeStep.js +30 -15
- package/build/upload/steps/completeStep/completeStep.js.map +1 -1
- package/build/upload/steps/completeStep/completeStep.mjs +31 -16
- package/build/upload/steps/completeStep/completeStep.mjs.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.js +32 -56
- package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +32 -56
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
- package/package.json +3 -3
- package/src/dateInput/DateInput.tests.story.tsx +7 -31
- package/src/dateLookup/DateLookup.rtl.spec.tsx +1 -1
- package/src/dateLookup/dateTrigger/DateTrigger.css +0 -8
- package/src/dateLookup/dateTrigger/DateTrigger.less +0 -8
- package/src/dateLookup/dateTrigger/DateTrigger.spec.js +1 -1
- package/src/dateLookup/dateTrigger/DateTrigger.tsx +9 -4
- package/src/field/Field.css +4 -0
- package/src/field/Field.less +5 -0
- package/src/field/Field.spec.tsx +3 -3
- package/src/field/Field.story.tsx +106 -7
- package/src/field/Field.tsx +12 -6
- package/src/i18n/en.json +3 -2
- package/src/index.ts +1 -1
- package/src/inlineAlert/InlineAlert.story.tsx +8 -72
- package/src/inlineAlert/InlineAlert.tsx +5 -3
- package/src/inputs/InputGroup.spec.tsx +1 -1
- package/src/inputs/SearchInput.spec.tsx +1 -1
- package/src/inputs/SelectInput.spec.tsx +1 -1
- package/src/label/Label.messages.tsx +12 -0
- package/src/label/Label.story.tsx +19 -25
- package/src/label/Label.tsx +38 -2
- package/src/label/index.ts +2 -0
- package/src/main.css +4 -14
- package/src/main.less +1 -0
- package/src/moneyInput/MoneyInput.story.tsx +0 -2
- package/src/radioGroup/RadioGroup.rtl.spec.tsx +1 -1
- package/src/select/Select.rtl.spec.tsx +1 -1
- package/src/switch/Switch.spec.tsx +1 -1
- package/src/upload/Upload.css +0 -6
- package/src/upload/Upload.less +0 -5
- package/src/upload/Upload.messages.ts +0 -4
- package/src/upload/Upload.spec.js +7 -8
- package/src/upload/Upload.story.tsx +0 -18
- package/src/upload/Upload.tsx +20 -39
- package/src/upload/steps/completeStep/completeStep.spec.js +9 -0
- package/src/upload/steps/completeStep/completeStep.tsx +29 -14
- package/src/upload/steps/uploadImageStep/uploadImageStep.spec.js +0 -12
- package/src/upload/steps/uploadImageStep/uploadImageStep.tsx +24 -43
- package/src/field/Field.tests.story.tsx +0 -33
|
@@ -2,9 +2,9 @@ import { select, text } from '@storybook/addon-knobs';
|
|
|
2
2
|
import { Meta } from '@storybook/react';
|
|
3
3
|
|
|
4
4
|
import { Sentiment } from '../common';
|
|
5
|
-
import { Input } from '../inputs/Input';
|
|
6
5
|
|
|
7
6
|
import InlineAlert, { InlineAlertProps } from './InlineAlert';
|
|
7
|
+
import { lorem40 } from '../test-utils';
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
component: InlineAlert,
|
|
@@ -29,81 +29,17 @@ export const Basic = () => {
|
|
|
29
29
|
|
|
30
30
|
const message = text('message', 'Please enter a password over 5 characters');
|
|
31
31
|
|
|
32
|
-
let typeClass = '';
|
|
33
|
-
switch (type) {
|
|
34
|
-
case Sentiment.ERROR:
|
|
35
|
-
case Sentiment.NEGATIVE:
|
|
36
|
-
typeClass = 'has-error';
|
|
37
|
-
break;
|
|
38
|
-
case Sentiment.SUCCESS:
|
|
39
|
-
case Sentiment.POSITIVE:
|
|
40
|
-
typeClass = 'has-success';
|
|
41
|
-
break;
|
|
42
|
-
case Sentiment.INFO:
|
|
43
|
-
case Sentiment.NEUTRAL:
|
|
44
|
-
typeClass = 'has-info';
|
|
45
|
-
break;
|
|
46
|
-
case Sentiment.WARNING:
|
|
47
|
-
typeClass = 'has-warning';
|
|
48
|
-
break;
|
|
49
|
-
case Sentiment.PENDING:
|
|
50
|
-
}
|
|
51
|
-
|
|
52
32
|
return (
|
|
53
33
|
<>
|
|
54
|
-
{/* eslint-disable-next-line react/no-adjacent-inline-elements */}
|
|
55
|
-
<p>
|
|
56
|
-
The styling for the input (the coloured border) and the visibility of the inline alert is
|
|
57
|
-
controlled through the use of <code>has-***</code> classes which are applied to the{' '}
|
|
58
|
-
<code>form-group</code> element. For example, to display an inline alert of type error, you
|
|
59
|
-
must also apply the class <code>has-error</code> to the parent <code>form-group</code>{' '}
|
|
60
|
-
element. The available classes are <code>has-error</code>, <code>has-info</code>,{' '}
|
|
61
|
-
<code>has-warning</code> and <code>has-success</code>.
|
|
62
|
-
</p>
|
|
63
34
|
<p>
|
|
64
|
-
|
|
65
|
-
<
|
|
66
|
-
|
|
35
|
+
Avoid using <code>InlineAlert</code> directly (unless for some custom use cases), for form
|
|
36
|
+
control validation, info messaging please use <code>Field</code> component
|
|
37
|
+
<pre>{'<Field sentiment={..} message={..}>'}</pre>
|
|
67
38
|
</p>
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<Input id="id0" value="Neptune is cool" />
|
|
73
|
-
<InlineAlert type={type}>{message}</InlineAlert>
|
|
74
|
-
</div>
|
|
75
|
-
<div className="form-group has-error">
|
|
76
|
-
<label className="control-label" htmlFor="id1">
|
|
77
|
-
Negative
|
|
78
|
-
</label>
|
|
79
|
-
<Input id="id1" value="Neptune is cool" />
|
|
80
|
-
<InlineAlert type="negative">{message}</InlineAlert>
|
|
81
|
-
</div>
|
|
82
|
-
<div className="form-group has-success">
|
|
83
|
-
<label className="control-label" htmlFor="id2">
|
|
84
|
-
Positive
|
|
85
|
-
</label>
|
|
86
|
-
<Input id="id2" value="Neptune is cool" />
|
|
87
|
-
<InlineAlert type="positive">
|
|
88
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
|
|
89
|
-
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
|
90
|
-
ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
91
|
-
</InlineAlert>
|
|
92
|
-
</div>
|
|
93
|
-
<div className="form-group has-neutral">
|
|
94
|
-
<label className="control-label" htmlFor="id3">
|
|
95
|
-
Neutral
|
|
96
|
-
</label>
|
|
97
|
-
<Input id="id3" value="Neptune is cool" />
|
|
98
|
-
<InlineAlert type="neutral">{message}</InlineAlert>
|
|
99
|
-
</div>
|
|
100
|
-
<div className="form-group">
|
|
101
|
-
<label className="control-label" htmlFor="id4">
|
|
102
|
-
No has-* class
|
|
103
|
-
</label>
|
|
104
|
-
<Input id="id4" value="Neptune is cool" />
|
|
105
|
-
<InlineAlert type="negative">{message}</InlineAlert>
|
|
106
|
-
</div>
|
|
39
|
+
<InlineAlert type={type}>{message}</InlineAlert>
|
|
40
|
+
<InlineAlert type="negative">{message}</InlineAlert>
|
|
41
|
+
<InlineAlert type="positive">{lorem40}</InlineAlert>
|
|
42
|
+
<InlineAlert type="negative">{message}</InlineAlert>
|
|
107
43
|
</>
|
|
108
44
|
);
|
|
109
45
|
};
|
|
@@ -3,6 +3,7 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
|
|
4
4
|
import { Sentiment, Size } from '../common';
|
|
5
5
|
import StatusIcon from '../statusIcon';
|
|
6
|
+
import Body from '../body';
|
|
6
7
|
|
|
7
8
|
export interface InlineAlertProps {
|
|
8
9
|
id?: string;
|
|
@@ -26,17 +27,18 @@ export default function InlineAlert({
|
|
|
26
27
|
children,
|
|
27
28
|
}: InlineAlertProps) {
|
|
28
29
|
return (
|
|
29
|
-
<
|
|
30
|
+
<Body
|
|
30
31
|
role="alert"
|
|
31
32
|
id={id}
|
|
32
33
|
className={clsx(
|
|
33
34
|
'alert alert-detach',
|
|
34
35
|
`alert-${type === Sentiment.NEGATIVE || type === Sentiment.ERROR ? 'danger' : type}`,
|
|
36
|
+
'd-flex',
|
|
35
37
|
className,
|
|
36
38
|
)}
|
|
37
39
|
>
|
|
38
40
|
{iconTypes.has(type) && <StatusIcon sentiment={type} size={Size.SMALL} />}
|
|
39
|
-
|
|
40
|
-
</
|
|
41
|
+
{children}
|
|
42
|
+
</Body>
|
|
41
43
|
);
|
|
42
44
|
}
|
|
@@ -214,6 +214,6 @@ describe('SelectInput', () => {
|
|
|
214
214
|
<SelectInput items={[{ type: 'option', value: 'USD' }]} value="USD" />
|
|
215
215
|
</Field>,
|
|
216
216
|
);
|
|
217
|
-
expect(screen.getByLabelText(
|
|
217
|
+
expect(screen.getByLabelText(/Currency/)).toHaveAttribute('aria-haspopup');
|
|
218
218
|
});
|
|
219
219
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
export default defineMessages({
|
|
4
|
+
optionalLabel: {
|
|
5
|
+
id: 'neptune.Label.optional',
|
|
6
|
+
defaultMessage: '(Optional)',
|
|
7
|
+
},
|
|
8
|
+
optionalAriaLabel: {
|
|
9
|
+
id: 'neptune.aria.Label.optional',
|
|
10
|
+
defaultMessage: 'This field is optional',
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import Info from '../info/Info';
|
|
4
|
-
import { Input } from '../inputs/Input';
|
|
5
1
|
import { Label } from './Label';
|
|
6
2
|
|
|
7
3
|
export default {
|
|
8
4
|
component: Label,
|
|
9
5
|
title: 'Label',
|
|
6
|
+
tags: ['autodocs'],
|
|
10
7
|
};
|
|
11
8
|
|
|
12
9
|
export const Basic = () => {
|
|
13
|
-
const [value, setValue] = useState<string | undefined>('This is some text');
|
|
14
10
|
return (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
11
|
+
<>
|
|
12
|
+
<p>
|
|
13
|
+
Avoid using <code>Label</code> component directly (unless for some custom use cases), for
|
|
14
|
+
form control labels and descriptions / info messages, please use <code>Field</code>{' '}
|
|
15
|
+
component
|
|
16
|
+
<pre>{'<Field label={..} description={..} required={..}>'}</pre>
|
|
17
|
+
</p>
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</span>
|
|
34
|
-
<Input value={value} id="input" onChange={({ target }) => setValue(target.value)} />
|
|
35
|
-
</Label>
|
|
19
|
+
<Label className="m-b-2">Text Input</Label>
|
|
20
|
+
|
|
21
|
+
<Label className="m-b-2">
|
|
22
|
+
<Label.Optional>Text Input</Label.Optional>
|
|
23
|
+
</Label>
|
|
24
|
+
|
|
25
|
+
<Label className="m-b-2">
|
|
26
|
+
<Label.Optional>Text Input with Description</Label.Optional>
|
|
27
|
+
<Label.Description>This a field Description</Label.Description>
|
|
28
|
+
</Label>
|
|
29
|
+
</>
|
|
36
30
|
);
|
|
37
31
|
};
|
package/src/label/Label.tsx
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
+
import messages from './Label.messages';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import Body from '../body';
|
|
5
|
+
import { CommonProps } from '../common';
|
|
6
|
+
import { PropsWithChildren } from 'react';
|
|
2
7
|
|
|
3
8
|
export type LabelProps = {
|
|
4
9
|
id?: string;
|
|
@@ -7,14 +12,45 @@ export type LabelProps = {
|
|
|
7
12
|
children?: React.ReactNode;
|
|
8
13
|
};
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
const Label = ({ id, htmlFor, className, children }: LabelProps) => {
|
|
11
16
|
return (
|
|
12
17
|
<label
|
|
13
18
|
id={id}
|
|
14
19
|
htmlFor={htmlFor}
|
|
15
|
-
className={clsx(
|
|
20
|
+
className={clsx(
|
|
21
|
+
'np-label d-flex flex-column m-b-0 np-text-body-default-bold text-primary',
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
16
24
|
>
|
|
17
25
|
{children}
|
|
18
26
|
</label>
|
|
19
27
|
);
|
|
20
28
|
};
|
|
29
|
+
|
|
30
|
+
export type LabelOptionalProps = PropsWithChildren<CommonProps>;
|
|
31
|
+
|
|
32
|
+
const Optional = ({ children, className }: LabelOptionalProps) => {
|
|
33
|
+
const { formatMessage } = useIntl();
|
|
34
|
+
return (
|
|
35
|
+
<div>
|
|
36
|
+
{children}
|
|
37
|
+
<Body
|
|
38
|
+
as="span"
|
|
39
|
+
aria-label={formatMessage(messages.optionalAriaLabel)}
|
|
40
|
+
className={clsx('text-secondary', 'm-l-1', className)}
|
|
41
|
+
>
|
|
42
|
+
{formatMessage(messages.optionalLabel)}
|
|
43
|
+
</Body>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type LabelDescriptionProps = PropsWithChildren<CommonProps>;
|
|
49
|
+
|
|
50
|
+
const Description = ({ children, className }: LabelDescriptionProps) =>
|
|
51
|
+
children ? <Body className={clsx('text-secondary', className)}>{children}</Body> : null;
|
|
52
|
+
|
|
53
|
+
Label.Optional = Optional;
|
|
54
|
+
Label.Description = Description;
|
|
55
|
+
|
|
56
|
+
export { Label };
|
package/src/main.css
CHANGED
|
@@ -1719,18 +1719,10 @@ button.np-option {
|
|
|
1719
1719
|
white-space: nowrap;
|
|
1720
1720
|
width: 100%;
|
|
1721
1721
|
}
|
|
1722
|
-
.np-date-trigger .control-label {
|
|
1723
|
-
font-weight: 400;
|
|
1724
|
-
font-weight: var(--font-weight-regular);
|
|
1725
|
-
}
|
|
1726
1722
|
.np-theme-personal .np-date-trigger {
|
|
1727
1723
|
padding-left: 16px;
|
|
1728
1724
|
padding-left: var(--size-16);
|
|
1729
1725
|
}
|
|
1730
|
-
.np-theme-personal .np-date-trigger .control-label + span {
|
|
1731
|
-
font-weight: 400;
|
|
1732
|
-
font-weight: var(--font-weight-regular);
|
|
1733
|
-
}
|
|
1734
1726
|
.clear-btn {
|
|
1735
1727
|
transition: color 0.15s ease-in-out;
|
|
1736
1728
|
color: #c9cbce;
|
|
@@ -2385,6 +2377,10 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
2385
2377
|
border-radius: 9999px !important;
|
|
2386
2378
|
border-radius: var(--radius-full) !important;
|
|
2387
2379
|
}
|
|
2380
|
+
.np-field-control {
|
|
2381
|
+
margin-top: 4px;
|
|
2382
|
+
margin-top: var(--size-4);
|
|
2383
|
+
}
|
|
2388
2384
|
.np-input-group {
|
|
2389
2385
|
display: inline-grid;
|
|
2390
2386
|
width: 100%;
|
|
@@ -5444,12 +5440,6 @@ html:not([dir="rtl"]) .np-navigation-option {
|
|
|
5444
5440
|
.tw-droppable-sm {
|
|
5445
5441
|
min-height: 245px;
|
|
5446
5442
|
}
|
|
5447
|
-
.upload-error-message {
|
|
5448
|
-
margin-top: 24px;
|
|
5449
|
-
margin-top: var(--padding-medium);
|
|
5450
|
-
border-top: 1px solid rgba(0,0,0,0.10196);
|
|
5451
|
-
border-top: 1px solid var(--color-border-neutral);
|
|
5452
|
-
}
|
|
5453
5443
|
.np-upload-button-container {
|
|
5454
5444
|
border-style: solid;
|
|
5455
5445
|
}
|
package/src/main.less
CHANGED
|
@@ -4,8 +4,6 @@ import { Lock } from '@transferwise/icons';
|
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
|
|
6
6
|
import MoneyInput, { CurrencyOptionItem } from '.';
|
|
7
|
-
import Provider from '../provider/Provider';
|
|
8
|
-
import translations from '../i18n';
|
|
9
7
|
|
|
10
8
|
export default {
|
|
11
9
|
component: MoneyInput,
|
|
@@ -12,6 +12,6 @@ describe('Select', () => {
|
|
|
12
12
|
<Select options={options} selected={options[0]} onChange={() => {}} />
|
|
13
13
|
</Field>,
|
|
14
14
|
);
|
|
15
|
-
expect(screen.getByLabelText(
|
|
15
|
+
expect(screen.getByLabelText(/Currency/)).toHaveTextContent('USD');
|
|
16
16
|
});
|
|
17
17
|
});
|
|
@@ -89,6 +89,6 @@ describe('Switch', () => {
|
|
|
89
89
|
<Switch checked onClick={props.onClick} />
|
|
90
90
|
</Field>,
|
|
91
91
|
);
|
|
92
|
-
expect(screen.getByLabelText(
|
|
92
|
+
expect(screen.getByLabelText(/Dark mode/)).toHaveAttribute('role', 'switch');
|
|
93
93
|
});
|
|
94
94
|
});
|
package/src/upload/Upload.css
CHANGED
package/src/upload/Upload.less
CHANGED
|
@@ -46,7 +46,6 @@ const props = {
|
|
|
46
46
|
psProcessingText: 'psProcessingText',
|
|
47
47
|
usAccept: 'image/*',
|
|
48
48
|
usButtonText: 'Or Select File',
|
|
49
|
-
usButtonRetryText: 'Try again',
|
|
50
49
|
usDropMessage: 'Drop file to start upload',
|
|
51
50
|
usPlaceholder: 'Drag and drop a file less than 5MB',
|
|
52
51
|
};
|
|
@@ -232,7 +231,7 @@ describe('Upload', () => {
|
|
|
232
231
|
expect(component.find(CompleteStep)).toHaveLength(1);
|
|
233
232
|
});
|
|
234
233
|
|
|
235
|
-
it('step
|
|
234
|
+
it('step CompleteStep is called with error props', async () => {
|
|
236
235
|
component = mount(<Upload {...props} />);
|
|
237
236
|
const upload = component.children();
|
|
238
237
|
asyncFileRead.mockImplementation(async () => {
|
|
@@ -245,12 +244,12 @@ describe('Upload', () => {
|
|
|
245
244
|
await waitForUpload();
|
|
246
245
|
component.update();
|
|
247
246
|
|
|
248
|
-
expect(component.find(
|
|
249
|
-
...
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
247
|
+
expect(component.find(CompleteStep).props()).toStrictEqual({
|
|
248
|
+
...COMPLETED_STEP_PROPS,
|
|
249
|
+
isImage: false,
|
|
250
|
+
isComplete: true,
|
|
251
|
+
isError: true,
|
|
252
|
+
uploadedImage: undefined,
|
|
254
253
|
});
|
|
255
254
|
});
|
|
256
255
|
|
|
@@ -6,7 +6,6 @@ import { MAX_SIZE_DEFAULT } from './Upload';
|
|
|
6
6
|
|
|
7
7
|
const meta = {
|
|
8
8
|
component: Upload,
|
|
9
|
-
title: 'Forms/Upload',
|
|
10
9
|
tags: ['autodocs'],
|
|
11
10
|
argTypes: {
|
|
12
11
|
maxSize: {
|
|
@@ -36,20 +35,3 @@ export const Basic = {
|
|
|
36
35
|
onCancel: fn(),
|
|
37
36
|
},
|
|
38
37
|
} satisfies Story;
|
|
39
|
-
|
|
40
|
-
export const Loading = {
|
|
41
|
-
args: {
|
|
42
|
-
animationDelay: 10000000000,
|
|
43
|
-
maxSize: MAX_SIZE_DEFAULT,
|
|
44
|
-
usAccept: 'image/*',
|
|
45
|
-
usLabel: 'Front of your ID document',
|
|
46
|
-
httpOptions: {
|
|
47
|
-
url: 'https://httpbin.org/post',
|
|
48
|
-
method: 'POST',
|
|
49
|
-
},
|
|
50
|
-
onStart: fn(),
|
|
51
|
-
onSuccess: fn(),
|
|
52
|
-
onFailure: fn(),
|
|
53
|
-
onCancel: fn(),
|
|
54
|
-
},
|
|
55
|
-
} satisfies Story;
|
package/src/upload/Upload.tsx
CHANGED
|
@@ -50,7 +50,6 @@ export interface UploadProps extends WrappedComponentProps {
|
|
|
50
50
|
*/
|
|
51
51
|
usAccept?: string;
|
|
52
52
|
usButtonText?: string;
|
|
53
|
-
usButtonRetryText?: string;
|
|
54
53
|
usDisabled?: boolean;
|
|
55
54
|
usDropMessage?: string;
|
|
56
55
|
usHelpImage?: React.ReactNode;
|
|
@@ -326,7 +325,6 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
326
325
|
usDropMessage,
|
|
327
326
|
usAccept,
|
|
328
327
|
usButtonText,
|
|
329
|
-
usButtonRetryText,
|
|
330
328
|
usDisabled,
|
|
331
329
|
usHelpImage,
|
|
332
330
|
usLabel,
|
|
@@ -361,8 +359,8 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
361
359
|
'tw-droppable-lg droppable-lg': size === 'lg',
|
|
362
360
|
'droppable-dropping': isDroppable,
|
|
363
361
|
'droppable-processing': isProcessing,
|
|
364
|
-
'droppable-complete': isComplete
|
|
365
|
-
'droppable-negative': isError
|
|
362
|
+
'droppable-complete': isComplete,
|
|
363
|
+
'droppable-negative': isError,
|
|
366
364
|
})}
|
|
367
365
|
onDragEnter={(event) => this.onDragEnter(event)}
|
|
368
366
|
onDragLeave={(event) => this.onDragLeave(event)}
|
|
@@ -385,36 +383,28 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
385
383
|
/>
|
|
386
384
|
)}
|
|
387
385
|
|
|
388
|
-
{
|
|
386
|
+
{isProcessing && (
|
|
387
|
+
<ProcessingStep
|
|
388
|
+
isComplete={isComplete}
|
|
389
|
+
isError={isError}
|
|
390
|
+
isSuccess={isSuccess}
|
|
391
|
+
psButtonText={psButtonText || intl.formatMessage(messages.psButtonText)}
|
|
392
|
+
psProcessingText={psProcessingText || intl.formatMessage(messages.psProcessingText)}
|
|
393
|
+
psButtonDisabled={psButtonDisabled}
|
|
394
|
+
onAnimationCompleted={async (status) => this.onAnimationCompleted(status)}
|
|
395
|
+
onClear={(event) => this.handleOnClear(event)}
|
|
396
|
+
/>
|
|
397
|
+
)}
|
|
398
|
+
{/* Starts render the step when isSuccess or isError are true so markup is there when css transition kicks in
|
|
389
399
|
css transition to work properly */}
|
|
390
|
-
{(isSuccess || isComplete) &&
|
|
400
|
+
{(isSuccess || isError || isComplete) && (
|
|
391
401
|
<CompleteStep
|
|
392
402
|
fileName={fileName}
|
|
393
403
|
isComplete={isComplete}
|
|
404
|
+
isError={isError}
|
|
394
405
|
isImage={isImage}
|
|
395
406
|
csButtonText={csButtonText || intl.formatMessage(messages.csButtonText)}
|
|
396
|
-
|
|
397
|
-
uploadedImage={uploadedImage}
|
|
398
|
-
onClear={(event) => this.handleOnClear(event)}
|
|
399
|
-
/>
|
|
400
|
-
)}
|
|
401
|
-
{isError && !isProcessing && (
|
|
402
|
-
<UploadImageStep
|
|
403
|
-
fileDropped={async (file) => {
|
|
404
|
-
this.reset();
|
|
405
|
-
await this.fileDropped(file);
|
|
406
|
-
}}
|
|
407
|
-
isComplete={!isError}
|
|
408
|
-
usAccept={usAccept}
|
|
409
|
-
usButtonText={usButtonRetryText || intl.formatMessage(messages.retry)}
|
|
410
|
-
usDisabled={usDisabled}
|
|
411
|
-
usHelpImage={null}
|
|
412
|
-
usLabel={usLabel}
|
|
413
|
-
usPlaceholder={
|
|
414
|
-
usPlaceholder ||
|
|
415
|
-
intl.formatMessage(messages.usPlaceholder, { maxSize: maxSize / 1000000 })
|
|
416
|
-
}
|
|
417
|
-
errorMessage={this.getErrorMessage(
|
|
407
|
+
csFailureText={this.getErrorMessage(
|
|
418
408
|
response != null &&
|
|
419
409
|
typeof response === 'object' &&
|
|
420
410
|
'status' in response &&
|
|
@@ -422,17 +412,8 @@ export class Upload extends Component<UploadProps, UploadState> {
|
|
|
422
412
|
? response.status
|
|
423
413
|
: undefined,
|
|
424
414
|
)}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
{isProcessing && (
|
|
428
|
-
<ProcessingStep
|
|
429
|
-
isComplete={isComplete}
|
|
430
|
-
isError={isError}
|
|
431
|
-
isSuccess={isSuccess}
|
|
432
|
-
psButtonText={psButtonText || intl.formatMessage(messages.psButtonText)}
|
|
433
|
-
psProcessingText={psProcessingText || intl.formatMessage(messages.psProcessingText)}
|
|
434
|
-
psButtonDisabled={psButtonDisabled}
|
|
435
|
-
onAnimationCompleted={async (status) => this.onAnimationCompleted(status)}
|
|
415
|
+
csSuccessText={csSuccessText || intl.formatMessage(messages.csSuccessText)}
|
|
416
|
+
uploadedImage={uploadedImage}
|
|
436
417
|
onClear={(event) => this.handleOnClear(event)}
|
|
437
418
|
/>
|
|
438
419
|
)}
|
|
@@ -3,6 +3,7 @@ import { shallow } from 'enzyme';
|
|
|
3
3
|
|
|
4
4
|
import Body from '../../../body';
|
|
5
5
|
import Button from '../../../button';
|
|
6
|
+
import StatusIcon from '../../../statusIcon/StatusIcon';
|
|
6
7
|
|
|
7
8
|
import CompleteStep from '.';
|
|
8
9
|
|
|
@@ -40,6 +41,14 @@ describe('CompleteStep', () => {
|
|
|
40
41
|
});
|
|
41
42
|
});
|
|
42
43
|
|
|
44
|
+
describe('when error is true', () => {
|
|
45
|
+
it('renders errorMessage and icon when error is true', () => {
|
|
46
|
+
component = shallow(<CompleteStep {...COMPLETED_STEP_PROPS} isError />);
|
|
47
|
+
expect(component.find('p').text()).toBe(COMPLETED_STEP_PROPS.csFailureText);
|
|
48
|
+
expect(component.find(StatusIcon)).toHaveLength(1);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
43
52
|
it('renders button when csButtonText is set up', () => {
|
|
44
53
|
expect(component.find(Button)).toHaveLength(1);
|
|
45
54
|
});
|