Skip to content

Commit f739b49

Browse files
Enable input number component to support type='range' attribute (#55583)
* Commit modifies the InputNumber component to allow the 'type' attribute specified by the user to take precedence over the default 'type="number"'. By swapping the order in which attributes are added to the builder, any user-defined 'type' attribute is now respected, enabling the usage of different input types like 'range'. Previously, the InputNumber component hardcoded the 'type' attribute as 'number', which prevented using it for other input types such as sliders (range inputs). * Adding a test to the inputNumberTests to ensure the user defined type attribute overrides the default. * Using the TestRederer to extract attributes and assert the user-defined type override the default * Retrieving frames with new methodology * Isolating the correct element to extract attributes from * Only asserting the type attribute = range * Isolating input element, atrributes and type attribute correctly * Improving methodology of handling render tree frames and isolating the input element and attributes * Ammendments to tests * Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com> * Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com> * Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com> * re-adding missing tests * Using helper methods in tests. * Update src/Components/Web/test/Forms/InputNumberTest.cs --------- Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com>
1 parent 25db949 commit f739b49

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/Components/Web/src/Forms/InputNumber.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
5353
{
5454
builder.OpenElement(0, "input");
5555
builder.AddAttribute(1, "step", _stepAttributeValue);
56-
builder.AddMultipleAttributes(2, AdditionalAttributes);
57-
builder.AddAttribute(3, "type", "number");
56+
builder.AddAttribute(2, "type", "number");
57+
builder.AddMultipleAttributes(3, AdditionalAttributes);
5858
builder.AddAttributeIfNotNullOrEmpty(4, "name", NameAttributeValue);
5959
builder.AddAttributeIfNotNullOrEmpty(5, "class", CssClass);
6060
builder.AddAttribute(6, "value", CurrentValueAsString);

src/Components/Web/test/Forms/InputNumberTest.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.AspNetCore.Components.Forms.Mapping;
5+
using Microsoft.AspNetCore.Components.Infrastructure;
6+
using Microsoft.AspNetCore.Components.RenderTree;
7+
using Microsoft.AspNetCore.Components.Test.Helpers;
8+
using Microsoft.Extensions.DependencyInjection;
9+
410
namespace Microsoft.AspNetCore.Components.Forms;
511

612
public class InputNumberTest
713
{
14+
private readonly TestRenderer _testRenderer;
15+
16+
public InputNumberTest()
17+
{
18+
var services = new ServiceCollection();
19+
services.AddLogging();
20+
_testRenderer = new TestRenderer(services.BuildServiceProvider());
21+
}
22+
823
[Fact]
924
public async Task ValidationErrorUsesDisplayAttributeName()
1025
{
@@ -49,6 +64,43 @@ public async Task InputElementIsAssignedSuccessfully()
4964
Assert.NotNull(inputSelectComponent.Element);
5065
}
5166

67+
[Fact]
68+
public async Task UserDefinedTypeAttributeOverridesDefault()
69+
{
70+
// Arrange
71+
var model = new TestModel();
72+
var hostComponent = new TestInputHostComponent<int, TestInputNumberComponent>
73+
{
74+
EditContext = new EditContext(model),
75+
ValueExpression = () => model.SomeNumber,
76+
AdditionalAttributes = new Dictionary<string, object>
77+
{
78+
{ "type", "range" } // User-defined 'type' attribute to override default
79+
}
80+
};
81+
82+
// Act
83+
var componentId = await RenderAndGetTestInputNumberComponentIdAsync(hostComponent);
84+
85+
// Retrieve the render tree frames and extract attributes using helper methods
86+
var frames = _testRenderer.GetCurrentRenderTreeFrames(componentId);
87+
88+
var typeAttributeFrame = frames.Array.Single(frame =>
89+
frame.FrameType == RenderTreeFrameType.Attribute &&
90+
frame.AttributeName == "type");
91+
92+
// Assert
93+
Assert.Equal("range", typeAttributeFrame.AttributeValue);
94+
}
95+
96+
private async Task<int> RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent<int, TestInputNumberComponent> hostComponent)
97+
{
98+
var hostComponentId = _testRenderer.AssignRootComponentId(hostComponent);
99+
await _testRenderer.RenderRootComponentAsync(hostComponentId);
100+
var batch = _testRenderer.Batches.Single();
101+
return batch.GetComponentFrames<TestInputNumberComponent>().Single().ComponentId;
102+
}
103+
52104
private class TestModel
53105
{
54106
public int SomeNumber { get; set; }

0 commit comments

Comments
 (0)