Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading