Extras
AppShell
BitAppShell is the outermost element of an application. It insets the four edges of the screen by the safe areas the device reports - the notch, the rounded corners, the home indicator - so the content never lands underneath any of them, paints those four bars in the background color of the theme, and gives any one of those edges back to a layout that insets it itself. Inside them it owns the one region the application scrolls in, which is what makes a Blazor app scroll like an app rather than like a page: the header and the footer stay put, only the middle moves, and the scroller is cascaded to every surface declared inside the shell, so a Modal, a Panel, a Dialog or an Overlay holds the right region without being told which one it is. That scroller is a full one - overflow per axis, a reserved scrollbar gutter, scroll padding for a sticky header, pinning to the end as content arrives and keeping the reader's place as content lands above them - and it takes the height of the on-screen keyboard off itself while one is open. On top of that the shell can send the reader to the top of each page they navigate to, or put them back exactly where they left each page off; report where it stands as it is scrolled and call back as it reaches an edge; be scrolled from code with GoToTop, GoToBottom, ScrollTo, ScrollBy and ScrollToElement; and hand a list of cascading values down to everything it contains.
Notes
To use this component, you need to install the Bit.BlazorUI.Extras(opens in a new tab) nuget package, as described in the Optional steps of the Getting started page.
The app shell belongs in MainLayout, wrapped around everything the application renders, and it fills whatever room it is given - so the html and body of the host page need a height of their own for it to have any, unless FullScreen is set, which pins the shell to the four edges of the window instead and takes the host page out of the question. The examples below can do neither: they put a shell inside a box of a fixed height, which is the only way to show a full-screen container on a page that is already inside one. Each also carries an Id, since the id of the shell's scrolling container is derived from it and only one element of a page can carry a given id.
A component that has to work on the region the application scrolls in, rather than on one of its own, is pointed at the shell's container: BitPullToRefresh and BitInfiniteScrolling take a ScrollerSelector of #BitAppShell-container - or, for a shell with an Id, the MainContainerId of that shell. A BitModal, BitPanel, BitDialog or BitOverlay needs none of that: the shell cascades its container and they read it.
The scrolling middle of the shell is a flex row, so a page put inside it is laid out as one flex item: give the element that holds the page a width of 100% - or make it the flex column the page is - and it fills the shell rather than shrinking to fit its own content.
The four insets come from the CSS env(safe-area-inset-*) variables, which a browser only reports as anything other than zero on a page whose viewport meta tag carries viewport-fit=cover. Without it - and on every desktop browser - all four are 0 and the bars take up no room at all, which is why the example below sizes them by hand to show them.
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
Safe area insets
Keyboard inset
Scrolling from code
Scroll events
Scroll behavior
Overscroll & NoScroll
Navigation
Cascading values
Overflow & gutter
Scroll padding
Endless content
Style & Class
RTL
API
Every parameter, public member, sub-class and enum this component exposes.
BitAppShell parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AutoGoToTop | bool | false | Enables auto-scroll to the top of the main container on navigation. A navigation that only changes the fragment of the url (an in-page anchor) is left alone. PersistScroll takes precedence over it. |
| AutoScroll | bool | false | Keeps the main container pinned to the end of its content as the content grows, for as long as the reader left it standing at the end. |
| AutoScrollThreshold | int | 0 | How near the end of the content (in pixels) the main container has to have been left for AutoScroll to keep pinning it there. |
| AvoidKeyboard | bool | false | Takes the height of the on-screen keyboard off the scrolling area while it is open, publishes it on the root as the --bit-ash-keyboard-inset CSS variable and marks the root with the data-bit-ash-keyboard attribute. It measures 0 wherever the browser shrinks the layout viewport itself. |
| ChildContent | RenderFragment? | null | The content of the app shell. It is rendered inside the main (scrolling) container. |
| Classes | BitAppShellClassStyles? | null | Custom CSS classes for different parts of the app shell. |
| FullScreen | bool | false | Pins the app shell to the four edges of the screen, so it fills the window whatever height the page around it has - which is what saves the host page from carrying a height of its own down through html and body. |
| Gutter | BitScrollbarGutter? | null | Reserves the room the scrollbar of the main container takes, whether or not there is anything left to scroll, so the layout does not shift between a page that scrolls and a page that does not. |
| NoBottomInset | bool | false | Removes the bottom safe area inset of the app shell, leaving the other three where they are. |
| NoEndInset | bool | false | Removes the trailing side safe area inset of the app shell - the right of a left-to-right shell - leaving the other three where they are. |
| NoInsets | bool | false | Removes the safe area insets, so the four edges of the app shell are not inset at all and the content fills the whole screen. |
| NoScroll | bool | false | Prevents the reader from scrolling the main container at all; the content that overflows is clipped. The scrolling methods of the component still move it. |
| NoStartInset | bool | false | Removes the leading side safe area inset of the app shell - the left of a left-to-right shell - leaving the other three where they are. |
| NoTopInset | bool | false | Removes the top safe area inset of the app shell, leaving the other three where they are. |
| OnKeyboardInsetChanged | EventCallback<double> | Callback for how much of the app shell the on-screen keyboard covers, in pixels, raised as that changes and with 0 as it closes. Only a shell with AvoidKeyboard set measures it at all. | |
| OnReachedBottom | EventCallback | Callback for when the main container reaches the bottom of its content, raised once per arrival rather than on every frame that stays there. | |
| OnReachedLeft | EventCallback | Callback for when the main container reaches the visual left edge of its content, which is the same edge whichever way the shell reads. | |
| OnReachedRight | EventCallback | Callback for when the main container reaches the visual right edge of its content. | |
| OnReachedTop | EventCallback | Callback for when the main container reaches the top of its content. | |
| OnScroll | EventCallback<BitScrollOffset> | Callback for the scroll position of the main container, raised as it is scrolled. Nothing is measured or reported until one of the scroll callbacks is handled. | |
| OnScrollEnd | EventCallback<BitScrollOffset> | Callback for when a scroll of the main container comes to a stop. | |
| OnScrollStart | EventCallback<BitScrollOffset> | Callback for when a scroll of the main container begins. | |
| OverflowX | BitOverflow? | null | What the main container does with content that overflows it sideways. Hidden clips it instead of offering it, and NoScroll wins over both axes. |
| OverflowY | BitOverflow? | null | What the main container does with content that overflows it downwards. See OverflowX. |
| Overscroll | BitOverscroll? | null | Determines what happens when the main container is scrolled past its edge. It defaults to None: no scroll chaining out of the shell and no pull-to-refresh or rubber-banding. |
| PersistScroll | bool | false | Persists scroll position of the main container per url in session storage and restores it on navigation. A fragment-only navigation is left alone. |
| PreserveScroll | bool | false | Keeps the place of the reader when content is added above what they are looking at, which is what an endless list growing upwards needs. |
| ReachOffset | int | 0 | How near an edge (in pixels) counts as having reached it, for OnReachedTop and OnReachedBottom. |
| ScrollBehavior | BitScrollBehavior? | null | The scroll behavior of the main container, which decides how every move the reader does not make by hand is animated. It defaults to Smooth, and is taken back off under the reduced motion preference. |
| ScrollPadding | string? | null | The room the main container keeps between its edges and anything scrolled into view inside it, as any CSS length - which is what keeps a header stuck to the top of the shell from covering what was just scrolled to. |
| ScrollThrottle | int | 0 | The shortest interval (in milliseconds) between two OnScroll reports. The default of 0 reports once per animation frame. |
| StableInsets | bool | false | Sizes the four inset bars from the largest safe areas the device can ask for rather than from the ones it is asking for right now, so the layout is not relaid out as the browser slides its own chrome in and out. |
| Styles | BitAppShellClassStyles? | null | Custom CSS styles for different parts of the app shell. |
| ValueList | BitCascadingValueList? | null | The cascading value list to be provided for the children of the app shell. Its values are provided before (so they can be overridden by) the ones of the Values parameter. |
| Values | IEnumerable<BitCascadingValue>? | null | The cascading values to be provided for the children of the app shell. |
BitAppShell public members
| Name | Type | Default value | Description |
|---|---|---|---|
| ClearPersistedScroll | Func<string?, Task> | Forgets every scroll position PersistScroll has kept, for the pages of this app shell and of any other - or, given a url, only the position kept for that one page. | |
| Container | const string | "BitAppShell.Container" | The name the app shell cascades the element of its main container under, which is what a Modal, a Panel, a Dialog or an Overlay inside the shell reads to hold the right scroller. |
| ContainerId | const string | "BitAppShell-container" | The id the main container carries when the app shell has no Id of its own. |
| ContainerRef | ElementReference? | null | The element reference to the main container of the app shell. |
| GetScrollOffset | Func<Task<BitScrollOffset?>> | Reads where the main container currently stands, measured in the browser. | |
| GoToBottom | Func<BitScrollBehavior?, Task> | Scrolls the main container to the bottom of its content. | |
| GoToTop | Func<BitScrollBehavior?, Task> | Scrolls the main container to top. | |
| MainContainerId | string | The id of the main container element of this app shell: ContainerId, or the Id of the shell with "-container" after it. | |
| Refresh | Func<Task> | Re-measures the main container and reports whatever has changed since it was last measured - for the changes neither its own size nor its content announce, such as a web font that has finished loading. | |
| ScrollBy | Func<double, double, BitScrollBehavior?, Task> | Scrolls the main container by an amount, from wherever it currently stands. | |
| ScrollTo | Func<double?, double?, BitScrollBehavior?, Task> | Scrolls the main container to a position. A null axis is left where it stands. | |
| ScrollToElement | Func<string, double, bool, BitScrollAlignment, BitScrollBehavior?, Task> | Brings an element inside the main container into view by scrolling the container itself rather than every scroller the page sits in. |
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. |
| 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. |
| IsEnabled | bool | true | Gets or sets a value indicating whether the component is enabled and can respond to user interaction. |
| 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. |
BitCascadingValueList properties
A helper class to ease the using of a list of the BitCascadingValue.
| Name | Type | Default value | Description |
|---|---|---|---|
| Add<T>(T value, string? name = null, bool isFixed = false) | void | Adds a typed BitCascadingValue to the list. |
BitCascadingValue properties
The cascading value to be provided using the BitCascadingValueProvider component.
| Name | Type | Default value | Description |
|---|---|---|---|
| Name | string? | null | The optional name of the cascading value. |
| Value | object? | null | The value to be provided. |
| IsFixed | bool | false | If true, indicates that Value will not change. |
BitAppShellClassStyles properties
| Name | Type | Default value | Description |
|---|---|---|---|
| Root | string? | null | Custom CSS classes/styles for the root of the BitAppShell. |
| Top | string? | null | Custom CSS classes/styles for the top inset bar of the BitAppShell. |
| Center | string? | null | Custom CSS classes/styles for the center row of the BitAppShell, which holds the two side inset bars and the main container. |
| Left | string? | null | Custom CSS classes/styles for the leading side inset bar of the BitAppShell. |
| Main | string? | null | Custom CSS classes/styles for the main (scrolling) container of the BitAppShell. |
| Right | string? | null | Custom CSS classes/styles for the trailing side inset bar of the BitAppShell. |
| Bottom | string? | null | Custom CSS classes/styles for the bottom inset bar of the BitAppShell. |
BitScrollOffset properties
Where the main container of the app shell stands, as measured in the browser. Everything is in CSS pixels; the members derived from the measured ones cost nothing to read.
| Name | Type | Default value | Description |
|---|---|---|---|
| Left | double | 0 | The raw scrollLeft of the container. |
| Top | double | 0 | How far the content has been scrolled down. |
| ScrollWidth | double | 0 | The full width of the content, including the part scrolled out of sight. |
| ScrollHeight | double | 0 | The full height of the content, including the part scrolled out of sight. |
| ClientWidth | double | 0 | The width of the visible area, without its scrollbar. |
| ClientHeight | double | 0 | The height of the visible area, without its scrollbar. |
| Rtl | bool | false | Whether the container was laid out right to left when it was measured. |
| DeltaLeft / DeltaTop | double | 0 | How far the container has moved since the position before this one was reported. Only the OnScroll reports carry them. |
| OffsetLeft | double | The distance from the visual left edge, which is Left made positive and direction independent. | |
| MaxLeft / MaxTop | double | The largest offset each axis can reach, which is how much of the content is out of sight. | |
| ScrollableX / ScrollableY | bool | Whether there is anything to scroll along each axis at all. | |
| AtLeft / AtRight / AtTop / AtBottom | bool | Whether the container is standing at each edge, within a pixel of slack. | |
| PercentX / PercentY | double | How far the container has been scrolled along each axis, from 0 to 1. | |
| ScrollingUp / ScrollingDown / ScrollingLeft / ScrollingRight | bool | Which way the move this report carries went, derived from the deltas - which is what a header that folds away on the way down reads. |
BitScrollBehavior enum
| Name | Value | Description |
|---|---|---|
| Smooth | 0 | Scrolling should animate smoothly. |
| Instant | 1 | Scrolling should happen instantly in a single jump. |
| Auto | 2 | Scroll behavior is determined by the computed value of scroll-behavior. |
BitOverflow enum
| Name | Value | Description |
|---|---|---|
| Auto | 0 | A scrollbar is offered along that axis when the content overflows, and nothing is shown when it does not. |
| Hidden | 1 | The overflow is clipped and no scrollbar is offered, though the axis can still be moved through the scrolling methods of the component. |
| Scroll | 2 | A scrollbar is always shown along that axis, whether or not there is anything to scroll. |
| Visible | 3 | The overflow is neither clipped nor scrollable, so it is painted outside the container. |
BitScrollbarGutter enum
| Name | Value | Description |
|---|---|---|
| Auto | 0 | The initial value: a classic scrollbar takes its room only while there is something to scroll, and an overlay scrollbar takes none at all. |
| Stable | 1 | The room is reserved whether or not there is anything to scroll, so the layout does not shift as pages of different lengths follow one another. |
| BothEdges | 2 | Like Stable, with the same room reserved on the opposite edge as well, so the content stays centered. |
BitOverscroll enum
| Name | Value | Description |
|---|---|---|
| Auto | 0 | The scroll carries on into the nearest scrolling ancestor, and the platform's own overscroll affordance is kept. |
| Contain | 1 | The scroll stops at the edge instead of carrying on into the page behind it, while the platform's own overscroll affordance is kept. |
| None | 2 | Like Contain, and the platform's own overscroll affordance is suppressed as well, so the container neither bounces nor triggers a pull to refresh. |
BitScrollAlignment enum
| Name | Value | Description |
|---|---|---|
| Start | 0 | The element is brought to the start of the container. |
| Center | 1 | The element is centered in the container along both axes. |
| End | 2 | The element is brought to the end of the container. |
| Nearest | 3 | The container moves as little as it can. |
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.