Reputation: 6246
I'm creating a Blazor component to have a NuGet package of the design. So, I can use it in different projects. I have a Razor called TopNavBar that displays the header of the page.
<div class="top-navbar style-1">
<div class="container p-0">
<div class="row align-items-center">
<div class="title">
@Title
</div>
<div class="col-lg-4">
<DarkLightSwitch />
</div>
</div>
</div>
</div>
As you can see, there is another reference to a DarkLightSwitch
razor page in the same Blazor component project. This is a simple switch to select a dark mode for the website. If the user clicks on the dark mode, the component has to call a JavaScript function to change the color for the all website.
@inject IJSRuntime jsRuntime
<div class="darkLight-btn">
<span class="icon @(IsDarkTheme ? "" : "active")"
id="light-icon" @onclick="OnLightClick">
<i class="la la-sun"></i>
</span>
<span class="icon @(IsDarkTheme ? "active" : "")"
id="dark-icon" @onclick="OnDarkClick">
<i class="la la-moon"></i>
</span>
</div>
@code {
/// <summary>
/// Is the dark theme activate?
/// </summary>
[Parameter] public bool IsDarkTheme { get; set; } = false;
protected async Task OnLightClick(MouseEventArgs args)
{
await jsRuntime.InvokeVoidAsync("switchToLight");
IsDarkTheme = false;
}
protected async Task OnDarkClick(MouseEventArgs args)
{
await jsRuntime.InvokeVoidAsync("switchToDark");
IsDarkTheme = true;
}
}
When I add the TopNavBar to a MainLayout.razor or any other page, if I click on the DarkLightSwitch nothing is happening because the page is rendered in a static mode.
If in the TopNavBar I call the DarkLightSwitch like this
<DarkLightSwitch @rendermode="RenderMode.InteractiveAuto" />
at run-time the component is not be found.
If I add the @rendermode
to the TopNavBar, the entire Razor page is not found.
Is there a way to fix it?
Upvotes: 0
Views: 1237
Reputation: 30177
I'm making some [major] assumptions based on your description:
You have built a Net8 solution using the Blazor Web App template with InteractiveAuto and Per page/component options selected. You have a third Razor Class Library project containing the components you want to put in a Nuget package.
Here's my version of your DarkLightSwitch
. Note mutating parameters within a component is a NONO. I'm assuming IsDarkTheme
is the default starting theme, so I've named it as such and only check it on start up to set the internal field.
@inject IJSRuntime JsRuntime
<div>
<button class="@_buttonCss" @onclick="this.OnClickAsync">@_buttonText</button>
</div>
@code {
// Allow the parameter to be null if it's not set.
// You should never set it in code
[Parameter] public bool IsDefaultDarkTheme { get; set; } = true;
private bool _isDark;
private bool _isInitialised;
private string _buttonCss => _isDark ? "btn btn-light" : "btn btn-dark";
private string _buttonText => _isDark ? "Switch To Light" : "Switch To Dark";
public override Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
if (!_isInitialised)
{
// only updates if the parameter has a value
_isDark = this.IsDefaultDarkTheme;
_isInitialised = true;
}
return base.SetParametersAsync(ParameterView.Empty);
}
private async Task OnClickAsync()
{
if (await JsRuntime.InvokeAsync<bool>("confirm", "Are you sure?"))
_isDark = !_isDark;
}
}
This library needs to be referenced by both the Server and Client projects.
MainLayout
in the Server project looks like this:
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<ComponentLibrary.DarkLightSwitch @rendermode="InteractiveAuto" />
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
There's a temporary Repo here.
Upvotes: 1