Skip to content
# Panel ## Description Panel is an overlay surface that slides in from any edge of the screen to host supplementary content - a form, a filter, a set of details, a navigation menu - without taking the user away from the page behind it. It comes with an optional header, scrolling body and footer, dims or leaves the page usable, locks the page scroll, traps and restores the focus, and is dismissed by the overlay, the Escape key, a swipe or a close button - each of which can be refused. ## Parameters | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | AbsolutePosition | `bool` | false | Lays the panel and its overlay out against the nearest positioned ancestor instead of the screen. The page scroll is then left alone; a named scroller is still locked. | | AutoToggleScroll | `bool` | false | Toggles the overflow of the scroller while the panel is open, instead of taking the scroll lock. An AbsolutePosition panel is pushed down by the room the scrollbar gave back. | | Blocking | `bool` | false | Keeps a click on the overlay from dismissing the panel. Escape and the swipe are controlled by NoDismissOnEscape and NoSwipe. | | Body | `RenderFragment?` | null | Alias of ChildContent, named for the scrolling body between the header and the footer. | | ChildContent | `RenderFragment?` | null | The content of the panel. | | Classes | `BitPanelClassStyles?` | null | Custom CSS classes for different parts of the panel. | | CloseButtonTitle | `string?` | null | The accessible name and tooltip of the close button. Defaults to "Close". | | CloseIcon | `BitIconInfo?` | null | The icon of the close button from an external icon library, given as its CSS classes. Takes precedence over CloseIconName. | | CloseIconName | `string?` | null | The name of the built-in Fluent UI icon of the close button. Defaults to Cancel. | | Footer | `RenderFragment?` | null | The footer of the panel, fixed at its far edge while the body scrolls. | | FooterText | `string?` | null | A plain-text footer. Footer takes precedence over it. | | FullSize | `bool` | false | Stretches the panel over the whole screen, overriding Size and the size cap. | | Header | `RenderFragment?` | null | The header of the panel, fixed at the edge it slides in from while the body scrolls. It names the panel for screen readers unless TitleAriaId or AriaLabel is set. | | HeaderText | `string?` | null | A plain-text header, rendered as a level-2 heading. Header takes precedence over it. | | IsAlert | `bool` | false | Reports the panel as an alertdialog instead of a dialog, for urgent content the user has to deal with. | | IsOpen | `bool` | false | Whether the panel is open. Two-way bindable: the panel writes it back when it dismisses itself. | | KeepMounted | `bool` | false | Keeps the content in the page after the first opening, hidden while closed, so its state survives a close. Nothing is rendered before the first opening either way. | | ModeFull | `bool` | false | Gives the overlay a background that dims the page. | | Modeless | `bool` | false | Renders no overlay, so the page stays usable. A modeless panel is not reported as modal, does not trap the focus and does not lock the scroll. | | NoAutoFocus | `bool` | false | Leaves the focus where it is when the panel opens. Otherwise the element marked data-autofocus, or the first focusable one, takes it. | | NoDismissOnEscape | `bool` | false | Keeps the Escape key from dismissing the panel. OnEscapeKeyDown still fires. An Escape that closes a popup inside the panel (an open dropdown list) never reaches the panel either way. | | NoFocusTrap | `bool` | false | Lets Tab leave the open panel. A Modeless panel never traps the focus. | | NoRestoreFocus | `bool` | false | Leaves the focus where it is when the panel closes, instead of returning it to the element that had it before the panel opened. | | NoScrollLock | `bool` | false | Leaves the page scrolling while the panel is open. Wheel and touch gestures on the overlay are forwarded to the named or app-shell scroller. | | NoSwipe | `bool` | false | Turns off the swipe gesture that dismisses the panel. To keep it but exempt one region (a canvas, a sideways-scrolling table), mark that region data-no-swipe instead; fields and mouse text selection are always exempt. | | OnDismiss | `EventCallback<MouseEventArgs>` | | Fires whenever the panel closes: close button, overlay, Escape, swipe, Close/Toggle, or IsOpen set to false from outside. Carries the click where there was one. | | OnDismissing | `EventCallback<BitPanelDismissArgs>` | | Fires before the panel closes itself; set Cancel to keep it open, and read Reason to tell the closings apart. Not raised when IsOpen is set to false from outside. | | OnEscapeKeyDown | `EventCallback<KeyboardEventArgs>` | | Fires for every Escape pressed inside the open panel, including the ones NoDismissOnEscape refuses - but not for one that closes a popup inside it. | | OnOpen | `EventCallback` | | Fires when the panel opens. | | OnOverlayClick | `EventCallback<MouseEventArgs>` | | Fires for a click on the overlay, before the panel is dismissed - and for a Blocking panel too. | | OnSwipeStart | `EventCallback<decimal>` | | Fires when a swipe starts on the panel, with the start coordinate along its axis. | | OnSwipeMove | `EventCallback<decimal>` | | Fires while a swipe moves, with the distance along the panel's axis. | | OnSwipeEnd | `EventCallback<decimal>` | | Fires when a swipe ends, with the distance along the panel's axis. | | OnToggle | `EventCallback<bool>` | | Fires when the panel opens or closes, with the new state. | | OnTransitionEnd | `EventCallback<bool>` | | Fires once the panel has finished sliding in or out, with the state it settled in. The other callbacks fire at the start of the movement. | | Placement | `BitPlacement?` | null | The edge the panel slides in from; Start and End follow the text direction, Left and Right stay where they are named in both. Center and the two combined values fall back to End. Defaults to End. | | Role | `string?` | null | Replaces the dialog (or alertdialog) role, e.g. complementary or region for a Modeless panel beside the page. | | ScrollerElement | `ElementReference?` | null | The scroller to lock while the panel is open, when no selector can reach it. Takes precedence over ScrollerSelector and the BitAppShell scroller. | | ScrollerSelector | `string?` | null | The CSS selector of the scroller to lock while the panel is open. Defaults to the BitAppShell scroller, or the page. | | ShowCloseButton | `bool` | false | Shows a close button at the end of the header row. | | Size | `double?` | null | The size in pixels along the axis the panel slides on (the width at Start/End/Left/Right, the height at Top/Bottom). Unset, the panel fits its content; other units go through --bit-Panel-size or Styles.Container. | | Styles | `BitPanelClassStyles?` | null | Custom CSS styles for different parts of the panel. | | SubtitleAriaId | `string?` | null | The id of the element that describes the panel (aria-describedby). | | SwipeTrigger | `decimal?` | null | How far the panel has to be dragged to be dismissed, as a fraction of its size (0 to 1, default 0.25). | | TitleAriaId | `string?` | null | The id of the element that names the panel (aria-labelledby). Defaults to the header; AriaLabel takes precedence. | | ZIndex | `int?` | null | The layer of the overlay; the panel sits one above it. A panel declared inside another needs none; this lifts one over a sibling panel or page chrome. | | 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. An attribute written on the component wins over an entry of the same name. | | 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. | ## Public Members | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Open | `Task` | | Opens the panel, unless it is disabled. | | Close | `Task` | | Closes the panel, unless OnDismissing refuses it. | | Toggle | `Task` | | Opens the panel when it is closed, and closes it when it is open. | | 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. | ## Enums ### BitPlacement Enum | Name | Value | Description | | :--- | :--- | :---------- | | Top | 0 | The top edge. | | Bottom | 1 | The bottom edge. | | Start | 2 | The edge the reading direction starts from - the left in LTR, the right in RTL. On the vertical axis, which does not turn around, it is the top. | | End | 3 | The edge the reading direction ends at - the right in LTR, the left in RTL. On the vertical axis, which does not turn around, it is the bottom. | | Left | 4 | The left edge, in both reading directions. | | Right | 5 | The right edge, in both reading directions. | | Center | 6 | The middle of the axis, against neither edge. | | TopAndBottom | 7 | Both edges of the block axis at once. | | StartAndEnd | 8 | Both edges of the inline axis at once, following the reading direction the way Start and End do. | ### BitPanelDismissReason Enum | Name | Value | Description | | :--- | :--- | :---------- | | Programmatic | 0 | The Close or Toggle method. | | Overlay | 1 | A click on the overlay. | | Escape | 2 | The Escape key. | | Swipe | 3 | A swipe towards the edge the panel slid in from. | | CloseButton | 4 | The close button in the header. | ### 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. | ## Sub Classes ### BitPanelClassStyles Properties | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Root | `string?` | null | Custom CSS classes/styles for the root element of the BitPanel. | | Overlay | `string?` | null | Custom CSS classes/styles for the overlay of the BitPanel. | | Container | `string?` | null | Custom CSS classes/styles for the container of the BitPanel, which is the panel surface itself. | | HeaderContainer | `string?` | null | Custom CSS classes/styles for the header row of the BitPanel, which holds the header beside the close button. | | Header | `string?` | null | Custom CSS classes/styles for the header of the BitPanel. | | CloseButton | `string?` | null | Custom CSS classes/styles for the close button of the BitPanel. | | CloseIcon | `string?` | null | Custom CSS classes/styles for the icon of the close button of the BitPanel. | | Body | `string?` | null | Custom CSS classes/styles for the body of the BitPanel, which scrolls between the header and the footer. | | Footer | `string?` | null | Custom CSS classes/styles for the footer of the BitPanel. | ### BitPanelDismissArgs Properties | Name | Type | Default Value | Description | | :--- | :--- | :------------ | :---------- | | Reason | `BitPanelDismissReason` | | What is closing the panel. | | Mouse | `MouseEventArgs?` | null | The click that is closing the panel, for a dismissal that came from a pointer. | | Cancel | `bool` | false | Set to true to refuse the dismissal and keep the panel open. | ## CSS Variables Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves. | Name | Default Value | Description | | :--- | :------------ | :---------- | | `--bit-Panel-background` | --bit-clr-bg-pri | Fill of the panel. | | `--bit-Panel-color` | --bit-clr-fg-pri | Text color of the panel and its close button. | | `--bit-Panel-shadow` | --bit-shd-sheet | Elevation of the panel. | | `--bit-Panel-radius` | --bit-shp-radius-sheet | Radius of the two corners the panel turns towards the page. FullSize panels stay square. | | `--bit-Panel-border-width` | 0 | Width of the rule along the edge the panel turns towards the page. | | `--bit-Panel-border-color` | --bit-clr-brd-sec | Color of that rule. | | `--bit-Panel-size` | fit-content | Size along the axis the panel slides on, in any CSS unit. The Size parameter wins. | | `--bit-Panel-max-size` | 85% | Cap of that size, which keeps a strip of the page visible. FullSize lifts it. | | `--bit-Panel-z-index` | --bit-zin-overlay | Layer of the overlay; the panel sits one above it. The ZIndex parameter wins. | | `--bit-Panel-overlay-background` | --bit-clr-bg-overlay | Fill of the overlay of a ModeFull panel. | | `--bit-Panel-overlay-backdrop-filter` | none | Filter applied to the page behind the overlay, e.g. blur(4px). | | `--bit-Panel-padding` | --bit-spa-dialog | Inset of the header, the body and the footer. | | `--bit-Panel-header-font-size` | --bit-tpg-fs-xl | Text size of the header. | | `--bit-Panel-header-font-weight` | --bit-tpg-fw-semibold | Weight of the header. | ## Examples \n**Basic**: ```razor Open panel Toggle panel

