Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
<AuthorizeView>
<Authorized>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown"
<a class="nav-link dropdown-toggle" href="#" id="adminDropdown" role="button" data-bs-toggle="dropdown"
aria-expanded="false">
<i class="user-tie"></i> Admin
<i class="user-tie"></i> <span class="nav-label">Admin</span>
</a>
<ul class="dropdown-menu ps-0" aria-labelledby="navbarDropdown">
<ul class="dropdown-menu ps-0" aria-labelledby="adminDropdown">
<li><h6 class="dropdown-header">Blog posts</h6></li>
<li><a class="dropdown-item" href="create">Create new</a></li>
<li><a class="dropdown-item" href="draft">Show drafts</a></li>
Expand All @@ -27,21 +27,21 @@
@if (authorName is not null)
{
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="user-tie"></i> @authorName
<a class="nav-link dropdown-toggle" href="#" id="authorDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="user-tie"></i> <span class="nav-label">@authorName</span>
</a>
<ul class="dropdown-menu ps-0" aria-labelledby="navbarDropdown">
<li><a class="nav-link" href="logout?redirectUri=@CurrentUri"><i class="lock"></i> Log out</a></li>
<ul class="dropdown-menu ps-0" aria-labelledby="authorDropdown">
<li><a class="dropdown-item" href="logout?redirectUri=@CurrentUri"><i class="lock"></i> Log out</a></li>
</ul>
</li>
}
else
{
<li class="nav-item"><a class="nav-link" href="/logout?redirectUri=@CurrentUri"><i class="lock"></i> Log out</a></li>
<li class="nav-item"><a class="nav-link" href="/logout?redirectUri=@CurrentUri"><i class="lock"></i> <span class="nav-label">Log out</span></a></li>
}
</Authorized>
<NotAuthorized>
<li class="nav-item"><a class="nav-link" href="/login?redirectUri=@CurrentUri" rel="nofollow"><i class="unlocked"></i> Log in</a></li>
<li class="nav-item"><a class="nav-link" href="/login?redirectUri=@CurrentUri" rel="nofollow"><i class="unlocked"></i> <span class="nav-label">Log in</span></a></li>
</NotAuthorized>
</AuthorizeView>

Expand Down
65 changes: 48 additions & 17 deletions src/LinkDotNet.Blog.Web/Features/Home/Components/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
@inject NavigationManager NavigationManager
@implements IDisposable

