Skip to content

Commit

Permalink
ThemeSwitcher updates
Browse files Browse the repository at this point in the history
  • Loading branch information
gvreddy04 committed Nov 2, 2024
1 parent 38037a7 commit 4c5d18f
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 182 deletions.
24 changes: 2 additions & 22 deletions BlazorBootstrap.Demo.RCL/Components/Layout/EmptyLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,8 @@
<div class="vr d-none d-lg-flex h-100 mx-lg-2 text-white"></div>
<hr class="d-lg-none my-2 text-white-50">
</li>
<li class="nav-item dropdown">
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static" aria-label="Toggle theme (light)">
<span class="blazorbootstrap-theme-indicator"><i class="bi bi-sun-fill"></i></span>
<span class="d-lg-none ms-2" id="bd-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center active rounded" data-bs-theme-value="light" aria-pressed="true" @onclick="SetLightTheme">
<i class="bi bi-sun-fill me-2"></i>Light<i class="bi bi-check2 ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="dark" aria-pressed="false" @onclick="SetDarkTheme">
<i class="bi bi-moon-stars-fill me-2"></i>Dark<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="auto" aria-pressed="false" @onclick="SetAutoTheme">
<i class="bi bi-circle-half me-2"></i>Auto<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
</ul>
<li class="nav-item">
<ThemeSwitcher />
</li>
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<BlazorBootstrapLayout>
<HeaderSection>
<ThemeSwitcher />
<ThemeSwitcher OnThemeChanged="OnThemeChanged" />
</HeaderSection>
<SidebarSection>
<Sidebar2 Href="/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,9 @@ internal override IEnumerable<NavItem> GetNavItems()

return navItems;
}

private void OnThemeChanged(string themeName)
{
JS.InvokeVoidAsync("updateDemoCodeThemeCss", themeName);
}
}
16 changes: 0 additions & 16 deletions BlazorBootstrap.Demo.RCL/Components/Layout/MainLayoutBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ public class MainLayoutBase : LayoutComponentBase

[Inject] protected IJSRuntime JS { get; set; } = default!;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await JS.InvokeVoidAsync("initializeTheme");

await base.OnAfterRenderAsync(firstRender);
}

protected override void OnInitialized()
{
version = $"v{Configuration["version"]}"; // example: v0.6.1
Expand All @@ -43,14 +35,6 @@ protected override void OnInitialized()
base.OnInitialized();
}

internal Task SetAutoTheme() => SetTheme("system");

internal Task SetDarkTheme() => SetTheme("dark");

internal Task SetLightTheme() => SetTheme("light");

internal async Task SetTheme(string themeName) => await JS.InvokeVoidAsync("setTheme", themeName);