Basic

Once upon a time, stories wove connections between people, a symphony of voices crafting shared dreams. Each word carried meaning, each pause brought understanding.
Close
``` ```csharp private bool isBasicPanelOpen; private BitPanel basicPanelRef = default!; ``` \n**Header and footer**: ```razor HeaderText & FooterText Header, Body & Footer You have no new notifications.
Filters
@for (var i = 1; i <= 30; i++) { var index = i; }
Apply Cancel
``` ```csharp private bool isHeaderTextPanelOpen; private bool isTemplatePanelOpen; ``` \n**Placement and size**: ```razor Open panel Size: @(panelFullSize ? "FullSize" : $"{panelSize}px") ``` ```csharp private BitPlacement panelPosition = BitPlacement.End; private double panelSize = 300; private bool panelFullSize; private bool isPositionPanelOpen; ``` \n**Overlay and dismissal**: ```razor Open panel
Overlay clicks: @overlayClickCount, Escape presses: @escapeKeyCount, dismissals: @dismissCount
Click the page behind this panel or press Escape.
``` ```csharp private bool overlayModeFull; private bool overlayBlocking; private bool overlayNoEscape; private bool overlayModeless; private int overlayClickCount; private int escapeKeyCount; private int dismissCount; private bool isOverlayPanelOpen; private readonly List> dismissalItems = [ new() { Text = "A", Value = "A" }, new() { Text = "B", Value = "B" }, new() { Text = "C", Value = "C" }, ]; ``` \n**Refusing a dismissal**: ```razor Open panel
Last attempt: @(guardedReason?.ToString() ?? "-"), refused: @guardedRefused
Save
``` ```csharp private bool guardPanel = true; private bool guardedRefused; private BitPanelDismissReason? guardedReason; private bool isGuardedPanelOpen; private BitPanel guardedPanelRef = default!; // The gestures that could be a slip are refused; the close button and the panel's own Save go through. private void HandleOnDismissing(BitPanelDismissArgs args) { guardedReason = args.Reason; args.Cancel = guardPanel && args.Reason is BitPanelDismissReason.Overlay or BitPanelDismissReason.Escape or BitPanelDismissReason.Swipe; guardedRefused = args.Cancel; } ``` \n**Accessibility**: ```razor Open panel

