diff --git a/WHATSNEW.md b/WHATSNEW.md index 5eaefd1e1a..af778cb7e3 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -1,3 +1,8 @@ +## v4.6.2 + +### Components +[DataGrid] Add remove sort capability on columns ([#1826](https://github.com/microsoft/fluentui-blazor/pull/1826)) + ## V4.6.1 ### Demo site and documentation diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index 9fd2a1e2e9..a774d3169c 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -1084,20 +1084,20 @@ - Gets or sets the title text for the column. + Gets or sets the title text for the column. This is rendered automatically if is not used. - Gets or sets the an optional CSS class name. + Gets or sets the an optional CSS class name. If specified, this is included in the class attribute of header and grid cells for this column. - Gets or sets an optional CSS style specification. + Gets or sets an optional CSS style specification. If specified, this is included in the style attribute of header and grid cells for this column. @@ -1119,7 +1119,7 @@ - Gets or sets an optional template for this column's header cell. + Gets or sets an optional template for this column's header cell. If not specified, the default header template includes the along with any applicable sort indicators and options buttons. @@ -1471,6 +1471,13 @@ The direction of sorting. If the value is , then it will toggle the direction on each call. A representing the completion of the operation. + + + Removes the grid's sort on double click if this is specified currently sorted on. + + The column to check against the current sorted on column. + A representing the completion of the operation. + Displays the UI for the specified column, closing any other column diff --git a/examples/Demo/Shared/Pages/DataGrid/DataGridPage.razor b/examples/Demo/Shared/Pages/DataGrid/DataGridPage.razor index 64df043ce0..5e285a1804 100644 --- a/examples/Demo/Shared/Pages/DataGrid/DataGridPage.razor +++ b/examples/Demo/Shared/Pages/DataGrid/DataGridPage.razor @@ -21,6 +21,18 @@ as this will interfere with the DataGrid scripts that use this attribute as well. Use the RowClass instead.

+

Accessibility

+

+ You can use the Arrow keys to navigate through a DataGrid. When a header cell is focused and the column is sortable, you can use the Tab key to select the sort button. + Pressing the Enter key will toggle the sorting direction. Pressing Ctrl+Enter removes the column sorting and restores the default/start situation with regards to sorting. + You cannot not remove the default grid sorting with this key combination. +

+

+ When a header cell is focused and the column allows setting options, you can use the Tab key to select the options button. + Pressing the Enter key then will toggle the options popover. Pressing Esc closes the popover + . +

+

Examples