internal virtual async Task<Sidebar2DataProviderResult> Sidebar2DataProvider(Sidebar2DataProviderRequest request)
{
if (navItems is null)
Expand Down
92 changes: 19 additions & 73 deletions BlazorBootstrap.Demo.RCL/wwwroot/js/blazorbootstrap.demo.rcl.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
async function copyToClipboard(text, dotNetHelper) {
/**
* Copies the provided text to the clipboard and invokes .NET methods based on the success or failure of the operation.
* @param {string} text - The text to be copied to the clipboard.
* @param {object} dotNetHelper - The .NET helper object to invoke methods on.
*/
async function copyToClipboard(text, dotNetHelper) {
let isCopied = true;

try {
Expand All @@ -15,13 +20,21 @@
);
}

/**
* Highlights all code blocks on the page using the Prism.js library.
* If the Prism.js custom class plugin is available, it prefixes all classes with 'prism-'.
*/
function highlightCode() {
if (Prism) {
Prism.plugins.customClass.prefix('prism-');
Prism.highlightAll();
}
};

/**
* Scrolls the page to the heading element specified by the URL hash.
* If a hash is present in the URL, it finds the corresponding element by ID and scrolls it into view.
*/
function navigateToHeading() {
if (window.location.hash) {
// get hash tag in URL
Expand All @@ -34,78 +47,11 @@ function navigateToHeading() {
}
}

// THEMES
const STORAGE_KEY = "blazorbootstrap-theme";
const DEFAULT_THEME = "light";
const SYSTEM_THEME = "system";

const state = {
chosenTheme: SYSTEM_THEME, // light|dark|system
appliedTheme: DEFAULT_THEME // light|dark
};

const showActiveTheme = () => {
let $themeIndicator = document.querySelector(".blazorbootstrap-theme-indicator>i");
if ($themeIndicator) {
if (state.appliedTheme === "light") {
$themeIndicator.className = "bi bi-sun-fill";
} else if (state.appliedTheme === "dark") {
$themeIndicator.className = "bi bi-moon-stars-fill";
} else {
$themeIndicator.className = "bi bi-circle-half";
}
}

let $themeSwitchers = document.querySelectorAll(".blazorbootstrap-theme-item>button");
if ($themeSwitchers) {
$themeSwitchers.forEach((el) => {
const bsThemeValue = el.dataset.bsThemeValue;
const iEl = el.querySelector(".bi.bi-check2");
if (state.chosenTheme === bsThemeValue) {
el.classList.add("active");
if (iEl)
iEl.classList.remove("d-none");
} else {
el.classList.remove("active");
if (iEl)
iEl.classList.add("d-none");
}
});
}
};

function setTheme(theme, save = true) {
state.chosenTheme = theme;
state.appliedTheme = theme;

if (theme === SYSTEM_THEME) {
state.appliedTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}

document.documentElement.setAttribute("data-bs-theme", state.appliedTheme);
if (save) {
window.localStorage.setItem(STORAGE_KEY, state.chosenTheme);
}
showActiveTheme();
updateDemoCodeThemeCss(state.appliedTheme);
};

function initializeTheme() {
const localTheme = window.localStorage.getItem(STORAGE_KEY);
if (localTheme) {
setTheme(localTheme, false);
} else {
setTheme(SYSTEM_THEME);
}
}

window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
const theme = event.matches ? "dark" : "light";
setTheme(theme);
});

/**
* Update the theme of the demo code
* @param {} theme
* @returns {}
*/
function updateDemoCodeThemeCss(theme) {
if (theme === "dark") {
let prismThemeLightLinkEl = document.getElementById('prismThemeLightLink');
Expand Down
44 changes: 23 additions & 21 deletions blazorbootstrap/Components/ThemeSwitcher/ThemeSwitcher.razor
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
@namespace BlazorBootstrap
@inherits BlazorBootstrapComponentBase

<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static" aria-label="Toggle theme (light)">
<span class="blazorbootstrap-theme-indicator"><i class="bi bi-sun-fill"></i></span>
<span class="d-lg-none ms-2" id="bd-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center active rounded" data-bs-theme-value="light" aria-pressed="true" @onclick="SetLightTheme">
<i class="bi bi-sun-fill me-2"></i>Light<i class="bi bi-check2 ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="dark" aria-pressed="false" @onclick="SetDarkTheme">
<i class="bi bi-moon-stars-fill me-2"></i>Dark<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="auto" aria-pressed="false" @onclick="SetAutoTheme">
<i class="bi bi-circle-half me-2"></i>Auto<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
</ul>
<div class="dropdown">
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center" id="bb-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static" aria-label="Toggle theme (light)">
<span class="blazorbootstrap-theme-indicator"><i class="bi bi-sun-fill"></i></span>
<span class="d-none ms-2" id="bb-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bb-theme-text">
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center active rounded" data-bs-theme-value="light" aria-pressed="true" @onclick="SetLightTheme">
<i class="bi bi-sun-fill me-2"></i>Light<i class="bi bi-check2 ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="dark" aria-pressed="false" @onclick="SetDarkTheme">
<i class="bi bi-moon-stars-fill me-2"></i>Dark<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
<li class="blazorbootstrap-theme-item px-1">
<button type="button" class="dropdown-item d-flex align-items-center rounded" data-bs-theme-value="system" aria-pressed="false" @onclick="SetAutoTheme">
<i class="bi bi-circle-half me-2"></i>Auto<i class="bi bi-check2 d-none ms-auto"></i>
</button>
</li>
</ul>
</div>
31 changes: 27 additions & 4 deletions blazorbootstrap/Components/ThemeSwitcher/ThemeSwitcher.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,38 @@

public partial class ThemeSwitcher : BlazorBootstrapComponentBase
{

private DotNetObjectReference<ThemeSwitcher>? objRef;

#region Methods

protected override Task OnInitializedAsync()
{
objRef ??= DotNetObjectReference.Create(this);

return base.OnInitializedAsync();
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await ThemeSwitcherJsInterop.InitializeAsync();
await ThemeSwitcherJsInterop.InitializeAsync(objRef);

await base.OnAfterRenderAsync(firstRender);
}

internal Task SetAutoTheme() => ThemeSwitcherJsInterop.SetAutoThemeAsync();
internal Task SetAutoTheme() => ThemeSwitcherJsInterop.SetAutoThemeAsync(objRef);

internal Task SetDarkTheme() => ThemeSwitcherJsInterop.SetDarkThemeAsync();
internal Task SetDarkTheme() => ThemeSwitcherJsInterop.SetDarkThemeAsync(objRef);

internal Task SetLightTheme() => ThemeSwitcherJsInterop.SetLightThemeAsync();
internal Task SetLightTheme() => ThemeSwitcherJsInterop.SetLightThemeAsync(objRef);

[JSInvokable]
public async Task OnThemeChangedJS(string themeName)
{
if (OnThemeChanged.HasDelegate)
await OnThemeChanged.InvokeAsync(themeName);
}

#endregion

Expand All @@ -25,4 +42,10 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
[Inject] private ThemeSwitcherJsInterop ThemeSwitcherJsInterop { get; set; } = default!;

#endregion

/// <summary>
/// Fired when the theme is changed.
/// </summary>
[Parameter]
public EventCallback<string> OnThemeChanged { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ public async ValueTask DisposeAsync()
}
}

public async Task InitializeAsync()
public async Task InitializeAsync(DotNetObjectReference<ThemeSwitcher>? objRef)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("initializeTheme");
await module.InvokeVoidAsync("initializeTheme", objRef);
}

internal Task SetAutoThemeAsync() => SetThemeAsync("system");
internal Task SetAutoThemeAsync(DotNetObjectReference<ThemeSwitcher>? objRef) => SetThemeAsync(objRef, "system");

internal Task SetDarkThemeAsync() => SetThemeAsync("dark");
internal Task SetDarkThemeAsync(DotNetObjectReference<ThemeSwitcher>? objRef) => SetThemeAsync(objRef, "dark");

internal Task SetLightThemeAsync() => SetThemeAsync("light");
internal Task SetLightThemeAsync(DotNetObjectReference<ThemeSwitcher>? objRef) => SetThemeAsync(objRef, "light");

internal async Task SetThemeAsync(string themeName)
internal async Task SetThemeAsync(DotNetObjectReference<ThemeSwitcher>? objRef, string themeName)
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("setTheme", themeName);
await module.InvokeVoidAsync("setTheme", objRef, themeName);
}

#endregion
Expand Down
Loading

0 comments on commit 4c5d18f

Please sign in to comment.