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

The IOffcanvasService 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" />
Optionally you can override these when instantiating an offcanvas through the 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 IOffcanvasService and call IOffcanvasService.Hide(), this will close the last opened <Offcanvas> tracked by the <OffcanvasProvider>.
  • You may keep track of the OffcanvasInstance and call IOffcanvasService.Hide(offcanvasInstance), this will close the provided instance.
  • You may keep track of the OffcanvasInstance and call offcanvasInstance.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 Stateful to true in the OffcanvasProvider or in the OffcanvasInstanceOptions. 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 the OffcanvasInstance returned by the IOffcanvasService.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 TypeDefault
UseOffcanvasStructure Uses the offcanvas standard structure, by setting this to true you are only in charge of providing the custom content. booleantrue
Stateful Keeps the OffcanvasInstance in memory after it has been closed. booleanfalse
ShowCloseButton Shows a close button in the offcanvas header when using the provider structure. booleantrue
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. booleantrue
Animated Gets or sets whether the component has any animations. booleantrue
AnimationDuration Gets or sets the animation duration. int150
Placement Specifies the position of the offcanvas. PlacementEnd
On this page