diff --git a/examples/Demo/Shared/Pages/DataGrid/Examples/DataGridTypical.razor b/examples/Demo/Shared/Pages/DataGrid/Examples/DataGridTypical.razor index 2127311907..164d8bcea1 100644 --- a/examples/Demo/Shared/Pages/DataGrid/Examples/DataGridTypical.razor +++ b/examples/Demo/Shared/Pages/DataGrid/Examples/DataGridTypical.razor @@ -8,7 +8,7 @@ @@ -21,8 +21,8 @@ - @@ -37,7 +37,7 @@ .ByDescending(x => x.Medals.Gold) .ThenDescending(x => x.Medals.Silver) .ThenDescending(x => x.Medals.Bronze); - + Func rowClass = x => x.Name.StartsWith("A") ? "highlighted-row" : null; Func rowStyle = x => x.Name.StartsWith("Au") ? "background-color: var(--highlight-bg);" : null; diff --git a/examples/Demo/Shared/wwwroot/docs/WhatsNew.md b/examples/Demo/Shared/wwwroot/docs/WhatsNew.md index c159023a7b..c421dcf1e8 100644 --- a/examples/Demo/Shared/wwwroot/docs/WhatsNew.md +++ b/examples/Demo/Shared/wwwroot/docs/WhatsNew.md @@ -1,3 +1,8 @@ +## v4.6.2 + +### Components +[DataGrid] Add remove sort capability on columns ([#1826](https://github.com/microsoft/fluentui-blazor/pull/1826)) + ## V4.6.1 ### Demo site and documentation @@ -8,7 +13,6 @@ - [Demo & docs] CSS files improvements ([#1807](https://github.com/microsoft/fluentui-blazor/pull/1807)) - [Demo & docs] The empty CSS rule in site.css has been removed ([#1809](https://github.com/microsoft/fluentui-blazor/pull/1809)) - ### Components - [AppBar] Add Count parameter and facilitate OnClick without navigation ([#1790](https://github.com/microsoft/fluentui-blazor/pull/1790)) - [CounterBadge] Add ShowWhen, Dot, and VerticalPosition ([#1786](https://github.com/microsoft/fluentui-blazor/pull/1786)) diff --git a/src/Core/Components/DataGrid/Columns/ColumnBase.razor b/src/Core/Components/DataGrid/Columns/ColumnBase.razor index a3fc18e1e7..b273076a44 100644 --- a/src/Core/Components/DataGrid/Columns/ColumnBase.razor +++ b/src/Core/Components/DataGrid/Columns/ColumnBase.razor @@ -1,4 +1,4 @@ -@using Microsoft.AspNetCore.Components.Rendering +@using Microsoft.AspNetCore.Components.Rendering @using Microsoft.FluentUI.AspNetCore.Components.DataGrid.Infrastructure @namespace Microsoft.FluentUI.AspNetCore.Components @typeparam TGridItem @@ -20,7 +20,7 @@ @if (ColumnOptions is not null && (Align == Align.Start || Align == Align.Center)) { - @if(Filtered.GetValueOrDefault()) + @if (Filtered.GetValueOrDefault()) { } @@ -33,22 +33,26 @@ if (Sortable.HasValue ? Sortable.Value : IsSortableByDefault()) { - -
@Title
+ + + +
@Title
- @if (Grid.SortByAscending.HasValue && ShowSortIcon) - { - if (Grid.SortByAscending == true) + @if (Grid.SortByAscending.HasValue && ShowSortIcon) { - + if (Grid.SortByAscending == true) + { + + } + else + { + + } } - else - { - - } - } -
+
+ + } else { @@ -60,7 +64,7 @@ @if (ColumnOptions is not null && Align == Align.End) { - @if(Filtered.GetValueOrDefault()) + @if (Filtered.GetValueOrDefault()) { } diff --git a/src/Core/Components/DataGrid/Columns/ColumnBase.razor.cs b/src/Core/Components/DataGrid/Columns/ColumnBase.razor.cs index 86bb5677ca..cbd6eb6702 100644 --- a/src/Core/Components/DataGrid/Columns/ColumnBase.razor.cs +++ b/src/Core/Components/DataGrid/Columns/ColumnBase.razor.cs @@ -14,20 +14,20 @@ public abstract partial class ColumnBase [CascadingParameter] internal InternalGridContext InternalGridContext { get; set; } = default!; /// - /// Gets or sets the title text for the column. + /// Gets or sets the title text for the column. /// This is rendered automatically if is not used. /// [Parameter] public string? Title { get; set; } /// - /// Gets or sets the an optional CSS class name. + /// Gets or sets the an optional CSS class name. /// If specified, this is included in the class attribute of header and grid cells /// for this column. /// [Parameter] public string? Class { get; set; } /// - /// Gets or sets an optional CSS style specification. + /// Gets or sets an optional CSS style specification. /// If specified, this is included in the style attribute of header and grid cells /// for this column. /// @@ -49,7 +49,7 @@ public abstract partial class ColumnBase [Parameter] public Func? TooltipText { get; set; } /// - /// Gets or sets an optional template for this column's header cell. + /// Gets or sets an optional template for this column's header cell. /// If not specified, the default header template includes the along with any applicable sort indicators and options buttons. /// [Parameter] public RenderFragment>? HeaderCellItemTemplate { get; set; } @@ -135,6 +135,14 @@ public abstract partial class ColumnBase /// True if the column should be sortable by default, otherwise false. protected virtual bool IsSortableByDefault() => false; + protected void HandleKeyDown(FluentKeyCodeEventArgs e) + { + if (e.CtrlKey && e.Key == KeyCode.Enter) + { + Grid.RemoveSortByColumnAsync(this); + } + } + public bool ShowSortIcon; /// diff --git a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs index ba9689cba7..d3b481115f 100644 --- a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs +++ b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs @@ -277,6 +277,7 @@ internal void AddColumn(ColumnBase column, SortDirection? initialSort { _sortByColumn = column; _sortByAscending = initialSortDirection.Value != SortDirection.Descending; + _internalGridContext.DefaultSortColumn = (column, initialSortDirection.Value); } } } @@ -319,6 +320,23 @@ public Task SortByColumnAsync(ColumnBase column, SortDirection direct return RefreshDataAsync(); } + /// + /// Removes the grid's sort on double click if this is specified currently sorted on. + /// + /// The column to check against the current sorted on column. + /// A representing the completion of the operation. + public Task RemoveSortByColumnAsync(ColumnBase column) + { + if (_sortByColumn == column && !column.IsDefaultSortColumn) + { + _sortByColumn = _internalGridContext.DefaultSortColumn.Column ?? null; + _sortByAscending = _internalGridContext.DefaultSortColumn.Direction != SortDirection.Descending; + } + + StateHasChanged(); // We want to see the updated sort order in the header, even before the data query is completed + return RefreshDataCoreAsync(); + } + /// /// Displays the UI for the specified column, closing any other column /// options UI that was previously displayed. @@ -331,6 +349,10 @@ public Task ShowColumnOptionsAsync(ColumnBase column) StateHasChanged(); return Task.CompletedTask; } + public void SetLoadingState(bool loading) + { + Loading = loading; + } /// /// Instructs the grid to re-fetch and render the current data from the supplied data source @@ -342,11 +364,6 @@ public async Task RefreshDataAsync() await RefreshDataCoreAsync(); } - public void SetLoadingState(bool loading) - { - Loading = loading; - } - // Same as RefreshDataAsync, except without forcing a re-render. We use this from OnParametersSetAsync // because in that case there's going to be a re-render anyway. private async Task RefreshDataCoreAsync() diff --git a/src/Core/Components/DataGrid/FluentDataGrid.razor.js b/src/Core/Components/DataGrid/FluentDataGrid.razor.js index d005da7c8b..96e06a8a8b 100644 --- a/src/Core/Components/DataGrid/FluentDataGrid.razor.js +++ b/src/Core/Components/DataGrid/FluentDataGrid.razor.js @@ -16,6 +16,7 @@ export function init(gridElement) { if (columnOptionsElement) { if (event.key === "Escape") { gridElement.dispatchEvent(new CustomEvent('closecolumnoptions', { bubbles: true })); + gridElement.focus(); } columnOptionsElement.addEventListener( "keydown", diff --git a/src/Core/Components/DataGrid/FluentDataGridCell.razor.css b/src/Core/Components/DataGrid/FluentDataGridCell.razor.css index bc391f64bf..0610a58026 100644 --- a/src/Core/Components/DataGrid/FluentDataGridCell.razor.css +++ b/src/Core/Components/DataGrid/FluentDataGridCell.razor.css @@ -1,4 +1,4 @@ -fluent-data-grid-cell { +fluent-data-grid-cell { text-overflow: ellipsis; } @@ -10,28 +10,44 @@ .column-header { display: flex; + width: 100%; + height: 100%; align-self: center; padding-inline: 0; + padding-right: 1px; + padding-left: 1px; } .column-header.col-justify-end, .column-header.col-justify-right { - width: 100%; - padding: 0; + + padding-right: 1px; + padding-left: 1px; justify-content: end; } .column-header.col-justify-center { - width: 100%; - padding: 0; + + padding-left: 1px; + padding-right: 1px; justify-content: center; } - .column-header > ::deep .col-sort-button { + .column-header > ::deep .keycapture { + display: flex; + flex-grow: 1; + } + + .column-header > ::deep .keycapture .col-sort-container { + display: flex; + flex-grow: 1; + } + + .column-header > ::deep .keycapture .col-sort-container .col-sort-button { flex-grow: 1; padding-inline-end: 5px; } - .column-header > ::deep .col-sort-button::part(content) { + .column-header > ::deep .keycapture .col-sort-container .col-sort-button::part(content) { overflow: hidden; text-overflow: ellipsis; } diff --git a/src/Core/Components/DataGrid/Infrastructure/InternalGridContext.cs b/src/Core/Components/DataGrid/Infrastructure/InternalGridContext.cs index bd5ee22a8b..3ca3080996 100644 --- a/src/Core/Components/DataGrid/Infrastructure/InternalGridContext.cs +++ b/src/Core/Components/DataGrid/Infrastructure/InternalGridContext.cs @@ -10,6 +10,9 @@ internal sealed class InternalGridContext private int _rowId = 0; private int _cellId = 0; + public (ColumnBase? Column, SortDirection? Direction) DefaultSortColumn { get; set; } + //public SortDirection? DefaultSortDirection { get; set; } + public Dictionary> Rows { get; set; } = []; public FluentDataGrid Grid { get; } diff --git a/src/Core/Components/Dialog/Services/DialogService-Dialog.cs b/src/Core/Components/Dialog/Services/DialogService-Dialog.cs index 373849691e..d8d6682f0f 100644 --- a/src/Core/Components/Dialog/Services/DialogService-Dialog.cs +++ b/src/Core/Components/Dialog/Services/DialogService-Dialog.cs @@ -72,7 +72,7 @@ public async Task ShowDialogAsync(RenderFragment renderFragmen return await ShowDialogAsync(typeof(RenderFragmentDialog), renderFragment, dialogParameters); } - private DialogParameters FixPanelParameters(DialogParameters value) + private static DialogParameters FixPanelParameters(DialogParameters value) { value.DialogType = DialogType.Panel;