Well, as you kind of expect when there is a new major version number, quite a lot actually (with over 150 commits to the repository between the previous version and this one). In this post we'll go through the changes and additions. Make sure you have some refreshments available, it's gonna be a long ride.

At the moment, the package is available on NuGet as the first Release Candidate (RC1) version. This means we will not be adding any new functionality between now and the release of the final version. We'll focus on finding and fixing bugs. It would be great if you can help us with this, take the package for a spin in your own (test) projects and report any issues in the Github repository. Depending on what is found, we might release another RC before the final release.

We'll present the changes in a condensed form first. Starting with what's new for the library and then what's new to the documentation and example site(s). After that, we'll dive into the details. If you're already using the library in your Blazor WASM or Server applications and you want to upgrade to this version, you're going to need that detailed information. As with most major releases, this one comes with breaking changes as well...

Library changes

  • Re-implemented the DataGrid (leveraging the ASP.NET Team's QuickGrid)
  • Re-implemented the Combobox, Listbox and Select components
  • Implemented a CSS baseline
  • General component updates
  • Updated the Accordion component
  • Updated the Anchor component
  • Updated the Button component
  • Updated the Icon component
  • Added a GlobalState service

Documentation and example changes

  • Extended dark/light theme settings with an accent color selection
  • Updated and enhanced the DemoSection component
  • Improved the APIDocumentation component
  • Added a sample data service
  • Added an 'Incubation lab' section where we offer examples of site building components and potential new library components

Library changes

DataGrid component

With regards to the implementation of the grid that was is in our package until now, we followed what was 'prescribed' by the fluent-data-grid. We wrapped the fluent-data-grid, fluent-data-grid-row and fluent-data-grid-cell and their attributes (parameters on the Blazor side) and by doing so styling and rendering is taken care of (by the web components script). For adding capabilities to the grid, we copied over a lot of the principles and code from the BlazorFluentUI package. In that process, some things were renamed to better align with the Web Component internals (like ColumDefinition). The result was nice but a bit clunky in the way the columns are defined. Also, sorting, etc. seemed to be more of an afterthought. We have a solution for all these problems now by leveraging the strengths of the ASP.NET Team's QuickGrid implementation.

For the 2.0 version of the grid we basically took this QuickGrid implementation, swapped out its rendering to use the <FluentDataGrid> components and renamed a lot of the parameters to keep in line with what we were already using on the Fluent UI side. By doing so, we completely broke every <FluentDataGrid> implementation out there. Please be aware of this when you upgrade. You can use the examples provided in the demo site to guide you in how to move to using the new implementation. Also, by doing this, you can now use all* of the great functionality being offered by the QuickGrid. Please take a look at the QuickGrid for Blazor site to see what else is possible.

*Only thing we did not copy over is the Theme parameter and functionality as the whole point of this library is to have a theme implemented already...

In it's simplest form , the end result in code would go from this (which does not come with any sorting capabilities):

<FluentDataGrid id="defaultGrid" RowsData=RowsGrid ColumnDefinitions=ColumnsGrid GridTemplateColumns="1fr 1fr" /> @code {
    record Person(int PersonId, string Name, DateOnly BirthDate);
    
    public List<ColumnDefinition<Person>> ColumnsGrid = new();

    IQueryable<Person> people = new[]
    {
        new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
        new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
        new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
        new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
        new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
        new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
    }.AsQueryable();
    
    protected override void OnInitialized()
    {
        ColumnsGrid.Add(new ColumnDefinition<Person>("Id", x => x.PersonId));
        ColumnsGrid.Add(new ColumnDefinition<Person>("Name", x => x.Name));
        ColumnsGrid.Add(new ColumnDefinition<Person>("Birthdate", x => x.BirthDate));

        base.OnInitialized();
    }
}

to this (with sorting capabilities baked in):

<FluentDataGrid RowsData="@people">
    <PropertyColumn Property="@(p => p.PersonId)" Sortable="true" /> 
    <PropertyColumn Property="@(p => p.Name)" Sortable="true" /> 
    <PropertyColumn Property="@(p => p.BirthDate)" Format="yyyy-MM-dd" Sortable="true" /> 
<FluentDataGrid>

@code {
    record Person(int PersonId, string Name, DateOnly BirthDate);

    IQueryable<Person> people = new[]
    {
        new Person(10895, "Jean Martin", new DateOnly(1985, 3, 16)),
        new Person(10944, "António Langa", new DateOnly(1991, 12, 1)),
        new Person(11203, "Julie Smith", new DateOnly(1958, 10, 10)),
        new Person(11205, "Nur Sari", new DateOnly(1922, 4, 27)),
        new Person(11898, "Jose Hernandez", new DateOnly(2011, 5, 3)),
        new Person(12130, "Kenji Sato", new DateOnly(2004, 1, 9)),
    }.AsQueryable();
}

Quite an improvement, we think.

An example implementation: Grid implementation example

Listbox, Select and Combobox components updates

Earlier versions of these components did not really work well in cases where you wanted to do binding or set pre-selected values. There were also no good examples on how to use the components. And the examples that did exist, assumed that the data shown would come from separate options instead of being inferred from a programmatically supplied list. We have now re-implemented these three components from the ground up (sharing a common base implementation) and are here again making breaking changes! We've also made a lot of examples of the components' usage available in the demo environment.

For the Combobox, you can now bind to the Value instead of to the text of an option. If you type a value instead of selecting an option from the list, the Value will reflect that.

For the Listbox and Select, you can bind to the Value but also to the (strongly typed!) SelectedItemor SelectedItems (multiple not working for Listbox yet because of an issue in the underlying web component).

Example of a multi-select implementation: Multi-select implementation example

A CSS baseline

We've received quite some feedback from users that they would like to have more tools and components available that help them with layout of sites and applications. The thing is that, although we sympathize with the idea, it does not really align well with the goal of this library: to provide a Blazor wrapper for the Fluent UI Web Components. That being said, we thought about how to accommodate to this wish while staying in line with the goal set. We think we've come up with a good middle ground. More on that later..

So why are we bringing this up here? We want to make sure the components look as good as possible in every browser, site and application, wherever the layout is defined. To help you in achieving this, we've added a CSS baseline named Reboot to the library which you can build upon. The CSS we provide is based on Bootstrap's Reboot solution (which in turn is based on Normalize). Using the baseline is completely optional and it is entirely possible to build a site without using Reboot. If you want to use Reboot, like this demo site, you'll need to include it in your index.html or _Layout.cshtml file like this:

<link href="_content/Microsoft.Fast.Components.FluentUI/css/reboot.css" rel="stylesheet" />

If you choose not to use it, please do add the variables.css file (which is otherwise imported through the reboot.css file) to your index.html or _Layout.cshtml file like this:

<link href="_content/Microsoft.Fast.Components.FluentUI/css/variables.css" rel="stylesheet" />

This file contains a number of CSS variables that are required to be defined for some of the components to work correctly.

See the Reboot page in the demosite for more information.

General component updates

We've added two parameters to the <FluentUIComponentBase> component to make them available to every component in the library. The added parameters are:

  • Class; This enables you to add (optional) CSS class names. If given, these will be included in the class attribute of the component.
  • Style; This enables you to add (optional) in-line styles. If given, these will be included in the style attribute of the component.

Utility CssBuilder and StyleBuilder implementations have been added to make it easier to compose values for these parameters. Examples of using this can be found in the source code.

We removed the ChildContent parameter from the base class and moved it down to the components themselves. This is done to make it possible to have components without any child content and/or have components with multiple contents sections.

Accordion component updates

With earlier versions of the library, we added event handling code to several components. Due to some missing code in the underlying web component script, event handling had not been added to the <FluentAccordion> component yet. This code has now been added and this allows you to detect the last changed accordion item. The example in the demo site has been enhanced to showcase this behavior.

Anchor component updates

One of the things that do not play nice in most SPA application frameworks are hyperlinks with bookmarks. This is due to the way the router mechanism works in these frameworks. Blazor is no exception here, so the <FluentAnchor> component could not be used to jump to a specific spot on a page earlier. With this version, a fix has been implemented that enables these jumps to work as expected. This is being used heavily in the new table of contents component that is now shown on every content page in the demo site. The fix also takes into account any text fragments in a link with a bookmark.

Button component updates

We've added a ButtonType enumaration to the library and are using this now in the <FluentButton> component to denote the type of button (it was a string parameter before). The default value for the type is Button. (The other available options are Submit and Reset)

Icon component updates

There are a number of breaking changes for the <FluentIcon> component. Upgrading to version 2 of the library means you will need to review all used icons carefully. The changes are:

  • We've updated <FluentIcon> to support more colors. A Color enum has been added for this. The UseAccentColor parameter has been removed for this.
  • It is now possible to use a custom color for rendering an icon. A CustomColor parameter has been added for this (and can only be used when the Color parameter has been set to Color.Custom)
  • The Filled parameter has been replaced with an IconVariant enum (with possible values of IconVariant.Filled or IconVariant.Regular (default))

To prevent icons being requested and downloaded on each and every <FluentIcon> call, a caching mechanism has been added. This leverages the standard Cache Web API which is supported by every modern browser. Icons downloaded to the cache have a (non configurable) validity of 7 days. After that period, an icon will be re-downloaded from the server.

Example of rendering icons with a specific color: Icons rendered in a specified color

There have also been a couple of releases of the underlying Fluent UI System Icons library since our last version shipped. We have merged these releases into version 2 now. The latest update we've synced up with is 1.1.187.

GlobalState Service

A GlobalState class has been added to the library which is added to the Services container automatically. At the moment the service contains two properties that you can use within your own code. These are Luminance and Dir, and give you access to the state of the current theme (light or dark) and the direction of the content (left to right or right to left). Both properties also come with a Set... method that raises a notification that you can subscribe to in your code. An example of this can be found in the CounterBadge component (see below).

Documentation and example site changes

With this version, we continued to enhance the documentation and examples in the demo sites. The WebAssembly version of the site is always available at https://aka.ms/fluentui-blazor. If you clone or download the repository, you can choose to run either the WebAsssembly or Sever version of the site locally. In the sections below, we'll describe the enhancements we made to these sites in more detail.

Updates and enhancements to the DemoSection component

A key component (no pun intended) to the demo site is the DemoSection component. Is has been greatly enhanced and now displays example, source and other related files (.cs, .css, .js), if any, in a tabbed fashion. This way examples are no longer stretched out to long listings of source code. Another new functionality of the component is that it now presents download options for all the files that make up the example. This way we hope to make it easier to re-use the examples in your own projects. Just remember to replace the namespace we uses in the examples with your own project's namespace.

As a last change, the code highlighting part of the DemoSection has now been made theme-aware.

Improved APIDocumentation component

The information on all of the component's parameters is being generated from the XML documentation (which gathers all source code comments). We built an APIDocumentation component for display this information. This component has now been enhanced to now get descriptions from a components' base class. Also the documentation generation for generic components has been greatly improved.

Add Color ('theme') selection to the site

Finally as a last visual change to the demo, we added a color selection to choose a different accent color to use. This works in tandem with the Light/Dark switch and shows how Design Tokens can be used to influence how components are being rendered.

The colors in the selection list come from an enum (called OfficeColor) that has been added to the library (and not just to the demo environment). The enum contains the RGB hex color codes for 17 different Office applications.

Incubation Lab

To show the art of the possible, test out new things, and address the ask around tools and components that can help with the layout of sites and applications, we've added an 'Incubation Lab' section to the demo environment. By leveraging the download options described earlier, we hope to make it easy for you to test and use these components in your own environments.

The components we showcase in the Lab are not part of the official library and are not included in the NuGet package. We only support these specific components on a best effort base through our GitHub repository.

Layout components

The following components have been added to aid developers in building layouts for sites and applications:

  • Header
  • Footer
  • BodyContent
  • Layout
  • MainLayout
  • Spacer
  • Stack

Using (most of) them together can yield something like this: Layout components working together

Please see the demo site for more documentation and usage examples

Other components

We've added some components that we think could be useful. They showcase how to wrap or build upon existing components, combine components with custom code and/or JavaScript or just how to create something completely new. We hope you will help us test-drive these components, both in the demo environment but also in your own projects, and provide us with feedback.

  • NavMenu, NavMenuGroup and NavMenuLink
    These components show how to wrap the existing <FluentTree> and <FluentTreeItem> components to build a (collapsible) navigation menu. See the left side of the image above for an example
  • CounterBadge
    The CounterBadge component is used to display a notification count on top of another component:
    CounterBadge
  • PresenceBadge
    The PresenceBadge component is used to display a status indicator such as available, away, or busy.
    PresenceBadge
  • MenuButton
    The MenuButton component show how easy it is to combine two other fluent components (<FluentButton> and <FluentMenu>) in a new component with its own specific funtionality
    MenuButton
  • Table of Contents
    The TableOfContents component uses an existing component (<FluentAccordion>) together with some custom code and JavaScript interop. The JavaScript scans the article-section of a page for all h2, h3 and h4 headings and the custom code presents them as a table of contents with clickable links to those headings in an accordion component.
    Table Of Contents component

Next steps

As describe earlier, we have made the RC1 version of the package available on NuGet. Please try it out in your own projects and let us know what you think. Also, please report any issues you find in the GitHub repository. Let's work together to make this a great new major version!

Comments


Comments are closed