SelectInput


The SelectInput component renders a Bulma-styled select element for typed option lists and supports colors, sizes, states, icons, validation, and change events.

API Documentation

How it works #

The SelectInput component renders a Bulma-styled HTML select element and binds the selected option to your Blazor state through a typed item collection.

How to use:
  1. Create a list of SelectInputItem<TValue> values for the available options.
  2. Add the SelectInput component and set the matching TValue type.
  3. Bind the selected value with @bind-Value and optionally provide a Placeholder.
This demo shows the basic setup for binding a selected value from a typed option list.
Selected value: pending
<SelectInput TValue="string"
             Items="@statusItems"
             Placeholder="Select a status"
             @bind-Value="selectedStatus" />
<div class="mt-3">Selected value: @selectedStatus</div>

@code {
    private string selectedStatus = "pending";

    private readonly List<SelectInputItem<string>> statusItems =
    [
        new("draft", "Draft"),
        new("pending", "Pending"),
        new("approved", "Approved")
    ];
}

Colors #

Apply Bulma color variants to the select wrapper with the Color parameter to match validation, status, or branding contexts.

How to use:
  1. Add the SelectInput component with your typed items and bound value.
  2. Set Color to one of the available SelectInputColor values such as Primary, Info, or Danger.
  3. Repeat with different color values to preview the supported variants.
This demo shows the supported color themes for SelectInput.
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@statusItems" Color="SelectInputColor.Link" @bind-Value="value1" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@statusItems" Color="SelectInputColor.Primary" @bind-Value="value2" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@statusItems" Color="SelectInputColor.Info" @bind-Value="value3" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@statusItems" Color="SelectInputColor.Success" @bind-Value="value4" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@statusItems" Color="SelectInputColor.Warning" @bind-Value="value5" />
<SelectInput TValue="string" Items="@statusItems" Color="SelectInputColor.Danger" @bind-Value="value6" />

@code {
    private string value1 = "draft";
    private string value2 = "draft";
    private string value3 = "draft";
    private string value4 = "draft";
    private string value5 = "draft";
    private string value6 = "draft";

    private readonly List<SelectInputItem<string>> statusItems =
    [
        new("draft", "Draft"),
        new("pending", "Pending"),
        new("approved", "Approved")
    ];
}

Styles #

Use the IsRounded parameter to apply Bulma's rounded select styling while keeping the same binding behavior.

How to use:
  1. Add the SelectInput component with your items and selected value.
  2. Set IsRounded="true" to enable the rounded select appearance.
  3. Optionally combine it with a color or placeholder to match your design.
This demo shows the rounded style option for SelectInput.
<SelectInput TValue="string"
             Items="@frameworkItems"
             IsRounded="true"
             @bind-Value="selectedFramework" />

@code {
    private string selectedFramework = "blazor";

    private readonly List<SelectInputItem<string>> frameworkItems =
    [
        new("blazor", "Blazor"),
        new("mvc", "ASP.NET MVC"),
        new("razor-pages", "Razor Pages")
    ];
}

Sizes #

Control the visual scale of the select with the Size parameter. Available options mirror Bulma's small, normal, medium, and large variants.

How to use:
  1. Add the SelectInput component with your typed items.
  2. Set Size to SelectInputSize.Small, Normal, Medium, or Large.
  3. Compare the rendered options to choose the best fit for your layout.
This demo illustrates the available size variants for SelectInput.
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@teamItems" Size="SelectInputSize.Small" @bind-Value="value1" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@teamItems" Size="SelectInputSize.Normal" @bind-Value="value2" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@teamItems" Size="SelectInputSize.Medium" @bind-Value="value3" />
<SelectInput TValue="string" Items="@teamItems" Size="SelectInputSize.Large" @bind-Value="value4" />

@code {
    private string value1 = "product";
    private string value2 = "product";
    private string value3 = "product";
    private string value4 = "product";

    private readonly List<SelectInputItem<string>> teamItems =
    [
        new("product", "Product"),
        new("design", "Design"),
        new("engineering", "Engineering")
    ];
}

States #

The State parameter lets you preview Bulma's hovered, focused, and loading styles without waiting for user interaction.

How to use:
  1. Add the SelectInput component with your typed items and selected value.
  2. Set State to SelectInputState.Hovered, Focused, or Loading.
  3. Optionally combine the loading state with a size to preview the scaled loading indicator.
This demo shows the normal, hovered, focused, and loading states for SelectInput.
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@planItems" @bind-Value="value1" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@planItems" State="SelectInputState.Hovered" @bind-Value="value2" />
<SelectInput TValue="string" ContainerCssClass="mb-3" Items="@planItems" State="SelectInputState.Focused" @bind-Value="value3" />
<SelectInput TValue="string" Items="@planItems" State="SelectInputState.Loading" @bind-Value="value4" />

@code {
    private string value1 = "starter";
    private string value2 = "starter";
    private string value3 = "starter";
    private string value4 = "starter";

    private readonly List<SelectInputItem<string>> planItems =
    [
        new("starter", "Starter"),
        new("pro", "Pro"),
        new("enterprise", "Enterprise")
    ];
}

With icons #

Use the LeftIcon and RightIcon templates to place icon components beside the select while keeping Bulma's icon-aware control layout.

How to use:
  1. Add the SelectInput component and provide your typed items and selection binding.
  2. Supply icon components inside the <LeftIcon> and <RightIcon> templates.
  3. For icon components such as BootstrapIcon, set IconContainerCssClass to is-left or is-right so the icon aligns with the select correctly.
