-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Blazor Sections API Proposal #46937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
API Review Notes:
API approved! namespace Microsoft.AspNetCore.Components.Sections;
+ public sealed class SectionOutlet : IComponent, IDisposable
+ {
+ [Parameter, EditorRequired] public object SectionId { get; set; }
+ // <inheritdoc/>
+ void Attach(RenderHandle renderHandle);
+ // <inheritdoc/>
+ Task SetParametersAsync(ParameterView parameters);
+ // <inheritdoc/>
+ public void Dispose();
+ }
+ public sealed class SectionContent : IComponent, IDisposable
+ {
+ [Parameter, EditorRequired] public object SectionId { get; set; }
+ [Parameter] public RenderFragment? ChildContent { get; set; }
+ // <inheritdoc/>
+ void Attach(RenderHandle renderHandle);
+ // <inheritdoc/>
+ Task SetParametersAsync(ParameterView parameters);
+ // <inheritdoc/>
+ public void Dispose();
+ } |
@guardrex can you add docs for this feature based on the description from @surayya-MS ? |
Yes. I'll ping on the (upcoming) docs issue if I get stuck. |
great idea👍 |
How does this work with cascading parameters? Are they supported? For example, should this MainLayout.razor <div class="top-row px-4">
<CascadingValue Value="@("Hello from MainLayout")">
<SectionOutlet SectionId="TopbarSection" />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</CascadingValue>
</div> CounterTopBar.razor <div>Here's some content with a cascading value: @CascadedValue</div>
@code {
[CascadingParameter] public string CascadedValue {get;set;}
} Counter.razor <CascadingValue Value="@("Hello from Counter")">
<SectionContent SectionId="MainLayout.TopbarSection">
<CounterTopBar />
</SectionContent>
</CascadingValue> I think that currently this parameter would be provided by the A real world example would be an app where a page has a state object, which it cascades to all components on the page. The |
@msynk I also like the idea of using some form of |
I think it's better to allow passing parameters to the |
@surayya-MS ... Are additional changes coming? I just put the PR up at ... ... which I can hold off on pinging u for review if additional changes are coming. |
@guardrex , yes. I'll update the issue description tomorrow. |
I've marked the PR as a draft for now. I'll keep an 👁️ on this issue and associated PRs here. I'll ping u later when the docs PR is ready for review after your next round of updates. |
New DesignThere is a problem with the current design. If you want to use a string for You cannot just do this Since the case where public sealed class SectionOutlet : IComponent, IDisposable
{
+ [Parameter] public string SectionName { get; set; }
- [Parameter, EditorRequired] public object SectionId { get; set; }
+ [Parameter] public object SectionId { get; set; }
} public sealed class SectionContent : IComponent, IDisposable
{
+ [Parameter] public string SectionName { get; set; }
- [Parameter, EditorRequired] public object SectionId { get; set; }
+ [Parameter] public object SectionId { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
} With You can set an ID either using Updated Usage ExamplesCommon use case would be to use Example:
<div class="top-row px-4">
<SectionOutlet SectionId="topbar" />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<SectionContent SectionId="topbar">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent> You'll get this: If you want to "hide" your Previous example could be achieved by using
@code{
internal static object TopbarSection = new();
}
<div class="top-row px-4">
<SectionOutlet SectionId="TopbarSection" />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<SectionContent SectionId="MainLayout.TopbarSection">
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</SectionContent> |
Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:
|
Thanks for the API update. I agree that I marked both I'm not sure if it's obvious that API Approved! namespace Microsoft.AspNetCore.Components.Sections;
+ public sealed class SectionOutlet : IComponent, IDisposable
+ {
+ [Parameter] public string? SectionName { get; set; }
+ [Parameter] public object? SectionId { get; set; }
+ // <inheritdoc/>
+ void Attach(RenderHandle renderHandle);
+ // <inheritdoc/>
+ Task SetParametersAsync(ParameterView parameters);
+ // <inheritdoc/>
+ public void Dispose();
+ }
+ public sealed class SectionContent : IComponent, IDisposable
+ {
+ [Parameter] public string? SectionName { get; set; }
+ [Parameter] public object? SectionId { get; set; }
+ [Parameter] public RenderFragment? ChildContent { get; set; }
+ // <inheritdoc/>
+ void Attach(RenderHandle renderHandle);
+ // <inheritdoc/>
+ Task SetParametersAsync(ParameterView parameters);
+ // <inheritdoc/>
+ public void Dispose();
+ } |
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 bySectionContent
with the sameSectionId
Usage Examples
Common use case would be to use
SectionOutlet
component inMainLayout.razor
and provide the desired content viaSectionContent
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:
MainLayout.razor
:SectionOutlet
into the default template'sMainLayout.razor
:SectionContent
intoCounter.razor
:You'll get this:
If you don't want to use a static field in
Mainlayout.razor
you could also use a string asSectionId
:In
Counter.razor
:Alternative Designs
The original design with string
Name
as an identifier instead of objectSectionId
.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
isIEquatable<T>
andEquals(object)
,GetHashCode()
not overriden.The text was updated successfully, but these errors were encountered: