DEV Community

Cover image for How to implement a Material Designed <input type='file'> field built on "MudBlazor"?
jsakamoto
jsakamoto

Posted on

How to implement a Material Designed <input type='file'> field built on "MudBlazor"?

Prologue

This article describes a technic of "Blazor" Web application programming - that is a framework for building web apps in C#.

There are some UI component libraries that can use to implement Blazor application that is Material Designed.

One of the libraries which I prefer is "MudBlazor".

GitHub logo Garderoben / MudBlazor

Blazor Component Library based on Material design. The goal is to do more with Blazor, utilizing CSS and keeping Javascript to a bare minimum.

"MudBlazor" provides many useful components for developers.
However, "MudBlazor" doesn't provide a file picker component (it means "MudBlazor" version of a <input type='file'> HTML element).

fig001

So I started to implement a Material Designed file picker component built on the "MudBlazor".

Basic concept

To implement a file picker component that has a customized appearance, we can use a <label> element for this purpose.

A <label> element can be associated with a <input type='file'> element by it's Id, like this:

<input type='file' id='foo' />
<label for='foo'>Chose File</label>
Enter fullscreen mode Exit fullscreen mode

On the HTML page above, a file picker dialog will be opened when a user clicks the "Choose File" label even if the <input type='file'> element is invisible.

movie-001

That's all of the basic concepts.

I will show the story that I improved this HTML code to be what I want to make it to be in the following sections.

Make the appearance of the label to be Material Designed button

At first, we have to use a <InputFile> official Blazor component instead of a native <input type='file'> HTML element to integrate with our C# code.

And, we have to hide the <InputFile> component because we will build a customized appearance by ourselves.

<!-- 👇 Use this component to integrate with C# code, -->
<!--    and hide it. -->
<InputFile Id='foo' style="display:none;" />
<label for='foo'>CLICK ME!</label>
Enter fullscreen mode Exit fullscreen mode

Next, I want to make the appearance of the label to be a Material Designed button.

What I have to do to do this is very easy.
It just applies CSS classes that are provided by "MudBlazor".

I applied the CSS classes below to the label.

  • mud-button-root
  • mud-button
  • mud-button-filled
  • mud-button-filled-primary
  • mud-button-filled-size-medium
  • mud-ripple
...
<label ... class="mud-button-root mud-button mud-button-filled mud-button-filled-primary mud-button-filled-size-medium mud-ripple">
  Choose File
</label>
Enter fullscreen mode Exit fullscreen mode

After doing this, we can see the label on the browser but the appearance of the label became the same with a <MudButton> component.

fig003

Add an element like an input field

Next, I want to display an element that has a similar appearance to a <MudTextField> component to show a picked file name, like native <input type='file'> HTML element.

For to do this, we have to markup 3 parts of the bellow.

  • The caption field to display the title of this file picker field.
  • The field like a read-only <input> element to display a picked file name.
  • The help text field displays some helpful text such as validation error messages.

I'll explain the details of the above step by step in the following sections.

Markup the caption field

To implement the caption field that has the same appearance as the other "MudBlazor" component such as the <MudTextField> component, we can use the <MudText> component with the Type property is Typo.caption.

<MudText Typo="Typo.caption">
    Avatar picture file
</MudText>
Enter fullscreen mode Exit fullscreen mode

fig004

Markup the field that resembles an input element to display a picked file name

This is just a field "like" an input element, is not real <input> HTML element, because the user can't input any keystrokes in this field.

Therefore I implemented this field by using a normal <label> HTML element with custom CSS styling applied to make it resemble a <MudInput> component.

One of the important points to do this is, how to set the color of the underline of this element same with <MudInput> 's it.

Fortunately, "MudBlazor" exposes its theme colors as standard "CSS variables".

So I could apply the same color with "MudBlazor" to my custom <label> element by CSS code as below.

.selected-file-name {
  border-bottom: solid 1px var(--mud-palette-lines-inputs);
}
Enter fullscreen mode Exit fullscreen mode

fig005

This is a standard way of general Web application programming and markup.

Markup the help text field

We can markup the help text field in the same way.

Wa have to do to markup the help text field is just apply CSS class that is provided by "MudBlazor", like this:

<div class="mud-input-helper-text">
    Max allowed file size is 512KB.
</div>
Enter fullscreen mode Exit fullscreen mode

fig006

If we have to display the help text field as an error message, apply the --mud-palette-error CSS variable for the text color of the field.

It was completed!

Finally, we created the Material Designed file picker component that has a similar appearance with a <MudTextField> component.

movie-002

All of the code of this article is published on my GitHub repository (follow the URL below).

GitHub logo sample-by-jsakamoto / MudBlazorInputFile

Sample code of Material Designed "input type=file" with MudBlazor

Notice

Unfortunately, this component doesn't accept any manipulations from a keyboard unlikely normal <input type='file'> HTML element.

And also, it doesn't accept drag & drop a file.

If you have to implement the above features, I have no idea at this time.
I think I can do it by "ClickJacking", but I do not want to recommend it because it is a dirty hack.

Conclusion

"MudBlazor" is exposing its parameters such as size information, theme colors, as CSS variables - it is Web standard way.

So we can implement a component that has the same appearance as the other "MudBlazor"'s components by referring to those CSS variables.

Learn, Practice, Share!

Top comments (0)