Skip to content

Commit

Permalink
blazor bootstrap layout component + theme switcher - preview version (#…
Browse files Browse the repository at this point in the history
…922)

blazor bootstrap layout component + theme switcher - preview version
  • Loading branch information
gvreddy04 authored Oct 30, 2024
1 parent a618c68 commit a9d1263
Show file tree
Hide file tree
Showing 12 changed files with 492 additions and 30 deletions.
93 changes: 63 additions & 30 deletions BlazorBootstrap.Demo.RCL/Components/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -1,40 +1,73 @@
@namespace BlazorBootstrap.Demo.RCL
@inherits MainLayoutBase

<div class="bb-page">
<BlazorBootstrapLayout>
<HeaderSection>
<ThemeSwitcher />
</HeaderSection>
<SidebarSection>
<Sidebar2 Href="/"
ImageSrc="https://demos.blazorbootstrap.com/images/logo/logo-white.svg"
Title="Blazor Bootstrap"
BadgeText="@Version"
DataProvider="Sidebar2DataProvider"
WidthUnit="Unit.Px"/>
</SidebarSection>

<Sidebar2 Href="/"
ImageSrc="https://demos.blazorbootstrap.com/images/logo/logo-white.svg"
Title="Blazor Bootstrap"
BadgeText="@Version"
DataProvider="Sidebar2DataProvider"
WidthUnit="Unit.Px" />
<ContentSection>
@Body

<main class="bb-scrollbar">
<div class="content my-4 my-md-4 px-4">
@Body
<Callout Class="text-center text-bold skippy border-0" HideHeading="true">
<a href="@GithubUrl" class="text-decoration-none" b-09pcjsuuk4="">
<i class="bi bi-star-fill" b-09pcjsuuk4=""></i>
<span b-09pcjsuuk4="">If you like Blazor Bootstrap, give it a star on GitHub!</span>
<i class="bi bi-star-fill" b-09pcjsuuk4=""></i>
</a>
</Callout>
</ContentSection>

<Callout Class="text-center text-bold skippy border-0" HideHeading="true">
<a href="@GithubUrl" class="text-decoration-none" b-09pcjsuuk4="">
<i class="bi bi-star-fill" b-09pcjsuuk4=""></i>
<span b-09pcjsuuk4="">If you like Blazor Bootstrap, give it a star on GitHub!</span>
<i class="bi bi-star-fill" b-09pcjsuuk4=""></i>
<FooterSection>
<div class="row">
<div class="col-lg-4 mb-3">
<a class="d-inline-flex align-items-center mb-2 text-body-emphasis text-decoration-none" href="/" aria-label="Bootstrap">
<img src="/images/logo/logo-color.svg" width="40" height="32" class="d-block me-2" alt="Blazor Bootstrap">
<span class="fs-5">Blazor Bootstrap</span>
</a>
</Callout>
<ul class="list-unstyled small text-muted">
<li class="mb-2">Designed and built with all the love in the world by the <strong><a href="https://www.nuget.org/packages/Blazor.Bootstrap">Blazor Bootstrap</a></strong> team with the help of our contributors.</li>
<li class="mb-2">Code licensed <a href="https://github.com/vikramlearning/blazorbootstrap/blob/main/LICENSE.txt" target="_blank" rel="license noopener">Apache License 2.0</a>.</li>
<li class="mb-2">Currently @Version.</li>
</ul>
</div>
<div class="col-6 col-lg-2 offset-lg-1 mb-3">
<h5>Links</h5>
<ul class="list-unstyled">
<li class="mb-2"><a href="/">Home</a></li>
<li class="mb-2"><a href="@DocsUrl" target="_blank" rel="noopener">Docs</a></li><!--!-->
<li class="mb-2"><a href="@BlogUrl" target="_blank" rel="noopener">Blog</a></li>
<li class="mb-2"><a href="@GithubUrl" target="_blank" rel="noopener">GitHub</a></li>
</ul>
</div>
<div class="col-6 col-lg-2 mb-3">
<h5>Guides</h5>
<ul class="list-unstyled">
<li class="mb-2"><a href="/getting-started/blazor-webassembly">Getting started</a></li>
<li class="mb-2"><a href="/getting-started#install-nuget-package">Install Nuget</a></li>
<li class="mb-2"><a href="https://github.com/vikramlearning/blazorbootstrap-starter-templates" target="_blank">Starter templates</a></li>
</ul>
</div>
<div class="col-6 col-lg-2 mb-3">
<h5>Community</h5>
<ul class="list-unstyled">
<li class="mb-2"><a href="@GithubIssuesUrl" target="_blank" rel="noopener">Issues</a></li>
<li class="mb-2"><a href="@GithubDiscussionsUrl" target="_blank" rel="noopener">Discussions</a></li>
<li class="mb-2"><a href="@OpenCollectiveUrl" target="_blank" rel="noopener">Open Collective</a></li>
<li class="mb-2"><a href="@StackoverflowUrl" target="_blank" rel="noopener">Stack Overflow</a></li>
</ul>
</div>
<div class="col-6 col-lg-2 mb-3"></div>
</div>

