Blazorise OffcanvasProvider component
Programatically instantiate offcanvas panels with custom content.
The offcanvas provider component provides an abstraction on top of Blazorise's Offcanvas component, enabling you to programatically instantiate offcanvas panels with custom content/components.
Usage
You need to place <OffcanvasProvider> somewhere in your application
razor code. It can be placed anywhere, but a good approach is to place it in App.razor, or Routes.razor like in
the following example.
An IOffcanvasService will be registered by Blazorise providing you with an API to programatically instantiate offcanvas panels.
Examples are provided further below.
<Router AppAssembly="typeof(App).Assembly"> <Found>...</Found> <NotFound>...</NotFound> </Router> <OffcanvasProvider />
The IOffcanvasService
TheIOffcanvasService is an important feature that lets you control <OffcanvasProvider> instantiation.
You are provided with various overloads of Show() to instantiate the <Offcanvas> to your liking.
This will return a OffcanvasInstance that represents the <Offcanvas> you've instantiated with all of its configuration.
You may also use the provided Hide() method to close offcanvas panels.
Options
You may provide options to<OffcanvasProvider> globally by setting them on the <OffcanvasProvider> component itself.
<Router AppAssembly="typeof(App).Assembly"> <Found>...</Found> <NotFound>...</NotFound> </Router> <OffcanvasProvider UseOffcanvasStructure Animated Placement="Placement.Start" />
OffcanvasService usage.
<Button Color="Color.Primary" Clicked="InstantiateOffcanvas">Override Options Example</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } public Task InstantiateOffcanvas() { return OffcanvasService.Show<CustomStructureOffcanvasExample>( "Override Options Example", new OffcanvasInstanceOptions() { Animated = false, UseOffcanvasStructure = false, Placement = Placement.Top } ); } }
Closing the instantiated Offcanvas panels
<OffcanvasProvider> will only keep track of the offcanvas panels that have been instantiated by itself.
To close an Offcanvas:
-
You can use Blazorise's
<CloseButton>component, which automatically knows how to close the currently opened<Offcanvas>when placed inside of it. -
Use the provided
IOffcanvasServiceand callIOffcanvasService.Hide(), this will close the last opened<Offcanvas>tracked by the<OffcanvasProvider>. -
You may keep track of the
OffcanvasInstanceand callIOffcanvasService.Hide(offcanvasInstance), this will close the provided instance. -
You may keep track of the
OffcanvasInstanceand calloffcanvasInstance.OffcanvasRef.Hide().
Stateful instantiated Offcanvas panels
<OffcanvasProvider> can keep the state of the offcanvas even after they have been closed.
To do this you will need to:
-
Set
Statefulto true in theOffcanvasProvideror in theOffcanvasInstanceOptions. The reason why you need to explicitly opt-in for this feature is because the instances you open will be kept in memory, and you should be mindful that you need to properly manage these. -
Provide a unique Id so the instance can be tracked and reopen. This can be set in
OffcanvasInstanceOptions.ElementId. Optionally you may keep track of theOffcanvasInstancereturned by theIOffcanvasService.Show()method to reopen the same instance.
Examples
Instantiate an offcanvas with a custom component
Instantiates an offcanvas with a counter example taking in the counter number from the provided parameter.OffcanvasService.Show provides various overloads you can use to instantiate your custom content.
<Button Color="Color.Primary" Clicked="ShowCounter">Show Counter</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } public Task ShowCounter() { Random random = new(); var newValue = random.NextInt64( 100 ); return OffcanvasService.Show<CounterExample>( "My Custom Content!", x => x.Add( x => x.Value, newValue ) ); } }
ShowCounter.razor
<Heading>Counter</Heading> <Paragraph>@Value</Paragraph> <Button Color="Color.Primary" Clicked="Increment">Increment</Button>
@code { [Parameter] public long Value { get; set; } private void Increment() { Value++; } }
Instantiate an offcanvas with a custom render fragment
<Button Color="Color.Primary" Clicked="ShowRenderFragment">Show Custom Structure</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } private RenderFragment customFragment => __builder => { <Paragraph>This content is provided by a custom RenderFragment</Paragraph> }; public Task ShowRenderFragment() { return OffcanvasService.Show( "My Custom RenderFragment!", customFragment ); } }
Instantiate an offcanvas with custom structure
If you want to customize the offcanvas structure, you can do so, by setting UseOffcanvasStructure to false and providing the structure inside the custom content you are instantiating.
You may do this by providing your custom html or by using the internal Offcanvas components.
<OffcanvasHeader><OffcanvasBody><OffcanvasFooter>
<Field Horizontal> <FieldLabel ColumnSize="ColumnSize.IsFull.OnTablet.Is2.OnDesktop">User Name</FieldLabel> <FieldBody ColumnSize="ColumnSize.IsFull.OnTablet.Is10.OnDesktop"> <TextInput @bind-Value="userName"></TextInput> </FieldBody> </Field> <Button Color="Color.Primary" Clicked="ShowCustomStructure">Show Custom Structure</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } private string userName = "John Doe"; public Task ShowCustomStructure() { return OffcanvasService.Show<CustomStructureOffcanvasExample>( parameters => parameters.Add( x => x.UserName, userName ), new OffcanvasInstanceOptions() { UseOffcanvasStructure = false } ); } }
CustomStructureOffcanvasExample.razor
<OffcanvasHeader> <Heading Size="HeadingSize.Is5">My Custom Structure</Heading> <CloseButton /> </OffcanvasHeader> <OffcanvasBody> Welcome @UserName! </OffcanvasBody> <OffcanvasFooter> <Button Color="Color.Success" Clicked="Confirm">Cheers!</Button> </OffcanvasFooter>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } [Parameter] public string UserName { get; set; } private Task Confirm() { return OffcanvasService.Hide(); } }
Interaction
Since you can pass in parameters into your component, you can take advantage of this to interact with your<Offcanvas>.
A common example, might be a generic formulary where the validation and success logic are not necessarily known by this component and are provided from "outside".
The following example setups a simple formulary showcasing this.
<Paragraph> @formularyMessage </Paragraph> <Button Color="Color.Primary" Clicked="ShowFormulary">Show</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } private string formularyMessage = string.Empty; public Task ShowFormulary() { formularyMessage = string.Empty; return OffcanvasService.Show<FormularyOffcanvasExample>( x => { x.Add( x => x.OnValidate, FormularyValidate ); x.Add( x => x.OnSuccess, FormularySuccess ); }, new OffcanvasInstanceOptions() { UseOffcanvasStructure = false } ); } private Task<bool> FormularyValidate( Employee employee ) => Task.FromResult( !string.IsNullOrWhiteSpace( employee.FirstName ) && !string.IsNullOrWhiteSpace( employee.Email ) ); private Task FormularySuccess( Employee employee ) { formularyMessage = $"Employee : {employee.FirstName} saved successfully!"; return InvokeAsync( StateHasChanged ); } }
FormularyOffcanvasExample.razor
<OffcanvasHeader> <Heading Size="HeadingSize.Is5">Please fill in the formulary</Heading> <CloseButton /> </OffcanvasHeader> <OffcanvasBody> <Field Horizontal> <FieldLabel ColumnSize="ColumnSize.IsFull.OnTablet.Is3.OnDesktop">First Name</FieldLabel> <FieldBody ColumnSize="ColumnSize.IsFull.OnTablet.Is9.OnDesktop"> <TextInput @bind-Value="model.FirstName"></TextInput> </FieldBody> </Field> <Field Horizontal> <FieldLabel ColumnSize="ColumnSize.IsFull.OnTablet.Is3.OnDesktop">Email</FieldLabel> <FieldBody ColumnSize="ColumnSize.IsFull.OnTablet.Is9.OnDesktop"> <TextInput @bind-Value="model.Email"></TextInput> </FieldBody> </Field> @if ( !isValid ) { <Paragraph> <Label>Invalid Submission!</Label> </Paragraph> } </OffcanvasBody> <OffcanvasFooter> <Button Color="Color.Success" Clicked="Confirm">Confirm</Button> <Button Color="Color.Secondary" Clicked="OffcanvasService.Hide">Close</Button> </OffcanvasFooter>
@code { private Employee model = new(); private bool isValid = true; [Inject] public IOffcanvasService OffcanvasService { get; set; } [Parameter] public Func<Employee, Task<bool>> OnValidate { get; set; } [Parameter] public Func<Employee, Task> OnSuccess { get; set; } private async Task Confirm() { if ( OnValidate is not null ) isValid = await OnValidate( model ); if ( !isValid ) { return; } await OnSuccess( model ); await OffcanvasService.Hide(); } }
Instantiate a stateful offcanvas
<Button Color="Color.Primary" Clicked="ShowStateful">Show Stateful</Button>
@code { [Inject] public IOffcanvasService OffcanvasService { get; set; } public Task ShowStateful() { return OffcanvasService.Show<CounterExample>( "My Stateful content", new OffcanvasInstanceOptions() { Stateful = true, ElementId = "StatefulOffcanvas", Placement = Placement.Start } ); } }
API
Attributes
You will find that <OffcanvasProvider> provides most regular <Offcanvas> parameters for you to override the panel behaviour.
OffcanvasProvider
| Name | Description | Type | Default |
|---|---|---|---|
UseOffcanvasStructure |
Uses the offcanvas standard structure, by setting this to true you are only in charge of providing the custom content. | boolean | true |
Stateful |
Keeps the OffcanvasInstance in memory after it has been closed. | boolean | false |
ShowCloseButton |
Shows a close button in the offcanvas header when using the provider structure. | boolean | true |
Opening |
Occurs before the offcanvas is opened. | Func<OffcanvasOpeningEventArgs, Task> | |
Closing |
Occurs before the offcanvas is closed. | Func<OffcanvasClosingEventArgs, Task> | |
Opened |
Occurs after the offcanvas has opened. | EventCallback | |
Closed |
Occurs after the offcanvas has closed. | EventCallback | |
ShowBackdrop |
Specifies the backdrop needs to be rendered for this Offcanvas. | boolean | true |
Animated |
Gets or sets whether the component has any animations. | boolean | true |
AnimationDuration |
Gets or sets the animation duration. | int | 150 |
Placement |
Specifies the position of the offcanvas. | Placement | End |