This demo shows left and right icon placement with SelectInput.
<SelectInput TValue="string"
             ContainerCssClass="mb-3"
             Items="@assigneeItems"
             Placeholder="Choose an assignee"
             @bind-Value="selectedAssignee">
    <LeftIcon>
        <BootstrapIcon IconContainerCssClass="is-left" Name="BootstrapIconName.PersonSquare" />
    </LeftIcon>
</SelectInput>

<SelectInput TValue="string"
             Items="@assigneeItems"
             Placeholder="Choose an assignee"
             Color="SelectInputColor.Success"
             @bind-Value="selectedReviewer">
    <LeftIcon>
        <BootstrapIcon IconContainerCssClass="is-left" Name="BootstrapIconName.Search" />
    </LeftIcon>
    <RightIcon>
        <BootstrapIcon IconContainerCssClass="is-right" Name="BootstrapIconName.CheckCircleFill" />
    </RightIcon>
</SelectInput>

@code {
    private string selectedAssignee = "vikram";
    private string selectedReviewer = "maya";

    private readonly List<SelectInputItem<string>> assigneeItems =
    [
        new("vikram", "Vikram"),
        new("maya", "Maya"),
        new("sam", "Sam")
    ];
}

Validations #

Integrate SelectInput with Blazor's form validation system by binding it inside an EditForm and pairing it with a placeholder option for required selection scenarios.

How to use:
  1. Create a form model with validation attributes such as [Required].
  2. Wrap the component in an EditForm and bind it to the model property with @bind-Value.
  3. Provide a Placeholder and render a ValidationMessage for the same property.
This demo shows required-field validation with a placeholder option and validation feedback.
Choose a role and submit the form.
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Components.Forms

<style>
    /* validations */
    .valid.modified:not([type=checkbox]) {
        border-color: hsl(var(--bulma-success-h), var(--bulma-success-s), var(--bulma-success-l)) !important;
        outline: 1px solid hsl(var(--bulma-success-h), var(--bulma-success-s), var(--bulma-success-l)) !important;
    }

    .invalid {
        border-color: hsl(var(--bulma-danger-h), var(--bulma-danger-s), var(--bulma-danger-l)) !important;
        outline: 1px solid hsl(var(--bulma-danger-h), var(--bulma-danger-s), var(--bulma-danger-l)) !important;
    }

    .validation-message {
        color: hsl(var(--bulma-danger-h), var(--bulma-danger-s), var(--bulma-danger-l)) !important;
    }
</style>

<EditForm EditContext="@editContext" OnValidSubmit="OnValidSubmit">
    <DataAnnotationsValidator />

    <div style="max-width: 24rem;">
        <SelectInput TValue="string"
                     Items="@roleItems"
                     Placeholder="Select a role"
                     @bind-Value="registration.Role" />
        <ValidationMessage For="@(() => registration.Role)" />
    </div>

    <Button Class="mt-3" Color="ButtonColor.Primary" Type="ButtonType.Submit">
        Submit
    </Button>
</EditForm>

<div class="mt-3">@resultMessage</div>

@code {
    private RegistrationModel registration = new();
    private EditContext? editContext;

    private string resultMessage = "Choose a role and submit the form.";

    private readonly List<SelectInputItem<string>> roleItems =
    [
        new("developer", "Developer"),
        new("designer", "Designer"),
        new("manager", "Manager")
    ];

    protected override void OnInitialized()
    {
        editContext = new EditContext(registration);
        base.OnInitialized();
    }

    private void OnValidSubmit()
    {
        resultMessage = $"Submitted role: {registration.Role}";
    }

    private sealed class RegistrationModel
    {
        [Required(ErrorMessage = "Please select a role.")]
        public string? Role { get; set; }
    }
}

Events: ValueChanged #

Handle the ValueChanged callback when you want to run custom logic as soon as the selected value changes.

How to use:
  1. Set the current Value and provide a ValueChanged callback.
  2. Update your local state inside the callback to keep the UI synchronized.
  3. Use the callback result anywhere else in your page or workflow.
This demo shows how to react to changes through the ValueChanged event.
Last value: medium
<SelectInput TValue="string"
             Items="@priorityItems"
             Value="@selectedPriority"
             ValueChanged="OnPriorityChanged"
             Placeholder="Select a priority" />
<div class="mt-3">Last value: @selectedPriority</div>

@code {
    private string selectedPriority = "medium";

    private readonly List<SelectInputItem<string>> priorityItems =
    [
        new("low", "Low"),
        new("medium", "Medium"),
        new("high", "High")
    ];

    private void OnPriorityChanged(string value)
    {
        selectedPriority = value;
    }
}

Events: TextChanged #

Use the TextChanged callback when you need the selected display text instead of, or in addition to, the typed value.

How to use:
  1. Set the current Text and provide a TextChanged callback.
  2. Update your local state with the selected label inside the callback.
  3. Display or process the selected text elsewhere in your page.
This demo shows how to react to selection changes through the TextChanged event.
Last text: Staging
<SelectInput TValue="string"
             Items="@environmentItems"
             Text="@selectedEnvironmentText"
             TextChanged="OnEnvironmentTextChanged"
             Placeholder="Select an environment" />
<div class="mt-3">Last text: @selectedEnvironmentText</div>

@code {
    private string selectedEnvironmentText = "Staging";

    private readonly List<SelectInputItem<string>> environmentItems =
    [
        new("dev", "Development"),
        new("staging", "Staging"),
        new("prod", "Production")
    ];

    private void OnEnvironmentTextChanged(string text)
    {
        selectedEnvironmentText = text;
    }
}
DO YOU KNOW?
This demo website is built using the BlazorExpress.Bulma library and published on the Azure Web App. See our source code on GitHub.