Skip to content

Surfaces

Modal

Bit.BlazorUIDialogPopup

Modal is a temporary surface that covers the page until it is dealt with. It behaves like a dialog out of the box - the focus moves in and stays, the page stops scrolling, Escape and the overlay dismiss it, the focus returns to the opener - and each behavior can be turned off. It hosts any content, optionally in a header, body and footer chrome, and can be sized, positioned, dragged, made modeless or kept mounted.

Notes

BitProModal of the Extras package has been merged into BitModal: replace BitProModal, BitProModalService and their Container, Reference, Parameters and ClassStyles types with the BitModal ones. ShowOverlay is now Modeless; the content is no longer padded unless the chrome (a header, a footer or a close button) is used; service Modals close on navigation unless CloseOnNavigation is false; and Blocking blocks the pointer only - add NoDismissOnEscape to block Escape too.

To show a Modal from code anywhere in the app, use the BitModalService.

Usage

Every example is live. Open its code to see exactly what produced the component running underneath.

Basic

IsOpen shows the Modal and is two-way bound, so Escape and a click on the overlay close it. The focus moves in when it opens, Tab stays inside it, and the focus returns to the opener when it closes. It animates in and out (instantly under reduced motion). NoBorder removes the accent along the top edge.

Sizing

A Modal is as big as its content, capped to the screen and scrolling inside itself beyond that. Width, Height, MaxWidth and MaxHeight take any CSS length and win over the stylesheet; MaxWidth gives text a readable measure. FullWidth, FullHeight and FullSize stretch the Modal to the area it covers.

Header & Footer

Given only content, the Modal is a bare surface for your own markup. HeaderText or a Header template, FooterText or a Footer template, and ShowCloseButton turn on a chrome: a padded column whose header and footer stay put while the body (ChildContent or Body) scrolls between them.

Dismissal

Blocking ignores clicks on the overlay; Escape still closes the Modal unless NoDismissOnEscape is set too, so always leave a visible way out. CanClose is asked before the user closes the Modal (close button, overlay, Escape) and keeps it open by answering false - closing it from code is not asked. A refused dismissal is answered with a short pulse (a ring under reduced motion).

Focus management

The focus lands on the first focusable element, or on the one marked data-autofocus (or autofocus). NoAutoFocus leaves it where it was, NoFocusTrap lets Tab leave the Modal, and NoRestoreFocus leaves it where it ended up when the Modal closes.

Scroll lock

An open Modal holds the page still, without a layout shift where the scrollbar was; the holds are counted across open Modals. NoScrollLock leaves the page scrolling. Inside a BitAppShell the shell's scroller is held; any other scrolling region is named with ScrollerSelector or ScrollerElement. AutoToggleScroll instead takes the overflow off that scroller while the Modal is open.

Overlay

The overlay is see-through by default; ModeFull dims the page behind it. Modeless removes the overlay and leaves the page usable: no focus trap, no scroll lock, and not announced as modal. AriaModal="false" alone reports a Modal as non-modal while keeping its overlay.

Position

Position places the Modal at any of nine spots; Start/End follow the text direction while Left/Right stay put. AbsolutePosition covers the element the Modal is declared in (which needs position: relative) instead of the screen.




Draggable

Draggable lets the user move the Modal. The whole Modal is the handle by default; DragElementSelector names a part of it instead, leaving the rest selectable and scrollable.

Accessibility

The Modal is a dialog with aria-modal. A HeaderText names it automatically and is announced as a heading. A Header template holds more than a title, so it names nothing by itself: point TitleAriaId (and SubtitleAriaId) at your own title and description, inside a template or anywhere in the content, or give it an AriaLabel. IsAlert makes it an alertdialog - the default for a Blocking Modal - for the interruptions that must be acknowledged. CloseButtonTitle names the close button (default "Close") for localization.

Keep mounted

A closed Modal is removed from the page, so its content starts over each time it opens. KeepMounted hides it instead (inert and hidden from assistive technologies), keeping its state. Nothing renders before the first open. Type in both, close and reopen: only the kept one remembers.

Events

OnOpen fires once the Modal is rendered and focused; OnDismiss whenever it closes. OnOverlayClick and OnEscapeKeyDown fire for every attempt, including the ones a Blocking or NoDismissOnEscape Modal refuses.



Opened? [False]
Dismissed? [False]
Overlay clicked? [False]
Escape pressed? [False]

Programmatic control

A Modal captured with @ref is driven by Open, Close and Toggle, which share their state with the binding. DefaultIsOpen is the starting state of a Modal whose IsOpen is not set.

Nested modals

A Modal declared inside another opens on top of it. One Escape closes one layer - the inner Modal, or an open dropdown inside a Modal - overlays stack, the scroll holds are counted, and the focus returns to the button inside the first Modal.

Cascading parameters

