Skip to content

Commit 0cfcf7c

Browse files
feat(number-input): update number input controls to new spec (#7687)
* fix(NumberInput): update button positions and icons * feat(NumberInput): reposition and restyle input controls and warnings * feat(NumberInput): add rule divider after warning and invalid icons * fix(number-input): adjust number controls for small field size * fix(number-input): adjust number controls for xl field size * fix(number-input): adjust spacing for xl and sm warning states * test(NumberInput): update icon assertions * fix(number-input): hide rule divider on warning state * fix(number-input): dimension changes during state change * fix(number-input): use light hover background token on number controls * fix(number-input): update invalid input control borders * fix(number-input): use decorative-01 for light dividers * fix(number-input): set disabled input divider color * fix(number-input): cover input control outlines on hover * fix(number-input): unhide dividers on input control hover * fix(number-input): modify display styles for rule dividers * fix(number-input): increase divider z-index for Firefox * fix(number-input): explicitly position left divider for Safari * fix(number-input): remove border on invalid controls * fix(number-input): extend divider rule styles to focus state * fix(number-input): update light invalid hover * fix(number-input): ignore pseudoelements on light variant control focus * fix(number-input): avoid percentage heights for Safari * fix(number-input): avoid conflicting outlines * docs(number-input): annotate Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent c2b4f1f commit 0cfcf7c

File tree

3 files changed

+260
-57
lines changed

3 files changed

+260
-57
lines changed

packages/components/src/components/number-input/_number-input.scss

Lines changed: 238 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@
3333
width: 100%;
3434
min-width: 9.375rem;
3535
height: rem(40px);
36-
padding-right: $carbon--spacing-07;
36+
padding-right: rem(128px);
3737
padding-left: $carbon--spacing-05;
3838
color: $text-01;
3939
font-weight: 300;
40-
4140
font-family: carbon--font-family('mono');
4241
background-color: $field-01;
43-
border: none;
44-
border-bottom: 1px solid $ui-04;
42+
border: 0;
43+
border-bottom: rem(1px) solid $ui-04;
4544
border-radius: 0;
4645
transition: background-color $duration--fast-01 motion(standard, productive),
4746
outline $duration--fast-01 motion(standard, productive);
@@ -73,6 +72,14 @@
7372
}
7473
}
7574

75+
.#{$prefix}--number--xl.#{$prefix}--number input[type='number'] {
76+
padding-right: rem(144px);
77+
}
78+
79+
.#{$prefix}--number--sm.#{$prefix}--number input[type='number'] {
80+
padding-right: rem(112px);
81+
}
82+
7683
.#{$prefix}--number input[type='number']:disabled,
7784
.#{$prefix}--number--readonly input[type='number'] {
7885
color: $disabled;
@@ -95,9 +102,11 @@
95102
top: 50%;
96103
right: 0;
97104
display: flex;
98-
flex-direction: column;
105+
flex-direction: row;
99106
align-items: center;
100107
justify-content: center;
108+
width: rem(80px);
109+
height: 100%;
101110
transform: translateY(-50%);
102111

103112
// Windows, Firefox HCM Fix
@@ -111,24 +120,36 @@
111120
.#{$prefix}--number__control-btn {
112121
@include button-reset;
113122

123+
position: relative;
114124
display: inline-flex;
115125
align-items: center;
116126
justify-content: center;
117-
width: rem(32px);
118-
height: rem(20px);
127+
height: 100%;
119128
color: $icon-01;
129+
border-bottom: rem(1px) solid $ui-04;
130+
131+
&::before,
132+
&::after {
133+
position: absolute;
134+
top: rem(2px);
135+
display: block;
136+
width: rem(2px);
137+
// height: calc(100% - 4px) is calculated differently in Safari
138+
height: rem(36px);
139+
background-color: $field-01;
140+
content: '';
141+
}
120142

121-
svg {
122-
position: relative;
123-
fill: currentColor;
143+
&::before {
144+
left: 0;
124145
}
125146

126-
&.up-icon svg {
127-
top: rem(5px);
147+
&::after {
148+
right: 0;
128149
}
129150

130-
&.down-icon svg {
131-
top: rem(-5px);
151+
svg {
152+
fill: currentColor;
132153
}
133154

134155
&:focus {
@@ -141,25 +162,189 @@
141162

142163
&:hover {
143164
color: $icon-01;
165+
background-color: $hover-ui;
144166
cursor: pointer;
167+
168+
&::before,
169+
&::after {
170+
background-color: $hover-ui;
171+
}
172+
}
173+
174+
&:focus::before,
175+
&:focus::after,
176+
&:hover:focus::before,
177+
&:hover:focus::after {
178+
background-color: transparent;
145179
}
146180

147181
&:disabled {
148182
color: $disabled;
183+
border-bottom-color: transparent;
149184
cursor: not-allowed;
150185
}
151186
}
152187

188+
// set orders to facilitate styling for rule dividers
189+
.#{$prefix}--number__control-btn.down-icon {
190+
order: 1;
191+
}
192+
193+
.#{$prefix}--number__control-btn.up-icon {
194+
order: 2;
195+
}
196+
197+
// add top and bottom outlines to number controls when input is focused
198+
.#{$prefix}--number
199+
input[type='number']:focus
200+
~ .#{$prefix}--number__controls
201+
.#{$prefix}--number__control-btn {
202+
border-bottom-width: 0;
203+
204+
&:hover {
205+
@include focus-outline('outline');
206+
207+
border: 0;
208+
}
209+
}
210+
211+
.#{$prefix}--number
212+
input[type='number'][data-invalid]
213+
~ .#{$prefix}--number__controls
214+
.#{$prefix}--number__control-btn {
215+
border-bottom-width: 0;
216+
}
217+
218+
// add invalid outline to number controls only when invalid input is not focused
219+
.#{$prefix}--number
220+
input[type='number'][data-invalid]:not(:focus)
221+
~ .#{$prefix}--number__controls
222+
.#{$prefix}--number__control-btn:hover {
223+
@include focus-outline('invalid');
224+
}
225+
226+
.#{$prefix}--number
227+
input[type='number']:focus
228+
~ .#{$prefix}--number__controls
229+
.#{$prefix}--number__control-btn.up-icon::after {
230+
background-color: transparent;
231+
}
232+
233+
.#{$prefix}--number
234+
input[type='number'][data-invalid]
235+
~ .#{$prefix}--number__controls
236+
.#{$prefix}--number__control-btn.up-icon::after {
237+
background-color: $support-01;
238+
}
239+
240+
.#{$prefix}--number
241+
input[type='number'][data-invalid]:focus
242+
~ .#{$prefix}--number__controls
243+
.#{$prefix}--number__control-btn.up-icon::after,
244+
.#{$prefix}--number
245+
input[type='number'][data-invalid]
246+
~ .#{$prefix}--number__controls
247+
.#{$prefix}--number__control-btn.up-icon:focus::after {
248+
background-color: $focus;
249+
}
250+
251+
.#{$prefix}--number__rule-divider {
252+
position: absolute;
253+
z-index: z('overlay');
254+
width: rem(1px);
255+
height: rem(16px);
256+
background-color: $ui-03;
257+
258+
&:first-of-type {
259+
order: 0;
260+
}
261+
}
262+
263+
// rule divider styles
264+
.#{$prefix}--number__controls
265+
.#{$prefix}--number__rule-divider:first-of-type {
266+
left: 0;
267+
background-color: transparent;
268+
}
269+
270+
.#{$prefix}--number__invalid
271+
+ .#{$prefix}--number__controls
272+
.#{$prefix}--number__rule-divider:first-of-type {
273+
background-color: $ui-03;
274+
}
275+
276+
.#{$prefix}--number--light .#{$prefix}--number__rule-divider,
277+
.#{$prefix}--number--light
278+
.#{$prefix}--number__invalid
279+
+ .#{$prefix}--number__controls
280+
.#{$prefix}--number__rule-divider:first-of-type {
281+
background-color: $decorative-01;
282+
}
283+
284+
.#{$prefix}--number
285+
input[type='number']:disabled
286+
+ .#{$prefix}--number__controls
287+
.#{$prefix}--number__rule-divider:first-of-type {
288+
background-color: transparent;
289+
}
290+
291+
.#{$prefix}--number
292+
input[type='number']:disabled
293+
+ .#{$prefix}--number__controls
294+
.#{$prefix}--number__rule-divider {
295+
background-color: $disabled-02;
296+
}
297+
298+
.#{$prefix}--number__control-btn:focus ~ .#{$prefix}--number__rule-divider {
299+
background-color: transparent;
300+
}
301+
153302
.#{$prefix}--number--readonly .#{$prefix}--number__control-btn {
154303
display: none;
155304
}
156305

157306
.#{$prefix}--number__invalid {
158307
position: absolute;
159-
right: 2rem;
308+
right: rem(96px);
160309
fill: $support-01;
161310
}
162311

