@transferwise/components 46.67.2 → 46.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/build/button/Button.js +22 -6
  2. package/build/button/Button.js.map +1 -1
  3. package/build/button/Button.mjs +22 -6
  4. package/build/button/Button.mjs.map +1 -1
  5. package/build/main.css +212 -210
  6. package/build/styles/button/Button.css +3 -0
  7. package/build/styles/main.css +212 -210
  8. package/build/styles/uploadInput/UploadInput.css +13 -81
  9. package/build/styles/uploadInput/uploadButton/UploadButton.css +77 -31
  10. package/build/styles/uploadInput/uploadItem/UploadItem.css +130 -109
  11. package/build/typeahead/Typeahead.js +22 -8
  12. package/build/typeahead/Typeahead.js.map +1 -1
  13. package/build/typeahead/Typeahead.mjs +22 -9
  14. package/build/typeahead/Typeahead.mjs.map +1 -1
  15. package/build/typeahead/typeaheadInput/TypeaheadInput.js +5 -2
  16. package/build/typeahead/typeaheadInput/TypeaheadInput.js.map +1 -1
  17. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs +5 -2
  18. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs.map +1 -1
  19. package/build/typeahead/typeaheadOption/TypeaheadOption.js +9 -6
  20. package/build/typeahead/typeaheadOption/TypeaheadOption.js.map +1 -1
  21. package/build/typeahead/typeaheadOption/TypeaheadOption.mjs +9 -6
  22. package/build/typeahead/typeaheadOption/TypeaheadOption.mjs.map +1 -1
  23. package/build/types/button/Button.d.ts.map +1 -1
  24. package/build/types/typeahead/Typeahead.d.ts +1 -1
  25. package/build/types/typeahead/Typeahead.d.ts.map +1 -1
  26. package/build/types/typeahead/typeaheadInput/TypeaheadInput.d.ts +2 -0
  27. package/build/types/typeahead/typeaheadInput/TypeaheadInput.d.ts.map +1 -1
  28. package/build/types/typeahead/typeaheadOption/TypeaheadOption.d.ts +2 -1
  29. package/build/types/typeahead/typeaheadOption/TypeaheadOption.d.ts.map +1 -1
  30. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  31. package/build/types/uploadInput/uploadButton/UploadButton.d.ts +5 -0
  32. package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
  33. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  34. package/build/uploadInput/UploadInput.js +30 -20
  35. package/build/uploadInput/UploadInput.js.map +1 -1
  36. package/build/uploadInput/UploadInput.mjs +30 -20
  37. package/build/uploadInput/UploadInput.mjs.map +1 -1
  38. package/build/uploadInput/uploadButton/UploadButton.js +25 -32
  39. package/build/uploadInput/uploadButton/UploadButton.js.map +1 -1
  40. package/build/uploadInput/uploadButton/UploadButton.mjs +25 -32
  41. package/build/uploadInput/uploadButton/UploadButton.mjs.map +1 -1
  42. package/build/uploadInput/uploadItem/UploadItem.js +32 -38
  43. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  44. package/build/uploadInput/uploadItem/UploadItem.mjs +33 -39
  45. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  46. package/build/uploadInput/uploadItem/UploadItemLink.js +2 -1
  47. package/build/uploadInput/uploadItem/UploadItemLink.js.map +1 -1
  48. package/build/uploadInput/uploadItem/UploadItemLink.mjs +2 -1
  49. package/build/uploadInput/uploadItem/UploadItemLink.mjs.map +1 -1
  50. package/package.json +4 -4
  51. package/src/button/Button.css +3 -0
  52. package/src/button/Button.less +6 -0
  53. package/src/button/Button.spec.js +81 -45
  54. package/src/button/Button.story.tsx +54 -20
  55. package/src/button/Button.tsx +32 -7
  56. package/src/button/__snapshots__/Button.spec.js.snap +56 -12
  57. package/src/flowNavigation/FlowNavigation.story.js +1 -1
  58. package/src/main.css +212 -210
  59. package/src/typeahead/Typeahead.spec.js +8 -0
  60. package/src/typeahead/Typeahead.tsx +29 -13
  61. package/src/typeahead/typeaheadInput/TypeaheadInput.tsx +9 -0
  62. package/src/typeahead/typeaheadOption/TypeaheadOption.spec.js +8 -0
  63. package/src/typeahead/typeaheadOption/TypeaheadOption.tsx +9 -6
  64. package/src/uploadInput/UploadInput.css +13 -81
  65. package/src/uploadInput/UploadInput.less +18 -80
  66. package/src/uploadInput/UploadInput.tests.story.tsx +5 -5
  67. package/src/uploadInput/UploadInput.tsx +43 -32
  68. package/src/uploadInput/uploadButton/UploadButton.css +77 -31
  69. package/src/uploadInput/uploadButton/UploadButton.less +77 -35
  70. package/src/uploadInput/uploadButton/UploadButton.tsx +37 -26
  71. package/src/uploadInput/uploadItem/UploadItem.css +130 -109
  72. package/src/uploadInput/uploadItem/UploadItem.less +130 -118
  73. package/src/uploadInput/uploadItem/UploadItem.tsx +26 -28
  74. package/src/uploadInput/uploadItem/UploadItemLink.tsx +3 -3
