Skip to content

Commit d949ec4

Browse files
feat(blazorui): add BitSpinButton features to BitNumberField #9973 (#10214)
1 parent 181d010 commit d949ec4

File tree

9 files changed

+687
-372
lines changed

9 files changed

+687
-372
lines changed

Diff for: src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTests.cs

+34-26
Original file line numberDiff line numberDiff line change
@@ -56,27 +56,26 @@ public void BitNumberFieldShouldHaveCorrectLabel(string label)
5656
}
5757

5858
[DataTestMethod,
59-
DataRow(true),
60-
DataRow(false)
59+
DataRow(null),
60+
DataRow(BitSpinButtonMode.Compact),
61+
DataRow(BitSpinButtonMode.Inline),
62+
DataRow(BitSpinButtonMode.Spread)
6163
]
62-
public void BitNumberFieldShouldRenderCorrectlyWithArrows(bool arrows)
64+
public void BitNumberFieldShouldRenderCorrectlyWithArrows(BitSpinButtonMode? mode)
6365
{
6466
var component = RenderComponent<BitNumberField<int>>(parameters =>
6567
{
66-
parameters.Add(p => p.ShowButtons, arrows);
68+
parameters.Add(p => p.Mode, mode);
6769
});
6870

69-
var arrowButtonHolder = component.FindAll(".bit-nfl-act");
70-
var arrowButtons = component.FindAll(".bit-nfl-act button");
71+
var arrowButtons = component.FindAll("button");
7172

72-
if (arrows)
73+
if (mode.HasValue)
7374
{
74-
Assert.AreEqual(1, arrowButtonHolder.Count);
7575
Assert.AreEqual(2, arrowButtons.Count);
7676
}
7777
else
7878
{
79-
Assert.AreEqual(0, arrowButtonHolder.Count);
8079
Assert.AreEqual(0, arrowButtons.Count);
8180
}
8281
}
@@ -92,7 +91,7 @@ public void BitNumberFieldShouldRenderCorrectIconWithEnableArrows(string iconNam
9291
{
9392
parameters.Add(p => p.IconName, iconName);
9493
parameters.Add(p => p.IconAriaLabel, iconAriaLabel);
95-
parameters.Add(p => p.ShowButtons, true);
94+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
9695
});
9796

9897
if (iconName.HasValue())
@@ -153,7 +152,7 @@ public void BitNumberFieldShouldRenderCorrectIncrementButton(string iconName, st
153152
parameters.Add(p => p.IncrementIconName, iconName);
154153
parameters.Add(p => p.IncrementAriaLabel, iconAriaLabel);
155154
parameters.Add(p => p.IsEnabled, isEnabled);
156-
parameters.Add(p => p.ShowButtons, true);
155+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
157156
});
158157

159158
var button = component.Find("button");
@@ -182,7 +181,7 @@ public void BitNumberFieldShouldRenderCorrectDecrementButton(string iconName, st
182181
parameters.Add(p => p.DecrementIconName, iconName);
183182
parameters.Add(p => p.DecrementAriaLabel, iconAriaLabel);
184183
parameters.Add(p => p.IsEnabled, isEnabled);
185-
parameters.Add(p => p.ShowButtons, true);
184+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
186185
});
187186

188187
var button = component.Find("button:last-child");
@@ -219,21 +218,30 @@ public void BitNumberFieldShouldHaveNumberFormaWhenItsPropertySet(string numberF
219218
}
220219