Edit profile

The second field takes the focus, since it is marked data-autofocus.
Close
``` ```csharp private bool a11yNoAutoFocus; private bool a11yNoFocusTrap; private bool a11yNoRestoreFocus; private bool a11yIsAlert; private bool isA11yPanelOpen; ``` \n**Page scrolling**: ```razor Open panel Try scrolling the page behind this panel. ``` ```csharp private string scrollMode = "Lock"; private bool isScrollPanelOpen; ``` \n**Swipe to dismiss**: ```razor Open panel
Start: @swipeStart
Diff: @swipeDiff

Dragging here does not move the panel (data-no-swipe).
``` ```csharp private double swipeTrigger = 0.25; private bool noSwipe; private decimal swipeStart; private decimal swipeDiff; private bool isSwipePanelOpen; ``` \n**Nested panels**: ```razor Open outer panel Open nested panel Open sibling panel Declared inside the outer panel, so it covers it without a ZIndex. Declared beside the outer panel and lifted over it by ZIndex. ``` ```csharp private bool isOuterPanelOpen; private bool isInnerPanelOpen; private bool isSiblingPanelOpen; ``` \n**Inside a container**: ```razor
The panel opens inside this box.
Open panel Contained by its box.
``` ```csharp private bool isAbsolutePanelOpen; ``` \n**Rendering and events**: ```razor Open panel
Opened @openCount times, last toggled to @lastToggleState, settled at @lastSettledState
``` ```csharp private bool keepMounted; private int openCount; private bool lastToggleState; private bool lastSettledState; private bool isRenderPanelOpen; ``` \n**Cascading parameters**: ```razor Cascaded values Own Placement Start edge, 320px, dimmed page and a close button - none of it set on this panel. Slides in from the end, everything else from the cascade. ``` ```csharp private readonly BitPanelParams[] panelParams = [ new() { Placement = BitPlacement.Start, Size = 320, ModeFull = true, ShowCloseButton = true, } ]; private bool isCascadedPanelOpen; private bool isOverridingPanelOpen; ``` \n**External Icons**: ```razor CloseIcon CloseIconName The close button is drawn by FontAwesome. The close button uses another built-in icon. ``` ```csharp private bool isExternalIconPanelOpen; private bool isIconNamePanelOpen; ``` \n**Style & Class**: ```razor Styles Classes CSS variables A 30vw panel, set through the Container. Every part carries a class of its own. Rounded inner corners, a primary edge, roomier padding and a darker, blurring overlay. ``` ```csharp private bool isStylesPanelOpen; private bool isClassesPanelOpen; private bool isCssVarsPanelOpen; ``` \n**RTL**: ```razor
آغاز پایان
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. ``` ```csharp private bool isRtlPanelOpenStart; private bool isRtlPanelOpenEnd; ```