Surfaces
ModalService
BitModalService shows a BitModal with any content - a component, a Type or markup - from anywhere in the app: a service, a view model, a handler. Each Show hands back a BitModalReference that closes the modal, completes with its answer and says whether the user dismissed it. A BitModalParameters customizes the modal around the content with the same options as BitModal, plus a close guard and a navigation policy.
Notes
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
Markup as content
Awaiting a result
Reaching the content
Guarding the close
Updating an open modal
Persistent modals
Closing on navigation
Tracking open modals
Cascading parameters
Custom container
External Icons
Style & Class
RTL
API
Every parameter, public member, sub-class and enum this component exposes.
BitModalService parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| OnAddModal | event Func<BitModalReference, Task>? | Raised for every modal shown through this service, whoever showed it. | |
| OnCloseModal | event Func<BitModalReference, Task>? | Raised once for every modal of this service that closes, however it closed: answered or closed by the application, dismissed by the user, closed by a navigation or by its container going away. | |
| IsContainerAvailable | bool | Whether a BitModalContainer is currently mounted for this service, i.e. whether a Show call right now would actually render its modal. It reflects live state rather than registration in DI. | |
| OpenModals | IReadOnlyList<BitModalReference> | A snapshot of the modals this service currently has open, in the order they were opened. It holds what the mounted container renders, plus the persistent modals that are still waiting for a container to mount. | |
| GetModal | BitModalReference? (string? id) | The open modal with the given id, or null when there is none - it was closed, or the id belongs to another service. | |
| Close | Task (BitModalReference modal) | Closes an already opened modal using its reference, with a null result. This is the application closing the modal, so the CanClose guard is not asked. | |
| Close | Task (BitModalReference modal, object? result) | Closes an already opened modal using its reference, with the result its Result task completes with. The CanClose guard is not asked. | |
| TryClose | Task<bool> (BitModalReference modal, object? result) | Asks a modal to close and reports whether it did: a modal whose CanClose guard turns the close down stays open and this answers false. | |
| CloseAll | Task | Closes every modal this service currently has open, each with a null result, the last one opened first - so each hands the focus back to the modal under it, and the last to the page. The CanClose guards are not asked. | |
| Refresh | Task (BitModalReference? modal) | Re-renders the open modals, invalidating their memoized merged parameters. Call it after mutating modal parameters in place, which doesn't change any object reference and is therefore not detected on its own. Without an argument it refreshes every open modal. | |
| Show | Task<BitModalReference> (Dictionary<string, object>? parameters) | Shows a new BitModal with a custom component with parameters as its content. | |
| Show | Task<BitModalReference> (BitModalParameters? modalParameters) | Shows a new BitModal with a custom component as its content with custom parameters for the modal. | |
| Show | Task<BitModalReference> (Dictionary<string, object>? parameters, BitModalParameters? modalParameters, bool persistent) | Shows a new BitModal with a custom component as its content with custom parameters for the custom component and the modal. A persistent modal survives a container remount and is injected into the next container that mounts. | |
| Show | Task<BitModalReference> (Type componentType, Dictionary<string, object>? parameters, BitModalParameters? modalParameters, bool persistent) | Shows a new BitModal with a component whose type is only known at run time as its content, for the callers that pick their content from a map or a route. Throws an ArgumentException for a type that is not a Blazor component. | |
| Show | Task<BitModalReference> (RenderFragment content, BitModalParameters? modalParameters, bool persistent) | Shows a new BitModal with the given markup as its content, for the content that is not worth a component of its own. The reference's Content stays null for such a modal, since markup is not a component instance. | |
| Show | Task<BitModalReference> (RenderFragment<BitModalReference> content, BitModalParameters? modalParameters, bool persistent) | Shows a new BitModal with markup built from the modal's own reference as its content, so the markup can close and answer the modal it is in: modal => @<BitButton OnClick="modal.Close">Got it</BitButton>. | |
| Show | Task<BitModalReference> (Func<BitModalReference, Dictionary<string, object>?> parametersFactory, BitModalParameters? modalParameters, bool persistent) | Shows a new BitModal, building the content component's parameters from a factory that receives the modal reference. Use this overload when a parameter needs the reference itself, such as an OnClose callback that closes this very modal. |
BitModalReference properties
The handle a Show call hands back: what the modal is, what it answered with, and the ways to close it.
| Name | Type | Default value | Description |
|---|---|---|---|
| Id | string | The unique id of the shown modal. | |
| Content | object? | null | The instance of the component rendered as the content of the modal. It is captured while the modal is rendered, which is after the Show call returns, so it is still null immediately afterwards. |
| IsClosed | bool | false | Whether this modal has already been closed. A reference is never reused, so once set it stays set. |
| IsDismissed | bool | false | Whether the modal was closed by the user - the close button, the overlay, the Escape key - rather than by the application. It is what tells a modal that was walked away from apart from one answered with nothing, which the Result alone cannot. |
| Persistent | bool | false | Whether the modal survives a container remount and is injected into the next container that mounts. |
| Parameters | BitModalParameters? | null | The parameters the modal is shown with, before they are merged with the container's own. |
| Result | Task<object?> | Completes when the modal is closed, with the value it was closed with - null for a modal that was dismissed rather than answered. | |
| Rendered | Task<bool> | Completes with true once a container has rendered the modal, and with false for a modal that was closed before it ever rendered - one shown while no container was mounted, or closed in the same breath it was shown. | |
| Close | Task | Closes the modal without a result. The CanClose guard is not asked. | |
| CloseWith | Task (object? result) | Closes the modal with the given result, which is what its Result task completes with. The CanClose guard is not asked. | |
| TryClose | Task<bool> (object? result) | Asks the modal to close and reports whether it did: a modal whose CanClose guard turns the close down stays open and this answers false. | |
| Dismiss | Task<bool> | Closes the modal as a dismissal - the way the close button, the overlay and the Escape key close it - which asks the CanClose guard and marks the reference as dismissed. The content's own cancel action. | |
| Update | Task (BitModalParameters? parameters) | Replaces the parameters the modal is shown with and re-renders it. The whole set is replaced rather than merged. | |
| Update | Task (Action<BitModalParameters> change) | Changes some of the parameters and re-renders the modal, leaving the others as they are: modal.Update(p => p.HeaderText = "Step 2"). The change is applied to a copy, so a set shared between showings is never changed under the other modals. | |
| GetResult<T> | Task<T?> | The result the modal was closed with, cast to T - the type's default for a modal that was dismissed or answered with something else. | |
| GetContentAsync<T> | Task<T?> | The component rendered as the content, cast to T, waiting for the modal to be rendered first. The type's default for a modal that never rendered or whose content is markup. |
BitModalContainer properties
The component that renders the modals of the service. Mount one, in the layout - or a container of your own derived from it, which keeps all of this and adds markup of its own (see BitModalContainerBase).
| Name | Type | Default value | Description |
|---|---|---|---|
| ModalParameters | BitModalParameters | new() | The defaults of every modal this container renders - the house style: a maximum width, a close button, a position. The parameters of one showing win over them, and they win over a BitModalParams cascaded by a BitParams. |
| Service | BitModalService? | null | The service this container renders the modals of, in place of the one registered in DI - for a region with modals of its own. Read when the container initializes; give the container a @key to switch it. |
BitModalContainerBase<TReference, TParameters> properties
The base of BitModalContainer: it attaches to the service, keeps the list of modals, closes them on navigation and when it goes away, and keeps a closed modal in the page until its exit animation has played. A container of your own for a BitModalService derives from BitModalContainer, which already names the service, merges the parameters and honours CloseOnNavigation, and writes only its markup; one for a service of a reference and parameters type of your own derives from this base and writes the three members marked abstract and virtual as well. What a derived container uses:
| Name | Type | Default value | Description |
|---|---|---|---|
| RenderModals | RenderFragment () | Renders every modal, in the order they were opened, with everything it expects from its container: the reference, the merged parameters and what lets it play its exit animation. Each is keyed by its Id and renders only when something of its own changes - its parameters, a Refresh, its closing - not with every render of the container. A container that cascades the reference and the parameters by hand instead takes a closed modal out of the page at once, with no exit animation. | |
| RenderModals | RenderFragment (RenderFragment<BitModalContainerItem<TReference>> template) | Renders every modal the same way, each inside markup of your own: the template is rendered once per modal, renders the modal itself through the Modal of the item it is handed - RenderModals(item => @<div>@item.Modal</div>) - and needs no @key - the container keys it. The template follows every render of the container; the modal inside it still renders only when it changes. | |
| ModalReferences | IReadOnlyList<TReference> | The modals this container renders, in the order they were opened - a closed one still playing its exit animation included. | |
| GetMergedParameters | TParameters? (TReference modalRef) | The merged parameters of the given modal, cached until the container's ModalParameters change or Refresh is called. | |
| ModalService | BitModalServiceBase<TReference, TParameters> | Abstract: the service this container renders the modals of. Read when the container initializes and not to be changed afterwards. | |
| MergeParameters | TParameters? (TParameters? modalParameters, TParameters? containerParameters) | Abstract: merges the parameters of one showing, which win, with the container's ModalParameters - BitModalParameters.Merge for a BitModalService. | |
| GetCloseOnNavigation | bool? (TReference modalRef) | null | Virtual: whether the given modal closes when the path changes, or null for the default, which closes every modal but a persistent one. Read it off the parameters the modals are shown with - BitModalContainer reads BitModalParameters.CloseOnNavigation off the merged ones - or the modals ignore what they ask for. |
BitModalContainerItem<TReference> properties
One modal of a container that puts markup of its own around each modal: the context of the template handed to RenderModals.
| Name | Type | Default value | Description |
|---|---|---|---|
| Reference | TReference | The reference of the modal - closed while it plays its exit animation, which is the only time a container holds a closed one. | |
| Modal | RenderFragment | The modal itself, with everything it expects from its container: render it once, where it goes. |
BitModalParameters properties
The options a modal is shown with. Every parameter of BitModal - including Class, Style, Dir, AriaLabel and Disabled - has a nullable counterpart here (null means "not set": the container's value, then a BitParams default, then the modal's own default is used), plus the two options only a service can offer:
| Name | Type | Default value | Description |
|---|---|---|---|
| CanClose | Func<Task<bool>>? | null | Asked before the user closes the modal - the close button, the overlay, the Escape key - and by TryClose and Dismiss. Answering false keeps the modal open. Close, CloseWith, CloseAll and a close on navigation are the application closing the modal and do not ask it. A guard on the container's parameters is the default for every modal; one of the modal's own is asked instead. |
| CloseOnNavigation | bool? | null | Whether the modal closes when the app navigates somewhere else, which it does by default (a persistent modal only closes when this is set to true). Only a change of path counts; a query string or a fragment changed on the same page does not. Set it to false for the modals that outlive a route change. |
BitModalContentParameters<TComponent> properties
The parameters of the content component, named by its own properties instead of strings. It is a Dictionary<string, object>, so it goes wherever a Show overload takes the content's parameters.
| Name | Type | Default value | Description |
|---|---|---|---|
| Add<TValue> | void (Expression<Func<TComponent, TValue>> parameter, TValue value) | Adds the value of one parameter, named as c => c.Parameter - the collection initializer form is { c => c.Parameter, value }. Throws an ArgumentException for an expression that names no [Parameter] property of TComponent, or a value its type cannot take. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.