@transferwise/components 0.0.0-experimental-4ba8514 → 0.0.0-experimental-2ea09db

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 (69) hide show
  1. package/build/i18n/en.json +0 -1
  2. package/build/i18n/en.json.js +0 -1
  3. package/build/i18n/en.json.js.map +1 -1
  4. package/build/i18n/en.json.mjs +0 -1
  5. package/build/i18n/en.json.mjs.map +1 -1
  6. package/build/inputs/SelectInput.js +0 -4
  7. package/build/inputs/SelectInput.js.map +1 -1
  8. package/build/inputs/SelectInput.mjs +0 -4
  9. package/build/inputs/SelectInput.mjs.map +1 -1
  10. package/build/main.css +210 -210
  11. package/build/moneyInput/MoneyInput.js +1 -8
  12. package/build/moneyInput/MoneyInput.js.map +1 -1
  13. package/build/moneyInput/MoneyInput.messages.js +0 -3
  14. package/build/moneyInput/MoneyInput.messages.js.map +1 -1
  15. package/build/moneyInput/MoneyInput.messages.mjs +0 -3
  16. package/build/moneyInput/MoneyInput.messages.mjs.map +1 -1
  17. package/build/moneyInput/MoneyInput.mjs +1 -8
  18. package/build/moneyInput/MoneyInput.mjs.map +1 -1
  19. package/build/styles/main.css +210 -210
  20. package/build/styles/uploadInput/UploadInput.css +13 -81
  21. package/build/styles/uploadInput/uploadButton/UploadButton.css +78 -31
  22. package/build/styles/uploadInput/uploadItem/UploadItem.css +130 -109
  23. package/build/types/inputs/SelectInput.d.ts +1 -3
  24. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  25. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  26. package/build/types/moneyInput/MoneyInput.messages.d.ts +0 -5
  27. package/build/types/moneyInput/MoneyInput.messages.d.ts.map +1 -1
  28. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  29. package/build/types/uploadInput/uploadButton/UploadButton.d.ts +5 -0
  30. package/build/types/uploadInput/uploadButton/UploadButton.d.ts.map +1 -1
  31. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  32. package/build/uploadInput/UploadInput.js +30 -20
  33. package/build/uploadInput/UploadInput.js.map +1 -1
  34. package/build/uploadInput/UploadInput.mjs +30 -20
  35. package/build/uploadInput/UploadInput.mjs.map +1 -1
  36. package/build/uploadInput/uploadButton/UploadButton.js +25 -32
  37. package/build/uploadInput/uploadButton/UploadButton.js.map +1 -1
  38. package/build/uploadInput/uploadButton/UploadButton.mjs +25 -32
  39. package/build/uploadInput/uploadButton/UploadButton.mjs.map +1 -1
  40. package/build/uploadInput/uploadItem/UploadItem.js +32 -38
  41. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  42. package/build/uploadInput/uploadItem/UploadItem.mjs +33 -39
  43. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  44. package/build/uploadInput/uploadItem/UploadItemLink.js +2 -1
  45. package/build/uploadInput/uploadItem/UploadItemLink.js.map +1 -1
  46. package/build/uploadInput/uploadItem/UploadItemLink.mjs +2 -1
  47. package/build/uploadInput/uploadItem/UploadItemLink.mjs.map +1 -1
  48. package/package.json +2 -2
  49. package/src/i18n/en.json +0 -1
  50. package/src/inputs/SelectInput.tsx +3 -8
  51. package/src/main.css +210 -210
  52. package/src/moneyInput/MoneyInput.messages.ts +0 -5
  53. package/src/moneyInput/MoneyInput.rtl.spec.tsx +0 -47
  54. package/src/moneyInput/MoneyInput.spec.js +11 -0
  55. package/src/moneyInput/MoneyInput.story.tsx +7 -10
  56. package/src/moneyInput/MoneyInput.tsx +1 -8
  57. package/src/uploadInput/UploadInput.css +13 -81
  58. package/src/uploadInput/UploadInput.less +18 -80
  59. package/src/uploadInput/UploadInput.tests.story.tsx +5 -5
  60. package/src/uploadInput/UploadInput.tsx +43 -32
  61. package/src/uploadInput/uploadButton/UploadButton.css +78 -31
  62. package/src/uploadInput/uploadButton/UploadButton.less +78 -35
  63. package/src/uploadInput/uploadButton/UploadButton.tsx +37 -26
  64. package/src/uploadInput/uploadItem/UploadItem.css +130 -109
  65. package/src/uploadInput/uploadItem/UploadItem.less +130 -118
  66. package/src/uploadInput/uploadItem/UploadItem.tsx +26 -28
  67. package/src/uploadInput/uploadItem/UploadItemLink.tsx +3 -3
  68. package/src/withId/withId.story.tsx +0 -1
  69. package/src/moneyInput/MoneyInput.docs.mdx +0 -34
