# Modal
## Description
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.
## 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. |
| 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 Modal. |
| Close | `Task` | | Closes the Modal. CanClose is not asked. |
| Toggle | `Task` | | Toggles the Modal between its open and closed states. |
| 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
### 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. |
## Sub Classes
### BitModalClassStyles Properties
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Root | `string?` | null | Custom CSS classes/styles for the root element of the BitModal. |
| Overlay | `string?` | null | Custom CSS classes/styles for the overlay of the BitModal. |
| Content | `string?` | null | Custom CSS classes/styles for the content of the BitModal. |
| HeaderContainer | `string?` | null | Custom CSS classes/styles for the header container of the BitModal. |
| Header | `string?` | null | Custom CSS classes/styles for the header of the BitModal. |
| CloseButton | `string?` | null | Custom CSS classes/styles for the close button of the BitModal. |
| CloseIcon | `string?` | null | Custom CSS classes/styles for the close icon of the BitModal. |
| Body | `string?` | null | Custom CSS classes/styles for the body of the BitModal. |
| Footer | `string?` | null | Custom CSS classes/styles for the footer of the BitModal. |
### 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. |
## 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-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. |
## Examples
\n**Basic**:
```razor
Open Modal
NoBorder
```
```csharp
private bool isOpenBasic;
private bool isOpenNoBorder;
```
\n**Sizing**:
```razor
MaxWidth
Width & Height
MaxHeight
FullWidth
FullHeight
FullSize
```
```csharp
private bool isOpenMaxWidth;
private bool isOpenFixedSize;
private bool isOpenMaxHeight;
private bool isOpenFullWidth;
private bool isOpenFullHeight;
private bool isOpenFullSize;
```
\n**Header & Footer**:
```razor
Own markup
HeaderText
Header template
Footer
The title, the close button and the padding all come from the Modal.
Search the docs
A Header template holds anything - here a search box under the title.
The footer stays at the bottom while the body scrolls, and lays its actions out the way the theme does.
```
```csharp
private bool isOpenCustomContent;
private bool isOpenHeaderText;
private bool isOpenHeaderTemplate;
private bool isOpenFooter;
```
\n**Dismissal**:
```razor
Blocking
Blocking + NoDismissOnEscape
CanClose
Type something, then try to close: the Modal stays open until the field is cleared or the changes are discarded.
Discard changes
```
```csharp
private bool isOpenBlocking;
private bool isOpenNoEscape;
private bool isOpenCanClose;
private string? editorName;
private void OpenCanClose()
{
editorName = null;
isOpenCanClose = true;
}
private Task CanCloseEditor() => Task.FromResult(string.IsNullOrEmpty(editorName));
private void DiscardEditor()
{
editorName = null;
isOpenCanClose = false;
}
```
\n**Focus management**:
```razor
Default focus
data-autofocus
NoAutoFocus
```
```csharp
private bool isOpenFocus;
private bool isOpenAutoFocus;
private bool isOpenNoFocus;
private readonly Dictionary autoFocusAttributes = new() { { "data-autofocus", true } };
```
\n**Scroll lock**:
```razor
Holds the page
NoScrollLock
AutoToggleScroll
The overflow of the page is taken away while this Modal is open.
```
```csharp
private bool isOpenScrollLock;
private bool isOpenNoScrollLock;
private bool isOpenAutoToggleScroll;
```
\n**Overlay**:
```razor
ModeFull
Modeless
Carry on with the page: this Modal holds neither the pointer, nor the keyboard, nor the scroll.
```
```csharp
private bool isOpenModeFull;
private bool isOpenModeless;
```
\n**Position**:
```razor
Top Left
Top Center
Top Right
Center Left
Center
Center Right
Bottom Left
Bottom Center
Bottom Right
This Modal is placed by the Position parameter.
AbsolutePosition
AbsolutePosition + AutoToggleScroll
This Modal covers the bordered box rather than the page.
The box behind this Modal, named by ScrollerSelector, is held still.
```
```csharp
private bool isOpenPosition;
private BitPosition position = BitPosition.Center;
private void OpenModalInPosition(BitPosition positionValue)
{
position = positionValue;
isOpenPosition = true;
}
private bool isOpenAbsolute;
private bool isOpenAbsoluteScroller;
```
\n**Draggable**:
```razor
Draggable
DragElementSelector
Press anywhere on this Modal and drag it around.
Only the bar drags this Modal, so this text can still be selected.
```
```csharp
private bool isOpenDraggable;
private bool isOpenDragHandle;
```
\n**Accessibility**:
```razor
Named by its header
TitleAriaId
Alert dialog
A screen reader announces this dialog as "Privacy settings".
```
```csharp
private bool isOpenAutoNamed;
private bool isOpenLabelled;
private bool isOpenAlert;
```
\n**Keep mounted**:
```razor
KeepMounted
Built again each time
```
```csharp
private bool isOpenKeptMounted;
private bool isOpenNotKeptMounted;
```
\n**Events**:
```razor
Open Modal
```
```csharp
private bool isEventsOpen;
private bool isOpened;
private int openedVersion;
private bool isDismissed;
private bool isOverlayClicked;
private bool isEscapePressed;
private async Task HandleOnOpen()
{
var version = ++openedVersion;
isOpened = true;
await Task.Delay(3000);
if (version != openedVersion) return;
isOpened = false;
StateHasChanged();
}
private async Task HandleOnDismiss()
{
isDismissed = true;
await Task.Delay(3000);
isDismissed = false;
}
private async Task HandleOnOverlayClick()
{
isOverlayClicked = true;
await Task.Delay(2000);
isOverlayClicked = false;
}
private async Task HandleOnEscapeKeyDown()
{
isEscapePressed = true;
await Task.Delay(2000);
isEscapePressed = false;
}
```
\n**Programmatic control**:
```razor
Open
Toggle
```
```csharp
private BitModal refModal = default!;
```
\n**Nested modals**:
```razor
Open Modal
```
```csharp
private bool isOpenOuter;
private bool isOpenInner;
private void HandleNestedDelete()
{
isOpenInner = false;
isOpenOuter = false;
}
```
\n**Cascading parameters**:
```razor
Takes the cascade
Its own position
Outside the cascade
Top center, dimmed page, close button and a 26rem cap - all from BitParams.
This one keeps its own Position and takes the rest from BitParams.
```
```csharp
private bool isOpenCascaded;
private bool isOpenCascadedOwn;
private bool isOpenUncascaded;
private readonly BitModalParams[] modalParams =
[
new()
{
ModeFull = true,
ShowCloseButton = true,
MaxWidth = "26rem",
Position = BitPosition.TopCenter,
}
];
```
\n**External Icons**:
```razor
Open Modal
The close button of this Modal wears a FontAwesome icon.
```
```csharp
private bool isOpenExternalIcon;
```
\n**Style & Class**:
```razor
Style
Class
Styles
Classes
The overlay, the content and the header each take a style of their own.
The overlay, the header container, the body and the footer each take a class of their own.
CSS variables
Fill, text, accent, corners, padding, header type, blurred overlay, cap and offset all come from variables.
```
```csharp
private bool isOpenStyle;
private bool isOpenClass;
private bool isOpenStyles;
private bool isOpenClasses;
private bool isOpenCssVars;
```
\n**RTL**:
```razor
باز کردن مُدال
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.
چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد.
```
```csharp
private bool isOpenRtl;
```
Story title
Everything in this Modal is its own markup: the title, the close button and the room around them.
Content taller than the screen scrolls inside the Modal rather than running off the edge of it.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lorem nulla, malesuada ut sagittis sit
amet, vulputate in leo. Maecenas vulputate congue sapien eu tincidunt. Etiam eu sem turpis. Fusce tempor
sagittis nunc, ut interdum ipsum vestibulum non. Proin dolor elit, aliquam eget tincidunt non, vestibulum ut
turpis. In hac habitasse platea dictumst. In a odio eget enim porttitor maximus. Aliquam nulla nibh,
ullamcorper aliquam placerat eu, viverra et dui. Phasellus ex lectus, maximus in mollis ac, luctus vel eros.
Vivamus ultrices, turpis sed malesuada gravida, eros ipsum venenatis elit, et volutpat eros dui et ante.
Quisque ultricies mi nec leo ultricies mollis. Vivamus egestas volutpat lacinia. Quisque pharetra eleifend
efficitur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas lorem nulla, malesuada ut sagittis sit
amet, vulputate in leo. Maecenas vulputate congue sapien eu tincidunt. Etiam eu sem turpis. Fusce tempor
sagittis nunc, ut interdum ipsum vestibulum non. Proin dolor elit, aliquam eget tincidunt non, vestibulum ut
turpis. In hac habitasse platea dictumst. In a odio eget enim porttitor maximus. Aliquam nulla nibh,
ullamcorper aliquam placerat eu, viverra et dui. Phasellus ex lectus, maximus in mollis ac, luctus vel eros.
Drag me by this bar
Opened? [@isOpened]
Dismissed? [@isDismissed]
Overlay clicked? [@isOverlayClicked]
Escape pressed? [@isEscapePressed]