<MainLayoutBaseFooter Version="@Version"
DocsUrl="@DocsUrl"
BlogUrl="@BlogUrl"
GithubUrl="@GithubUrl"
TwitterUrl="@TwitterUrl"
LinkedInUrl="@LinkedInUrl"
OpenCollectiveUrl="@OpenCollectiveUrl"
GithubIssuesUrl="@GithubIssuesUrl"
GithubDiscussionsUrl="@GithubDiscussionsUrl"
StackoverflowUrl="@StackoverflowUrl" />

</main>
</div>
</FooterSection>
</BlazorBootstrapLayout>

<MainLayoutBaseServices />
165 changes: 165 additions & 0 deletions blazorbootstrap/Components/Core/BlazorBootstrapLayoutComponentBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using Microsoft.Extensions.Configuration;

namespace BlazorBootstrap;

public abstract class BlazorBootstrapLayoutComponentBase : LayoutComponentBase, IDisposable, IAsyncDisposable
{
#region Fields and Constants

private bool isAsyncDisposed;

private bool isDisposed;

#endregion

#region Methods

/// <inheritdoc />
protected override async Task OnAfterRenderAsync(bool firstRender)
{
IsRenderComplete = true;

await base.OnAfterRenderAsync(firstRender);
}

/// <inheritdoc />
protected override void OnInitialized()
{
Id ??= IdUtility.GetNextId();

base.OnInitialized();
}

public static string BuildClassNames(params (string? cssClass, bool when)[] cssClassList)
{
var list = new HashSet<string>();

if (cssClassList is not null && cssClassList.Any())
foreach (var (cssClass, when) in cssClassList)
if (!string.IsNullOrWhiteSpace(cssClass) && when)
list.Add(cssClass);

if (list.Any())
return string.Join(" ", list);

return string.Empty;
}

public static string BuildClassNames(string? userDefinedCssClass, params (string? cssClass, bool when)[] cssClassList)
{
var list = new HashSet<string>();

if (cssClassList is not null && cssClassList.Any())
foreach (var (cssClass, when) in cssClassList)
if (!string.IsNullOrWhiteSpace(cssClass) && when)
list.Add(cssClass);

if (!string.IsNullOrWhiteSpace(userDefinedCssClass))
list.Add(userDefinedCssClass.Trim());

if (list.Any())
return string.Join(" ", list);

return string.Empty;
}

public static string BuildStyleNames(string? userDefinedCssStyle, params (string? cssStyle, bool when)[] cssStyleList)
{
var list = new HashSet<string>();

if (cssStyleList is not null && cssStyleList.Any())
foreach (var (cssStyle, when) in cssStyleList)
if (!string.IsNullOrWhiteSpace(cssStyle) && when)
list.Add(cssStyle);

if (!string.IsNullOrWhiteSpace(userDefinedCssStyle))
list.Add(userDefinedCssStyle.Trim());

if (list.Any())
return string.Join(';', list);

return string.Empty;
}

/// <inheritdoc />
/// <see href="https://learn.microsoft.com/en-us/dotnet/api/system.idisposable?view=net-6.0" />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

/// <inheritdoc />
/// <see
/// href="https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync#implement-both-dispose-and-async-dispose-patterns" />
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore(true).ConfigureAwait(false);

Dispose(false);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
if (disposing)
{
// cleanup
}

isDisposed = true;
}
}

