@transferwise/components 0.0.0-experimental-438bbba → 0.0.0-experimental-cf33ac7

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 (61) hide show
  1. package/build/card/Card.js.map +1 -1
  2. package/build/card/Card.mjs.map +1 -1
  3. package/build/circularButton/CircularButton.js.map +1 -1
  4. package/build/circularButton/CircularButton.mjs.map +1 -1
  5. package/build/common/locale/index.js.map +1 -1
  6. package/build/common/locale/index.mjs.map +1 -1
  7. package/build/dateLookup/tableLink/TableLink.js.map +1 -1
  8. package/build/dateLookup/tableLink/TableLink.mjs.map +1 -1
  9. package/build/instructionsList/InstructionsList.js.map +1 -1
  10. package/build/instructionsList/InstructionsList.mjs.map +1 -1
  11. package/build/main.css +210 -210
  12. package/build/styles/main.css +210 -210
  13. package/build/styles/uploadInput/UploadInput.css +13 -81
  14. package/build/styles/uploadInput/uploadButton/UploadButton.css +78 -31
  15. package/build/styles/uploadInput/uploadItem/UploadItem.css +130 -109
  16. package/build/types/card/Card.d.ts.map +1 -1
  17. package/build/types/circularButton/CircularButton.d.ts.map +1 -1
  18. package/build/types/instructionsList/InstructionsList.d.ts.map +1 -1
  19. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  20. package/build/types/uploadInput/uploadButton/UploadButton.d.ts +6 -1
  21. package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
  22. package/build/types/uploadInput/uploadItem/UploadItem.d.ts +1 -5
  23. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  24. package/build/types/uploadInput/uploadItem/UploadItemLink.d.ts +5 -5
  25. package/build/types/uploadInput/uploadItem/UploadItemLink.d.ts.map +1 -1
  26. package/build/uploadInput/UploadInput.js +28 -38
  27. package/build/uploadInput/UploadInput.js.map +1 -1
  28. package/build/uploadInput/UploadInput.mjs +29 -39
  29. package/build/uploadInput/UploadInput.mjs.map +1 -1
  30. package/build/uploadInput/uploadButton/UploadButton.js +31 -38
  31. package/build/uploadInput/uploadButton/UploadButton.js.map +1 -1
  32. package/build/uploadInput/uploadButton/UploadButton.mjs +32 -39
  33. package/build/uploadInput/uploadButton/UploadButton.mjs.map +1 -1
  34. package/build/uploadInput/uploadItem/UploadItem.js +33 -56
  35. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  36. package/build/uploadInput/uploadItem/UploadItem.mjs +34 -57
  37. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  38. package/build/uploadInput/uploadItem/UploadItemLink.js +5 -7
  39. package/build/uploadInput/uploadItem/UploadItemLink.js.map +1 -1
  40. package/build/uploadInput/uploadItem/UploadItemLink.mjs +5 -7
  41. package/build/uploadInput/uploadItem/UploadItemLink.mjs.map +1 -1
  42. package/package.json +3 -3
  43. package/src/card/Card.spec.tsx +5 -4
  44. package/src/card/Card.story.tsx +6 -4
  45. package/src/card/Card.tsx +2 -3
  46. package/src/circularButton/CircularButton.tsx +1 -1
  47. package/src/common/locale/index.ts +1 -1
  48. package/src/dateLookup/tableLink/TableLink.tsx +15 -15
  49. package/src/instructionsList/InstructionsList.tsx +4 -1
  50. package/src/main.css +210 -210
  51. package/src/uploadInput/UploadInput.css +13 -81
  52. package/src/uploadInput/UploadInput.less +17 -79
  53. package/src/uploadInput/UploadInput.tests.story.tsx +8 -3
  54. package/src/uploadInput/UploadInput.tsx +41 -68
  55. package/src/uploadInput/uploadButton/UploadButton.css +78 -31
  56. package/src/uploadInput/uploadButton/UploadButton.less +78 -35
  57. package/src/uploadInput/uploadButton/UploadButton.tsx +153 -147
  58. package/src/uploadInput/uploadItem/UploadItem.css +130 -109
  59. package/src/uploadInput/uploadItem/UploadItem.less +129 -118
  60. package/src/uploadInput/uploadItem/UploadItem.tsx +123 -146
  61. package/src/uploadInput/uploadItem/UploadItemLink.tsx +25 -23
