@transferwise/components 0.0.0-experimental-58ab0d7 → 0.0.0-experimental-4530892

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 (179) hide show
  1. package/build/avatarLayout/AvatarLayout.js +2 -9
  2. package/build/avatarLayout/AvatarLayout.js.map +1 -1
  3. package/build/avatarLayout/AvatarLayout.mjs +2 -9
  4. package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
  5. package/build/avatarView/AvatarView.js +12 -1
  6. package/build/avatarView/AvatarView.js.map +1 -1
  7. package/build/avatarView/AvatarView.mjs +12 -1
  8. package/build/avatarView/AvatarView.mjs.map +1 -1
  9. package/build/button/Button.js +79 -78
  10. package/build/button/Button.js.map +1 -1
  11. package/build/button/Button.mjs +80 -79
  12. package/build/button/Button.mjs.map +1 -1
  13. package/build/circularButton/CircularButton.js +18 -21
  14. package/build/circularButton/CircularButton.js.map +1 -1
  15. package/build/circularButton/CircularButton.mjs +19 -22
  16. package/build/circularButton/CircularButton.mjs.map +1 -1
  17. package/build/criticalBanner/CriticalCommsBanner.js +2 -2
  18. package/build/criticalBanner/CriticalCommsBanner.js.map +1 -1
  19. package/build/criticalBanner/CriticalCommsBanner.mjs +1 -1
  20. package/build/definitionList/DefinitionList.js.map +1 -1
  21. package/build/definitionList/DefinitionList.mjs.map +1 -1
  22. package/build/header/Header.js +2 -2
  23. package/build/header/Header.js.map +1 -1
  24. package/build/header/Header.mjs +1 -1
  25. package/build/i18n/de.json +1 -0
  26. package/build/i18n/de.json.js +1 -0
  27. package/build/i18n/de.json.js.map +1 -1
  28. package/build/i18n/de.json.mjs +1 -0
  29. package/build/i18n/de.json.mjs.map +1 -1
  30. package/build/i18n/it.json +1 -0
  31. package/build/i18n/it.json.js +1 -0
  32. package/build/i18n/it.json.js.map +1 -1
  33. package/build/i18n/it.json.mjs +1 -0
  34. package/build/i18n/it.json.mjs.map +1 -1
  35. package/build/i18n/ja.json +1 -0
  36. package/build/i18n/ja.json.js +1 -0
  37. package/build/i18n/ja.json.js.map +1 -1
  38. package/build/i18n/ja.json.mjs +1 -0
  39. package/build/i18n/ja.json.mjs.map +1 -1
  40. package/build/i18n/pt.json +1 -0
  41. package/build/i18n/pt.json.js +1 -0
  42. package/build/i18n/pt.json.js.map +1 -1
  43. package/build/i18n/pt.json.mjs +1 -0
  44. package/build/i18n/pt.json.mjs.map +1 -1
  45. package/build/i18n/ru.json +1 -0
  46. package/build/i18n/ru.json.js +1 -0
  47. package/build/i18n/ru.json.js.map +1 -1
  48. package/build/i18n/ru.json.mjs +1 -0
  49. package/build/i18n/ru.json.mjs.map +1 -1
  50. package/build/i18n/th.json +1 -0
  51. package/build/i18n/th.json.js +1 -0
  52. package/build/i18n/th.json.js.map +1 -1
  53. package/build/i18n/th.json.mjs +1 -0
  54. package/build/i18n/th.json.mjs.map +1 -1
  55. package/build/i18n/zh-HK.json +1 -0
  56. package/build/i18n/zh-HK.json.js +1 -0
  57. package/build/i18n/zh-HK.json.js.map +1 -1
  58. package/build/i18n/zh-HK.json.mjs +1 -0
  59. package/build/i18n/zh-HK.json.mjs.map +1 -1
  60. package/build/index.js +2 -2
  61. package/build/index.mjs +1 -1
  62. package/build/link/Link.js +3 -8
  63. package/build/link/Link.js.map +1 -1
  64. package/build/link/Link.mjs +3 -8
  65. package/build/link/Link.mjs.map +1 -1
  66. package/build/main.css +17 -419
  67. package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js +3 -1
  68. package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.js.map +1 -1
  69. package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs +3 -1
  70. package/build/primitives/PrimitiveAnchor/src/PrimitiveAnchor.mjs.map +1 -1
  71. package/build/primitives/PrimitiveButton/src/PrimitiveButton.js +4 -1
  72. package/build/primitives/PrimitiveButton/src/PrimitiveButton.js.map +1 -1
  73. package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs +4 -1
  74. package/build/primitives/PrimitiveButton/src/PrimitiveButton.mjs.map +1 -1
  75. package/build/select/Select.js +3 -5
  76. package/build/select/Select.js.map +1 -1
  77. package/build/select/Select.mjs +2 -4
  78. package/build/select/Select.mjs.map +1 -1
  79. package/build/styles/avatarLayout/AvatarLayout.css +0 -11
  80. package/build/styles/button/Button.css +16 -243
  81. package/build/styles/circularButton/CircularButton.css +17 -158
  82. package/build/styles/main.css +17 -419
  83. package/build/types/avatarLayout/AvatarLayout.d.ts +2 -1
  84. package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
  85. package/build/types/avatarLayout/index.d.ts +0 -1
  86. package/build/types/avatarLayout/index.d.ts.map +1 -1
  87. package/build/types/avatarView/AvatarView.d.ts.map +1 -1
  88. package/build/types/button/Button.d.ts +23 -1
  89. package/build/types/button/Button.d.ts.map +1 -1
  90. package/build/types/button/index.d.ts +2 -2
  91. package/build/types/button/index.d.ts.map +1 -1
  92. package/build/types/circularButton/CircularButton.d.ts +11 -4
  93. package/build/types/circularButton/CircularButton.d.ts.map +1 -1
  94. package/build/types/definitionList/DefinitionList.d.ts +1 -2
  95. package/build/types/definitionList/DefinitionList.d.ts.map +1 -1
  96. package/build/types/link/Link.d.ts +2 -2
  97. package/build/types/link/Link.d.ts.map +1 -1
  98. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.d.ts.map +1 -1
  99. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts +1 -1
  100. package/build/types/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.d.ts.map +1 -1
  101. package/build/types/primitives/PrimitiveButton/src/PrimitiveButton.d.ts.map +1 -1
  102. package/build/types/select/Select.d.ts.map +1 -1
  103. package/build/upload/steps/completeStep/completeStep.js +2 -2
  104. package/build/upload/steps/completeStep/completeStep.js.map +1 -1
  105. package/build/upload/steps/completeStep/completeStep.mjs +1 -1
  106. package/build/upload/steps/processingStep/processingStep.js +2 -2
  107. package/build/upload/steps/processingStep/processingStep.js.map +1 -1
  108. package/build/upload/steps/processingStep/processingStep.mjs +1 -1
  109. package/build/uploadInput/UploadInput.js +3 -3
  110. package/build/uploadInput/UploadInput.js.map +1 -1
  111. package/build/uploadInput/UploadInput.mjs +1 -1
  112. package/package.json +3 -3
  113. package/src/avatarLayout/AvatarLayout.css +0 -11
  114. package/src/avatarLayout/AvatarLayout.less +1 -18
  115. package/src/avatarLayout/AvatarLayout.tsx +3 -11
  116. package/src/avatarLayout/index.ts +0 -1
  117. package/src/avatarView/AvatarView.tsx +15 -1
  118. package/src/button/Button.css +16 -243
  119. package/src/button/Button.less +14 -212
  120. package/src/button/Button.spec.tsx +231 -54
  121. package/src/button/Button.story.tsx +137 -644
  122. package/src/button/Button.tsx +132 -98
  123. package/src/button/__snapshots__/Button.spec.tsx.snap +309 -0
  124. package/src/button/index.ts +3 -2
  125. package/src/circularButton/CircularButton.css +17 -158
  126. package/src/circularButton/CircularButton.less +22 -91
  127. package/src/circularButton/CircularButton.story.tsx +45 -24
  128. package/src/circularButton/CircularButton.tsx +38 -25
  129. package/src/dateInput/DateInput.spec.tsx +45 -26
  130. package/src/definitionList/DefinitionList.story.tsx +57 -57
  131. package/src/definitionList/DefinitionList.tsx +1 -1
  132. package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +1 -1
  133. package/src/i18n/de.json +1 -0
  134. package/src/i18n/it.json +1 -0
  135. package/src/i18n/ja.json +1 -0
  136. package/src/i18n/pt.json +1 -0
  137. package/src/i18n/ru.json +1 -0
  138. package/src/i18n/th.json +1 -0
  139. package/src/i18n/zh-HK.json +1 -0
  140. package/src/iconButton/IconButton.story.tsx +6 -6
  141. package/src/inputs/SelectInput.story.tsx +1 -1
  142. package/src/link/Link.tsx +6 -15
  143. package/src/main.css +17 -419
  144. package/src/main.less +0 -1
  145. package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.tsx +7 -1
  146. package/src/primitives/PrimitiveAnchor/src/PrimitiveAnchor.types.ts +1 -1
  147. package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +3 -1
  148. package/src/primitives/PrimitiveButton/src/PrimitiveButton.tsx +8 -1
  149. package/src/primitives/PrimitiveButton/test/PrimitiveButton.spec.tsx +5 -2
  150. package/src/select/Select.tsx +0 -1
  151. package/src/slidingPanel/SlidingPanel.spec.tsx +69 -0
  152. package/build/button/Button.resolver.js +0 -78
  153. package/build/button/Button.resolver.js.map +0 -1
  154. package/build/button/Button.resolver.mjs +0 -76
  155. package/build/button/Button.resolver.mjs.map +0 -1
  156. package/build/button/LegacyButton.js +0 -114
  157. package/build/button/LegacyButton.js.map +0 -1
  158. package/build/button/LegacyButton.mjs +0 -112
  159. package/build/button/LegacyButton.mjs.map +0 -1
  160. package/build/styles/button/Button.vars.css +0 -55
  161. package/build/styles/button/LegacyButton.css +0 -23
  162. package/build/types/button/Button.resolver.d.ts +0 -31
  163. package/build/types/button/Button.resolver.d.ts.map +0 -1
  164. package/build/types/button/Button.types.d.ts +0 -70
  165. package/build/types/button/Button.types.d.ts.map +0 -1
  166. package/build/types/button/LegacyButton.d.ts +0 -30
  167. package/build/types/button/LegacyButton.d.ts.map +0 -1
  168. package/src/button/Button.resolver.tsx +0 -120
  169. package/src/button/Button.types.ts +0 -93
  170. package/src/button/Button.vars.css +0 -55
  171. package/src/button/Button.vars.less +0 -69
  172. package/src/button/LegacyButton.css +0 -23
  173. package/src/button/LegacyButton.less +0 -24
  174. package/src/button/LegacyButton.spec.tsx +0 -146
  175. package/src/button/LegacyButton.story.tsx +0 -224
  176. package/src/button/LegacyButton.tsx +0 -161
  177. package/src/circularButton/_button-label-states.less +0 -34
  178. package/src/definitionList/DefinitionList.spec.js +0 -91
  179. package/src/slidingPanel/SlidingPanel.spec.js +0 -56