protected virtual ValueTask DisposeAsyncCore(bool disposing)
{
if (!isAsyncDisposed)
{
if (disposing)
{
// cleanup
}

isAsyncDisposed = true;
}

return ValueTask.CompletedTask;
}

#endregion

#region Properties, Indexers

[Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> AdditionalAttributes { get; set; } = default!;

[Parameter] public string? Class { get; set; }

protected virtual string? ClassNames => Class;

[Inject] protected IConfiguration Configuration { get; set; } = default!;

public ElementReference Element { get; set; }

[Parameter] public string? Id { get; set; }

protected bool IsRenderComplete { get; private set; }

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

[Parameter] public string? Style { get; set; }

protected virtual string? StyleNames => Style;

#endregion

#region Other

~BlazorBootstrapLayoutComponentBase()
{
Dispose(false);
}

#endregion
}
27 changes: 27 additions & 0 deletions blazorbootstrap/Components/Layout/BlazorBootstrapLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@namespace BlazorBootstrap
@inherits BlazorBootstrapLayoutComponentBase

<div class="@ClassNames">

@SidebarSection

<main class="bb-scrollbar">
@if (HeaderSection is not null)
{
<div class="@HeaderSectionCssClassNames">
@HeaderSection
</div>
}

<article class="@ContentSectionCssClassNames">
@ContentSection
</article>

@if (FooterSection is not null)
{
<div class="@FooterSectionCssClassNames">
@FooterSection
</div>
}
</main>
</div>
24 changes: 24 additions & 0 deletions blazorbootstrap/Components/Layout/BlazorBootstrapLayout.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace BlazorBootstrap;

public partial class BlazorBootstrapLayout : BlazorBootstrapLayoutComponentBase
{
#region Properties, Indexers

protected override string? ClassNames => BuildClassNames(Class, ("bb-page", true));

[Parameter] public RenderFragment? ContentSection { get; set; }
[Parameter] public string? ContentSectionCssClass { get; set; }
protected string? ContentSectionCssClassNames => BuildClassNames(ContentSectionCssClass, ("p-4", true));

[Parameter] public RenderFragment? FooterSection { get; set; }
[Parameter] public string? FooterSectionCssClass { get; set; } = "bg-body-tertiary";
protected string? FooterSectionCssClassNames => BuildClassNames(FooterSectionCssClass, ("bb-footer p-4", true));

[Parameter] public RenderFragment? HeaderSection { get; set; }
[Parameter] public string? HeaderSectionCssClass { get; set; } = "d-flex justify-content-end";
protected string? HeaderSectionCssClassNames => BuildClassNames(HeaderSectionCssClass, ("bb-top-row px-4", true));

[Parameter] public RenderFragment? SidebarSection { get; set; }

#endregion
}
Empty file.
24 changes: 24 additions & 0 deletions blazorbootstrap/Components/ThemeSwitcher/ThemeSwitcher.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@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>
28 changes: 28 additions & 0 deletions blazorbootstrap/Components/ThemeSwitcher/ThemeSwitcher.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace BlazorBootstrap;

public partial class ThemeSwitcher : BlazorBootstrapComponentBase
{
#region Methods

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

await base.OnAfterRenderAsync(firstRender);
}

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

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

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

#endregion

#region Properties, Indexers

[Inject] private ThemeSwitcherJsInterop ThemeSwitcherJsInterop { get; set; } = default!;

#endregion
}
Empty file.
Loading

0 comments on commit a9d1263

Please sign in to comment.