312+
.#{$prefix}--number--xl .#{$prefix}--number__invalid {
313+
right: rem(112px);
314+
}
315+
316+
.#{$prefix}--number--sm .#{$prefix}--number__invalid {
317+
right: rem(80px);
318+
}
319+
320+
.#{$prefix}--number__invalid + .#{$prefix}--number__rule-divider {
321+
position: absolute;
322+
right: rem(80px);
323+
}
324+
325+
.#{$prefix}--number--xl
326+
.#{$prefix}--number__invalid
327+
+ .#{$prefix}--number__rule-divider {
328+
right: rem(96px);
329+
}
330+
331+
.#{$prefix}--number--sm
332+
.#{$prefix}--number__invalid
333+
+ .#{$prefix}--number__rule-divider {
334+
right: rem(64px);
335+
}
336+
337+
.#{$prefix}--number__control-btn.down-icon:hover
338+
~ .#{$prefix}--number__rule-divider,
339+
.#{$prefix}--number__control-btn.up-icon:hover
340+
+ .#{$prefix}--number__rule-divider,
341+
.#{$prefix}--number__control-btn.down-icon:focus
342+
~ .#{$prefix}--number__rule-divider,
343+
.#{$prefix}--number__control-btn.up-icon:focus
344+
+ .#{$prefix}--number__rule-divider {
345+
background-color: transparent;
346+
}
347+
163348
.#{$prefix}--number__invalid--warning {
164349
fill: $support-03;
165350
}
@@ -180,6 +365,22 @@
180365
background-color: $field-02;
181366
}
182367

368+
.#{$prefix}--number--light .#{$prefix}--number__control-btn::before,
369+
.#{$prefix}--number--light .#{$prefix}--number__control-btn::after {
370+
background-color: $field-02;
371+
}
372+
373+
.#{$prefix}--number--light .#{$prefix}--number__control-btn:focus::before,
374+
.#{$prefix}--number--light .#{$prefix}--number__control-btn:focus::after {
375+
background-color: transparent;
376+
}
377+
378+
.#{$prefix}--number--light .#{$prefix}--number__control-btn:hover,
379+
.#{$prefix}--number--light .#{$prefix}--number__control-btn:hover::before,
380+
.#{$prefix}--number--light .#{$prefix}--number__control-btn:hover::after {
381+
background-color: $hover-light-ui;
382+
}
383+
183384
.#{$prefix}--number--mobile {
184385
width: auto;
185386
min-width: rem(144px);
@@ -233,8 +434,18 @@
233434
height: rem(48px);
234435
}
235436

437+
.#{$prefix}--number--xl .#{$prefix}--number__controls {
438+
width: rem(96px);
439+
}
440+
236441
.#{$prefix}--number--xl .#{$prefix}--number__control-btn {
237-
height: rem(24px);
442+
width: rem(48px);
443+
444+
&::before,
445+
&::after {
446+
// height: calc(100% - 4px) is calculated differently in Safari
447+
height: rem(44px);
448+
}
238449
}
239450

240451
.#{$prefix}--number--xl.#{$prefix}--number--mobile
@@ -243,22 +454,22 @@
243454
height: rem(48px);
244455
}
245456

246-
.#{$prefix}--number--xl .#{$prefix}--number__control-btn.up-icon svg {
247-
// Needed to maintain arrow spacing between input sizes.
248-
top: rem(6.6px);
249-
}
250-
251-
.#{$prefix}--number--xl .#{$prefix}--number__control-btn.down-icon svg {
252-
// Needed to maintain arrow spacing between input sizes.
253-
top: rem(-6.6px);
254-
}
255-
256457
.#{$prefix}--number--sm input[type='number'] {
257458
height: rem(32px);
258459
}
259460

461+
.#{$prefix}--number--sm .#{$prefix}--number__controls {
462+
width: rem(64px);
463+
}
464+
260465
.#{$prefix}--number--sm .#{$prefix}--number__control-btn {
261-
height: rem(16px);
466+
width: rem(32px);
467+
468+
&::before,
469+
&::after {
470+
// height: calc(100% - 4px) is calculated differently in Safari
471+
height: rem(28px);
472+
}
262473
}
263474

264475
.#{$prefix}--number--sm.#{$prefix}--number--mobile
@@ -267,16 +478,6 @@
267478
height: rem(32px);
268479
}
269480

270-
.#{$prefix}--number--sm .#{$prefix}--number__control-btn.up-icon svg {
271-
// Needed to maintain arrow spacing between input sizes.
272-
top: rem(3.4px);
273-
}
274-
275-
.#{$prefix}--number--sm .#{$prefix}--number__control-btn.down-icon svg {
276-
// Needed to maintain arrow spacing between input sizes.
277-
top: rem(-3.4px);
278-
}
279-
280481
//No label positioning adjustment
281482
.#{$prefix}--number--nolabel .bx--label + .bx--form__helper-text {
282483
margin-top: 0;

0 commit comments

Comments
 (0)