diff --git a/Blazor_Server/Components/App.razor b/Blazor_Server/Components/App.razor
index 75ad4bb..7f7654a 100644
--- a/Blazor_Server/Components/App.razor
+++ b/Blazor_Server/Components/App.razor
@@ -8,12 +8,24 @@
+
-
-
- An unhandled error has occurred.
-
Reload
-
🗙
-
\ No newline at end of file
+@code
+{
+ private bool IconMenuActive { get; set; } = false;
+ private string? IconMenuCssClass => IconMenuActive ? "width: 80px;" : null;
+
+ protected void ToggleIconMenu(bool iconMenuActive)
+ {
+ IconMenuActive = iconMenuActive;
+ }
+}
\ No newline at end of file
diff --git a/Blazor_Server/Components/Layout/NavMenu.razor b/Blazor_Server/Components/Layout/NavMenu.razor
index 122b9de..2226d0f 100644
--- a/Blazor_Server/Components/Layout/NavMenu.razor
+++ b/Blazor_Server/Components/Layout/NavMenu.razor
@@ -1,29 +1,184 @@
-
+@inject IJSRuntime JSRuntime
+
+
-
-
-
+
\ No newline at end of file
+
+
+
+
+
+
+@code
+{
+ [Parameter]
+ public EventCallback
ShowIconMenu { get; set; }
+
+ private bool IconMenuActive { get; set; } = false;
+ private bool collapseNavMenu = true;
+ private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
+ private Dictionary subMenuStates = new Dictionary();
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ await JSRuntime.InvokeVoidAsync("setResizeCallback", DotNetObjectReference.Create(this));
+ }
+ }
+
+ [JSInvokable]
+ public async Task OnResize(bool isBelowThreshold)
+ {
+ if (isBelowThreshold && IconMenuActive)
+ {
+ collapseNavMenu = true;
+ await ToggleIconMenu();
+
+ await ShowIconMenu.InvokeAsync(IconMenuActive);
+
+ await InvokeAsync(StateHasChanged);
+ }
+ }
+
+ private void ToggleNavMenu()
+ {
+ collapseNavMenu = !collapseNavMenu;
+ }
+
+ private async Task ToggleIconMenu()
+ {
+ IconMenuActive = !IconMenuActive;
+
+ await ShowIconMenu.InvokeAsync(IconMenuActive);
+ }
+
+ private void ToggleSubMenu(string subMenuKey)
+ {
+ if (subMenuStates.ContainsKey(subMenuKey) && subMenuStates[subMenuKey])
+ {
+ subMenuStates[subMenuKey] = false;
+ }
+ else
+ {
+ foreach (var key in subMenuStates.Keys.ToList())
+ {
+ subMenuStates[key] = false;
+ }
+
+ if (subMenuStates.ContainsKey(subMenuKey))
+ {
+ subMenuStates[subMenuKey] = !subMenuStates[subMenuKey];
+ }
+ else
+ {
+ subMenuStates[subMenuKey] = true;
+ }
+ }
+ }
+
+ private bool IsSubMenuOpen(string subMenuKey)
+ {
+ return subMenuStates.ContainsKey(subMenuKey) && subMenuStates[subMenuKey];
+ }
+}
\ No newline at end of file
diff --git a/Blazor_Server/Components/Layout/NavMenu.razor.css b/Blazor_Server/Components/Layout/NavMenu.razor.css
index c838327..061beb5 100644
--- a/Blazor_Server/Components/Layout/NavMenu.razor.css
+++ b/Blazor_Server/Components/Layout/NavMenu.razor.css
@@ -1,49 +1,34 @@
.navbar-toggler {
- appearance: none;
- cursor: pointer;
- width: 3.5rem;
- height: 2.5rem;
- color: white;
- position: absolute;
- top: 0.5rem;
- right: 1rem;
- border: 1px solid rgba(255, 255, 255, 0.1);
- background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
-}
-
-.navbar-toggler:checked {
- background-color: rgba(255, 255, 255, 0.5);
+ background-color: rgba(255, 255, 255, 0.1);
}
.top-row {
height: 3.5rem;
- background-color: rgba(0,0,0,0.4);
+ background-color: rgba(0, 0, 0, 0.4);
+}
+
+.bottom-row {
+ position: absolute;
+ bottom: 0;
+ padding-bottom: 10px;
+ text-align: right;
+ width: 100%;
+ padding-right: 28px;
+}
+
+.icon-menu-arrow {
+ text-align: right;
}
.navbar-brand {
font-size: 1.1rem;
}
-.bi {
- display: inline-block;
- position: relative;
- width: 1.25rem;
- height: 1.25rem;
- margin-right: 0.75rem;
- top: -1px;
- background-size: cover;
-}
-
-.bi-house-door-fill-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
-}
-
-.bi-plus-square-fill-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
-}
-
-.bi-list-nested-nav-menu {
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
+.oi {
+ width: 2rem;
+ font-size: 1.1rem;
+ vertical-align: text-top;
+ top: -2px;
}
.nav-item {
@@ -59,47 +44,40 @@
padding-bottom: 1rem;
}
- .nav-item ::deep .nav-link {
+ .nav-item ::deep a {
color: #d7d7d7;
- background: none;
- border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
- width: 100%;
}
-.nav-item ::deep a.active {
- background-color: rgba(255,255,255,0.37);
- color: white;
-}
+ .nav-item ::deep a.active {
+ background-color: rgba(255, 255, 255, 0.25);
+ color: white;
+ }
-.nav-item ::deep .nav-link:hover {
- background-color: rgba(255,255,255,0.1);
- color: white;
-}
-
-.nav-scrollable {
- display: none;
-}
-
-.navbar-toggler:checked ~ .nav-scrollable {
- display: block;
-}
+ .nav-item ::deep a:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ color: white;
+ }
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
- .nav-scrollable {
- /* Never collapse the sidebar for wide screens */
+ .collapse {
display: block;
-
- /* Allow sidebar to scroll for tall menus */
- height: calc(100vh - 3.5rem);
- overflow-y: auto;
}
+}
+
+.nav-item label,
+.sub-menu label {
+ margin-left: 8px;
+}
+
+.nav-item .chevron-icon {
+ padding-left: 8px;
}
\ No newline at end of file