Types
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.
Usage
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>
Disabled
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" />
Read-Only
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" />
Required
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" />
Step
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" />
Min & Max
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" />
Sizes
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
];
}
Radius
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
];
}
Colors
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
];
}
Variants
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
];
}
Label Placements
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
.
Clear Button
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..";
}
}
}
Start & End Content
Add custom content, such as icons or labels, to the start or end of the numbox for added functionality.
<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="Distance"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_distanceIcon" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_euroSymbolIcon" />
</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="Distance"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
EndContent="@_distanceIcon" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
EndContent="@_euroSymbolIcon" />
</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="Distance"
Placeholder="100"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_distanceIcon"
EndContent="@_kmContent" />
<LumexNumbox TValue="decimal?"
Label="Price"
Placeholder="0.00"
LabelPlacement="@LabelPlacement.Outside"
StartContent="@_euroSymbolIcon"
EndContent="@_currenciesContent" />
</div>
<small class="text-default-500 mt-1">Both</small>
</div>
</div>
</div>
@code {
private RenderFragment _thermometerIcon =
@<LumexIcon Icon="@Icons.Rounded.Thermometer"
Size="@new("20")"
Class="text-default-400 shrink-0">
</LumexIcon>;
private RenderFragment _distanceIcon =
@<LumexIcon Icon="@Icons.Rounded.Distance"
Size="@new("20")"
Class="text-default-400 shrink-0">
</LumexIcon>;
private RenderFragment _euroSymbolIcon =
@<LumexIcon Icon="@Icons.Rounded.EuroSymbol"
Size="@new("16")"
Class="text-default-400 shrink-0">
</LumexIcon>;
private RenderFragment _tempCelsiusContent =
@<div class="pointer-events-none flex items-center">
<span class="text-default-400 text-small">°C</span>
</div>;
private RenderFragment _kmContent =
@<div class="pointer-events-none flex items-center">
<span class="text-default-400 text-small">km</span>
</div>;
private RenderFragment _currenciesContent =
@<div class="flex items-center">
<label class="sr-only" for="currency">Currency</label>
<select class="outline-none border-0 bg-transparent text-default-400 text-small"
id="currency"
name="currency"
@onclick:stopPropagation="@true">
<option>USD</option>
<option>ARS</option>
<option>EUR</option>
</select>
</div>;
}
Description
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" />
Error Message
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" );
}
}
}
Debounce Delay
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
.
Value: 25
<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;
}
Two-way Data Binding
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.
Value:
Value: 25
<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;
}
}
Custom Styles
This component supports named slots that allow you to apply custom CSS to specific parts of the component.
- Root: 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.
<LumexNumbox TValue="double?"
Label="Temperature °C"
Placeholder="Enter the temperature"
Radius="@Radius.Large"
Clearable="@true"
StartContent="@_thermometer"
Value="25"
Classes="@_classes" />
@code {
private RenderFragment _thermometer =
@<LumexIcon Icon="@Icons.Rounded.Thermometer"
Size="@new("20")"
Class="text-secondary-400 shrink-0">
</LumexIcon>;
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()
};
}
API
See the API references below for a complete guide to all the parameters available for the components mentioned here.