@@ -2,173 +2,32 @@
2
2
  display: inline-flex;
3
3
  flex-direction: column;
4
4
  align-items: center;
5
- text-align: center;
6
5
  cursor: pointer;
7
- position: relative;
8
6
  }
9
- .np-circular-btn .tw-icon {
10
- position: absolute;
11
- top: 16px;
12
- top: var(--size-16);
13
- pointer-events: none;
14
- color: white;
15
- transition: color 0.15s ease-in-out;
16
- width: 100%;
17
- left: 0;
18
- }
19
- [dir="rtl"] .np-circular-btn .tw-icon {
20
- right: 0;
21
- left: auto;
22
- left: initial;
23
- }
24
- @media (max-width: 320px) {
25
- .np-circular-btn .tw-icon {
26
- top: 12px;
27
- top: var(--size-12);
28
- }
29
- }
30
- .np-circular-btn .tw-icon > svg {
31
- margin: 0 auto;
32
- }
33
- .np-theme-personal .np-circular-btn {
34
- /* stylelint-disable-next-line no-duplicate-selectors */
35
- }
36
- .np-theme-personal .np-circular-btn .tw-icon,
37
- .np-theme-personal .np-circular-btn .tw-icon:hover,
38
- .np-theme-personal .np-circular-btn .tw-icon:active {
39
- color: var(--color-interactive-control);
40
- }
41
- .np-theme-personal .np-circular-btn.negative .tw-icon,
42
- .np-theme-personal .np-circular-btn.negative.secondary:not(.disabled):not(:disabled):hover .tw-icon,
43
- .np-theme-personal .np-circular-btn.negative.secondary:not(.disabled):not(:disabled):active .tw-icon {
44
- color: var(--color-contrast) !important;
45
- }
46
- .np-theme-personal .np-circular-btn.negative.secondary:not(.disabled):not(:disabled) .tw-icon {
47
- color: var(--color-sentiment-negative) !important;
48
- }
49
- .np-circular-btn.accent .np-circular-btn__label {
50
- color: #00a2dd;
51
- color: var(--color-interactive-accent);
52
- }
53
- .np-circular-btn.accent:not(.disabled):not(:disabled):hover .np-circular-btn__label {
54
- color: #008fc9;
55
- color: var(--color-interactive-accent-hover);
56
- }
57
- .np-circular-btn.accent:active .np-circular-btn__label,
58
- .np-circular-btn.accent input[type="button"]:active ~ .np-circular-btn__label {
59
- color: #0081ba;
60
- color: var(--color-interactive-accent-active);
61
- }
62
- .np-circular-btn.accent.secondary .tw-icon {
63
- color: #00a2dd;
64
- color: var(--color-interactive-accent);
65
- }
66
- .np-circular-btn.accent.secondary:not(.disabled):not(:disabled):hover .tw-icon,
67
- .np-circular-btn.accent.secondary input[type="button"]:active + .tw-icon {
68
- color: white;
69
- }
70
- .np-circular-btn.positive .np-circular-btn__label {
71
- color: #2ead4b;
72
- color: var(--color-interactive-positive);
73
- }
74
- .np-circular-btn.positive:not(.disabled):not(:disabled):hover .np-circular-btn__label {
75
- color: #069939;
76
- color: var(--color-interactive-positive-hover);
77
- }
78
- .np-circular-btn.positive:active .np-circular-btn__label,
79
- .np-circular-btn.positive input[type="button"]:active ~ .np-circular-btn__label {
80
- color: #008b2b;
81
- color: var(--color-interactive-positive-active);
82
- }
83
- .np-circular-btn.positive.secondary .tw-icon {
84
- color: #2ead4b;
85
- color: var(--color-interactive-positive);
86
- }
87
- .np-circular-btn.positive.secondary:not(.disabled):not(:disabled):hover .tw-icon,
88
- .np-circular-btn.positive.secondary input[type="button"]:active + .tw-icon {
89
- color: white;
90
- }
91
- .np-circular-btn.negative .np-circular-btn__label {
92
- color: #e74848;
93
- color: var(--color-interactive-negative);
94
- }
95
- .np-circular-btn.negative:not(.disabled):not(:disabled):hover .np-circular-btn__label {
96
- color: #d03238;
97
- color: var(--color-interactive-negative-hover);
98
- }
99
- .np-circular-btn.negative:active .np-circular-btn__label,
100
- .np-circular-btn.negative input[type="button"]:active ~ .np-circular-btn__label {
101
- color: #bf1e2c;
102
- color: var(--color-interactive-negative-active);
103
- }
104
- .np-circular-btn.negative.secondary .tw-icon {
105
- color: #e74848;
106
- color: var(--color-interactive-negative);
107
- }
108
- .np-circular-btn.negative.secondary:not(.disabled):not(:disabled):hover .tw-icon,
109
- .np-circular-btn.negative.secondary input[type="button"]:active + .tw-icon {
110
- color: white;
111
- }
112
- .np-theme-personal .np-circular-btn.accent .np-circular-btn__label {
7
+ .np-circular-btn-primary-default .np-circular-btn-label,
8
+ .np-circular-btn-secondary-default .np-circular-btn-label {
113
9
  color: var(--color-interactive-primary);
114
10
  }
115
- .np-theme-personal .np-circular-btn.accent:not(.disabled):not(:disabled):hover .np-circular-btn__label {
11
+ .np-circular-btn-primary-default .np-circular-btn-label:not(.disabled):not(:disabled):hover,
12
+ .np-circular-btn-secondary-default .np-circular-btn-label:not(.disabled):not(:disabled):hover {
116
13
  color: var(--color-interactive-primary-hover);
117
14
  }
118
- .np-theme-personal .np-circular-btn.accent:active .np-circular-btn__label,
119
- .np-theme-personal .np-circular-btn.accent input[type="button"]:active ~ .np-circular-btn__label {
15
+ .np-circular-btn-primary-default .np-circular-btn-label:not(.disabled):not(:disabled):active,
16
+ .np-circular-btn-secondary-default .np-circular-btn-label:not(.disabled):not(:disabled):active {
120
17
  color: var(--color-interactive-primary-active);
121
18
  }
122
- .np-theme-personal .np-circular-btn.accent.secondary .tw-icon {
123
- color: var(--color-interactive-primary);
124
- }
125
- .np-theme-personal .np-circular-btn.accent.secondary:not(.disabled):not(:disabled):hover .tw-icon,
126
- .np-theme-personal .np-circular-btn.accent.secondary input[type="button"]:active + .tw-icon {
127
- color: white;
128
- color: var(--color-interactive-control);
129
- }
130
- .np-theme-personal .np-circular-btn.accent.secondary:active input[type="button"] + .tw-icon {
131
- color: var(--color-interactive-control);
132
- }
133
- .np-theme-personal .np-circular-btn.positive .np-circular-btn__label {
134
- color: var(--color-interactive-primary);
135
- }
136
- .np-theme-personal .np-circular-btn.positive:not(.disabled):not(:disabled):hover .np-circular-btn__label {
137
- color: var(--color-interactive-primary-hover);
138
- }
139
- .np-theme-personal .np-circular-btn.positive:active .np-circular-btn__label,
140
- .np-theme-personal .np-circular-btn.positive input[type="button"]:active ~ .np-circular-btn__label {
141
- color: var(--color-interactive-primary-active);
142
- }
143
- .np-theme-personal .np-circular-btn.positive.secondary .tw-icon {
144
- color: var(--color-interactive-primary);
145
- }
146
- .np-theme-personal .np-circular-btn.positive.secondary:not(.disabled):not(:disabled):hover .tw-icon,
147
- .np-theme-personal .np-circular-btn.positive.secondary input[type="button"]:active + .tw-icon {
148
- color: white;
149
- color: var(--color-interactive-control);
150
- }
151
- .np-theme-personal .np-circular-btn.positive.secondary:active input[type="button"] + .tw-icon {
152
- color: var(--color-interactive-control);
153
- }
154
- .np-theme-personal .np-circular-btn.negative .np-circular-btn__label {
155
- color: var(--color-sentiment-negative);
156
- }
157
- .np-theme-personal .np-circular-btn.negative:not(.disabled):not(:disabled):hover .np-circular-btn__label {
158
- color: var(--color-sentiment-negative-hover);
159
- }
160
- .np-theme-personal .np-circular-btn.negative:active .np-circular-btn__label,
161
- .np-theme-personal .np-circular-btn.negative input[type="button"]:active ~ .np-circular-btn__label {
162
- color: var(--color-sentiment-negative-active);
19
+ .np-circular-btn-primary-negative .np-circular-btn-label,
20
+ .np-circular-btn-secondary-negative .np-circular-btn-label {
21
+ color: var(--color-sentiment-negative-primary);
163
22
  }
164
- .np-theme-personal .np-circular-btn.negative.secondary .tw-icon {
165
- color: var(--color-sentiment-negative);
23
+ .np-circular-btn-primary-negative .np-circular-btn-label:not(.disabled):not(:disabled):hover,
24
+ .np-circular-btn-secondary-negative .np-circular-btn-label:not(.disabled):not(:disabled):hover {
25
+ color: var(--color-sentiment-negative-primary-hover);
166
26
  }
167
- .np-theme-personal .np-circular-btn.negative.secondary:not(.disabled):not(:disabled):hover .tw-icon,
168
- .np-theme-personal .np-circular-btn.negative.secondary input[type="button"]:active + .tw-icon {
169
- color: white;
170
- color: var(--color-interactive-control);
27
+ .np-circular-btn-primary-negative .np-circular-btn-label:not(.disabled):not(:disabled):active,
28
+ .np-circular-btn-secondary-negative .np-circular-btn-label:not(.disabled):not(:disabled):active {
29
+ color: var(--color-sentiment-negative-primary-active);
171
30
  }
172
- .np-theme-personal .np-circular-btn.negative.secondary:active input[type="button"] + .tw-icon {
173
- color: var(--color-interactive-control);
31
+ .np-circular-btn-disabled {
32
+ cursor: not-allowed;
174
33
  }
@@ -1,105 +1,36 @@
1
- @import (reference) "../../node_modules/@transferwise/neptune-css/src/less/mixins/_logical-properties.less";
2
- @import "./_button-label-states.less";
3
-
4
1
  .np-circular-btn {
5
2
  display: inline-flex;
6
3
  flex-direction: column;
7
4
  align-items: center;
8
- text-align: center;
9
5
  cursor: pointer;
10
- position: relative;
11
-
12
- .tw-icon {
13
- position: absolute;
14
- top: var(--size-16);
15
- pointer-events: none;
16
- color: white;
17
- transition: color 0.15s ease-in-out;
18
- width: 100%;
19
- .left(0);
20
6
 
21
- @media (--screen-400-zoom) {
22
- top: var(--size-12);
23
- }
24
-
25
- > svg {
26
- margin: 0 auto;
7
+ &-primary-default,
8
+ &-secondary-default {
9
+ .np-circular-btn-label {
10
+ color: var(--color-interactive-primary);
11
+ &:not(.disabled, :disabled):hover {
12
+ color: var(--color-interactive-primary-hover);
13
+ }
14
+ &:not(.disabled, :disabled):active {
15
+ color: var(--color-interactive-primary-active);
16
+ }
27
17
  }
28
18
  }
29
19
 
30
- .np-theme-personal & {
31
- /* stylelint-disable-next-line no-duplicate-selectors */
32
- .tw-icon {
33
- &,
34
- &:hover,
35
- &:active {
36
- color: var(--color-interactive-control);
20
+ &-primary-negative,
21
+ &-secondary-negative {
22
+ .np-circular-btn-label {
23
+ color: var(--color-sentiment-negative-primary);
24
+ &:not(.disabled, :disabled):hover {
25
+ color: var(--color-sentiment-negative-primary-hover);
26
+ }
27
+ &:not(.disabled, :disabled):active {
28
+ color: var(--color-sentiment-negative-primary-active);
37
29
  }
38
- }
39
-
40
- &.negative .tw-icon,
41
- &.negative.secondary:not(.disabled, :disabled):hover .tw-icon,
42
- &.negative.secondary:not(.disabled, :disabled):active .tw-icon {
43
- // TODO, this will need to be removed when we update our CSS architecture
44
- color: var(--color-contrast) !important;
45
- }
46
-
47
- &.negative.secondary:not(.disabled, :disabled) .tw-icon {
48
- // TODO, this will need to be removed when we update our CSS architecture
49
- color: var(--color-sentiment-negative) !important;
50
30
  }
51
31
  }
52
- }
53
-
54
- .button-label-states(
55
- np-circular-btn,
56
- accent,
57
- var(--color-interactive-accent),
58
- var(--color-interactive-accent-hover),
59
- var(--color-interactive-accent-active)
60
- );
61
-
62
- .button-label-states(
63
- np-circular-btn,
64
- positive,
65
- var(--color-interactive-positive),
66
- var(--color-interactive-positive-hover),
67
- var(--color-interactive-positive-active)
68
- );
69
32
 
70
- .button-label-states(
71
- np-circular-btn,
72
- negative,
73
- var(--color-interactive-negative),
74
- var(--color-interactive-negative-hover),
75
- var(--color-interactive-negative-active)
76
- );
77
-
78
- .np-theme-personal {
79
- .button-label-states(
80
- np-circular-btn,
81
- accent,
82
- var(--color-interactive-primary),
83
- var(--color-interactive-primary-hover),
84
- var(--color-interactive-primary-active),
85
- true
86
- );
87
-
88
- .button-label-states(
89
- np-circular-btn,
90
- positive,
91
- var(--color-interactive-primary),
92
- var(--color-interactive-primary-hover),
93
- var(--color-interactive-primary-active),
94
- true
95
- );
96
-
97
- .button-label-states(
98
- np-circular-btn,
99
- negative,
100
- var(--color-sentiment-negative),
101
- var(--color-sentiment-negative-hover),
102
- var(--color-sentiment-negative-active),
103
- true
104
- );
33
+ &-disabled {
34
+ cursor: not-allowed;
35
+ }
105
36
  }
@@ -5,14 +5,16 @@ import { ControlType, Priority } from '../common';
5
5
  import { Meta, StoryObj } from '@storybook/react';
6
6
  import CircularButton from './CircularButton';
7
7
  import { storyConfig } from '../test-utils';
8
+ import Title from '../title';
9
+ import Body from '../body';
8
10
 
9
11
  export default {
10
12
  component: CircularButton,
11
13
  title: 'Actions/CircularButton',
14
+ tags: ['autodocs'],
12
15
  args: {
13
16
  children: 'Button text',
14
- // Needs to be cast because we're mapping icon names to components
15
- icon: 'Freeze' as unknown as React.ReactElement,
17
+ icon: <Icons.Freeze />,
16
18
  },
17
19
  argTypes: {
18
20
  icon: {
@@ -28,8 +30,8 @@ type Story = StoryObj<typeof CircularButton>;
28
30
 
29
31
  export const Basic: Story = {
30
32
  args: {
31
- priority: Priority.PRIMARY,
32
- type: ControlType.ACCENT,
33
+ priority: 'primary',
34
+ type: 'default',
33
35
  disabled: false,
34
36
  },
35
37
  };
@@ -41,26 +43,45 @@ export const All: Story = {
41
43
  render: (props) => {
42
44
  return (
43
45
  <>
44
- <div className="m-b-2">
45
- <div className="title-4 m-b-1">Accent</div>
46
- <CircularButton {...props} priority={Priority.PRIMARY} type={ControlType.ACCENT} />
47
- <CircularButton {...props} priority={Priority.SECONDARY} type={ControlType.ACCENT} />
48
- </div>
49
- <div className="m-b-2">
50
- <div className="title-4 m-b-1">Positive</div>
51
- <CircularButton {...props} priority={Priority.PRIMARY} type={ControlType.POSITIVE} />
52
- <CircularButton {...props} priority={Priority.SECONDARY} type={ControlType.POSITIVE} />
53
- </div>
54
- <div className="m-b-2">
55
- <div className="title-4 m-b-1">Negative</div>
56
- <CircularButton {...props} priority={Priority.PRIMARY} type={ControlType.NEGATIVE} />
57
- <CircularButton {...props} priority={Priority.SECONDARY} type={ControlType.NEGATIVE} />
58
- </div>
59
- <div className="m-b-2">
60
- <div className="title-4 m-b-1">Disabled</div>
61
- <CircularButton {...props} disabled />
62
- <CircularButton {...props} priority={Priority.SECONDARY} disabled />
63
- </div>
46
+ <Title type="title-subsection" className="m-y-2">
47
+ Default (Primary and secondary)
48
+ </Title>
49
+ <Body>
50
+ <CircularButton {...props} priority="primary" type="default" />
51
+ <CircularButton {...props} priority="secondary" type="default" />
52
+ <CircularButton {...props} priority="primary" type="default" disabled />
53
+ <CircularButton {...props} priority="secondary" type="default" disabled />
54
+ </Body>
55
+
56
+ <Title type="title-subsection" className="m-y-2">
57
+ Negative (Primary and secondary)
58
+ </Title>
59
+ <Body>
60
+ <CircularButton {...props} priority="primary" type="negative" />
61
+ <CircularButton {...props} priority="secondary" type="negative" />
62
+ <CircularButton {...props} priority="primary" type="negative" disabled />
63
+ <CircularButton {...props} priority="secondary" type="negative" disabled />
64
+ </Body>
65
+
66
+ <Title type="title-body" className="m-y-2">
67
+ Accent (Deprecated)
68
+ </Title>
69
+ <Body>
70
+ <CircularButton {...props} priority="primary" type="accent" />
71
+ <CircularButton {...props} priority="secondary" type="accent" />
72
+ <CircularButton {...props} priority="primary" type="accent" disabled />
73
+ <CircularButton {...props} priority="secondary" type="accent" disabled />
74
+ </Body>
75
+
76
+ <Title type="title-body" className="m-y-2">
77
+ Positive (Deprecated)
78
+ </Title>
79
+ <Body>
80
+ <CircularButton {...props} priority="primary" type="positive" />
81
+ <CircularButton {...props} priority="secondary" type="positive" />
82
+ <CircularButton {...props} priority="primary" type="positive" disabled />
83
+ <CircularButton {...props} priority="secondary" type="positive" disabled />
84
+ </Body>
64
85
  </>
65
86
  );
66
87
  },
@@ -1,20 +1,28 @@
1
1
  import { clsx } from 'clsx';
2
- import { cloneElement } from 'react';
3
2
 
4
3
  import Body from '../body/Body';
5
- import { typeClassMap, priorityClassMap } from '../button/classMap';
6
4
  import { Breakpoint, ControlType, Priority, Typography } from '../common';
7
- import Circle from '../common/circle';
5
+ import IconButton, { IconButtonProps } from '../iconButton';
8
6
  import { useMedia } from '../common/hooks/useMedia';
9
7
 
8
+ /**
9
+ * @deprecated use `'default'` instead
10
+ */
11
+ type DeprecatedTypes = `${ControlType.ACCENT | ControlType.POSITIVE}`;
12
+
10
13
  export interface CircularButtonProps {
11
14
  className?: string;
12
15
  children: string;
13
16
  disabled?: boolean;
14
- icon: React.ReactElement<{ size?: unknown }>;
15
- onClick?: React.MouseEventHandler<HTMLInputElement>;
17
+ icon: React.ReactElement<{ size?: unknown }> | React.ReactNode;
18
+ onClick?: React.MouseEventHandler<HTMLInputElement> &
19
+ React.MouseEventHandler<HTMLButtonElement> &
20
+ React.MouseEventHandler<HTMLAnchorElement>;
16
21
  priority?: `${Priority.PRIMARY | Priority.SECONDARY}`;
17
- type?: `${ControlType.ACCENT | ControlType.POSITIVE | ControlType.NEGATIVE}`;
22
+ /**
23
+ * `"accent"` and `"positive"` values are **deprecated**, please use `"default"` instead
24
+ */
25
+ type?: DeprecatedTypes | 'default' | `${ControlType.NEGATIVE}`;
18
26
  }
19
27
 
20
28
  const CircularButton = ({
@@ -22,30 +30,35 @@ const CircularButton = ({
22
30
  children,
23
31
  disabled,
24
32
  icon,
33
+ onClick,
25
34
  priority = Priority.PRIMARY,
26
- type = ControlType.ACCENT,
27
- ...rest
35
+ type = 'default',
28
36
  }: CircularButtonProps) => {
29
- const classes = clsx('btn np-btn', 'm-b-1', typeClassMap[type], priorityClassMap[priority]);
30
-
31
- const iconElement = Number(icon.props.size) !== 24 ? cloneElement(icon, { size: 24 }) : icon;
32
-
33
37
  const isTinyViewport = useMedia(`(max-width: ${Breakpoint.ZOOM_400}px)`);
34
-
35
38
  return (
36
- <label className={clsx('np-circular-btn', priority, type, disabled && 'disabled', className)}>
37
- <Circle
38
- as="input"
39
- // @ts-expect-error it's input[type=button] element
40
- type="button"
41
- size={isTinyViewport ? 72 : 56}
42
- aria-label={children}
43
- className={classes}
39
+ <label
40
+ className={clsx(
41
+ 'np-circular-btn',
42
+ `np-circular-btn-${priority}-${type}`,
43
+ { 'np-circular-btn-disabled': disabled },
44
+ className,
45
+ )}
46
+ >
47
+ <IconButton
48
+ size={isTinyViewport ? 32 : 56}
49
+ priority={priority}
50
+ type={['accent', 'positive'].includes(type) ? 'default' : (type as IconButtonProps['type'])}
51
+ className={clsx('m-b-1')}
44
52
  disabled={disabled}
45
- {...rest}
46
- />
47
- {iconElement}
48
- <Body as="span" className="np-circular-btn__label" type={Typography.BODY_DEFAULT_BOLD}>
53
+ onClick={onClick}
54
+ >
55
+ {icon}
56
+ </IconButton>
57
+ <Body
58
+ as="span"
59
+ className={clsx('np-circular-btn-label', { disabled })}
60
+ type={Typography.BODY_DEFAULT_BOLD}
61
+ >
49
62
  {children}
50
63
  </Body>
51
64
  </label>
@@ -1,19 +1,17 @@
1
- import { screen, fireEvent } from '@testing-library/react';
2
- import userEvent from '@testing-library/user-event';
3
1
  import { DateInput, DateInputProps, Field } from '..';
4
- import { mockMatchMedia, mockResizeObserver, render } from '../test-utils';
2
+ import { mockMatchMedia, mockResizeObserver, render, userEvent, screen } from '../test-utils';
5
3
 
6
- describe('Date Input Component', () => {
7
- const props: DateInputProps = { onChange: jest.fn() };
4
+ mockMatchMedia();
5
+ mockResizeObserver();
8
6
 
9
- beforeEach(() => {
10
- mockMatchMedia();
11
- mockResizeObserver();
12
- });
7
+ describe('Date Input Component', () => {
8
+ const props: DateInputProps = {
9
+ onChange: jest.fn(),
10
+ onFocus: jest.fn(),
11
+ onBlur: jest.fn(),
12
+ };
13
13
 
14
- afterEach(() => {
15
- jest.resetAllMocks();
16
- });
14
+ afterEach(jest.clearAllMocks);
17
15
 
18
16
  describe('when initialised without a model', () => {
19
17
  it('sets day field to empty', () => {
@@ -104,7 +102,7 @@ describe('Date Input Component', () => {
104
102
  await userEvent.click(monthSelect);
105
103
  await userEvent.click(screen.getByRole('option', { name: /January/ }));
106
104
  expect(props.onChange).toHaveBeenCalledWith(null);
107
- });
105
+ }, 10_000);
108
106
 
109
107
  it('calls the onChange callback with null when changing the year but nothing else is filled out', async () => {
110
108
  render(<DateInput {...props} />);
@@ -126,7 +124,7 @@ describe('Date Input Component', () => {
126
124
  await userEvent.click(monthSelect);
127
125
  await userEvent.click(screen.getByRole('option', { name: /January/ }));
128
126
  expect(props.onChange).toHaveBeenCalledWith('2022-01-01');
129
- });
127
+ }, 10_000);
130
128
 
131
129
  it('calls the onChange callback with the correct value when changing the year', async () => {
132
130
  render(<DateInput {...props} value="0122-12-1" />);
@@ -178,19 +176,40 @@ describe('Date Input Component', () => {
178
176
  });
179
177
  });
180
178
 
181
- describe('when switching from day input to year input', () => {
182
- it('does not call onBlur nor onFocus', () => {
183
- const onFocus = jest.fn();
184
- const onBlur = jest.fn();
179
+ describe('propagating focus and blur callbacks', () => {
180
+ it('should propagate if focusing from or blurring to external component', async () => {
181
+ render(
182
+ <>
183
+ <button type="button">starting point</button>
184
+ <DateInput {...props} />
185
+ </>,
186
+ );
187
+ await userEvent.tab();
188
+ await userEvent.tab();
189
+ await userEvent.tab({ shift: true });
190
+ expect(props.onFocus).toHaveBeenCalledTimes(1);
191
+ expect(props.onBlur).toHaveBeenCalledTimes(1);
192
+ });
185
193
 
186
- render(<DateInput {...props} />);
187
- const dayInput = screen.getByRole('textbox', { name: /day/i });
188
- const yearInput = screen.getByRole('textbox', { name: /year/i });
189
- fireEvent.focus(dayInput);
190
- fireEvent.blur(dayInput);
191
- fireEvent.focus(yearInput);
192
- expect(onFocus).not.toHaveBeenCalled();
193
- expect(onBlur).not.toHaveBeenCalled();
194
+ it('should not propagate if switching between internals', async () => {
195
+ render(
196
+ <>
197
+ <button type="button">external button</button>
198
+ <DateInput {...props} />
199
+ </>,
200
+ );
201
+ const externalButton = screen.getByRole('button', { name: 'external button' });
202
+
203
+ await userEvent.click(externalButton);
204
+ await userEvent.click(screen.getByRole('textbox', { name: /day/i }));
205
+ await userEvent.click(screen.getByRole('textbox', { name: /year/i }));
206
+ await userEvent.click(externalButton);
207
+
208
+ // 1 call is caused by the initial switch to the component,
209
+ // as reflected in `should propagate if focusing from or
210
+ // blurring to external component` test
211
+ expect(props.onFocus).toHaveBeenCalledTimes(1);
212
+ expect(props.onBlur).toHaveBeenCalledTimes(1);
194
213
  });
195
214
  });
196
215