Components

Textbox

Textbox allows users to input text data, making it essential for forms and data collection.

Usage

The textbox component provides a simple way to input and edit text data.

<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
    <LumexTextbox Type="@InputType.Email" Label="Email" />
    <LumexTextbox Type="@InputType.Email" Label="Email" Placeholder="Enter your email" />
</div>

Disabled

You can disable a textbox to prevent user interaction. A disabled textbox is faded and does not respond to user clicks.

<LumexTextbox Disabled="@true"
              Type="@InputType.Email"
              Label="Email"
              Placeholder="[email protected]"
              Class="max-w-xs" />

Read-Only

Set the textbox component to read-only to display the current state without allowing changes.

<LumexTextbox ReadOnly="@true"
              Type="@InputType.Email"
              Label="Email"
              Placeholder="[email protected]"
              Class="max-w-xs" />

Required

Mark the textbox as required to indicate that it must be filled out before form submission. An asterisk will appear at the end of the label.

<LumexTextbox Required="@true"
              Type="@InputType.Email"
              Label="Email"
              Placeholder="[email protected]"
              Class="max-w-xs" />

Sizes

The textbox component supports multiple sizes to fit different layouts and design needs.

Small
Medium
Large
<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">
                <LumexTextbox Size="@size" Type="@InputType.Email" Label="Email" />
                <LumexTextbox Size="@size" Type="@InputType.Email" Label="Email" Placeholder="Enter your email" />
            </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 textbox for rounded or squared corners.