@@ -1,6 +1,6 @@
1
1
  import { PlusCircle as PlusIcon, Upload as UploadIcon } from '@transferwise/icons';
2
2
  import { clsx } from 'clsx';
3
- import { ChangeEvent, DragEvent, useRef, useState, forwardRef, RefObject } from 'react';
3
+ import { ChangeEvent, DragEvent, useRef, useState } from 'react';
4
4
  import { useIntl } from 'react-intl';
5
5
 
6
6
  import Body from '../../body';
@@ -17,6 +17,12 @@ export type UploadButtonProps = {
17
17
  */
18
18
  disabled?: boolean;
19
19
 
20
+ /**
21
+ * Should be true, if the UploadInput has at least 1
22
+ * file (valid or invalid) listed.
23
+ */
24
+ withEntries?: boolean;
25
+
20
26
  /**
21
27
  * Allow multiple file uploads
22
28
  */
@@ -70,174 +76,174 @@ const onDragOver = (event: DragEvent): void => {
70
76
  };
71
77
 
72
78
  const DEFAULT_FILE_INPUT_ID = 'np-upload-button';
73
- const UploadButton = forwardRef<HTMLInputElement, UploadButtonProps>(
74
- (
75
- {
76
- disabled,
77
- multiple,
78
- description,
79
- fileTypes = imageFileTypes,
80
- sizeLimit = DEFAULT_SIZE_LIMIT,
81
- maxFiles,
82
- onChange,
83
- id = DEFAULT_FILE_INPUT_ID,
84
- uploadButtonTitle,
85
- },
86
- ref,
87
- ) => {
88
- const { formatMessage } = useIntl();
89
- const inputRef = useRef<HTMLInputElement>(null);
90
-
91
- const [isDropping, setIsDropping] = useState(false);
92
-
93
- const dragCounter = useRef(0);
94
-
95
- const reset = (): void => {
96
- dragCounter.current = 0;
79
+ const UploadButton = ({
80
+ disabled,
81
+ withEntries,
82
+ multiple,
83
+ description,
84
+ fileTypes = imageFileTypes,
85
+ sizeLimit = DEFAULT_SIZE_LIMIT,
86
+ maxFiles,
87
+ onChange,
88
+ id = DEFAULT_FILE_INPUT_ID,
89
+ uploadButtonTitle,
90
+ }: UploadButtonProps) => {
91
+ const { formatMessage } = useIntl();
92
+ const inputReference = useRef<HTMLInputElement>(null);
93
+
94
+ const [isDropping, setIsDropping] = useState(false);
95
+
96
+ const dragCounter = useRef(0);
97
+
98
+ const reset = (): void => {
99
+ dragCounter.current = 0;
100
+ setIsDropping(false);
101
+ };
102
+
103
+ const onDragLeave = (event: DragEvent): void => {
104
+ event.preventDefault();
105
+ dragCounter.current -= 1;
106
+ if (dragCounter.current === 0) {
97
107
  setIsDropping(false);
98
- };
99
-
100
- const onDragLeave = (event: DragEvent): void => {
101
- event.preventDefault();
102
- dragCounter.current -= 1;
103
- if (dragCounter.current === 0) {
104
- setIsDropping(false);
105
- }
106
- };
107
-
108
- const onDragEnter = (event: DragEvent): void => {
109
- event.preventDefault();
110
- dragCounter.current += 1;
111
- if (dragCounter.current === 1) {
112
- setIsDropping(true);
113
- }
114
- };
115
-
116
- const onDrop = (event: DragEvent): void => {
117
- event.preventDefault();
118
- reset();
119
- if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
120
- onChange(event.dataTransfer.files);
121
- }
122
- };
123
-
124
- const filesSelected = (event: ChangeEvent<HTMLInputElement>): void => {
125
- const { files } = event.target;
108
+ }
109
+ };
126
110
 
127
- if (files) {
128
- onChange(files);
111
+ const onDragEnter = (event: DragEvent): void => {
112
+ event.preventDefault();
113
+ dragCounter.current += 1;
114
+ if (dragCounter.current === 1) {
115
+ setIsDropping(true);
116
+ }
117
+ };
129
118
 
130
- if (inputRef.current) {
131
- inputRef.current.value = '';
132
- }
133
- }
134
- };
119
+ const onDrop = (event: DragEvent): void => {
120
+ event.preventDefault();
121
+ reset();
122
+ if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
123
+ onChange(event.dataTransfer.files);
124
+ }
125
+ };
135
126
 
136
- const getFileTypesDescription = (): string => {
137
- if (fileTypes === '*') {
138
- return fileTypes;
139
- }
127
+ const filesSelected = (event: ChangeEvent<HTMLInputElement>): void => {
128
+ const { files } = event.target;
140
129
 
141
- return getAllowedFileTypes(Array.isArray(fileTypes) ? fileTypes : [fileTypes]).join(', ');
142
- };
130
+ if (files) {
131
+ onChange(files);
143
132
 
144
- function getDescription() {
145
- if (description) {
146
- return description;
133
+ if (inputReference.current) {
134
+ inputReference.current.value = '';
147
135
  }
136
+ }
137
+ };
148
138
 
149
- const fileTypesDescription = getFileTypesDescription();
139
+ const getFileTypesDescription = (): string => {
140
+ if (fileTypes === '*') {
141
+ return fileTypes;
142
+ }
150
143
 
151
- const derivedFileDescription =
152
- fileTypesDescription === '*' ? formatMessage(MESSAGES.allFileTypes) : fileTypesDescription;
144
+ return getAllowedFileTypes(Array.isArray(fileTypes) ? fileTypes : [fileTypes]).join(', ');
145
+ };
153
146
 
154
- return formatMessage(MESSAGES.instructions, {
155
- fileTypes: derivedFileDescription,
156
- size: Math.round(sizeLimit / 1000),
157
- });
147
+ function getDescription() {
148
+ if (description) {
149
+ return description;
158
150
  }
159
151
 
160
- function getAcceptedTypes(): Pick<React.ComponentPropsWithoutRef<'input'>, 'accept'> {
161
- const areAllFilesAllowed = getFileTypesDescription() === '*';
152
+ const fileTypesDescription = getFileTypesDescription();
162
153
 
163
- if (areAllFilesAllowed) {
164
- return {}; // file input by default allows all files
165
- }
154
+ const derivedFileDescription =
155
+ fileTypesDescription === '*' ? formatMessage(MESSAGES.allFileTypes) : fileTypesDescription;
166
156
 
167
- if (Array.isArray(fileTypes)) {
168
- return { accept: fileTypes.join(',') };
169
- }
157
+ return formatMessage(MESSAGES.instructions, {
158
+ fileTypes: derivedFileDescription,
159
+ size: Math.round(sizeLimit / 1000),
160
+ });
161
+ }
170
162
 
171
- return { accept: fileTypes as string };
172
- }
163
+ function getAcceptedTypes(): Pick<React.ComponentPropsWithoutRef<'input'>, 'accept'> {
164
+ const areAllFilesAllowed = getFileTypesDescription() === '*';
173
165
 
174
- function renderDescription() {
175
- return (
176
- <Body className={clsx({ 'text-primary': !disabled })}>
177
- {getDescription()}
178
- {maxFiles && (
179
- <>
180
- <br />
181
- {`Maximum ${maxFiles} files.`}
182
- </>
183
- )}
184
- </Body>
185
- );
166
+ if (areAllFilesAllowed) {
167
+ return {}; // file input by default allows all files
186
168
  }
187
169
 
188
- function renderButtonTitle() {
189
- if (uploadButtonTitle) {
190
- return uploadButtonTitle;
191
- }
192
- return formatMessage(multiple ? MESSAGES.uploadFiles : MESSAGES.uploadFile);
170
+ if (Array.isArray(fileTypes)) {
171
+ return { accept: fileTypes.join(',') };
193
172
  }
194
173
 
174
+ return { accept: fileTypes as string };
175
+ }
176
+
177
+ function renderDescription() {
195
178
  return (
196
- <div
197
- className={clsx('np-upload-button-container', 'droppable', {
198
- 'droppable-dropping': isDropping,
199
- })}
200
- {...(!disabled && { onDragEnter, onDragLeave, onDrop, onDragOver })}
201
- >
202
- <input
203
- ref={ref}
204
- id={id}
205
- type="file"
206
- {...getAcceptedTypes()}
207
- {...(multiple && { multiple: true })}
208
- className="tw-droppable-input"
209
- disabled={disabled}
210
- name="file-upload"
211
- data-testid={TEST_IDS.uploadInput}
212
- onChange={filesSelected}
213
- />
214
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
215
- <label htmlFor={id} className={clsx('btn', 'np-upload-button')}>
216
- <div className="media">
217
- <div className="np-upload-icon media-middle media-left">
218
- <UploadIcon size={24} className="text-link" />
219
- </div>
220
- <div className="media-body text-xs-left" data-testid={TEST_IDS.mediaBody}>
221
- <Body type={Typography.BODY_LARGE_BOLD} className="d-block">
222
- {renderButtonTitle()}
223
- </Body>
224
- {renderDescription()}
225
- </div>
226
- </div>
227
- </label>
228
-
229
- {/* Drop area overlay */}
230
- {isDropping && (
231
- <div
232
- className={clsx('droppable-card', 'droppable-dropping-card', 'droppable-card-content')}
233
- >
234
- <PlusIcon className="m-x-1" size={24} />
235
- <div>{formatMessage(MESSAGES.dropFile)}</div>
236
- </div>
179
+ <Body className="np-upload-input__text">
180
+ {getDescription()}
181
+ {maxFiles && (
182
+ <>
183
+ <br />
184
+ {`Maximum ${maxFiles} files.`}
185
+ </>
237
186
  )}
238
- </div>
187
+ </Body>
239
188
  );
240
- },
241
- );
189
+ }
190
+
191
+ function renderButtonTitle() {
192
+ if (uploadButtonTitle) {
193
+ return uploadButtonTitle;
194
+ }
195
+ return formatMessage(multiple ? MESSAGES.uploadFiles : MESSAGES.uploadFile);
196
+ }
197
+
198
+ return (
199
+ <label
200
+ className={clsx(
201
+ 'np-upload-input__upload-button',
202
+ `np-upload-input__upload-button--${disabled ? 'disabled' : 'enabled'}`,
203
+ `np-upload-input__upload-button--${withEntries ? 'with' : 'without'}-entries`,
204
+ {
205
+ 'is-dropping': isDropping,
206
+ },
207
+ )}
208
+ htmlFor={id}
209
+ {...(!disabled && { onDragEnter, onDragLeave, onDrop, onDragOver })}
210
+ >
211
+ <span className="np-upload-input__icon">
212
+ <UploadIcon size={24} className="text-link" />
213
+ </span>
214
+ <div className="np-upload-input__item-content" data-testid={TEST_IDS.mediaBody}>
215
+ <Body type={Typography.BODY_LARGE_BOLD} className="np-upload-input__title">
216
+ {renderButtonTitle()}
217
+ </Body>
218
+ {renderDescription()}
219
+ </div>
220
+ <input
221
+ ref={inputReference}
222
+ className="np-upload-input__upload-button-input sr-only"
223
+ type="file"
224
+ id={id}
225
+ {...getAcceptedTypes()}
226
+ {...(multiple && { multiple: true })}
227
+ disabled={disabled}
228
+ name="file-upload"
229
+ data-testid={TEST_IDS.uploadInput}
230
+ onChange={filesSelected}
231
+ />
232
+ {isDropping && (
233
+ <div
234
+ className={clsx(
235
+ 'np-upload-input__drop-file-overlay',
236
+ 'droppable-card',
237
+ 'droppable-dropping-card',
238
+ 'droppable-card-content',
239
+ )}
240
+ >
241
+ <PlusIcon className="m-x-1" size={24} />
242
+ <div>{formatMessage(MESSAGES.dropFile)}</div>
243
+ </div>
244
+ )}
245
+ </label>
246
+ );
247
+ };
242
248
 
243
249
  export default UploadButton;
@@ -1,144 +1,165 @@
1
- .np-upload-item {
2
- border: 1px solid #c9cbce;
3
- border: 1px solid var(--color-interactive-secondary);
1
+ .np-upload-input__item {
4
2
  position: relative;
5
- }
6
- .np-upload-item:first-child ~ div:not(.np-upload-item--link):before,
7
- .np-upload-item:not(:first-child).np-upload-item--link .np-upload-item__link:before,
8
- .np-upload-item.np-upload-item--link:hover .np-upload-item__link:after {
3
+ padding: 16px;
4
+ padding: var(--size-16);
5
+ display: flex;
6
+ align-items: flex-start;
7
+ border-left: var(--outerBorder);
8
+ border-right: var(--outerBorder);
9
+ }
10
+ .np-upload-input__item:first-child {
11
+ border-top: var(--outerBorder);
12
+ border-top-left-radius: 10px;
13
+ border-top-left-radius: var(--radius-small);
14
+ border-top-right-radius: 10px;
15
+ border-top-right-radius: var(--radius-small);
16
+ }
17
+ .np-upload-input__item + .np-upload-input__item:before {
18
+ content: " ";
9
19
  display: block;
10
20
  position: absolute;
11
21
  height: 1px;
12
- background-color: rgba(0,0,0,0.10196);
13
- background-color: var(--color-border-neutral);
14
- content: " ";
15
22
  left: 16px;
16
23
  left: var(--size-16);
17
24
  width: calc(100% - 2 * 16px);
18
25
  width: calc(100% - 2 * var(--size-16));
19
- }
20
- .np-upload-item:first-child ~ div:not(.np-upload-item--link):before,
21
- .np-upload-item:not(:first-child).np-upload-item--link .np-upload-item__link:before {
22
26
  top: 0;
27
+ background: rgba(0,0,0,0.10196);
28
+ background: var(--color-border-neutral);
23
29
  }
24
- .np-upload-item.np-upload-item--link:hover .np-upload-item__link:after {
25
- bottom: -1px;
26
- }
27
- .np-upload-item:first-child ~ div {
28
- border-top: 1px;
30
+ .np-upload-input__item .np-upload-input__item-content {
31
+ padding-right: 32px;
32
+ padding-right: var(--size-32);
33
+ flex: 1;
29
34
  }
30
- .np-upload-item:not(:first-child) .np-upload-item__link:hover {
31
- border-top-color: rgba(0,0,0,0.10196);
32
- border-top-color: var(--color-border-neutral);
35
+ @media (max-width: 320px) {
36
+ .np-upload-input__item .np-upload-input__item-content {
37
+ padding-right: 64px;
38
+ padding-right: var(--size-64);
39
+ }
33
40
  }
34
- .np-upload-item:not(:last-child) {
35
- border-bottom: 0;
41
+ .np-upload-input__item .np-upload-input__title,
42
+ .np-upload-input__item .np-upload-input__text {
43
+ margin: 0;
44
+ -moz-text-align-last: left;
45
+ text-align-last: left;
46
+ color: #5d7079;
47
+ color: var(--color-content-secondary);
48
+ }
49
+ .np-upload-input__item .np-upload-input__title + .np-upload-input__text {
50
+ margin-top: 4px;
51
+ margin-top: var(--size-4);
52
+ }
53
+ .np-upload-input__item .np-upload-input__icon {
54
+ padding-right: 16px;
55
+ padding-right: var(--size-16);
56
+ }
57
+ .np-upload-input__item .np-upload-input__item-link,
58
+ .np-upload-input__item .np-upload-input__item-container {
59
+ align-items: flex-start;
60
+ display: flex;
61
+ width: 100%;
36
62
  }
37
- .np-upload-item.np-upload-item--link:hover + .np-upload-item:before,
38
- .np-upload-item.np-upload-item--link:hover + .np-upload-button-container:before,
39
- .np-upload-item.np-upload-item--link:hover + .np-upload-item .np-upload-item__link:before,
40
- .np-upload-item.np-upload-item--link:hover + .np-upload-button-container .np-upload-item__link:before {
41
- display: none;
63
+ .np-upload-input__item .np-upload-input__item-action {
64
+ --iconSize: var(--size-24);
65
+ --clickArea: 44px;
66
+ --buttonTopRightOffset: var(--size-16);
67
+ --clickAreaTopRightOffset: calc((var(--clickArea) - var(--iconSize)) * -0.5);
68
+ position: absolute;
69
+ right: 16px;
70
+ right: var(--buttonTopRightOffset);
71
+ top: 16px;
72
+ top: var(--buttonTopRightOffset);
42
73
  }
43
- .np-upload-button-container:hover:before,
44
- .np-upload-button-container.droppable-dropping:before {
45
- left: 0 !important;
46
- width: 100% !important;
74
+ @media (max-width: 320px) {
75
+ .np-upload-input__item .np-upload-input__item-action {
76
+ --iconSize: var(--size-48);
77
+ --clickAreaTopRightOffset: calc(-1 * var(--buttonTopRightOffset));
78
+ }
47
79
  }
48
- .np-upload-button-container:has(:focus-visible) {
49
- outline: var(--ring-outline-color) solid var(--ring-outline-width);
50
- outline-offset: var(--ring-outline-offset);
51
- border-color: transparent;
52
- outline-offset: -3px;
80
+ .np-upload-input__item .np-upload-input__item-action .np-upload-input__item-button {
81
+ -webkit-appearance: none;
82
+ -moz-appearance: none;
83
+ appearance: none;
84
+ height: var(--iconSize);
85
+ width: var(--iconSize);
86
+ padding: 0 4px;
87
+ padding: 0 var(--size-4);
88
+ border-radius: 50%;
89
+ border: 0;
90
+ background-color: rgba(134,167,189,0.10196);
91
+ background-color: var(--color-background-neutral);
92
+ color: var(--color-interactive-primary);
93
+ transition: color, background-color 0.15s ease-in-out;
94
+ outline-offset: 0;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
53
98
  }
54
- .np-upload-item--single-file:focus-visible,
55
- .np-upload-item__link:focus-visible,
56
- .np-upload-button-container:has(:focus-visible) {
57
- outline-width: 3px;
99
+ .np-upload-input__item .np-upload-input__item-action .np-upload-input__item-button:before {
100
+ content: '';
101
+ display: block;
102
+ width: var(--clickArea);
103
+ height: var(--clickArea);
104
+ border-radius: 50%;
105
+ position: absolute;
106
+ top: var(--clickAreaTopRightOffset);
107
+ right: var(--clickAreaTopRightOffset);
58
108
  }
59
- .np-upload-item--link a {
60
- flex: 1;
61
- -webkit-text-decoration: none;
62
- text-decoration: none;
63
- border-top: 1px solid transparent;
64
- border-radius: inherit;
109
+ .np-upload-input__item .np-upload-input__item-action .np-upload-input__item-button:hover {
110
+ background-color: var(--color-sentiment-negative);
111
+ color: var(--color-contrast-overlay) !important;
65
112
  }
66
- .np-upload-item--link a:focus-visible {
67
- outline-offset: -2px;
113
+ .np-upload-input__item .np-upload-input__item-action .np-upload-input__item-button:active {
114
+ background-color: var(--color-background-neutral-active);
68
115
  }
69
- .np-upload-item--link a:hover:before {
70
- display: none !important;
116
+ .np-upload-input__item.is-interactive {
117
+ padding: 0;
71
118
  }
72
- .np-upload-item--link a:hover:after {
73
- left: 0 !important;
74
- width: 100% !important;
119
+ .np-upload-input__item.is-interactive:hover:not(:has(.np-upload-input__item-button:hover)):before,
120
+ .np-upload-input__item.is-interactive:hover:not(:has(.np-upload-input__item-button:hover)) + .np-upload-input__item:before {
121
+ width: 100%;
122
+ left: 0;
75
123
  }
76
- .np-upload-item--link a:hover,
77
- .np-upload-item--link a:active {
124
+ .np-upload-input__item.is-interactive .np-upload-input__item-link {
125
+ padding: 16px;
126
+ padding: var(--size-16);
78
127
  -webkit-text-decoration: none;
79
128
  text-decoration: none;
129
+ border-radius: inherit;
130
+ border-top: 1px solid transparent;
131
+ background-clip: padding-box;
132
+ }
133
+ .np-upload-input__item.is-interactive .np-upload-input__item-link:focus-visible {
134
+ outline-offset: -2px;
135
+ outline-width: 3px;
80
136
  }
81
- .np-upload-item--link a:hover .np-upload-button,
82
- .np-upload-item--link a:active .np-upload-button {
137
+ .np-upload-input__item.is-interactive .np-upload-input__item-link:hover,
138
+ .np-upload-input__item.is-interactive .np-upload-input__item-link:active {
83
139
  background-color: rgba(134,167,189,0.10196);
84
140
  background-color: var(--color-background-neutral);
85
- border-radius: inherit;
86
141
  }
87
- .np-upload-item--link:first-of-type a {
88
- border-top: 0;
142
+ .np-upload-input__item.is-interactive:first-child .np-upload-input__item-link {
143
+ border-top-width: 0;
89
144
  }
90
- .np-upload-item__body {
91
- display: flex;
92
- align-items: center;
93
- justify-content: space-between;
145
+ .np-upload-input__item .np-upload-input-errors {
146
+ padding-left: 0;
147
+ list-style-type: "";
148
+ }
149
+ .np-upload-input__item .np-upload-input-errors > li {
94
150
  position: relative;
95
- border-radius: inherit;
151
+ padding-left: 16px;
152
+ padding-left: var(--size-16);
96
153
  }
97
- .np-upload-item__remove-button {
98
- display: flex;
99
- align-items: center;
100
- justify-content: center;
101
- align-self: flex-start;
154
+ .np-upload-input__item .np-upload-input-errors > li::before {
155
+ content: '•';
102
156
  position: absolute;
103
- height: 24px;
104
- height: var(--size-24);
105
- min-height: 0;
106
- width: 24px;
107
- width: var(--size-24);
108
- padding: 0;
109
- border-radius: 50% !important;
110
- outline-offset: 0 !important;
111
- background-color: rgba(134,167,189,0.10196);
112
- background-color: var(--color-background-neutral);
113
- border: none;
114
- color: var(--color-interactive-primary);
115
- right: 16px;
116
- right: var(--size-16);
117
- top: 16px;
118
- top: var(--size-16);
119
- transition: color, background-color 0.15s ease-in-out;
157
+ display: block;
158
+ left: 0;
120
159
  }
121
160
  @media (max-width: 320px) {
122
- .np-upload-item__remove-button {
123
- top: 16px;
124
- top: var(--size-16);
125
- right: 16px;
126
- right: var(--size-16);
127
- height: 48px;
128
- height: var(--size-48);
129
- width: 48px;
130
- width: var(--size-48);
161
+ .np-upload-input__item .np-upload-input-errors > li {
162
+ padding-left: 32px;
163
+ padding-left: var(--size-32);
131
164
  }
132
165
  }
133
- .np-upload-item__remove-button:hover {
134
- background-color: var(--color-sentiment-negative);
135
- color: var(--color-contrast-overlay) !important;
136
- }
137
- .np-upload-item__remove-button:before {
138
- display: block;
139
- width: 44px;
140
- height: 44px;
141
- content: '';
142
- border-radius: 50%;
143
- position: absolute;
144
- }