diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/ChipFieldTextField.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/ChipFieldTextField.cs
new file mode 100644
index 00000000..18ffb825
--- /dev/null
+++ b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/ChipFieldTextField.cs
@@ -0,0 +1,24 @@
+using System.ComponentModel;
+using Microsoft.AspNetCore.Components;
+
+namespace MudExtensions
+{
+ ///
+ /// The text field rendered inside . It validates Required against the chips of
+ /// the chip field instead of the typed text, so it agrees with the chip field's own validation.
+ /// It is public only because Razor can't render internal components; it isn't meant to be used directly.
+ ///
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public sealed class ChipFieldTextField : MudTextFieldExtended
+ {
+ ///
+ /// Returns true when the parent chip field has at least one chip.
+ ///
+ [Parameter]
+ public Func? HasChips { get; set; }
+
+ ///
+ protected override bool HasValue(T? value) => HasChips?.Invoke() ?? base.HasValue(value);
+ }
+}
diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor
index 40adf2fe..f8e84676 100644
--- a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor
+++ b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor
@@ -2,8 +2,9 @@
@inherits MudTextFieldExtended
@typeparam T
-
-
+
diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs
index f2f6ee81..e14d7061 100644
--- a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs
+++ b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs
@@ -21,9 +21,11 @@ public MudChipField()
_valuesState = registerScope.RegisterParameter?>(nameof(Values))
.WithParameter(() => Values)
.WithEventCallback(() => ValuesChanged);
+ _hasChips = () => HasValue(default);
}
private readonly ParameterState?> _valuesState;
+ private readonly Func _hasChips;
///
/// Protected classes.
@@ -285,6 +287,13 @@ public async Task Closed(MudChip chip)
await _textFieldExtendedReference.FocusAsync();
}
+ ///
+ /// The chip field has a value when it has at least one chip, so Required checks the chips instead of the typed text.
+ ///
+ ///
+ ///
+ protected override bool HasValue(T? value) => _valuesState.Value is { Count: > 0 };
+
///
/// Clear the text field.
///
diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/Pages/Index.razor b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/Pages/Index.razor
index e41859b7..823aa77d 100644
--- a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/Pages/Index.razor
+++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/Pages/Index.razor
@@ -6,6 +6,4 @@
Welcome to your new app.
-
-
-
+
diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/ChipField/ChipFieldRequiredTest.razor b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/ChipField/ChipFieldRequiredTest.razor
new file mode 100644
index 00000000..2e418cb9
--- /dev/null
+++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/ChipField/ChipFieldRequiredTest.razor
@@ -0,0 +1,15 @@
+@namespace MudExtensions.UnitTests.TestComponents
+
+
+
+ Validate
+
+
+@code {
+ public static string __description__ = "A required chip field should be valid when it has chips, even if its text input is empty";
+
+ public MudForm? Form { get; private set; }
+
+ [Parameter]
+ public List? Values { get; set; }
+}
diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/wwwroot/index.html b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/wwwroot/index.html
index 2fb25308..b4be3167 100644
--- a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/wwwroot/index.html
+++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/wwwroot/index.html
@@ -30,7 +30,7 @@
-
+