None
Small
Medium
Large
<div class="w-full grid grid-cols-1 gap-4 md:grid-cols-2">
    @foreach( var radius in _radiuses )
    {
        <div>
            <LumexTextbox Radius="@radius" Label="Radius" Placeholder="@radius.ToString()" />
            <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 textbox color to match your theme or emphasize certain fields.

Default
Primary
Secondary
Success
Warning
Danger
Info
<div class="w-full grid grid-cols-1 gap-4 md:grid-cols-2">
    @foreach( var color in _colors )
    {
        <div>
            <LumexTextbox Color="@color"
                          Type="@InputType.Email"
                          Label="Email"
                          Placeholder="Enter your email"
                          Value="[email protected]" />
            <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 textbox variants, such as Flat, Underlined, or Outlined, for various visual styles.

Flat
Outlined
Underlined
<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">
                <LumexTextbox Variant="@variant" Type="@InputType.Email" Label="Email" />
                <LumexTextbox Variant="@variant" Type="@InputType.Email" Label="Email" Placeholder="Enter your email" />
            </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 textbox for flexibility in layout and design.

Inside
Outside
<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">
                <LumexTextbox LabelPlacement="@placement" Type="@InputType.Email" Label="Email" />
                <LumexTextbox LabelPlacement="@placement" Type="@InputType.Email" Label="Email" Placeholder="Enter your email" />
            </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">
    <LumexTextbox Clearable="@true"
                  Type="@InputType.Email"
                  Label="Email"
                  Placeholder="Enter your email"
                  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 string? _value = "[email protected]";

    private void Notify()
    {
        _value = null;

        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 textbox for added functionality.

https://
Start
.org
End
https://
.org
@doe.com
Both
<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">
                <LumexTextbox Type="@InputType.Url"
                              Label="Website"
                              Placeholder="lumexui.org"
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_protocolContent" />

                <LumexTextbox Type="@InputType.Search"
                              Label="Search"
                              Placeholder="Type to search..."
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_searchIcon" />

                <LumexTextbox Type="@InputType.Email"
                              Label="Email"
                              Placeholder="[email protected]"
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_mailIcon" />
            </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">
                <LumexTextbox Type="@InputType.Url"
                              Label="Website"
                              Placeholder="lumexui"
                              LabelPlacement="@LabelPlacement.Outside"
                              EndContent="@_domainContent" />

                <LumexTextbox Type="@InputType.Search"
                              Label="Search"
                              Placeholder="Type to search..."
                              LabelPlacement="@LabelPlacement.Outside"
                              EndContent="@_searchIcon" />

                <LumexTextbox Type="@InputType.Email"
                              Label="Email"
                              Placeholder="[email protected]"
                              LabelPlacement="@LabelPlacement.Outside"
                              EndContent="@_mailIcon" />
            </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">
                <LumexTextbox Type="@InputType.Url"
                              Label="Website"
                              Placeholder="lumexui"
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_protocolContent"
                              EndContent="@_domainContent" />

                <LumexTextbox Type="@InputType.Search"
                              Label="Search"
                              Placeholder="Type to search..."
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_searchIcon"
                              EndContent="@_micIcon" />

                <LumexTextbox Type="@InputType.Email"
                              Label="Email"
                              Placeholder="john"
                              LabelPlacement="@LabelPlacement.Outside"
                              StartContent="@_mailIcon"
                              EndContent="@_emailDomainContent" />
            </div>
            <small class="text-default-500 mt-1">Both</small>
        </div>
    </div>
</div>

@code {
    private RenderFragment _mailIcon =
        @<LumexIcon Icon="@Icons.Rounded.Mail"
                    Size="@new("20")"
                    Class="text-default-400 shrink-0">
        </LumexIcon>;

    private RenderFragment _searchIcon =
        @<LumexIcon Icon="@Icons.Rounded.Search"
                    Size="@new("20")"
                    Class="text-default-400 shrink-0">
        </LumexIcon>;

    private RenderFragment _micIcon =
        @<LumexIcon Icon="@Icons.Rounded.Mic"
                    Size="@new("20")"
                    Class="text-primary-300 shrink-0">
        </LumexIcon>;

    private RenderFragment _protocolContent =
        @<div class="pointer-events-none flex items-center">
            <span class="text-default-400 text-small">https://</span>
        </div>;

    private RenderFragment _domainContent =
        @<div class="pointer-events-none flex items-center">
            <span class="text-default-400 text-small">.org</span>
        </div>;

    private RenderFragment _emailDomainContent =
        @<div class="pointer-events-none flex items-center">
            <span class="text-default-400 text-small">&#64;doe.com</span>
        </div>;
}

Description

Provide a brief description below the textbox to offer guidance or additional context.

We'll never share your email with anyone else.
<LumexTextbox Type="@InputType.Email"
              Label="Email"
              Placeholder="[email protected]"
              Description="We'll never share your email with anyone else."
              Class="max-w-xs" />

Error Message

Display an error message below the textbox 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.

Please enter a valid email
@using FluentValidation
@using FluentValidation.Results

<LumexTextbox Type="@InputType.Email"
              Variant="@InputVariant.Underlined"
              Label="Email"
              Required="@true"
              ErrorMessage="@_userValidator.EmailErrorMessage"
              Invalid="@(!string.IsNullOrEmpty(_userValidator.EmailErrorMessage))"
              Color="@(!string.IsNullOrEmpty(_userValidator.EmailErrorMessage) ? ThemeColor.Danger : ThemeColor.Success)"
              Value="@_user.Email"
              ValueChanged="@OnEmailChange"
              Class="max-w-xs" />

@code {
    private User _user = new();
    private UserValidator _userValidator = new();

    protected override void OnInitialized()
    {
        _user.Email = "john2doe.com";
        Validate();
    }

    private void OnEmailChange( string value )
    {
        _user.Email = value;
        Validate();
    }

    private void Validate()
    {
        var result = _userValidator.Validate( _user );
        if( !result.IsValid )
        {
            _userValidator.EmailErrorMessage = result.Errors
                .Where( failure => failure.PropertyName == nameof( User.Email ) )
                .Select( failure => failure.ErrorMessage )
                .FirstOrDefault();
        }
        else
        {
            _userValidator.EmailErrorMessage = null;
        }
    }

    public class User
    {
        public string? Email { get; set; }
    }

    public class UserValidator : AbstractValidator<User>
    {
        public string? EmailErrorMessage { get; set; }

        public UserValidator()
        {
            RuleFor( user => user.Email )
                .NotEmpty().WithMessage( "Email is required" )
                .EmailAddress().WithMessage( "Please enter a valid email" );
        }
    }
}

Debounce Delay

Enable debounced input to delay updates to the textbox value, reducing the frequency of changes and improving performance. You can achieve this by setting the DebounceDelay value and Behavior to OnInput.

Value:

<div class="w-full flex flex-col gap-2">
    <LumexTextbox DebounceDelay="250"
                  Behavior="@InputBehavior.OnInput"
                  Label="Search"
                  Placeholder="Type to search..."
                  Clearable="@true"
                  Class="max-w-xs"
                  @bind-Value="@_value" />

    <p class="text-sm text-default-500">
        Value: @_value
    </p>
</div>

@code {
    private string? _value;
}

Two-way Data Binding

The textbox 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: value

<div class="w-full flex flex-wrap gap-4 md:flex-nowrap">
    <div class="w-full flex flex-col gap-2">
        <LumexTextbox 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">
        <LumexTextbox 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 string? _valueOne;
    private string? _valueTwo = "value";

    private void OnValueChanged( string value )
    {
        _valueTwo = value;
    }
}

Custom Styles

This component suppots named slots (represented as data-* attributes) 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 textbox.
  • Classes: The CSS class names for the textbox slots that style entire textbox.
<LumexTextbox Label="Search"
                Placeholder="Type to search..."
                Radius="@Radius.Large"
                Clearable="@true"
                StartContent="@_searchIcon"
                Classes="@_classes" />

@code {
    private RenderFragment _searchIcon =
        @<LumexIcon Icon="@Icons.Rounded.Search"
                    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.

.

An unhandled error has occurred. Reload 🗙