221220
[DataTestMethod,
222-
DataRow(true),
223-
DataRow(false)
221+
DataRow(null),
222+
DataRow(BitLabelPosition.Start),
223+
DataRow(BitLabelPosition.End),
224+
DataRow(BitLabelPosition.Top),
225+
DataRow(BitLabelPosition.Bottom)
224226
]
225-
public void BitNumberFieldShouldHaveLabelPositionClassName(bool inlineLabel)
227+
public void BitNumberFieldShouldHaveLabelPositionClassName(BitLabelPosition? labelPosition)
226228
{
227229
var component = RenderComponent<BitNumberField<int>>(parameters =>
228230
{
229-
parameters.Add(p => p.InlineLabel, inlineLabel);
231+
parameters.Add(p => p.LabelPosition, labelPosition);
230232
});
231233

232-
var lblClass = inlineLabel ? "ilb" : "tlb";
234+
var lblClass = labelPosition switch
235+
{
236+
BitLabelPosition.Bottom => "bit-nfl-lbt",
237+
BitLabelPosition.Start => "bit-nfl-lst",
238+
BitLabelPosition.End => "bit-nfl-led",
239+
_ => "bit-nfl-ltp"
240+
};
233241

234242
var numberFieldButton = component.Find(".bit-nfl");
235243

236-
Assert.IsTrue(numberFieldButton.ClassList.Contains($"bit-nfl-{lblClass}"));
244+
Assert.IsTrue(numberFieldButton.ClassList.Contains(lblClass));
237245
}
238246

239247
[DataTestMethod,
@@ -268,7 +276,7 @@ public void BitNumberFieldWrapperShouldHaveCorrectAttributes(string title, strin
268276
parameters.Add(p => p.AriaPositionInSet, ariaPositionInSet);
269277
});
270278

271-
var ntfWrapper = component.Find(".bit-nfl-wrp");
279+
var ntfWrapper = component.Find(".bit-nfl-cnt");
272280

273281
if (string.IsNullOrEmpty(title) is false)
274282
{
@@ -334,7 +342,7 @@ public async Task BitNumberFieldOnIncrementTest(int countOfClicks)
334342
var onIncrementEventCounter = 0;
335343
var component = RenderComponent<BitNumberField<int>>(parameters =>
336344
{
337-
parameters.Add(p => p.ShowButtons, true);
345+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
338346
parameters.Add(p => p.OnIncrement, () => onIncrementEventCounter++);
339347
});
340348

@@ -359,7 +367,7 @@ public async Task BitNumberFieldOnDecrementTest(int countOfClicks)
359367
var onDecrementEventCounter = 20;
360368
var component = RenderComponent<BitNumberField<int>>(parameters =>
361369
{
362-
parameters.Add(p => p.ShowButtons, true);
370+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
363371
parameters.Add(p => p.OnDecrement, () => onDecrementEventCounter--);
364372
});
365373

@@ -519,7 +527,7 @@ public void BitNumberFieldIncrementButtonClickTest(int defaultValue, string step
519527
parameters.Add(p => p.Step, step);
520528
parameters.Add(p => p.Max, max);
521529
parameters.Add(p => p.DefaultValue, defaultValue);
522-
parameters.Add(p => p.ShowButtons, true);
530+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
523531
});
524532

525533
var input = component.Find("input");
@@ -576,7 +584,7 @@ public void BitNumberFieldDecrementButtonClickTest(int defaultValue, string step
576584
parameters.Add(p => p.Step, step);
577585
parameters.Add(p => p.Min, min);
578586
parameters.Add(p => p.DefaultValue, defaultValue);
579-
parameters.Add(p => p.ShowButtons, true);
587+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
580588
});
581589

582590
var input = component.Find("input");
@@ -748,7 +756,7 @@ public async Task BitNumberFieldTwoWayBoundWithCustomHandlerShouldWorkCorrect(in
748756
parameters.Add(p => p.Step, step);
749757
parameters.Add(p => p.Value, BitNumberFieldTwoWayBoundValue);
750758
parameters.Add(p => p.ValueChanged, HandleValueChanged);
751-
parameters.Add(p => p.ShowButtons, true);
759+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
752760
});
753761