BitParams hands a BitModalParams to every Modal under it. The values are defaults, not overrides: a parameter a Modal sets itself wins, and so does one a BitModalService showing is given. Content, templates, callbacks and the open state stay on the Modal.

External Icons

CloseIcon takes an icon from an external library (FontAwesome, Bootstrap Icons, ...) and wins over CloseIconName, which names a built-in Fluent UI icon.

Style & Class

Style and Class reach the root (the layer over the page); Styles and Classes reach each part: Root, Overlay, Content, HeaderContainer, Header, CloseButton, CloseIcon, Body and Footer.



The public --bit-Modal-* variables (listed under CSS variables below) inherit, so one set on :root restyles every Modal and one set on a Modal's Style restyles that Modal. --bit-Modal-offset keeps a Modal off the screen edges, and --bit-Modal-max-width caps it without ever pushing it off a small screen.

RTL

Dir="BitDir.Rtl" lays the Modal out right-to-left, including its chrome; Start/End positions follow along.

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.

BitModal CSS variables

Name Default value Description
--bit-Modal-z-index --bit-zin-modal Stacking order of a Modal fixed to the screen, to keep it above or below the app's own layers.
--bit-Modal-offset 0px Room kept between the Modal and the edges of the area it covers, including in FullWidth / FullHeight.
--bit-Modal-max-width 100% Widest the Modal grows; never wider than the area less the offset. The MaxWidth parameter wins over it.
--bit-Modal-max-height 100% Tallest the Modal grows before it scrolls; never taller than the area less the offset. The MaxHeight parameter wins over it.
--bit-Modal-background --bit-clr-bg-pri Fill of the surface, including the sticky header and footer.
--bit-Modal-color --bit-clr-fg-pri Text color of the surface, which the close button follows.
--bit-Modal-radius --bit-shp-radius-dialog Corner radius of the surface.
--bit-Modal-shadow --bit-shd-dialog Elevation of the surface.
--bit-Modal-border-color --bit-clr-pri Color of the accent along the top edge (removed by NoBorder).
--bit-Modal-border-width 4px Thickness of the accent along the top edge.
--bit-Modal-overlay-background --bit-clr-bg-overlay Fill of the overlay in ModeFull.
--bit-Modal-overlay-backdrop-filter none Filter applied to the page behind the overlay, e.g. blur(4px).
--bit-Modal-padding --bit-spa-dialog Inner padding of the header, body and footer of the chrome.
--bit-Modal-header-font-size --bit-tpg-fs-xl Text size of the header.
--bit-Modal-header-font-weight --bit-tpg-fw-semibold Weight of the header.

API

Every parameter, public member, sub-class and enum this component exposes.

BitModal parameters

Name Type Default value Description
AbsolutePosition bool false Positions the Modal absolute instead of fixed, so it covers the element it is declared in (which needs position: relative) rather than the screen.
AriaModal bool true Announces the Modal as modal to assistive technologies. A Modal that is not modal leaves the page behind it reachable with the keyboard (no focus trap, no scroll lock).
AutoToggleScroll bool false Takes the overflow off the scroller (ScrollerElement, ScrollerSelector, the BitAppShell's, or the page) while the Modal is open, instead of the default scroll lock.
Blocking bool false Prevents a click on the overlay from dismissing the Modal. Escape still dismisses it unless NoDismissOnEscape is set too.
Body RenderFragment? null The content of the body section, an alias of ChildContent that takes precedence over it.
CanClose Func<Task<bool>>? null Asked before the user dismisses the Modal (close button, overlay, Escape); answering false keeps it open. Not asked when the app closes it (Close, IsOpen).
ChildContent RenderFragment? null The content of the Modal, it can be any custom tag or text.
Classes BitModalClassStyles? null Custom CSS classes for different parts of the BitModal component.
CloseButtonTitle string? null The title and aria-label of the close button, for accessibility and localization. Defaults to "Close".
CloseIcon BitIconInfo? null The icon of the close button from an external icon library. Takes precedence over CloseIconName.
CloseIconName string? null The name of the close button icon from the built-in Fluent UI icons. Defaults to Cancel.
DefaultIsOpen bool? null The initial open state when IsOpen is not set (uncontrolled mode).
DragElementSelector string? null The CSS selector of the drag handle of a Draggable Modal. The whole content by default.
Draggable bool false Lets the user drag the Modal around.
Footer RenderFragment? null The template of the footer section. Takes precedence over FooterText.
FooterText string? null The text of the footer section.
FullHeight bool false Makes the Modal as tall as the area it covers.
FullSize bool false Makes the Modal as wide and as tall as the area it covers (FullWidth + FullHeight).
FullWidth bool false Makes the Modal as wide as the area it covers.
Header RenderFragment? null The template of the header section. Takes precedence over HeaderText. It does not name the dialog by itself: point TitleAriaId at the title inside it.
HeaderText string? null The text of the header section, announced as a level-2 heading. Names the dialog unless TitleAriaId or AriaLabel is set.
Height string? null The CSS height of the Modal (any CSS length). Wins over FullHeight; capped by MaxHeight or the screen.
IsAlert bool? null Renders the Modal as an alertdialog instead of a dialog. When not set, a Blocking Modal that is not Modeless is an alertdialog.
IsOpen bool false Whether the Modal is displayed.
KeepMounted bool false Hides the Modal when closed instead of removing it, so its content keeps its state. Nothing renders before the first open; a closed kept Modal is inert.
MaxHeight string? null The CSS height the Modal does not grow past (any CSS length); it scrolls inside itself beyond it. The screen height when not set.
MaxWidth string? null The CSS width the Modal does not grow past (any CSS length). The screen width when not set.
ModeFull bool false Gives the overlay an opaque background that dims the page behind the Modal.
Modeless bool false Leaves the page usable: no overlay, no focus trap, no scroll lock, and not announced as modal. Blocking is ignored.
NoAutoFocus bool false Keeps the focus where it was when the Modal opens. By default it moves to the element marked data-autofocus (or autofocus), the first focusable element, or the content itself.
NoBorder bool false Removes the accent border along the top edge of the Modal.
NoDismissOnEscape bool false Prevents the Escape key from dismissing the Modal.
NoFocusTrap bool false Lets Tab move the focus out of the Modal while it is open.
NoRestoreFocus bool false Keeps the focus where it ends up when the Modal closes instead of returning it to the element that opened it.
NoScrollLock bool false Leaves the page scrolling while the Modal is open. By default it is held still without a layout shift, and the holds of several open Modals are counted.
OnDismiss EventCallback<MouseEventArgs> Invoked whenever the Modal closes, whether the user dismissed it or the app closed it. Not invoked for a dismissal CanClose turns down.
OnEscapeKeyDown EventCallback<KeyboardEventArgs> Invoked for every Escape pressed inside the Modal, including the ones it refuses to be dismissed by.
OnOpen EventCallback Invoked once the Modal has opened, rendered and placed the focus.
OnOverlayClick EventCallback<MouseEventArgs> Invoked for every click on the overlay, including the ones a Blocking Modal refuses to be dismissed by.
Position BitPosition? null Where the Modal sits in the area it covers. The center when not set.
ScrollerElement ElementReference? null The scroller the Modal holds while it is open. Takes precedence over ScrollerSelector and the BitAppShell's scroller.
ScrollerSelector string? null The CSS selector of the scroller the Modal holds while it is open, for layouts that scroll a region of their own. The BitAppShell's scroller, or the page, when not set.
ShowCloseButton bool false Shows a close button in the header that dismisses the Modal.
Styles BitModalClassStyles? null Custom CSS styles for different parts of the BitModal component.
SubtitleAriaId string? null The id of the element that describes the Modal (aria-describedby).
TitleAriaId string? null The id of the element that names the Modal (aria-labelledby). Wins over the header.
Width string? null The CSS width of the Modal (any CSS length). Wins over FullWidth; capped by MaxWidth or the screen.

BitModal public members

Name Type Default value Description
Open Task Opens the Modal.
Close Task Closes the Modal. CanClose is not asked.
Toggle Task Toggles the Modal between its open and closed states.

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.

BitIconInfo properties

Name Type Default value Description
Name string? null Gets or sets the name of the icon.
BaseClass string? null Gets or sets the base CSS class for the icon. For built-in Fluent UI icons, this defaults to "bit-icon". For external icon libraries like FontAwesome, you might set this to "fa" or leave empty.
Prefix string? null Gets or sets the CSS class prefix used before the icon name. For built-in Fluent UI icons, this defaults to "bit-icon--". For external icon libraries, you might set this to "fa-" or leave empty.

BitPosition enum

Name Value Description
TopLeft 0 The top left corner, in both reading directions.
TopCenter 1 The top edge, centered horizontally.
TopRight 2 The top right corner, in both reading directions.
TopStart 3 The top edge, on the side the reading direction starts from.
TopEnd 4 The top edge, on the side the reading direction ends at.
CenterLeft 5 The left edge, centered vertically, in both reading directions.
Center 6 Centered both ways.
CenterRight 7 The right edge, centered vertically, in both reading directions.
CenterStart 8 Centered vertically, on the side the reading direction starts from.
CenterEnd 9 Centered vertically, on the side the reading direction ends at.
BottomLeft 10 The bottom left corner, in both reading directions.
BottomCenter 11 The bottom edge, centered horizontally.
BottomRight 12 The bottom right corner, in both reading directions.
BottomStart 13 The bottom edge, on the side the reading direction starts from.
BottomEnd 14 The bottom edge, on the side the reading direction ends at.

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.