-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Background and Motivation
Related to #28182.
There is a need for a feature that will allow customers to change a part of main layout depending on which page they are on. A solution to achieve that exists and was described in #28182 (comment). Similar solution was implemented as part of #10450. https://github.com/dotnet/aspnetcore/tree/main/src/Components/Components/src/Sections these classes are internal.
We want to make them a part of public API (and change a few things for other potential use cases).
Proposed API
SectionOutlet component that renders content provided by SectionContent with the same SectionId
public sealed class SectionOutlet : IComponent, IDisposable
{
[Parameter, EditorRequired] public object SectionId { get; set; }
}public sealed class SectionContent : IComponent, IDisposable
{
[Parameter, EditorRequired] public object SectionId { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
{Usage Examples
Common use case would be to use SectionOutlet component in MainLayout.razor and provide the desired content via SectionContent component in other pages.
This is not the only case. You could use SectionOutlet SectionContent to modify a part of parent component depending on which child components are rendered.
Example:
- Add this code into the default template's
MainLayout.razor:
@code{
internal static object TopbarSection = new();
}- Add
SectionOutletinto the default template'sMainLayout.razor:
<div class="top-row px-4">
<SectionOutlet SectionId="TopbarSection" />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>- Add
SectionContentintoCounter.razor:
<SectionContent SectionId="MainLayout.TopbarSection">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>You'll get this:
If you don't want to use a static field inMainlayout.razor you could also use a string as SectionId:
<SectionOutlet SectionId="@("topbar")" />In Counter.razor:
<SectionContent SectionId="@("topbar")">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent>Alternative Designs
The original design with string Name as an identifier instead of object SectionId.
public sealed class SectionOutlet : IComponent, IDisposable
{
[Parameter, EditorRequired] public string Name { get; set; }
}public sealed class SectionContent : IComponent, IDisposable
{
[Parameter, EditorRequired] public string Name { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
{With this design you cannot hide your SectionOutlet. This is useful when you are developing a library and you don't want any accidental content in the user's app to be rendered in library's component.
Risks
Case when SectionId is IEquatable<T> and Equals(object), GetHashCode() not overriden.
