Skip to content

Virtualization supports anchor modes #65742

@ilonatommy

Description

@ilonatommy

Is there an existing issue for this?

  • I have searched the existing issues

Background

The Virtualize component has no opt-in edge-pinning behavior. Developers building chat windows, log viewers (Aspire), or notification feeds cannot tell the component "stay pinned to the bottom/top when new items arrive."

The existing _pendingScrollToBottom + convergence mechanism is purely a loading convergence tool — it keeps the viewport pinned while items that are already being loaded settle into place (e.g. visible on jump to the end with slow network). It does not fire when new items are appended.

.net 10 behavior (before #65951):

Acts like Anchor = Beginning. To avoid breaking changes Beginning will be the default value.

Scenario scrollTop Visible items Behavior
At top + prepend Stays 0 New items appear Beginning-like
At bottom + append Stays at old pos 1000px from new bottom No auto-scroll

Proposed API

/// <summary>
/// Controls how the viewport behaves at the edges of the list when
/// new items arrive. Flags can be combined to pin both edges.
/// </summary>
[Flags]
public enum VirtualizeAnchorMode
{
    /// <summary>
    /// No edge pinning. The viewport stays at its current scroll position
    /// regardless of item changes.
    /// </summary>
    None = 0,

    /// <summary>
    /// Pins the viewport to the beginning of the list. When the user is
    /// at or near the top and new items arrive at the beginning, the viewport
    /// stays at the top showing the newest items — matching standard news
    /// feed / notification list UX.
    /// </summary>
    Beginning = 1,

    /// <summary>
    /// Pins the viewport to the end of the list. When the user is at or near
    /// the bottom and new items arrive at the end, the viewport auto-scrolls
    /// to show them. If the user has scrolled away, auto-scroll disengages
    /// until they return to the bottom — matching standard chat / log UX.
    /// </summary>
    End = 2
}

On Virtualize<TItem>:

[Parameter]
public VirtualizeAnchorMode AnchorMode { get; set; } = VirtualizeAnchorMode.Beginning;

UX Rationale

AnchorMode.Beginning (default - backward compatible) - news feed / notification list:

  • At the top: new items slide in, user sees newest content immediately
  • Scrolled down: no interference, user continues reading

AnchorMode.End - chat / log viewer:

  • At the bottom: new items arrive, viewport auto-scrolls to show them
  • Scrolled up: no interference, user browses history
  • Scroll back to bottom: auto-scroll re-engages

AnchorMode.None - static/reference content (documentation viewer, search results, product catalog). After #65951 virtualization works only in this mode.

  • Any position: new items arrive -> no interference - viewport stays exactly where the user is reading.

AnchorMode.Beginning | AnchorMode.End - niche scenario, I don't have real use case for it but there is no technical reason why we would not allow it. Other combinations (none + beginning/end) do not make sense at all.

Current state:

Test None Beginning End
Prepend @ top (10)
Append @ bottom (10)
Mid-list prepend (10)
Large prepend @ top (1000)
Large append @ bottom (1000)
Append @ mid-list
Disengage after leaving edge

Metadata

Metadata

Assignees

Labels

area-blazorIncludes: Blazor, Razor Componentsfeature-blazor-virtualizationThis issue is related to the Blazor Virtualize component

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions