Data Grid

fluent-data-grid

The fluent-data-grid component is used to display tabular data. The fluent-data-grid-row and fluent-data-grid-cell components are typically created programmatically by the parent grid but some authors may find it useful to create them manually.

Setup

import {
    provideFluentDesignSystem,
    fluentDataGridCell,
    fluentDataGridRow,
    fluentDataGrid
} from "@fluentui/web-components";

provideFluentDesignSystem()
    .register(
        fluentDataGridCell(),
        fluentDataGridRow(),
        fluentDataGrid()
    );

Example

Note: data must be provided to the grid via a property.

document.getElementById("samplegrid").rowsData = [
    { item1: "value 1-1", item2: "value 2-1" },
    { item1: "value 1-2", item2: "value 2-2" },
    { item1: "value 1-3", item2: "value 2-3" },
]; 

FluentDataGrid

The <FluentDataGrid> component is used to display tabular data. The <FluentDataGridRow> and <FluentDataGridCell> components are typically created programmatically by the parent grid but some authors may find it useful to create them manually.

<FluentDataGrid> wraps the <fluent-data-grid> element, a web component implementation of a data grid leveraging the Fluent UI design system.

Usage

@using Microsoft.Fast.Components.FluentUI
<h2>Manual grid</h2>
<FluentDataGrid id="manualGrid" GenerateHeader=GenerateHeaderOptions.None GridTemplateColumns="1fr 1fr" TItem=string>
    <FluentDataGridRow TItem=string RowType="DataGridRowType.Header">
        <FluentDataGridCell GridColumn=1 CellType="DataGridCellType.ColumnHeader">Column 1</FluentDataGridCell>
        <FluentDataGridCell GridColumn=2 CellType="DataGridCellType.ColumnHeader">Column 2</FluentDataGridCell>
    </FluentDataGridRow>
    <FluentDataGridRow TItem=string>
        <FluentDataGridCell GridColumn=1>1.1</FluentDataGridCell>
        <FluentDataGridCell GridColumn=2>1.2</FluentDataGridCell>
    </FluentDataGridRow>
    <FluentDataGridRow TItem=string>
        <FluentDataGridCell GridColumn=1>2.1</FluentDataGridCell>
        <FluentDataGridCell GridColumn=2> 2.2</FluentDataGridCell>
    </FluentDataGridRow>
</FluentDataGrid>

<h2>Sorting/Filtering grid</h2>
<FluentTextField @oninput="FilterChanged">Filter Fruit</FluentTextField>
<FluentDataGrid id="sortingGrid" GridTemplateColumns="1fr 1fr 1fr" RowsData=SortedRowsGrid ColumnDefinitions=SortingColumnsGrid>
    <HeaderCellTemplate>
        <FluentButton @onclick=@(()=>SortColumn(context))>
            @context.Title
            @if (context.Title == lastSortColumn?.Title)
            {
                @(isAscending ? " ↑" : " ↓")
            }
        </FluentButton>
    </HeaderCellTemplate>
</FluentDataGrid>

@code {
    public record SampleGridData(string Fruit, string Cost, string Color);
    public List<ColumnDefinition<SampleGridData>> SortingColumnsGrid = new ();

    List<SampleGrid3Data> RawSortedRowsGrid = new List<SampleGridData>()
    {
        new SampleGrid3Data("apples", "$1.50", "red" ),
        new SampleGrid3Data("bananas", "$0.99", "yellow" ),
        new SampleGrid3Data("grapes", "$1.99", "purple" ),
        new SampleGrid3Data("oranges", "$1.25", "orange" )

    };
    List<SampleGridData> SortedRowsGrid = new();

    protected override void OnInitialized()
    {
        SortingColumnsGrid.Add(new ColumnDefinition<SampleGridData>("Fruit", x => x.Fruit));
        SortingColumnsGrid.Add(new ColumnDefinition<SampleGridData>("Cost", x => x.Cost));
        SortingColumnsGrid.Add(new ColumnDefinition<SampleGridData>("Color", x => x.Color));

        SortedRowsGrid = RawSortedRowsGrid;

        base.OnInitialized();
    }

    private void FilterChanged(ChangeEventArgs args)
    {
        var filter = args.Value as string;

        if (string.IsNullOrWhiteSpace(filter))
        {
            SortedRowsGrid = RawSortedRowsGrid;
        }
        else
        {
            SortedRowsGrid = RawSortedRowsGrid.Where(x => x.Fruit.Contains(filter)).ToList();
        }
        if (lastSortColumn != null)
        {
            SortedRowsGrid.Sort(new CustomComparer(lastSortColumn.FieldSelector!, isAscending));
        }
    }

    private void SortColumn(ColumnDefinition<SampleGridData> columnDefinition)
    {
        if (lastSortColumn?.Title == columnDefinition.Title)
        {
            isAscending = !isAscending;
        }
        else
        {
            lastSortColumn = columnDefinition;
            isAscending = true;
        }
        SortedRowsGrid.Sort(new CustomComparer(columnDefinition.FieldSelector!, isAscending));
    }

    class CustomComparer : IComparer<SampleGridData>
    {
        Func<SampleGridData, object> _selector;
        bool _isAscending;

        public CustomComparer(Func<SampleGridData, object> selector, bool isAscending)
        {
            _selector = selector;
            _isAscending = isAscending;
        }

        int IComparer<SampleGridData>.Compare(SampleGridData? x, SampleGridData? y)
        {
            var xs = _selector(x!) as string;
            var ys = _selector(y!) as string;
            if (xs == null || ys == null)
                return 0;
            return string.Compare(xs, ys) * (_isAscending ? 1 : -1);
        }
    }
}

Example

See the component in action with implementation examples at the Blazor demo site.