-
Notifications
You must be signed in to change notification settings - Fork 468
[dev-v5][DataGrid] Add pinned (sticky/frozen) column support #4671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
vnbaaij
merged 17 commits into
dev-v5
from
copilot/research-fluentdatagrid-implementation
Apr 7, 2026
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
7263ea1
feat: add pinned (sticky) column support to FluentDataGrid
Copilot e1acae8
chore: remove Core.Scripts build artifact and add .gitignore for obj/
Copilot 3040afb
chore: remove tracked Core.Scripts build artifact
Copilot dfec835
chore: start datagrid header layering fix
Copilot b0dcbdd
fix: move datagrid header popup z-index to menu layer
Copilot 4f21ed9
test: update datagrid snapshot expectations
Copilot 3ef8bb9
chore: start pinned resize min-width fix
Copilot f97c2c8
fix: preserve pinned column min-width on resize
Copilot ea97c1a
Example adjustments and CSS tweaks
vnbaaij 20196b9
refactor: avoid repeated computed style lookup for min width
Copilot cc6a697
Update docs
vnbaaij 71f59ba
Delete .gitignore
vnbaaij 3787a2a
Merge branch 'dev-v5' into copilot/research-fluentdatagrid-implementa…
vnbaaij dff971a
Simplify pinned-column wording, preserve demo page metadata, and remo…
Copilot cfe9a91
Do not use stripped effect on the example. Use percentage for 1st sti…
vnbaaij 8291b33
Add CSS fallback
vnbaaij 21b8472
Adjust position of actual resize div pinned columns at the end
vnbaaij File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -424,3 +424,4 @@ all-icons.json | |
| all-emojis.json | ||
| /global.json | ||
| /src/Core.Scripts/src/BuildConstants.ts | ||
| /src/Core.Scripts/obj/ | ||
42 changes: 42 additions & 0 deletions
42
...uentUI.Demo.Client/Documentation/Components/DataGrid/Examples/DataGridPinnedColumns.razor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| <div style="overflow-x: auto;"> | ||
| <FluentDataGrid Items="@employees" | ||
| Style="min-width: max-content;" | ||
| ResizableColumns="true" | ||
| DisplayMode="DataGridDisplayMode.Grid"> | ||
| <PropertyColumn Title="ID" Property="@(e => e.Id)" Width="10%" Pin="DataGridColumnPin.Start" Sortable="true" /> | ||
| <PropertyColumn Title="Full Name" Property="@(e => e.FullName)" Width="160px" Pin="DataGridColumnPin.Start" Sortable="true" /> | ||
| <PropertyColumn Title="Department" Property="@(e => e.Department)" Sortable="true" /> | ||
| <PropertyColumn Title="Location" Property="@(e => e.Location)" Sortable="true" /> | ||
| <PropertyColumn Title="Start Date" Property="@(e => e.StartDate)" Sortable="true" /> | ||
| <PropertyColumn Title="Salary" Property="@(e => e.Salary)" Width="120px" Sortable="true" Align="DataGridCellAlignment.End" /> | ||
| <TemplateColumn Title="Actions" Width="120px" Pin="DataGridColumnPin.End"> | ||
| <FluentButton IconStart="@(new Icons.Regular.Size16.Edit())" Appearance="ButtonAppearance.Subtle" Title="Edit" @onclick="@(() => selectedName = context.FullName + " (edit)")" /> | ||
| <FluentButton IconStart="@(new Icons.Regular.Size16.Delete())" Appearance="ButtonAppearance.Subtle" Title="Delete" @onclick="@(() => selectedName = context.FullName + " (delete)")" /> | ||
| </TemplateColumn> | ||
| </FluentDataGrid> | ||
| </div> | ||
|
|
||
| @if (!string.IsNullOrEmpty(selectedName)) | ||
| { | ||
| <p style="margin-top: 1rem;">Last action: <strong>@selectedName</strong></p> | ||
| } | ||
|
|
||
| @code { | ||
| string selectedName = string.Empty; | ||
|
|
||
| record Employee(int Id, string FullName, string Department, string Location, string StartDate, string Salary); | ||
|
|
||
| IQueryable<Employee> employees = new[] | ||
| { | ||
| new Employee(1, "Denis Voituron", "Engineering", "Brussels", "2019-03-01", "$120,000"), | ||
| new Employee(2, "Vincent Baaij", "Engineering", "Amsterdam", "2018-07-15", "$130,000"), | ||
| new Employee(3, "Harry Mars", "Executive", "Medina", "1975-04-04", "$1,000,000"), | ||
| new Employee(4, "Bruno Styles", "Executive", "Bellevue", "1992-02-17", "$950,000"), | ||
| new Employee(5, "Taylor Eilish", "Developer Relations", "Portland", "2007-01-22", "$200,000"), | ||
| new Employee(6, "Billie Swift", "Languages", "Seattle", "2005-08-01", "$180,000"), | ||
| new Employee(7, "Jacky Bond", "Framework", "Seattle", "2010-06-14", "$190,000"), | ||
| new Employee(8, "James Chan", "Framework", "Cambridge", "2009-03-30", "$185,000"), | ||
| new Employee(9, "John Cage", "Community", "San Diego", "2011-11-01", "$160,000"), | ||
| new Employee(10, "Nick Travolta", "Engineering", "New York", "2016-05-20", "$155,000"), | ||
| }.AsQueryable(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
...emo.Client/Documentation/Components/DataGrid/Pages/DataGridPinnedColumnsPage.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| --- | ||
| title: Pinned columns | ||
| route: /DataGrid/PinnedColumns | ||
| --- | ||
|
|
||
| # Pinned columns | ||
|
|
||
| Columns can be pinned (frozen) to the start or end edge of the grid so that they remain visible | ||
| while the user scrolls horizontally through wider datasets. Using `Start`/`End` instead of | ||
| `Left`/`Right` means pinned columns automatically work correctly in both LTR and RTL layouts. | ||
|
|
||
| ## Parameters | ||
|
|
||
| Set the `Pin` parameter on any `PropertyColumn` or `TemplateColumn`: | ||
|
|
||
| | Value | Behavior | | ||
| |---|---| | ||
| | `DataGridColumnPin.None` | Default — column scrolls normally | | ||
| | `DataGridColumnPin.Start` | Column stays anchored to the start edge | | ||
| | `DataGridColumnPin.End` | Column stays anchored to the end edge | | ||
|
|
||
| ## Rules | ||
|
|
||
| * **Explicit width required.** Every pinned column must declare a `Width`. | ||
| Pixel and non-pixel CSS units are supported. After the grid renders, sticky offsets are | ||
| recomputed from the rendered header widths so pinned columns stay aligned. | ||
| * **Start-pinned columns must be contiguous at the start.** Each start-pinned column must | ||
| immediately follow another start-pinned column, or be the very first column. | ||
| * **End-pinned columns must be contiguous at the end.** Each end-pinned column must | ||
| immediately precede another end-pinned column, or be the very last column. | ||
| * Violating the missing-width or ordering rules throws an `ArgumentException` with a descriptive message. | ||
|
|
||
| ## Scrollable container | ||
|
|
||
| Sticky positioning only activates inside a scrollable ancestor. Wrap the grid in a container with | ||
| `overflow-x: auto` and give the grid `Style="min-width: max-content;"` so that a horizontal scroll | ||
| bar appears when columns overflow the container: | ||
|
|
||
| ```razor | ||
| <div style="overflow-x: auto;"> | ||
| <FluentDataGrid Items="@employees" Style="min-width: max-content;"> | ||
| <PropertyColumn Title="ID" Property="@(e => e.Id)" Width="60px" Pin="DataGridColumnPin.Start" /> | ||
| <PropertyColumn Title="Name" Property="@(e => e.Name)" Width="160px" Pin="DataGridColumnPin.Start" /> | ||
| <PropertyColumn Title="City" Property="@(e => e.City)" /> | ||
| <TemplateColumn Title="Actions" Width="120px" Pin="DataGridColumnPin.End"> | ||
| ... | ||
| </TemplateColumn> | ||
| </FluentDataGrid> | ||
| </div> | ||
| ``` | ||
|
|
||
| ## Theming the pinned background | ||
|
|
||
| Pinned cells receive a solid background to prevent scrolling content from showing through. The | ||
| color defaults to `--colorNeutralBackground2` and can be overridden per-grid with the CSS custom | ||
| property `--fluent-data-grid-pinned-background`: | ||
|
|
||
| ```css | ||
| .my-grid { | ||
| --fluent-data-grid-pinned-background: var(--colorNeutralBackground2); | ||
| } | ||
| ``` | ||
|
|
||
| ## Notes | ||
|
|
||
| * Column resizing keeps pinned columns aligned as widths change. | ||
| * Virtualization and paging are fully compatible because each rendered row's cells carry the | ||
| same `position: sticky` styling regardless of which page or scroll position is active. | ||
| * RTL layouts are fully supported: start and end automatically map to the correct physical | ||
| direction based on the document's writing mode. | ||
|
|
||
| ## Example | ||
|
|
||
| Demonstrates pinned (frozen) columns using `Pin="DataGridColumnPin.Start"` and `Pin="DataGridColumnPin.End"`. | ||
|
|
||
| The two leftmost columns and the Actions column remain visible while the rest scroll horizontally. The grid is | ||
| wrapped in a scrollable container to enable sticky positioning and horizontal scrolling when needed. Resize the window | ||
| or the columns in the grid to see the effect. | ||
|
|
||
| **Pinned columns require an explicit `Width`**. | ||
|
|
||
| {{ DataGridPinnedColumns }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.