The numbox component is almost identical to the
textbox
but includes additional features specific to numeric input.
It supports various numeric types, including
short
, int
, long
,
float
, double
, and decimal
.
Additionally, their nullable counterparts (e.g., int?
,
double?
, decimal?
) are also supported,
providing flexibility for scenarios where input values may be optional or undefined.
The numbox component provides a simple way to input and edit numeric data.
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?" Label="Temperature °C" />
<LumexNumbox TValue="double?" Label="Temperature °C" Placeholder="Enter the temperature" />
</div>
You can disable a numbox to prevent user interaction.
A disabled numbox is faded and does not respond to user clicks.
<LumexNumbox TValue="double?"
Disabled="@true"
Label="Temperature °C"
Placeholder="Enter the temperature"
Class="max-w-xs" />
Set the numbox component to read-only to display the
current state without allowing changes.
<LumexNumbox TValue="double?"
ReadOnly="@true"
Label="Temperature °C"
Placeholder="Enter the temperature"
Class="max-w-xs"
Value="25" />
Mark the numbox as required to indicate that it
must be filled out before form submission.
An asterisk will appear at the end of the label.
<LumexNumbox TValue="double?"
Required="@true"
Label="Temperature °C"
Placeholder="Enter the temperature"
Class="max-w-xs" />
The step
attribute defines the increment or decrement
value when using the spin buttons, enabling fine-tuned adjustments.
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="Enter the temperature"
Class="max-w-xs"
step="0.5" />
Set minimum and maximum constraints to restrict input
values within a specific range, ensuring valid and meaningful data.
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="Enter the temperature"
Class="max-w-xs"
min="10"
max="20"
step="0.5" />
The numbox component supports multiple sizes to
fit different layouts and design needs.
<div class="w-full grid grid-cols-1 gap-4">
@foreach( var size in _sizes )
{
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?" Size="@size" Label="Temperature °C" />
<LumexNumbox TValue="double?" Size="@size" Label="Temperature °C" Placeholder="Enter the temperature" />
</div>
<small class="text-default-400 mt-1">@size</small>
</div>
}
</div>
@code {
private Size[] _sizes = [
Size.Small,
Size.Medium,
Size.Large
];
}
Adjust the border radius of the numbox for rounded or squared corners.
<div class="w-full grid grid-cols-1 gap-4 md:grid-cols-2">
@foreach( var radius in _radiuses )
{
<div>
<LumexNumbox TValue="double?"
Radius="@radius"
Label="Radius"
Placeholder="@radius.ToString()"
Value="25" />
<small class="text-default-400 mt-1">@radius</small>
</div>
}
</div>
@code {
private Radius[] _radiuses = [
Radius.None,
Radius.Small,
Radius.Medium,
Radius.Large
];
}
Customize the numbox color to match your theme or emphasize certain fields.
<div class="w-full grid grid-cols-1 gap-4 md:grid-cols-2">
@foreach( var color in _colors )
{
<div>
<LumexNumbox TValue="double?"
Color="@color"
Label="Temperature °C"
Placeholder="Enter the temperature"
Value="25" />
<small class="text-default-400 mt-1">@color</small>
</div>
}
</div>
@code {
private ThemeColor[] _colors = [
ThemeColor.Default,
ThemeColor.Primary,
ThemeColor.Secondary,
ThemeColor.Success,
ThemeColor.Warning,
ThemeColor.Danger,
ThemeColor.Info
];
}
Choose from different numbox variants,
such as Flat
, Underlined
,
or Outlined
, for various visual styles.
<div class="w-full grid grid-cols-1 gap-4">
@foreach( var variant in _variants )
{
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?" Variant="@variant" Label="Temperature °C" />
<LumexNumbox TValue="double?" Variant="@variant" Label="Temperature °C" Placeholder="Enter the temperature" />
</div>
<small class="text-default-400 mt-1">@variant</small>
</div>
}
</div>
@code {
private InputVariant[] _variants = [
InputVariant.Flat,
InputVariant.Outlined,
InputVariant.Underlined
];
}
Position the label either inside or outside the numbox
for flexibility in layout and design.
<div class="w-full grid grid-cols-1 gap-4">
@foreach( var placement in _labelPlacements )
{
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?" LabelPlacement="@placement" Label="Temperature °C" />
<LumexNumbox TValue="double?" LabelPlacement="@placement" Label="Temperature °C" Placeholder="Enter the temperature" />
</div>
<small class="text-default-400 mt-1">@placement</small>
</div>
}
</div>
@code {
private LabelPlacement[] _labelPlacements = [
LabelPlacement.Inside,
LabelPlacement.Outside
];
}
If the Label
parameter is not set, the LabelPlacement
parameter will default to Outside
.
Enable the button to clear the input with a single click.
<div class="w-full">
<LumexNumbox TValue="double?"
Clearable="@true"
Label="Temperature °C"
Placeholder="Enter the temperature"
Value="@_value"
Variant="@InputVariant.Outlined"
OnCleared="@Notify"
Class="max-w-xs" />
</div>
<p class="text-sm text-default-500">@_text</p>
@code {
private string? _text;
private double? _value = 25;
private void Notify()
{
_value = default;
if( string.IsNullOrEmpty( _text ) )
{
_text = "Input is cleared!";
}
else
{
_text += " ..and again..";
}
}
}
Add custom content, such as icons or labels, to the
start or end of the numbox for added functionality.
@using LumexUI.Shared.Icons
<div class="grid gap-4">
<div class="w-full grid grid-cols-1 gap-4">
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="25"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_thermometerIcon" />
<LumexNumbox TValue="double?"
Label="Speed"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_circleGaugeIcon" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_dollarSignIcon" />
</div>
<small class="text-default-500 mt-1">Start</small>
</div>
</div>
<div class="w-full grid grid-cols-1 gap-4">
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="25"
LabelPlacement="@LabelPlacement.Outside"
EndContent="@_thermometerIcon" />
<LumexNumbox TValue="double?"
Label="Speed"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
EndContent="@_circleGaugeIcon" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
EndContent="@_dollarSignIcon" />
</div>
<small class="text-default-500 mt-1">End</small>
</div>
</div>
<div class="w-full grid grid-cols-1 gap-4">
<div>
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="25"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_thermometerIcon"
EndContent="@_tempCelsiusContent" />
<LumexNumbox TValue="double?"
Label="Speed"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_circleGaugeIcon"
EndContent="@_speedContent" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_dollarSignIcon"
EndContent="@_currenciesContent" />
</div>
<small class="text-default-500 mt-1">Both</small>
</div>
</div>
</div>
@code {
private RenderFragment _thermometerIcon = @<ThermometerIcon Size="20" class="text-default-400 shrink-0" />;
private RenderFragment _circleGaugeIcon = @<CircleGaugeIcon Size="20" class="text-default-400 shrink-0" />;
private RenderFragment _dollarSignIcon = @<DollarSignIcon Size="20" class="text-default-400 shrink-0" />;
private RenderFragment _tempCelsiusContent =
@<div class="pointer-events-none flex items-center">
<span class="text-default-400 text-small">°C</span>
</div>;
private RenderFragment _speedContent =
@<div class="pointer-events-none flex items-center">
<span class="text-default-400 text-small">km/h</span>
</div>;
private RenderFragment _currenciesContent =
@<div class="flex items-center">
<label class="sr-only" for="currency">Currency</label>
<select class="outline-hidden border-0 bg-transparent text-default-400 text-small"
id="currency"
name="currency"
@onclick:stopPropagation="@true">
<option>USD</option>
<option>EUR</option>
<option>SEK</option>
</select>
</div>;
}
Provide a brief description below the numbox to
offer guidance or additional context.
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="Enter the temperature"
Description="The temperature is used to calculate the process time."
Class="max-w-xs" />
Display an error message below the numbox to indicate validation issues.
You can combine the Invalid
and ErrorMessage
parameters to show an invalid input.
An error message is shown only when the Invalid
parameter is set to true
.
@using FluentValidation
@using FluentValidation.Results
<LumexNumbox TValue="double?"
Variant="@InputVariant.Outlined"
Label="Temperature °C"
Required="@true"
ErrorMessage="@_userValidator.TempErrorMessage"
Invalid="@(!string.IsNullOrEmpty(_userValidator.TempErrorMessage))"
Color="@(!string.IsNullOrEmpty(_userValidator.TempErrorMessage) ? ThemeColor.Danger : ThemeColor.Success)"
Value="@_user.Temperature"
ValueChanged="@OnAgeChange"
Class="max-w-xs" />
@code {
private User _user = new();
private UserValidator _userValidator = new();
protected override void OnInitialized()
{
_user.Temperature = -274.15;
Validate();
}
private void OnAgeChange( double? value )
{
_user.Temperature = value;
Validate();
}
private void Validate()
{
var result = _userValidator.Validate( _user );
if( !result.IsValid )
{
_userValidator.TempErrorMessage = result.Errors
.Where( failure => failure.PropertyName == nameof( User.Temperature ) )
.Select( failure => failure.ErrorMessage )
.FirstOrDefault();
}
else
{
_userValidator.TempErrorMessage = null;
}
}
public class User
{
public double? Temperature { get; set; }
}
public class UserValidator : AbstractValidator<User>
{
public string? TempErrorMessage { get; set; }
public UserValidator()
{
RuleFor( user => user.Temperature )
.NotNull().WithMessage( "Temperature can't be null" )
.GreaterThan( -273.15 ).WithMessage( "Temperature cannot be lower than or equal to absolute zero" );
}
}
}
Enable debounced input to delay updates to the numbox value,
reducing the frequency of changes and improving performance.
You can achieve this by setting the DebounceDelay
value and
Behavior
to OnInput
.
<div class="w-full flex flex-col gap-2">
<LumexNumbox TValue="double?"
DebounceDelay="250"
Behavior="@InputBehavior.OnInput"
Label="Temperature °C"
Placeholder="Enter the temperatute"
Clearable="@true"
Class="max-w-xs"
@bind-Value="@_value" />
<p class="text-sm text-default-500">
Value: @_value
</p>
</div>
@code {
private double? _value = 25;
}
The numbox component supports two-way data binding,
allowing you to programmatically control the value.
You can achieve this using the @bind-Value
directive,
or the Value
and ValueChanged
parameters.
<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
<div class="w-full flex flex-col gap-2">
<LumexNumbox TValue="double?"
Label="Value"
Placeholder="Enter any value"
Clearable="@true"
@bind-Value="@_valueOne" />
<p class="text-sm text-default-500">
Value: @_valueOne
</p>
</div>
<div class="w-full flex flex-col gap-2">
<LumexNumbox TValue="double?"
Label="Value"
Placeholder="Enter any value"
Clearable="@true"
Value="@_valueTwo"
ValueChanged="@OnValueChanged" />
<p class="text-sm text-default-500">
Value: @_valueTwo
</p>
</div>
</div>
@code {
private double? _valueOne;
private double? _valueTwo = 25;
private void OnValueChanged( double? value )
{
_valueTwo = value;
}
}
This component supports named slots, which allow custom
styles to be applied to specific parts of the component:
- Base: The overall wrapper.
- Label: The label element.
- MainWrapper: The wrapper of the input wrapper (when the label is outside).
- InputWrapper: The wrapper of the label and the inner wrapper (when the label is inside).
- InnerWrapper: The wrapper of the input, start/end content.
- Input: The input element.
- ClearButton: The clear button element.
- HelperWrapper: The wrapper of a description and an error message.
- Description: The description of the input field.
- ErrorMessage: The error message of the input field.
You can customize the component(s) by passing
any Tailwind CSS classes to the following component parameters:
Textbox
Class
: The CSS class name that styles the wrapper of the numbox.
Classes
: The CSS class names for the numbox slots that style entire numbox.
@using LumexUI.Shared.Icons
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="Enter the temperature"
Radius="@Radius.Large"
Clearable="@true"
Value="25"
Classes="@_classes">
<StartContent>
<ThermometerIcon Size="20" class="text-secondary-400 shrink-0" />
</StartContent>
</LumexNumbox>
@code {
private InputFieldSlots _classes = new()
{
Label = "text-default-700",
InnerWrapper = "bg-transparent",
InputWrapper = ElementClass.Empty()
.Add( "shadow-xl" )
.Add( "bg-default-200/50" )
.Add( "backdrop-blur-xl" )
.Add( "backdrop-saturate-200" )
.Add( "hover:bg-default-200/70" )
.Add( "group-data-[focus=true]:bg-default-200/85" )
.ToString(),
Input = ElementClass.Empty()
.Add( "bg-transparent" )
.Add( "text-default-900" )
.Add( "placeholder:text-default-500" )
.ToString()
};
}
See the API references below for a complete guide to all the
parameters available for the components mentioned here.