@@ -1,86 +1,18 @@
1
- .np-upload-input.form-control {
2
- height: auto;
3
- padding: 0;
4
- padding: initial;
1
+ .np-upload-input {
2
+ --outerBorder: 1px solid var(--color-interactive-secondary);
3
+ border-radius: 10px;
4
+ border-radius: var(--radius-small);
5
5
  }
6
- .np-upload-input > div:first-child,
7
- .np-upload-input > div:first-child .np-upload-item--single-file,
8
- .np-upload-input > div:first-child .np-upload-item--link {
9
- border-top-left-radius: 10px;
10
- border-top-left-radius: var(--radius-small);
11
- border-top-right-radius: 10px;
12
- border-top-right-radius: var(--radius-small);
6
+ .np-upload-input .np-upload-input__section {
7
+ margin: 0;
13
8
  }
14
- .np-upload-input > div:last-child {
15
- border-bottom-left-radius: 10px;
16
- border-bottom-left-radius: var(--radius-small);
17
- border-bottom-right-radius: 10px;
18
- border-bottom-right-radius: var(--radius-small);
9
+ .np-upload-input .np-upload-input__section:only-child .np-upload-input__item {
10
+ border-radius: 10px;
11
+ border-radius: var(--radius-small);
12
+ border-bottom: var(--outerBorder);
19
13
  }
20
- .np-theme-personal .np-upload-input.disabled .btn {
21
- cursor: inherit;
22
- }
23
- .np-theme-personal .np-upload-input .np-upload-icon {
24
- color: var(--color-interactive-primary);
25
- }
26
- .np-theme-personal .np-upload-input .media-body {
27
- padding-right: 32px;
28
- padding-right: var(--size-32);
29
- color: var(--color-content-link);
30
- white-space: break-spaces;
31
- }
32
- @media (max-width: 320px) {
33
- .np-theme-personal .np-upload-input .media-body {
34
- padding-right: 64px;
35
- padding-right: var(--size-64);
36
- }
37
- }
38
- .np-theme-personal .np-upload-input .media-body .np-text-body-large-bold {
39
- -webkit-text-decoration: underline;
40
- text-decoration: underline;
41
- text-underline-offset: 0.3em;
42
- }
43
- .np-theme-personal .np-upload-input .media-body .np-text-body-default,
44
- .np-theme-personal .np-upload-input .media-body .np-upload-description,
45
- .np-theme-personal .np-upload-input .media-body .text-positive {
46
- color: #5d7079 !important;
47
- color: var(--color-content-secondary) !important;
48
- }
49
- .np-theme-personal .np-upload-input .media-body .text-negative {
50
- color: var(--color-sentiment-negative) !important;
51
- }
52
- .np-theme-personal .np-upload-input-errors {
53
- list-style: none;
54
- padding-left: 0;
55
- }
56
- .np-theme-personal .np-upload-input-errors li {
57
- position: relative;
58
- padding-left: 16px;
59
- padding-left: var(--size-16);
60
- }
61
- @media (max-width: 320px) {
62
- .np-theme-personal .np-upload-input-errors li {
63
- padding-left: 32px;
64
- padding-left: var(--size-32);
65
- }
66
- }
67
- .np-theme-personal .np-upload-input-errors li:before {
68
- content: '•';
69
- position: absolute;
70
- display: block;
14
+ .np-upload-input .np-upload-input__section:has(.np-upload-input__item:last-child.is-interactive:hover):not(:has(.np-upload-input__item-button:hover)) + .np-upload-input__section--uploader .np-upload-input__upload-button::before {
71
15
  left: 0;
72
- }
73
- .np-theme-personal .np-upload-input .status-circle {
74
- width: 24px;
75
- width: var(--size-x-small);
76
- height: 24px;
77
- height: var(--size-x-small);
78
- }
79
- @media (max-width: 320px) {
80
- .np-theme-personal .np-upload-input .status-circle {
81
- width: 48px;
82
- width: var(--size-large);
83
- height: 48px;
84
- height: var(--size-large);
85
- }
16
+ width: 100%;
17
+ top: 0;
86
18
  }
@@ -3,90 +3,28 @@
3
3
  @import (reference) './uploadItem/UploadItem.less';
4
4
 
5
5
  .np-upload-input {
6
- &.form-control {
7
- height: auto;
8
- padding: initial;
9
- }
10
-
11
- & > div {
12
- &:first-child,
13
- &:first-child .np-upload-item--single-file,
14
- &:first-child .np-upload-item--link {
15
- border-top-left-radius: var(--radius-small);
16
- border-top-right-radius: var(--radius-small);
17
- }
18
-
19
- &:last-child {
20
- border-bottom-left-radius: var(--radius-small);
21
- border-bottom-right-radius: var(--radius-small);
22
- }
23
- }
24
- }
25
-
26
- .np-theme-personal {
27
- .np-upload-input {
28
- &.disabled .btn {
29
- cursor: inherit;
30
- }
31
-
32
- .np-upload-icon {
33
- color: var(--color-interactive-primary);
34
- }
35
-
36
- .media-body {
37
- padding-right: var(--size-32);
38
- color: var(--color-content-link);
39
- white-space: break-spaces;
40
-
41
- @media (--screen-400-zoom) {
42
- padding-right: var(--size-64);
43
- }
44
-
45
- .np-text-body-large-bold {
46
- text-decoration: underline;
47
- .link-underline();
48
- }
49
-
50
- .np-text-body-default,
51
- .np-upload-description,
52
- .text-positive {
53
- color: var(--color-content-secondary) !important;
54
- }
55
-
56
- .text-negative {
57
- color: var(--color-sentiment-negative) !important;
58
- }
59
- }
60
-
61
- &-errors {
62
- list-style: none;
63
- padding-left: 0;
6
+ --outerBorder: 1px solid var(--color-interactive-secondary);
7
+ border-radius: var(--radius-small);
64
8
 
65
- li {
66
- position: relative;
67
- padding-left: var(--size-16);
9
+ .np-upload-input__section {
10
+ margin: 0;
68
11
 
69
- @media (--screen-400-zoom) {
70
- padding-left: var(--size-32);
71
- }
72
-
73
- &:before {
74
- content: '•';
75
- position: absolute;
76
- display: block;
77
- left: 0;
78
- }
12
+ // only 1 file allowed and already uploaded (no UploadButton shown)
13
+ &:only-child {
14
+ .np-upload-input__item {
15
+ border-radius: var(--radius-small);
16
+ border-bottom: var(--outerBorder);
79
17
  }
80
18
  }
81
19
 
82
- .status-circle {
83
- width: var(--size-x-small);
84
- height: var(--size-x-small);
85
-
86
- @media (--screen-400-zoom) {
87
- width: var(--size-large);
88
- height: var(--size-large);
89
- }
20
+ // if the last item in the file list is interactive (not an error)
21
+ // and the user is hovering over it, then we need to adjust the
22
+ // bottom separator, which happens to be in .np-upload-input__section--uploader
23
+ &:has(.np-upload-input__item:last-child.is-interactive:hover):not(:has(.np-upload-input__item-button:hover))
24
+ + .np-upload-input__section--uploader .np-upload-input__upload-button::before {
25
+ left: 0;
26
+ width: 100%;
27
+ top: 0;
90
28
  }
91
29
  }
92
- }
30
+ }
@@ -25,23 +25,23 @@ const files = [
25
25
  filename: 'purchase-receipt-1.pdf',
26
26
  },
27
27
  {
28
- id: 6,
29
- filename: 'purchase-receipt-1.pdf',
28
+ id: 3,
29
+ filename: 'purchase-receipt-2.pdf',
30
30
  url: 'https://wise.com/public-resources/assets/logos/wise/brand_logo_inverse.svg',
31
31
  },
32
32
  {
33
- id: 3,
33
+ id: 4,
34
34
  filename: 'receipt failed.png',
35
35
  status: Status.FAILED,
36
36
  },
37
37
  {
38
- id: 4,
38
+ id: 5,
39
39
  filename: 'receipt failed With error string.png',
40
40
  status: Status.FAILED,
41
41
  error: 'Something went wrong',
42
42
  },
43
43
  {
44
- id: 5,
44
+ id: 6,
45
45
  filename: 'receipt failed With error object.png',
46
46
  status: Status.FAILED,
47
47
  error: { message: 'Something went wrong' },
@@ -345,39 +345,50 @@ const UploadInput = ({
345
345
  className={clsx('np-upload-input', className, { disabled })}
346
346
  {...inputAttributes}
347
347
  >
348
- {uploadedFiles.map((file, index) => (
349
- <UploadItem
350
- key={file.id}
351
- ref={(el: UploadItemRef | null) => {
352
- itemRefs.current[index] = el;
353
- }}
354
- file={file}
355
- singleFileUpload={!multiple}
356
- canDelete={
357
- (!!onDeleteFile || file.status === Status.FAILED) &&
358
- (!file.status || !PROGRESS_STATUSES.has(file.status))
359
- }
360
- onDelete={
361
- file.status === Status.FAILED
362
- ? () => removeFile(file)
363
- : () => setMarkedFileForDelete(file)
364
- }
365
- onDownload={onDownload}
366
- />
367
- ))}
348
+ <div
349
+ className="np-upload-input__section"
350
+ aria-live="polite"
351
+ aria-relevant="all"
352
+ role="region"
353
+ >
354
+ {uploadedFiles.map((file, index) => (
355
+ <UploadItem
356
+ key={file.id}
357
+ ref={(el: UploadItemRef | null) => {
358
+ itemRefs.current[index] = el;
359
+ }}
360
+ file={file}
361
+ singleFileUpload={!multiple}
362
+ canDelete={
363
+ (!!onDeleteFile || file.status === Status.FAILED) &&
364
+ (!file.status || !PROGRESS_STATUSES.has(file.status))
365
+ }
366
+ onDelete={
367
+ file.status === Status.FAILED
368
+ ? () => removeFile(file)
369
+ : () => setMarkedFileForDelete(file)
370
+ }
371
+ onDownload={onDownload}
372
+ />
373
+ ))}
374
+ </div>
368
375
  {(multiple || (!multiple && !uploadedFiles.length)) && (
369
- <UploadButton
370
- ref={uploadInputRef}
371
- id={id}
372
- uploadButtonTitle={uploadButtonTitle}
373
- disabled={areMaximumFilesUploadedAlready() || disabled}
374
- multiple={multiple}
375
- fileTypes={fileTypes}
376
- sizeLimit={sizeLimit}
377
- description={description}
378
- maxFiles={maxFiles}
379
- onChange={addFiles}
380
- />
376
+ <div className="np-upload-input__section np-upload-input__section--uploader">
377
+ <UploadButton
378
+ ref={uploadInputRef}
379
+ id={id}
380
+ uploadButtonTitle={uploadButtonTitle}
381
+ disabled={areMaximumFilesUploadedAlready() || disabled}
382
+ multiple={multiple}
383
+ fileTypes={fileTypes}
384
+ sizeLimit={sizeLimit}
385
+ description={description}
386
+ maxFiles={maxFiles}
387
+ withEntries={Boolean(uploadedFiles.length)}
388
+ onChange={addFiles}
389
+
390
+ />
391
+ </div>
381
392
  )}
382
393
  </div>
383
394
  <Modal
@@ -1,44 +1,91 @@
1
- .np-upload-button-container {
2
- border-style: solid;
3
- }
4
- .np-upload-button-container .droppable-card-content {
1
+ .np-upload-input__upload-button {
2
+ position: relative;
3
+ padding: 16px;
4
+ padding: var(--size-16);
5
5
  display: flex;
6
+ align-items: center;
7
+ margin: 0;
8
+ border-bottom-left-radius: 10px;
9
+ border-bottom-left-radius: var(--radius-small);
10
+ border-bottom-right-radius: 10px;
11
+ border-bottom-right-radius: var(--radius-small);
12
+ border: var(--outerBorder);
13
+ cursor: pointer;
14
+ }
15
+ .np-upload-input__upload-button .np-upload-input__title {
16
+ color: var(--color-content-link);
17
+ -webkit-text-decoration: underline;
18
+ text-decoration: underline;
19
+ text-underline-offset: 0.3em;
20
+ }
21
+ .np-upload-input__upload-button .np-upload-input__title + .np-upload-input__text {
22
+ margin-top: 4px;
23
+ margin-top: var(--size-4);
24
+ line-height: 22px;
6
25
  }
7
- .np-upload-button-container.droppable-dropping {
8
- border-color: #c9cbce !important;
9
- border-color: var(--color-interactive-secondary) !important;
26
+ .np-upload-input__upload-button .np-upload-input__icon {
27
+ padding-right: 16px;
28
+ padding-right: var(--size-16);
29
+ color: var(--color-interactive-primary);
10
30
  }
11
- .np-upload-button-container.droppable-dropping:before {
12
- z-index: 2;
31
+ .np-upload-input__upload-button.is-dropping .np-upload-input__icon,
32
+ .np-upload-input__upload-button.is-dropping .np-upload-input__item-content {
33
+ display: none;
13
34
  }
14
- .np-upload-button-container input[type="file"] {
35
+ .np-upload-input__upload-button:focus-within,
36
+ .np-upload-input__upload-button:focus-visible {
37
+ outline: var(--ring-outline-color) solid 3px;
38
+ outline-offset: -3px;
39
+ }
40
+ .np-upload-input__upload-button-input {
41
+ position: absolute;
15
42
  opacity: 0;
16
43
  z-index: -1;
17
- position: absolute;
18
44
  }
19
- .np-upload-button-container .np-upload-button {
20
- border: none;
45
+ .np-upload-input__upload-button-input:focus {
46
+ outline: none;
21
47
  }
22
- .np-upload-button {
23
- width: 100%;
24
- border-top: 1px solid transparent;
25
- padding: 16px;
26
- padding: var(--padding-small);
27
- border-radius: 0;
48
+ .np-upload-input__upload-button .np-upload-input__drop-file-overlay {
49
+ display: flex;
50
+ flex: 1;
51
+ padding: 13px 0 !important;
52
+ background-color: transparent;
53
+ transition: transform 0.3s ease;
54
+ position: relative;
28
55
  }
29
- label.np-upload-button:not(.disabled):hover,
30
- label.np-upload-button:not(.disabled):active {
31
- background-color: var(--color-background-screen-hover);
56
+ .np-upload-input__upload-button--with-entries {
57
+ border-top-width: 0;
32
58
  }
33
- .disabled label.np-upload-button:not(.disabled):hover,
34
- .disabled label.np-upload-button:not(.disabled):active {
35
- background-color: transparent;
59
+ .np-upload-input__upload-button--with-entries:before {
60
+ display: block;
61
+ position: absolute;
62
+ height: 1px;
63
+ background-color: rgba(0,0,0,0.10196);
64
+ background-color: var(--color-border-neutral);
65
+ content: " ";
66
+ left: 16px;
67
+ left: var(--size-16);
68
+ width: calc(100% - 2 * 16px);
69
+ width: calc(100% - 2 * var(--size-16));
70
+ top: 0;
71
+ }
72
+ .np-upload-input__upload-button--without-entries {
73
+ border-top: var(--outerBorder);
74
+ border-radius: 10px;
75
+ border-radius: var(--radius-small);
36
76
  }
37
- .np-upload-button .media {
38
- align-items: flex-start;
77
+ .np-upload-input__upload-button--enabled.is-dropping,
78
+ .np-upload-input__upload-button--enabled:hover,
79
+ .np-upload-input__upload-button--enabled:active {
80
+ background: rgba(134,167,189,0.10196);
81
+ background: var(--color-background-neutral);
82
+ }
83
+ .np-upload-input__upload-button--enabled.is-dropping:before,
84
+ .np-upload-input__upload-button--enabled:hover:before,
85
+ .np-upload-input__upload-button--enabled:active:before {
86
+ width: 100%;
87
+ left: 0;
39
88
  }
40
- @media (max-width: 320px) {
41
- .np-upload-icon {
42
- padding-left: 0;
43
- }
89
+ .np-upload-input__upload-button--disabled {
90
+ cursor: inherit;
44
91
  }
@@ -1,55 +1,98 @@
1
- .np-upload-button-container {
2
- border-style: solid;
1
+ .np-upload-input__upload-button {
2
+ position: relative;
3
+ padding: var(--size-16);
4
+ display: flex;
5
+ align-items: center;
6
+ margin: 0;
7
+ border-bottom-left-radius: var(--radius-small);
8
+ border-bottom-right-radius: var(--radius-small);
9
+ border: var(--outerBorder);
10
+ cursor: pointer;
3
11
 
4
- .droppable-card-content {
5
- display: flex;
12
+ .np-upload-input__title {
13
+ color: var(--color-content-link);
14
+ text-decoration: underline;
15
+ text-underline-offset: 0.3em;
16
+
17
+ & + .np-upload-input__text {
18
+ margin-top: var(--size-4);
19
+ line-height: 22px;
20
+ }
6
21
  }
7
22
 
8
- &.droppable-dropping {
9
- border-color: var(--color-interactive-secondary) !important;
23
+ .np-upload-input__icon {
24
+ padding-right: var(--size-16);
25
+ color: var(--color-interactive-primary);
26
+ }
10
27
 
11
- &:before {
12
- z-index: 2;
28
+ &.is-dropping {
29
+ .np-upload-input__icon,
30
+ .np-upload-input__item-content {
31
+ display: none;
13
32
  }
14
33
  }
15
34
 
16
- input[type="file"] {
35
+ &:focus-within,
36
+ &:focus-visible {
37
+ outline: var(--ring-outline-color) solid 3px;
38
+ outline-offset: -3px;
39
+ }
40
+
41
+ &-input {
42
+ position: absolute;
17
43
  opacity: 0;
18
44
  z-index: -1;
19
- position: absolute;
45
+
46
+ &:focus {
47
+ outline: none;
48
+ }
20
49
  }
21
50
 
22
- .np-upload-button {
23
- border: none;
51
+ .np-upload-input__drop-file-overlay {
52
+ display: flex;
53
+ flex: 1;
54
+ padding: 13px 0 !important;
55
+ background-color: transparent;
56
+ transition: transform 0.3s ease;
57
+ position: relative;
24
58
  }
25
59
  }
26
60
 
27
- .np-upload-button {
28
- width: 100%;
29
- border-top: 1px solid transparent;
30
- padding: var(--padding-small);
31
- border-radius: 0;
32
-
33
- label& {
34
- &:not(.disabled) {
35
- &:hover,
36
- &:active {
37
- background-color: var(--color-background-screen-hover);
38
-
39
- .disabled & {
40
- background-color: transparent;
41
- }
42
- }
43
- }
44
- }
61
+ // at least 1 file uploaded or 1 error visible
62
+ .np-upload-input__upload-button--with-entries {
63
+ border-top-width: 0;
45
64
 
46
- .media {
47
- align-items: flex-start;
65
+ &:before {
66
+ display: block;
67
+ position: absolute;
68
+ height: 1px;
69
+ background-color: var(--color-border-neutral);
70
+ content: " ";
71
+ left: var(--size-16);
72
+ width: calc(100% - 2 * var(--size-16));
73
+ top: 0;
48
74
  }
49
75
  }
50
76
 
51
- .np-upload-icon{
52
- @media (max-width: 320px) {
53
- padding-left: 0;
77
+ // no files uploaded (only button shown)
78
+ .np-upload-input__upload-button--without-entries {
79
+ border-top: var(--outerBorder);
80
+ border-radius: var(--radius-small);
81
+ }
82
+
83
+ .np-upload-input__upload-button--enabled {
84
+ &.is-dropping,
85
+ &:hover,
86
+ &:active {
87
+ background: var(--color-background-neutral);
88
+
89
+ &:before {
90
+ width: 100%;
91
+ left: 0;
92
+ }
54
93
  }
55
94
  }
95
+
96
+ .np-upload-input__upload-button--disabled {
97
+ cursor: inherit;
98
+ }
@@ -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
  );