Deconstructing Search Input Box on Fluent UI's Demo Website…
Tags: blazor, fluentui, searchbox, autocomplete
Published: 2024-06-12 00:40:43

The search box component that we see on the demo website is actually implemented using `FluentAutocomplete`. This component combines a text box and a drop-down list box to provide autocomplete functionality.

I want to share my insights on how the `FluentAutocomplete` is implemented on FluentUI's demo website. This will enable us to implement or customize it ourselves. By understanding the underlying structure and functionality, we can tailor the `FluentAutocomplete` to better suit our specific needs and enhance our applications.

Blazor is a web framework that allows C# and .NET developers to create interactive web apps. It enables developers to create rich, modern web applications with a combination of C# code, HTML, and CSS, without relying heavily on JavaScript.

Autocomplete is a feature commonly found in user interfaces that provides suggestions to the user as they type, helping them complete their input more quickly and accurately. In the context of web development, an autocomplete component typically combines a text input field with a dropdown list that displays suggested options based on the user's input.

First, let's navigate to the `Shared` folder in FluentUI's GitHub repository.

You can find the repository here:
```
https://github.com/microsoft/fluentui-blazor/tree/dev/examples/Demo/Shared/Shared
```

Next, we need to locate the search box component in the `DemoMainLayout.razor` file:
```
<div class="search">
    <DemoSearch />
</div>
```

The `DemoSearch` element is a Blazor web component implemented in the `DemoSearch.razor` file. By Blazor's convention, the name of the Razor file becomes the component name, allowing it to be used like an HTML tag.

The following code block `FluentAutocomplete` is implemented in `DemoSearch.razor`.

```
<FluentAutocomplete TOption="NavItem"
                    Width="200px"
                    AutoComplete="off"
                    Placeholder="Search everything..."
                    MaximumSelectedOptions="1"
                    OptionText="@(item => item.Title)"
                    @bind-ValueText="@_searchTerm"
                    @bind-SelectedOptions="_selectedOptions"
                    @bind-SelectedOptions:after="HandleSearchClicked"
                    OnOptionsSearch="@HandleSearchInput"
                    ShowOverlayOnEmptyResults="false">
    <OptionTemplate>
        <span slot="start">
            <FluentIcon Value="@(context.Icon)" Class="search-result-icon" Color="Color.Neutral" Slot="start"/>
        </span>
        @context.Title
    </OptionTemplate>
</FluentAutocomplete>
```
In this code, `TOption` is a generic type parameter representing the type of options that the `<FluentAutocomplete>` component will operate on. In this case, it will be working with the `NavItem` class, which is defined in `NavItem.cs`.


`Width="200px"` : Sets the width of the search box.
`AutoComplete="off"` : Disables autocomplete in the input field.
`Placeholder="Search everything..."` : Sets the placeholder text.
`MaximumSelectedOptions="1"` : Limits the number of selectable options to 1.

Since `NavItem` is used as `TOption`, we can specify `OptionText` using the `Title` property of `NavItem`. This property is used to display for each `NavItem` in the dropdown list.

```
@bind-ValueText="@_searchTerm"
@bind-SelectedOptions="_selectedOptions"
@bind-SelectedOptions:after="HandleSearchClicked"
OnOptionsSearch="@HandleSearchInput"
```
The above code block within the <FluentAutocomplete> component is responsible for establishing data bindings with the methods it will call.

In a Blazor component, C# code is typically written within a `@code { }` block using the `@code` directive. Alternatively, code can be placed in a separate code-behind `.cs` file. By convention, the code-behind file should have the same name as the Razor file with a `.razor.cs` extension, such as `MyComponent.razor.cs`. 

Therefore, we can find the `DemoSearch.razor`'s C# code in `DemoSearch.razor.cs`. 

This code `@bind-ValueText="@_searchTerm"` will bind the value of the text box to the `_searchTerm`. On the other hand, this `@bind-SelectedOptions="_selectedOptions"` will just set `_selectedOptions`.

Lastly, `OnOptionsSearch` event is an `EventCallback<OptionsSearchEventArgs<TOption>>` that is used to filter the list of options based on the text input by the user. `EventCallBack` is a generic type that allows passing event data to a method in the component. By setting `OnOptionsSearch="@HandleSearchInput"`, we specify that the `HandleSearchInput` method will handle the filtering logic. This method processes the user's input and updates the list of options accordingly. We can see these code implementations in `DemoSearch.razor.cs`.

This should now provide a clear and coherent explanation of how the `FluentAutocomplete` component is implemented and how it works.

The `FluentAutocomplete` component is part of the FluentUI Blazor library, which provides a range of UI components designed for Blazor applications. You can explore more about FluentUI Blazor [here](https://www.fluentui-blazor.net/Autocomplete).

## Additional Resources

- [FluentUI Blazor Official Website](https://www.fluentui-blazor.net/)