Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sidebar 2 component #605

Merged
merged 18 commits into from
Mar 9, 2024
Merged
Prev Previous commit
Next Next commit
Sidebar2 updates
gvreddy04 committed Mar 8, 2024
commit fdf1e9b8be6ba2e39401673c811b06b148f24e74
3 changes: 2 additions & 1 deletion blazorbootstrap/Components/Sidebar2/Sidebar2Item.razor
Original file line number Diff line number Diff line change
@@ -41,7 +41,8 @@
HasChilds="@childItem.HasChildItems"
ChildItems="@childItem.ChildItems"
Class="@childItem.Class"
Level="@childItem.Level" />
Level="@childItem.Level"
OnNavItemGroupExpanded="HandleNavItemGroupExpanded" />
}
}
</div>
68 changes: 19 additions & 49 deletions blazorbootstrap/Components/Sidebar2/Sidebar2Item.razor.cs
Original file line number Diff line number Diff line change
@@ -37,63 +37,26 @@ protected override void OnParametersSet()
return;

foreach (var childItem in ChildItems)
if (ShouldExpand(NavigationManager.Uri, childItem.Href!))
if (NavLinkExtensions.ShouldExpand(NavigationManager, childItem.Href!, Match))
{
navItemGroupExpanded = true;

Console.WriteLine($"{Text} - navItemGroupExpanded: {navItemGroupExpanded}");

// Only on after render
//if (Rendered && navItemGroupExpanded && OnNavItemGroupExpanded is not null)
if (navItemGroupExpanded && OnNavItemGroupExpanded is not null)
{
OnNavItemGroupExpanded?.Invoke(true);
}

return;
}
}

private void AutoHideNavMenu()
{
Parent.HideNavMenuOnMobile();
}

private bool EqualsHrefExactlyOrIfTrailingSlashAdded(string currentUriAbsolute, string hrefAbsolute)
{
if (string.Equals(currentUriAbsolute, hrefAbsolute, StringComparison.OrdinalIgnoreCase)) return true;

if (currentUriAbsolute.Length == hrefAbsolute.Length - 1)
// Special case: highlight links to http://host/path/ even if you're
// at http://host/path (with no trailing slash)
//
// This is because the router accepts an absolute URI value of "same
// as base URI but without trailing slash" as equivalent to "base URI",
// which in turn is because it's common for servers to return the same page
// for http://host/vdir as they do for host://host/vdir/ as it's no
// good to display a blank page in that case.
if (hrefAbsolute[^1] == '/'
&& hrefAbsolute.StartsWith(currentUriAbsolute, StringComparison.OrdinalIgnoreCase))
return true;

return false;
}

private static bool IsStrictlyPrefixWithSeparator(string value, string prefix)
{
var prefixLength = prefix.Length;

return value.Length > prefixLength
&& value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
&& (
// Only match when there's a separator character either at the end of the
// prefix or right after it.
// Example: "/abc" is treated as a prefix of "/abc/def" but not "/abcdef"
// Example: "/abc/" is treated as a prefix of "/abc/def" but not "/abcdef"
prefixLength == 0
|| !char.IsLetterOrDigit(prefix[prefixLength - 1])
|| !char.IsLetterOrDigit(value[prefixLength])
);
}

private bool ShouldExpand(string currentUriAbsolute, string href)
{
var hrefAbsolute = href == null ? null : NavigationManager.ToAbsoluteUri(href).AbsoluteUri;

return hrefAbsolute != null
&& (EqualsHrefExactlyOrIfTrailingSlashAdded(currentUriAbsolute, hrefAbsolute)
|| (Match == NavLinkMatch.Prefix && IsStrictlyPrefixWithSeparator(currentUriAbsolute, hrefAbsolute)));
Root.HideNavMenuOnMobile();
}

private void ToggleNavItemGroup() => navItemGroupExpanded = !navItemGroupExpanded;
@@ -131,13 +94,20 @@ private bool ShouldExpand(string currentUriAbsolute, string href)

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

[CascadingParameter] public Sidebar2 Parent { get; set; } = default!;
[CascadingParameter] public Sidebar2 Root { get; set; } = default!;

[Parameter] public Target Target { get; set; }

private string targetString => Target.ToTargetString()!;

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

[Parameter] public Action<bool> OnNavItemGroupExpanded { get; set; } = default!;

private void HandleNavItemGroupExpanded(bool expanded)
{
Console.WriteLine($"{Level}: {Text}");
}

#endregion
}
52 changes: 52 additions & 0 deletions blazorbootstrap/Extensions/NavLinkExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace BlazorBootstrap;

public static class NavLinkExtensions
{
private static bool EqualsHrefExactlyOrIfTrailingSlashAdded(string currentUriAbsolute, string hrefAbsolute)
{
if (string.Equals(currentUriAbsolute, hrefAbsolute, StringComparison.OrdinalIgnoreCase)) return true;

if (currentUriAbsolute.Length == hrefAbsolute.Length - 1)
// Special case: highlight links to http://host/path/ even if you're
// at http://host/path (with no trailing slash)
//
// This is because the router accepts an absolute URI value of "same
// as base URI but without trailing slash" as equivalent to "base URI",
// which in turn is because it's common for servers to return the same page
// for http://host/vdir as they do for host://host/vdir/ as it's no
// good to display a blank page in that case.
if (hrefAbsolute[^1] == '/'
&& hrefAbsolute.StartsWith(currentUriAbsolute, StringComparison.OrdinalIgnoreCase))
return true;

return false;
}

private static bool IsStrictlyPrefixWithSeparator(string value, string prefix)
{
var prefixLength = prefix.Length;

return value.Length > prefixLength
&& value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
&& (
// Only match when there's a separator character either at the end of the
// prefix or right after it.
// Example: "/abc" is treated as a prefix of "/abc/def" but not "/abcdef"
// Example: "/abc/" is treated as a prefix of "/abc/def" but not "/abcdef"
prefixLength == 0
|| !char.IsLetterOrDigit(prefix[prefixLength - 1])
|| !char.IsLetterOrDigit(value[prefixLength])
);
}

public static bool ShouldExpand(
NavigationManager navigationManager,
string href,
NavLinkMatch match)
{
var hrefAbsolute = href is null ? null : navigationManager.ToAbsoluteUri(href).AbsoluteUri;
return hrefAbsolute is not null
&& (EqualsHrefExactlyOrIfTrailingSlashAdded(navigationManager.Uri, hrefAbsolute)
|| (match == NavLinkMatch.Prefix && IsStrictlyPrefixWithSeparator(navigationManager.Uri, hrefAbsolute)));
}
}
9 changes: 0 additions & 9 deletions blazorbootstrap/Models/Sidebar2DataProviderRequest.cs
Original file line number Diff line number Diff line change
@@ -49,15 +49,6 @@ public Sidebar2DataProviderResult ApplyTo(IEnumerable<NavItem> data)
}
}

//Console.WriteLine($"{JsonSerializer.Serialize(result)}");

Console.WriteLine($"{result[2].Text}");
Console.WriteLine($"{result[2].HasChildItems}");
Console.WriteLine($"{result[2].ChildItems[2].Text}");
Console.WriteLine($"{result[2].ChildItems[2].HasChildItems}");
Console.WriteLine($"{result[2].ChildItems[2].ChildItems[0].Text}");
Console.WriteLine($"{result[2].ChildItems[2].ChildItems[0].HasChildItems}");

return new Sidebar2DataProviderResult { Data = result };
}