Extras
InfiniteScrolling
BitInfiniteScrolling fetches the next page from its ItemsProvider as soon as the end of the list comes into view, so nothing is loaded before it is needed. It renders the loading, empty, end and error states (each replaceable by a template), can load on demand through a Load more button (from the start or after a few automatic pages), run reversed to prepend older items without moving the reader, scroll sideways, or render as an accessible ARIA feed. A page in flight is cancelled when no longer needed, and the loaded items can be capped, keyed, edited from code and reset from a key.
Notes
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
PageSize & states
Templates
Manual
Error handling
Reversed
Horizontal
flex: 0 0 auto so the row overflows instead of squeezing them.
Scroller
200px ahead here), LastElementHeight gives the trigger element a size, and
Threshold sets how much of it has to be visible.
Events & progress
Public members
ResetKey
Accessibility
Cascading parameters
Style & Class
:root.
RTL
CSS variables
The public custom properties this component reads off its root, for what no parameter covers.
Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property:
set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it,
or on the Style of one instance to restyle that one alone. Leave a variable unset and the component falls back to the theme token beside it.
BitInfiniteScrolling CSS variables
| Name | Default value | Description |
|---|---|---|
| --bit-InfiniteScrolling-status-color | var(--bit-clr-fg-sec) | Text color of the loading, empty and end blocks. |
| --bit-InfiniteScrolling-status-font-size | var(--bit-tpg-fs-sm) | Font size of every status block and of the button. |
| --bit-InfiniteScrolling-status-padding | spacing(1) | Padding of every status block. |
| --bit-InfiniteScrolling-status-gap | spacing(1) | Room between the loading spinner and its text. |
| --bit-InfiniteScrolling-status-text-align | center | Alignment of every status block. |
| --bit-InfiniteScrolling-error-color | var(--bit-clr-err) | Text color of the default error block. |
| --bit-InfiniteScrolling-spinner-size | var(--bit-siz-icon-md) | Diameter of the default loading spinner. |
| --bit-InfiniteScrolling-spinner-color | var(--bit-clr-pri) | The moving arc of the spinner. |
| --bit-InfiniteScrolling-spinner-track-color | var(--bit-clr-brd-pri) | The ring the arc of the spinner travels on. |
| --bit-InfiniteScrolling-button-color | var(--bit-clr-pri) | Label of the Load more / Retry button. |
| --bit-InfiniteScrolling-button-hover-color | var(--bit-clr-pri-hover) | Label of the button under the pointer. |
| --bit-InfiniteScrolling-button-background | transparent | Background of the button. |
| --bit-InfiniteScrolling-button-hover-background | var(--bit-InfiniteScrolling-button-background) | Background of the button under the pointer. |
| --bit-InfiniteScrolling-button-radius | var(--bit-shp-radius-button) | Corner radius of the button and its focus ring. |
| --bit-InfiniteScrolling-button-padding | var(--bit-siz-ctrl-pad-y-sm) var(--bit-siz-ctrl-pad-x-sm) | Padding of the button. |
| --bit-InfiniteScrolling-item-focus-color | var(--bit-clr-pri-focus) | Focus indicator of an article in the Feed mode. |
API
Every parameter, public member, sub-class and enum this component exposes.
BitInfiniteScrolling parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AutoLoadLimit | int? | null | The number of the pages the list loads on its own, as its end comes into view, before it switches to the Load more button of the manual mode. The count starts over with every refresh; null keeps the loading automatic for good. |
| ChildContent | RenderFragment<TItem>? | null | The custom template to render each item. |
| Classes | BitInfiniteScrollingClassStyles? | null | Custom CSS classes for different parts of the component. |
| EmptyMessage | string | There is no item | The message to render when there is no item available and no EmptyTemplate is provided. |
| EmptyTemplate | RenderFragment? | null | The custom template to render when there is no item available. |
| EndMessage | string? | null | The message to render after the last page, when there is no more item to fetch. Nothing is rendered while both this parameter and the EndTemplate are empty. |
| EndTemplate | RenderFragment? | null | The custom template to render after the last page, when there is no more item to fetch. |
| ErrorMessage | string | Failed to load the items. | The message to render when the items provider throws and no ErrorTemplate is provided. With an ErrorTemplate it is what screen readers are told instead. |
| ErrorTemplate | RenderFragment<Exception>? | null | The custom template to render when the items provider throws, receiving the thrown exception as its context. It replaces the default error message and its retry button. |
| Feed | bool | false | Renders the list as a WAI-ARIA feed: every item is wrapped in a focusable article carrying aria-posinset / aria-setsize, Page Down / Page Up move between the articles and Ctrl+End / Ctrl+Home leave the feed. A page loaded from the built-in button moves the focus to its first article. |
| Horizontal | bool | false | Lays the list out along the horizontal axis, so the pages are fetched while scrolling sideways and every scroll operation of the component works on the horizontal axis of its scroll container. The root element becomes a flex row in this mode and the sentinel element is given a width instead of a height. |
| ItemAriaLabel | Func<TItem, string?>? | null | The function that returns the accessible name of the article of each item in the Feed mode, which a screen reader announces as the focus lands on it. Without one an article is announced by its whole content. |
| ItemKey | Func<TItem, object>? | null | The function that returns a stable key for each item, which is rendered as the @key of that item. A keyed item is matched by its key instead of by its position, so a page prepended above the rendered items inserts new nodes rather than rewriting the content of every node below it. |
| ItemsProvider | BitInfiniteScrollingItemsProvider<TItem>? | null | The item provider function that will be called when scrolling ends. It receives a BitInfiniteScrollingItemsProviderRequest and returns the items of that page, optionally as a BitInfiniteScrollingItemsProviderResult that also states where the data ends. |
| ItemTemplate | RenderFragment<TItem>? | null | Alias for ChildContent. |
| LastElementClass | string? | null | The CSS class of the last element that triggers the loading. |
| LastElementHeight | string? | null | The height of the last element that triggers the loading. |
| LastElementStyle | string? | null | The CSS style of the last element that triggers the loading. |
| LastElementWidth | string? | null | The width of the last element that triggers the loading, which is the size along the scroll axis in the horizontal mode. |
| LoadedMessage | string? | null | The message the live region announces to screen readers after each loaded page, formatted with the number of the items of that page ({0}) and of all the loaded items ({1}). |
| LoadingMessage | string | Loading... | The message to render while loading the new items and no LoadingTemplate is provided. |
| LoadingTemplate | RenderFragment? | null | The custom template to render while loading the new items. |
| LoadMoreTemplate | RenderFragment? | null | The custom template of the button that loads the next page in the manual mode and retries a failed load. |
| LoadMoreText | string | Load more | The text of the button that loads the next page in the manual mode. The button keeps its place and the focus (aria-disabled) while the page it asked for is loading. |
| Manual | bool | false | Replaces the automatic loading with an explicit button, so each page is fetched only when the user asks for it. |
| MaxItems | int? | null | The maximum number of items to load. The component stops fetching new pages as soon as the number of the loaded items reaches this value, and the last page it requests is narrowed down to what is still missing, so the list never grows beyond the cap. |
| OnEnd | EventCallback | The callback that is invoked when the last page is loaded and there is no more item to fetch. | |
| OnError | EventCallback<Exception> | The callback that is invoked when the items provider throws, receiving the thrown exception. | |
| OnItemsLoaded | EventCallback<IReadOnlyList<TItem>> | The callback that is invoked after each successful load, receiving the newly loaded items of that page. | |
| PageSize | int | 0 | The number of the items to request in each page, which is sent to the items provider as the Count of its request. A provider returning fewer items than this value is considered the last page. |
| Preload | bool | false | Pre-loads the data at the initialization of the component. Useful in prerendering mode. |
| ResetKey | object? | null | An arbitrary value that resets the component whenever it changes: the loaded items are thrown away and the first page is fetched again from the items provider. It is what tells the component that a provider written as a lambda over a changed filter now answers differently. |
| Reversed | bool | false | Prepends each loaded page before the already rendered items and moves the sentinel element to the top of the list, so scrolling up loads the older items of a chat or a log while the scroll position stays put. The list starts out scrolled to its newest items, and its root element becomes a flex column in this mode. |
| RootMargin | string? | null | The rootMargin parameter of the IntersectionObserver, which grows (or shrinks) the area around the scroll viewport that the last element is checked against. |
| RetryText | string | Retry | The text of the button that retries the failed load. |
| ScrollerSelector | string? | null | The CSS selector of the scroll container, by default the root element of the component is selected for this purpose. The window, document, body and html values all select the viewport of the page itself. |
| Styles | BitInfiniteScrollingClassStyles? | null | Custom CSS styles for different parts of the component. |
| Threshold | decimal? | null | The threshold parameter for the IntersectionObserver that specifies a ratio of intersection area to total bounding box area of the last element. It defaults to 0, which fires as soon as a single pixel of the last element shows up. |
BitInfiniteScrolling public members
| Name | Type | Default value | Description |
|---|---|---|---|
| Error | Exception? | null | The exception of the last failed load, or null while the last load succeeded. |
| HasMore | bool | true | Determines whether another page can still be fetched from the items provider. |
| IsLoading | bool | false | Determines whether a page is currently being fetched from the items provider. |
| Items | IReadOnlyList<TItem> | The items loaded so far, in the order they are rendered. | |
| TotalCount | int? | null | The total number of the items of the data source, as it was last reported by a BitInfiniteScrollingItemsProviderResult returned from the items provider. |
| AppendItemsAsync | Func<IEnumerable<TItem>, Task> | Appends the provided items to the end of the already loaded items, without calling the items provider. | |
| LoadMoreAsync | Func<Task> | Loads the next page of the items, the same way reaching the end of the list does. It is the way to load the next page in the manual mode, and to retry a failed load. | |
| PrependItemsAsync | Func<IEnumerable<TItem>, Task> | Prepends the provided items to the beginning of the already loaded items, without calling the items provider. The scroll position is kept stable. | |
| RemoveItemAsync | Func<TItem, Task<bool>> | Removes the first occurrence of the provided item from the loaded items, and reports whether it was found. | |
| SetItemsAsync | Func<IEnumerable<TItem>, Task> | Replaces every loaded item with the provided ones, without calling the items provider. It is the way to filter, sort, deduplicate or patch the loaded items in place. | |
| GetScrollOffsetAsync | Func<Task<double>> | Returns the current offset of the scroll container, in pixels, along the scroll axis of the component. | |
| ScrollToOffsetAsync | Func<double, bool, Task> | Scrolls the scroll container to the provided offset, in pixels, along the scroll axis of the component. | |
| RefreshDataAsync | Func<Task> | Refreshes the items and re-renders them from scratch. | |
| ScrollToBottomAsync | Func<bool, Task> | Scrolls the scroll container to its bottom. Useful in the reversed (chat) mode. | |
| ScrollToTopAsync | Func<bool, Task> | Scrolls the scroll container to its top. |
BitComponentBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | string? | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | string? | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | BitDir? | null | Gets or sets the text directionality for the component's content. |
| Disabled | bool | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. |
| ForceAnimation | bool | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | Dictionary<string, object> | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. |
| Id | string? | null | Gets or sets the unique identifier for the component's root element. |
| Style | string? | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | string? | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | BitVisibility | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
BitComponentBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| UniqueId | Guid | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | ElementReference | Gets the reference to the root HTML element associated with this component. |
BitInfiniteScrollingClassStyles properties
Custom CSS classes/styles for different parts of the BitInfiniteScrolling.
| Name | Type | Default value | Description |
|---|---|---|---|
| Root | string? | null | Custom CSS classes/styles for the root element of the BitInfiniteScrolling. |
| Item | string? | null | Custom CSS classes/styles for the element that wraps each item: the article of the Feed mode, or the (display:contents) element that carries the key of a keyed item. |
| LastElement | string? | null | Custom CSS classes/styles for the sentinel (last) element of the BitInfiniteScrolling that triggers the loading. |
| Loading | string? | null | Custom CSS classes/styles for the loading container of the BitInfiniteScrolling. |
| Spinner | string? | null | Custom CSS classes/styles for the spinner of the default loading container of the BitInfiniteScrolling. |
| Empty | string? | null | Custom CSS classes/styles for the empty container of the BitInfiniteScrolling. |
| End | string? | null | Custom CSS classes/styles for the end container of the BitInfiniteScrolling that renders after the last page. |
| Error | string? | null | Custom CSS classes/styles for the error container of the BitInfiniteScrolling. |
| Button | string? | null | Custom CSS classes/styles for the button of the BitInfiniteScrolling that loads the next page in manual mode and retries a failed load. |
BitInfiniteScrollingItemsProviderResult<T> properties
The optional result of a BitInfiniteScrollingItemsProvider, which lets a provider state explicitly whether another page still exists and how many items the data source holds in total. It is itself an IEnumerable of the items of the page, so a provider can return one wherever a plain sequence is expected.
| Name | Type | Default value | Description |
|---|---|---|---|
| Items | IEnumerable<T> | The items of the requested page. | |
| HasMore | bool? | null | Whether another page can still be fetched, or null to let the component infer it from the size of the page: a page shorter than the requested count is the last one. |
| TotalCount | int? | null | The total number of the items of the data source, when the provider knows it. The component exposes the last reported value through its TotalCount member. |
BitInfiniteScrollingItemsProviderRequest properties
A request to a BitInfiniteScrollingItemsProvider for the next page of items.
| Name | Type | Default value | Description |
|---|---|---|---|
| Skip | int | The number of items already loaded, which is the index of the first item requested. | |
| Count | int | The maximum number of items requested, which is the PageSize parameter of the component. It is 0 when no page size is configured. | |
| CancellationToken | CancellationToken | A token that is cancelled when this request is no longer needed, for example when the data gets refreshed or the component gets disposed while the request is still in flight. |
BitVisibility enum
| Name | Value | Description |
|---|---|---|
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
BitDir enum
| Name | Value | Description |
|---|---|---|
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.