754762
var incrementButton = component.Find("button.bit-nfl-aup");
@@ -788,7 +796,7 @@ public void BitNumberFieldContinuousIncrementOnPointerDownTest(int defaultValue,
788796
parameters.Add(p => p.Step, step);
789797
parameters.Add(p => p.Max, max);
790798
parameters.Add(p => p.DefaultValue, defaultValue);
791-
parameters.Add(p => p.ShowButtons, true);
799+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
792800
});
793801

794802
var input = component.Find("input");
@@ -814,7 +822,7 @@ public void BitNumberFieldContinuousDecrementOnPointerDownTest(int defaultValue,
814822
parameters.Add(p => p.Step, step);
815823
parameters.Add(p => p.Min, min);
816824
parameters.Add(p => p.DefaultValue, defaultValue);
817-
parameters.Add(p => p.ShowButtons, true);
825+
parameters.Add(p => p.Mode, BitSpinButtonMode.Compact);
818826
});
819827

820828
var input = component.Find("input");

Diff for: src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor

+146-36
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
}
3939

4040
<div title="@Title"
41-
style="@Styles?.InputWrapper"
42-
class="bit-nfl-wrp @Classes?.InputWrapper"
41+
style="@Styles?.InputContainer"
42+
class="bit-nfl-cnt@(HideInput ? " bit-nfl-hdi" : "") @Classes?.InputContainer"
4343
aria-label="@AriaLabel"
4444
aria-setsize="@AriaSetSize"
4545
aria-posinset="@AriaPositionInSet">
@@ -56,39 +56,89 @@
5656
</div>
5757
}
5858

59-
<input @ref="InputElement" @attributes="@InputHtmlAttributes"
60-
@onblur="HandleOnBlur"
61-
@onfocus="HandleOnFocus"
62-
@onkeydown="HandleOnKeyDown"
63-
@onfocusin="HandleOnFocusIn"
64-
@onfocusout="HandleOnFocusOut"
65-
@onchange="HandleOnStringValueChangeAsync"
66-
@oninput="HandleOnStringValueInputAsync"
67-
form=""
68-
min="@_min"
69-
max="@_max"
70-
name="@Name"
71-
step="@_step"
72-
id="@_inputId"
73-
readonly="@ReadOnly"
74-
required="@Required"
75-
style="@Styles?.Input"
76-
autofocus="@AutoFocus"
77-
inputmode="@GetInputMode()"
78-
placeholder="@Placeholder"
79-
aria-labelledby="@_labelId"
80-
value="@CurrentValueAsString"
81-
disabled="@(IsEnabled is false)"
82-
class="bit-nfl-inp @Classes?.Input"
83-
autocomplete="@(AutoComplete ?? "off")"
84-
type="@(NumberFormat.HasValue() ? "text" : "number")"
85-
aria-valuemin="@_min"
86-
aria-valuemax="@_max"
87-
aria-describedby="@AriaDescription"
88-
aria-valuenow="@(AriaValueNow ?? CurrentValue)"
89-
aria-valuetext="@(AriaValueText ?? CurrentValueAsString)"
90-
aria-disabled="@(IsEnabled is false)" />
91-
@if (ShowButtons)
59+
@if (Mode == BitSpinButtonMode.Spread)
60+
{
61+
<button @ref="_buttonDecrement"
62+
@onpointerup="HandleOnPointerUpOrOut"
63+
@onpointerout="HandleOnPointerUpOrOut"
64+
@onpointerdown="() => HandleOnPointerDown(false)"
65+
type="button"
66+
tabindex="-1"
67+
style="@Styles?.DecrementButton"
68+
class="bit-nfl-sbn @Classes?.DecrementButton"
69+
disabled="@(IsEnabled is false)"
70+
title="@DecrementTitle"
71+
aria-disabled="@(IsEnabled is false)"
72+
aria-label="@DecrementAriaLabel">
73+
<span style="@Styles?.DecrementIconContainer" class="bit-nfl-aic @Classes?.DecrementIconContainer">
74+
<i style="@Styles?.DecrementIcon"
75+
class="bit-nfl-bic bit-nfl-sbi bit-icon bit-icon--@(DecrementIconName ?? "ChevronDownSmall") @Classes?.DecrementIcon" />
76+
</span>
77+
</button>
78+
}
79+
80+
@if (HideInput)
81+
{
82+
<input @ref="InputElement" @attributes="@InputHtmlAttributes"
83+
form=""
84+
min="@_min"
85+
max="@_max"
86+
name="@Name"
87+
step="@_step"
88+
id="@_inputId"
89+
readonly="@(ReadOnly || IsInputReadOnly)"
90+
required="@Required"
91+
autofocus="@AutoFocus"
92+
inputmode="@_inputMode"
93+
placeholder="@Placeholder"
94+
aria-labelledby="@_labelId"
95+
value="@CurrentValueAsString"
96+
disabled="@(IsEnabled is false)"
97+
type="hidden"
98+
aria-valuemin="@_min"
99+
aria-valuemax="@_max"
100+
aria-describedby="@AriaDescription"
101+
aria-valuenow="@(AriaValueNow ?? CurrentValue)"
102+
aria-valuetext="@(AriaValueText ?? CurrentValueAsString)"
103+
aria-disabled="@(IsEnabled is false)" />
104+
}
105+
else
106+
{
107+
<input @ref="InputElement" @attributes="@InputHtmlAttributes"
108+
@onblur="HandleOnBlur"
109+
@onfocus="HandleOnFocus"
110+
@onkeydown="HandleOnKeyDown"
111+
@onfocusin="HandleOnFocusIn"
112+
@onfocusout="HandleOnFocusOut"
113+
@onchange="HandleOnStringValueChangeAsync"
114+
@oninput="HandleOnStringValueInputAsync"
115+
form=""
116+
min="@_min"
117+
max="@_max"
118+
name="@Name"
119+
step="@_step"
120+
id="@_inputId"
121+
readonly="@(ReadOnly || IsInputReadOnly)"
122+
required="@Required"
123+
style="@Styles?.Input"
124+
autofocus="@AutoFocus"
125+
inputmode="@_inputMode"
126+
placeholder="@Placeholder"
127+
aria-labelledby="@_labelId"
128+
value="@CurrentValueAsString"
129+
disabled="@(IsEnabled is false)"
130+
class="bit-nfl-inp@(Mode == BitSpinButtonMode.Spread ? " bit-nfl-cin" : "") @Classes?.Input"
131+
autocomplete="@(AutoComplete ?? "off")"
132+
type="@(NumberFormat.HasValue() ? "text" : "number")"
133+
aria-valuemin="@_min"
134+
aria-valuemax="@_max"
135+
aria-describedby="@AriaDescription"
136+
aria-valuenow="@(AriaValueNow ?? CurrentValue)"
137+
aria-valuetext="@(AriaValueText ?? CurrentValueAsString)"
138+
aria-disabled="@(IsEnabled is false)" />
139+
}
140+
141+
@if (Mode == BitSpinButtonMode.Compact)
92142
{
93143
<span style="@Styles?.ButtonsContainer" class="bit-nfl-act @Classes?.ButtonsContainer">
94144
<button @ref="_buttonIncrement"
@@ -100,8 +150,9 @@
100150
date-is-focusable="false"
101151
style="@Styles?.IncrementButton"
102152
class="bit-nfl-aup @Classes?.IncrementButton"
103-
aria-label="@IncrementAriaLabel"
104153
disabled="@(IsEnabled is false)"
154+
title="@IncrementTitle"
155+
aria-label="@IncrementAriaLabel"
105156
aria-disabled="@(IsEnabled is false)">
106157
<span style="@Styles?.IncrementIconContainer" class="bit-nfl-aic @Classes?.IncrementIconContainer">
107158
<i style="@Styles?.IncrementIcon"
@@ -119,6 +170,7 @@
119170
style="@Styles?.DecrementButton"
120171
class="bit-nfl-adn @Classes?.DecrementButton"
121172
disabled="@(IsEnabled is false)"
173+
title="@DecrementTitle"
122174
aria-label="@DecrementAriaLabel"
123175
aria-disabled="@(IsEnabled is false)">
124176
<span style="@Styles?.DecrementIconContainer" class="bit-nfl-aic @Classes?.DecrementIconContainer">
@@ -128,6 +180,64 @@
128180
</button>
129181
</span>
130182
}
183+
else if (Mode == BitSpinButtonMode.Inline)
184+
{
185+
<button @ref="_buttonDecrement"
186+
@onpointerup="HandleOnPointerUpOrOut"
187+
@onpointerout="HandleOnPointerUpOrOut"
188+
@onpointerdown="() => HandleOnPointerDown(false)"
189+
type="button"
190+
tabindex="-1"
191+
style="@Styles?.DecrementButton"
192+
class="bit-nfl-sbn @Classes?.DecrementButton"
193+
disabled="@(IsEnabled is false)"
194+
title="@DecrementTitle"
195+
aria-disabled="@(IsEnabled is false)"
196+
aria-label="@DecrementAriaLabel">
197+
<span style="@Styles?.DecrementIconContainer" class="bit-nfl-aic @Classes?.DecrementIconContainer">
198+
<i style="@Styles?.DecrementIcon"
199+
class="bit-nfl-bic bit-nfl-sbi bit-icon bit-icon--@(DecrementIconName ?? "ChevronDownSmall") @Classes?.DecrementIcon" />
200+
</span>
201+
</button>
202+
203+
<button @ref="_buttonIncrement"
204+
@onpointerup="HandleOnPointerUpOrOut"
205+
@onpointerout="HandleOnPointerUpOrOut"
206+
@onpointerdown="() => HandleOnPointerDown(true)"
207+
type="button"
208+
tabindex="-1"
209+
style="@Styles?.IncrementButton"
210+
class="bit-nfl-sbn @Classes?.IncrementButton"
211+
disabled="@(IsEnabled is false)"
212+
title="@IncrementTitle"
213+
aria-disabled="@(IsEnabled is false)"
214+
aria-label="@IncrementAriaLabel">
215+
<span style="@Styles?.IncrementIconContainer" class="bit-nfl-aic @Classes?.IncrementIconContainer">
216+
<i style="@Styles?.IncrementIcon"
217+
class="bit-nfl-bic bit-nfl-sbi bit-icon bit-icon--@(IncrementIconName ?? "ChevronDownSmall bit-ico-r180") @Classes?.IncrementIcon" />
218+
</span>
219+
</button>
220+
}
221+
else if (Mode == BitSpinButtonMode.Spread)
222+
{
223+
<button @ref="_buttonIncrement"
224+
@onpointerup="HandleOnPointerUpOrOut"
225+
@onpointerout="HandleOnPointerUpOrOut"
226+
@onpointerdown="() => HandleOnPointerDown(true)"
227+
type="button"
228+
tabindex="-1"
229+
style="@Styles?.IncrementButton"
230+
class="bit-nfl-sbn @Classes?.IncrementButton"
231+
disabled="@(IsEnabled is false)"
232+
title="@IncrementTitle"
233+
aria-disabled="@(IsEnabled is false)"
234+
aria-label="@IncrementAriaLabel">
235+
<span style="@Styles?.IncrementIconContainer" class="bit-nfl-aic @Classes?.IncrementIconContainer">
236+
<i style="@Styles?.IncrementIcon"
237+
class="bit-nfl-bic bit-nfl-sbi bit-icon bit-icon--@(IncrementIconName ?? "ChevronDownSmall bit-ico-r180") @Classes?.IncrementIcon" />
238+
</span>
239+
</button>
240+
}
131241

132242
@if (SuffixTemplate is not null)
133243
{

0 commit comments

Comments
 (0)