@@ -25,6 +25,12 @@ export type UploadButtonProps = {
25
25
  */
26
26
  disabled?: boolean;
27
27
 
28
+ /**
29
+ * Should be true, if the UploadInput has at least 1
30
+ * file (valid or invalid) listed.
31
+ */
32
+ withEntries?: boolean;
33
+
28
34
  /**
29
35
  * Allow multiple file uploads
30
36
  */
@@ -82,6 +88,7 @@ const UploadButton = forwardRef<HTMLInputElement | null, UploadButtonProps>(
82
88
  (
83
89
  {
84
90
  disabled,
91
+ withEntries,
85
92
  multiple,
86
93
  description,
87
94
  fileTypes = imageFileTypes,
@@ -188,7 +195,7 @@ const UploadButton = forwardRef<HTMLInputElement | null, UploadButtonProps>(
188
195
 
189
196
  function renderDescription() {
190
197
  return (
191
- <Body className={clsx({ 'text-primary': !disabled })}>
198
+ <Body className="np-upload-input__text">
192
199
  {getDescription()}
193
200
  {maxFiles && (
194
201
  <>
@@ -208,49 +215,53 @@ const UploadButton = forwardRef<HTMLInputElement | null, UploadButtonProps>(
208
215
  }
209
216
 
210
217
  return (
211
- <div
212
- className={clsx('np-upload-button-container', 'droppable', {
213
- 'droppable-dropping': isDropping,
214
- })}
218
+ <label
219
+ className={clsx(
220
+ 'np-upload-input__upload-button',
221
+ `np-upload-input__upload-button--${disabled ? 'disabled' : 'enabled'}`,
222
+ `np-upload-input__upload-button--${withEntries ? 'with-entries' : 'without-entries'}`,
223
+ {
224
+ 'is-dropping': isDropping,
225
+ },
226
+ )}
227
+ htmlFor={id}
215
228
  {...(!disabled && { onDragEnter, onDragLeave, onDrop, onDragOver })}
216
229
  >
230
+ <span className="np-upload-input__icon">
231
+ <UploadIcon size={24} className="text-link" />
232
+ </span>
233
+ <div className="np-upload-input__item-content" data-testid={TEST_IDS.mediaBody}>
234
+ <Body type={Typography.BODY_LARGE_BOLD} className="np-upload-input__title">
235
+ {renderButtonTitle()}
236
+ </Body>
237
+ {renderDescription()}
238
+ </div>
217
239
  <input
218
- ref={inputRef}
219
- id={id}
240
+ className="np-upload-input__upload-button-input sr-only"
220
241
  type="file"
242
+ id={id}
221
243
  {...getAcceptedTypes()}
222
244
  {...(multiple && { multiple: true })}
223
- className="tw-droppable-input"
245
+ ref={inputRef}
224
246
  disabled={disabled}
225
247
  name="file-upload"
226
248
  data-testid={TEST_IDS.uploadInput}
227
249
  onChange={filesSelected}
228
250
  />
229
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
230
- <label htmlFor={id} className={clsx('btn', 'np-upload-button')}>
231
- <div className="media">
232
- <div className="np-upload-icon media-middle media-left">
233
- <UploadIcon size={24} className="text-link" />
234
- </div>
235
- <div className="media-body text-xs-left" data-testid={TEST_IDS.mediaBody}>
236
- <Body type={Typography.BODY_LARGE_BOLD} className="d-block">
237
- {renderButtonTitle()}
238
- </Body>
239
- {renderDescription()}
240
- </div>
241
- </div>
242
- </label>
243
-
244
- {/* Drop area overlay */}
245
251
  {isDropping && (
246
252
  <div
247
- className={clsx('droppable-card', 'droppable-dropping-card', 'droppable-card-content')}
253
+ className={clsx(
254
+ 'np-upload-input__drop-file-overlay',
255
+ 'droppable-card',
256
+ 'droppable-dropping-card',
257
+ 'droppable-card-content',
258
+ )}
248
259
  >
249
260
  <PlusIcon className="m-x-1" size={24} />
250
261
  <div>{formatMessage(MESSAGES.dropFile)}</div>
251
262
  </div>
252
263
  )}
253
- </div>
264
+ </label>
254
265
  );
255
266
  },
256
267
  );
@@ -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
+ --clickAreaSize: 44px;
66
+ --buttonTopRightOffset: var(--size-16);
67
+ --clickAreaTopRightOffset: calc((var(--clickAreaSize) - 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(--clickAreaSize);
103
+ height: var(--clickAreaSize);
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
- }
@@ -1,160 +1,172 @@
1
1
  @import (reference) "../../../node_modules/@transferwise/neptune-css/src/less/ring.less";
2
2
 
3
- // Be aware of touching styles related to :before/:after pseudo-elements in this file, delimiters between items build by using them
4
- .np-upload-item {
5
- border: 1px solid var(--color-interactive-secondary);
3
+ .np-upload-input__item {
6
4
  position: relative;
5
+ padding: var(--size-16);
6
+ display: flex;
7
+ align-items: flex-start;
8
+ border-left: var(--outerBorder);
9
+ border-right: var(--outerBorder);
7
10
 
8
- &:first-child ~ div:not(.np-upload-item--link):before,
9
- &:not(:first-child).np-upload-item--link .np-upload-item__link:before,
10
- &.np-upload-item--link:hover .np-upload-item__link:after {
11
- display: block;
12
- position: absolute;
13
- height: 1px;
14
- background-color: var(--color-border-neutral);
15
- content: " ";
16
- left: var(--size-16);
17
- width: calc(100% - 2 * var(--size-16));
18
- }
19
-
20
- &:first-child ~ div:not(.np-upload-item--link):before,
21
- &:not(:first-child).np-upload-item--link .np-upload-item__link:before {
22
- top: 0;
23
- }
24
-
25
- &.np-upload-item--link:hover .np-upload-item__link:after {
26
- bottom: -1px;
11
+ &:first-child {
12
+ border-top: var(--outerBorder);
13
+ border-top-left-radius: var(--radius-small);
14
+ border-top-right-radius: var(--radius-small);
27
15
  }
28
16
 
29
- &:first-child {
30
- & ~ div {
31
- border-top: 1px;
17
+ & + .np-upload-input__item {
18
+ &:before {
19
+ content: " ";
20
+ display: block;
21
+ position: absolute;
22
+ height: 1px;
23
+ left: var(--size-16);
24
+ width: calc(100% - 2 * var(--size-16));
25
+ top: 0;
26
+ background: var(--color-border-neutral);
32
27
  }
33
28
  }
34
29
 
35
- &:not(:first-child) {
36
- .np-upload-item__link:hover {
37
- border-top-color: var(--color-border-neutral);
30
+ .np-upload-input__item-content {
31
+ padding-right: var(--size-32);
32
+ flex: 1;
33
+
34
+ @media (max-width: 320px) {
35
+ padding-right: var(--size-64);
38
36
  }
39
37
  }
40
38
 
41
- &:not(:last-child) {
42
- border-bottom: 0;
39
+ .np-upload-input__title,
40
+ .np-upload-input__text {
41
+ margin: 0;
42
+ text-align-last: left;
43
+ color: var(--color-content-secondary);
43
44
  }
44
45
 
45
-
46
- &.np-upload-item--link:hover + .np-upload-item,
47
- &.np-upload-item--link:hover + .np-upload-button-container {
48
- &:before,
49
- .np-upload-item__link:before {
50
- display: none;
51
- }
46
+ .np-upload-input__title + .np-upload-input__text {
47
+ margin-top: var(--size-4);
52
48
  }
53
- }
54
49
 
55
- .np-upload-button-container {
56
- &:hover:before,
57
- &.droppable-dropping:before {
58
- left: 0 !important;
59
- width: 100% !important;
50
+ .np-upload-input__icon {
51
+ padding-right: var(--size-16);
60
52
  }
61
53
 
62
- &:has(:focus-visible) {
63
- .ring();
64
- border-color: transparent;
65
- outline-offset: -3px;
54
+ .np-upload-input__item-link,
55
+ .np-upload-input__item-container {
56
+ align-items: flex-start;
57
+ display: flex;
58
+ width: 100%;
66
59
  }
67
- }
68
60
 
69
- .np-upload-item--single-file:focus-visible,
70
- .np-upload-item__link:focus-visible,
71
- .np-upload-button-container:has(:focus-visible) {
72
- outline-width: 3px;
73
- }
61
+ .np-upload-input__item-action {
62
+ --iconSize: var(--size-24);
63
+ --clickAreaSize: 44px;
64
+ --buttonTopRightOffset: var(--size-16);
65
+ // Offset towards the parent's top-right edge
66
+ // ensuring no overflow on smaller screens
67
+ --clickAreaTopRightOffset: calc((var(--clickAreaSize) - var(--iconSize)) * -.5);
74
68
 
75
- .np-upload-item--link {
76
- a {
77
- flex: 1;
78
- text-decoration: none;
79
- border-top: 1px solid transparent;
80
- border-radius: inherit;
69
+ position: absolute;
70
+ right: var(--buttonTopRightOffset);
71
+ top: var(--buttonTopRightOffset);
81
72
 
82
- &:focus-visible {
83
- outline-offset: -2px;
73
+ @media (--screen-400-zoom) {
74
+ --iconSize: var(--size-48);
75
+ --clickAreaTopRightOffset: calc(-1 * var(--buttonTopRightOffset));
84
76
  }
85
77
 
86
- &:hover {
78
+ .np-upload-input__item-button {
79
+ appearance: none;
80
+ height: var(--iconSize);
81
+ width: var(--iconSize);
82
+ padding: 0 var(--size-4);
83
+ border-radius: 50%;
84
+ border: 0;
85
+ background-color: var(--color-background-neutral);
86
+ color: var(--color-interactive-primary);
87
+ transition: color, background-color 0.15s ease-in-out;
88
+ outline-offset: 0;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+
87
93
  &:before {
88
- display: none !important;
94
+ content: '';
95
+ display: block;
96
+ width: var(--clickAreaSize);
97
+ height: var(--clickAreaSize);
98
+ border-radius: 50%;
99
+ position: absolute;
100
+ top: var(--clickAreaTopRightOffset);
101
+ right: var(--clickAreaTopRightOffset);
102
+ }
103
+
104
+ &:hover {
105
+ background-color: var(--color-sentiment-negative);
106
+ color: var(--color-contrast-overlay) !important;
89
107
  }
90
108
 
91
- &:after {
92
- left: 0 !important;
93
- width: 100% !important;
109
+ &:active {
110
+ background-color: var(--color-background-neutral-active);
94
111
  }
95
112
  }
113
+ }
114
+
115
+ &.is-interactive {
116
+ padding: 0;
96
117
 
97
- &:hover,
98
- &:active {
118
+ &:hover:not(:has(.np-upload-input__item-button:hover)) {
119
+
120
+ &:before,
121
+ & + .np-upload-input__item:before {
122
+ width: 100%;
123
+ left: 0;
124
+ }
125
+ }
126
+
127
+ .np-upload-input__item-link {
128
+ padding: var(--size-16);
99
129
  text-decoration: none;
100
- .np-upload-button {
130
+ border-radius: inherit;
131
+ border-top: 1px solid transparent;
132
+ background-clip: padding-box;
133
+
134
+ &:focus-visible {
135
+ outline-offset: -2px;
136
+ outline-width: 3px;
137
+ }
138
+
139
+ &:hover,
140
+ &:active {
101
141
  background-color: var(--color-background-neutral);
102
- border-radius: inherit;
103
142
  }
104
143
  }
105
- }
106
144
 
107
- &:first-of-type a {
108
- border-top: 0;
145
+ &:first-child {
146
+ .np-upload-input__item-link {
147
+ border-top-width: 0;
148
+ }
149
+ }
109
150
  }
110
- }
111
151
 
112
- .np-upload-item__body {
113
- display: flex;
114
- align-items: center;
115
- justify-content: space-between;
116
- // We should have the `relative` position for the body, because we have `absolute` position for `np-upload-item__remove-button` to achieve appropriate `hover` effects
117
- position: relative;
118
- border-radius: inherit;
119
- }
152
+ .np-upload-input-errors {
153
+ padding-left: 0;
154
+ list-style-type: "";
120
155
 
121
- .np-upload-item__remove-button {
122
- display: flex;
123
- align-items: center;
124
- justify-content: center;
125
- align-self: flex-start;
126
- position: absolute;
127
- height: var(--size-24);
128
- min-height: 0;
129
- width: var(--size-24);
130
- padding: 0;
131
- border-radius: 50% !important;
132
- outline-offset: 0 !important;
133
- background-color: var(--color-background-neutral);
134
- border: none;
135
- color: var(--color-interactive-primary);
136
- right: var(--size-16);
137
- top: var(--size-16);
138
- transition: color, background-color 0.15s ease-in-out;
139
-
140
- @media (--screen-400-zoom) {
141
- top: var(--size-16);
142
- right: var(--size-16);
143
- height: var(--size-48);
144
- width: var(--size-48);
145
- }
156
+ & > li {
157
+ position: relative;
158
+ padding-left: var(--size-16);
146
159
 
147
- &:hover {
148
- background-color: var(--color-sentiment-negative);
149
- color: var(--color-contrast-overlay) !important;
150
- }
160
+ &::before {
161
+ content: '•';
162
+ position: absolute;
163
+ display: block;
164
+ left: 0;
165
+ }
151
166
 
152
- &:before {
153
- display: block;
154
- width: 44px;
155
- height: 44px;
156
- content: '';
157
- border-radius: 50%;
158
- position: absolute;
167
+ @media (max-width: 320px) {
168
+ padding-left: var(--size-32);
169
+ }
170
+ }
159
171
  }
160
172
  }