<nav class="navbar navbar-expand-lg navbar-light w-100">
<nav class="navbar navbar-expand-lg w-100">
<div class="container-fluid">
@if (!string.IsNullOrEmpty(Configuration.Value.BlogBrandUrl))
{
Expand All @@ -19,20 +19,26 @@
{
<a class="nav-brand barcode ms-5" href="/">@Configuration.Value.BlogName</a>
}
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-top-actions d-flex align-items-center d-lg-none ms-auto">
<button type="button" class="nav-icon-button" @onclick="ToggleSearchOverlay"
title="Search" aria-label="Search">
<i class="search"></i>
</button>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 me-5 column-gap-4">
<li><a class="nav-link" href="/"><i class="home"></i> Home</a></li>
<li><a class="nav-link" href="/archive"><i class="books"></i> Archive</a></li>
<li><a class="nav-link" href="/bookmarks"><i class="bookmark"></i> Bookmarks</a>
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="/"><i class="home"></i> <span class="nav-label">Home</span></a></li>
<li class="nav-item"><a class="nav-link" href="/archive"><i class="books"></i> <span class="nav-label">Archive</span></a></li>
<li class="nav-item"><a class="nav-link" href="/bookmarks"><i class="bookmark"></i> <span class="nav-label">Bookmarks</span></a>
</li>
@if (Configuration.Value.IsAboutMeEnabled)
{
<li class="nav-item">
<a class="nav-link" href="AboutMe">
<i class="profile"></i> About me
<i class="profile"></i> <span class="nav-label">About me</span>
</a>
</li>
}
Expand All @@ -41,14 +47,14 @@
{
<li class="nav-item">
<a class="nav-link" href="SupportMe">
<i class="coin-dollar"></i> Support me
<i class="coin-dollar"></i> <span class="nav-label">Support me</span>
</a>
</li>
}

<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="rssDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="RSS Selector">
<i class="rss2"></i> RSS
<i class="rss2"></i> <span class="nav-label">RSS</span>
</a>
<ul class="dropdown-menu" aria-labelledby="rssDropdown">
<li><a class="dropdown-item" href="/feed.rss" target="_blank" aria-label="RSS with All Posts">All Posts (Summary)</a></li>
Expand All @@ -57,31 +63,45 @@
</li>

<AccessControl CurrentUri="@currentUri"></AccessControl>
</ul>

@* On mobile the utilities strip only earns a divider when it holds more
than the lone theme toggle - otherwise it is a single orphaned icon. *@
<hr class="dropdown-divider my-2 @(Configuration.Value.EnableTagDiscoveryPanel ? "d-lg-none" : "d-none")">

<ul class="navbar-nav navbar-utilities mb-2 mb-lg-0 me-5 @(Configuration.Value.EnableTagDiscoveryPanel ? "navbar-utilities--strip" : "")">
<li class="nav-item d-flex align-items-center"><ThemeToggler Class="nav-link"></ThemeToggler></li>

@if (Configuration.Value.EnableTagDiscoveryPanel)
{
<li class="nav-item d-flex align-items-center me-lg-2 mb-2 mb-lg-0">
<a class="nav-link d-flex align-items-center justify-content-center" @onclick="ToggleTagDiscoveryPanel"
style="font-family: 'icons'; font-weight: 900; cursor: pointer;"
title="Discover new topics"> &#xE936; </a>
<button type="button" class="nav-icon-button" @onclick="ToggleTagDiscoveryPanel"
title="Discover new topics" aria-label="Discover new topics">
<i class="price-tags"></i>
</button>
</li>
}

<li class="d-flex">
<SearchInput SearchEntered="NavigateToSearchPage"></SearchInput>
</li>
@if (!_isSearchOpen)
{
<li class="d-none d-lg-flex">
<SearchInput SearchEntered="NavigateToSearchPage"></SearchInput>
</li>
}
</ul>
</div>
</div>
</nav>
<TagDiscoveryPanel IsOpen="@_isOpen" OnClose="CloseTagDiscoveryPanel" />
<SearchOverlay IsOpen="@_isSearchOpen" OnClose="CloseSearchOverlay" SearchEntered="NavigateToSearchPage" />

@code {
private string currentUri = string.Empty;

private bool _isOpen;

private bool _isSearchOpen;

protected override void OnInitialized()
{
NavigationManager.LocationChanged += UpdateUri;
Expand All @@ -90,6 +110,7 @@

private void NavigateToSearchPage(string searchTerm)
{
_isSearchOpen = false;
var escapeDataString = Uri.EscapeDataString(searchTerm);
NavigationManager.NavigateTo($"search/{escapeDataString}");
}
Expand All @@ -114,4 +135,14 @@
{
_isOpen = false;
}

private void ToggleSearchOverlay()
{
_isSearchOpen = !_isSearchOpen;
}

private void CloseSearchOverlay()
{
_isSearchOpen = false;
}
}
18 changes: 13 additions & 5 deletions src/LinkDotNet.Blog.Web/Features/Home/Components/SearchInput.razor
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
<div class="search-bar">
<input type="text" class="search-bar-input" placeholder="search" aria-label="search" spellcheck="true" @bind-value="searchTerm"
@onkeyup="@CheckForEnter" title="Search for blog post via title or tags"/>
<button class="search-bar-button" aria-label="search submit" @onclick="CallSearchEntered"><i class="search"></i></button>
<div class="search-bar-slot @(FullWidth ? "search-bar-slot--full" : "")">
<div class="search-bar @(FullWidth ? "search-bar--full" : "")">
<input @ref="_inputRef" type="text" class="search-bar-input" placeholder="search" aria-label="search" @bind-value="searchTerm"
@onkeyup="@CheckForEnter" title="Search for blog post via title or tags"/>
<button class="search-bar-button" aria-label="search submit" @onclick="CallSearchEntered"><i class="search"></i></button>
</div>
</div>


@code {
private string searchTerm = string.Empty;
private ElementReference _inputRef;

[Parameter]
public EventCallback<string> SearchEntered { get; set; }

[Parameter]
public bool FullWidth { get; set; }

public async Task FocusAsync() => await _inputRef.FocusAsync();

private async Task CallSearchEntered()
{
if (string.IsNullOrWhiteSpace(searchTerm))
Expand All @@ -26,7 +34,7 @@
{
if (e.Code is "Enter" or "NumpadEnter")
{
await SearchEntered.InvokeAsync(searchTerm);
await CallSearchEntered();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@using Microsoft.AspNetCore.Components.Web;

@if (IsOpen)
{
<div class="position-fixed top-0 start-0 w-100 h-100 bg-dark bg-opacity-25"
style="z-index:1040; backdrop-filter: blur(2px);"
@onclick="Close">
</div>

<div class="position-fixed top-0 start-0 w-100 d-flex justify-content-center"
style="z-index:1050; pointer-events:none; padding-top: 15vh;">

<div class="bg-body border rounded shadow p-3 w-100"
style="max-width: 500px; margin: 0 1rem; pointer-events:auto;"
@onkeydown="HandleKeyDown">

<SearchInput @ref="_searchInput" FullWidth="true" SearchEntered="OnSearchEntered"></SearchInput>
</div>
</div>
}

@code {
[Parameter] public bool IsOpen { get; set; }
[Parameter] public EventCallback OnClose { get; set; }
[Parameter] public EventCallback<string> SearchEntered { get; set; }

private SearchInput? _searchInput;
private bool _shouldFocus;

protected override void OnParametersSet()
{
if (IsOpen)
{
_shouldFocus = true;
}
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (IsOpen && _shouldFocus && _searchInput is not null)
{
_shouldFocus = false;
await _searchInput.FocusAsync();
}
}

private async Task OnSearchEntered(string searchTerm)
{
await SearchEntered.InvokeAsync(searchTerm);
}

private async Task Close()
{
await OnClose.InvokeAsync();
}

private async Task HandleKeyDown(KeyboardEventArgs e)
{
if (e.Key == "Escape")
{
await Close();
}
}
}
Loading