sort of working drawer menu (wip)
This commit is contained in:
parent
6e520b0cd7
commit
bb5f51d8a8
@ -1,7 +1,17 @@
|
|||||||
<div class="drawer-container">
|
<div class="drawer-wrapper" [ngClass]="{'ready': viewInitialized, 'collapsed': isCollapsed()}">
|
||||||
<ng-content select="drawer-content"></ng-content>
|
<div class="drawer-container">
|
||||||
|
<ng-content select="drawer-content"></ng-content>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-content-container">
|
<div class="main-content-container">
|
||||||
|
<button class="menu-button secondary" (click)="handleMenuButton($event)">
|
||||||
|
<span class="material-symbols-outlined collapsed-icon" [ngClass]="{'active': isCollapsed()}">
|
||||||
|

|
||||||
|
</span>
|
||||||
|
<span class="material-symbols-outlined open-icon" [ngClass]="{'active': !isCollapsed()}">
|
||||||
|

|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
<div class="top-nav-container">
|
<div class="top-nav-container">
|
||||||
<ng-content select="top-nav-container"></ng-content>
|
<ng-content select="top-nav-container"></ng-content>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,28 +1,148 @@
|
|||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
--transition-duration: .3s;
|
||||||
|
--menu-trasition-duration: calc(var(--transition-duration) / 2);
|
||||||
|
|
||||||
|
.material-symbols-outlined.collapsed-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.material-symbols-outlined.open-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(.drawer-wrapper.collapsed) {
|
||||||
|
.material-symbols-outlined.collapsed-icon {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.material-symbols-outlined.open-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:has(.open-icon.active) {
|
||||||
|
|
||||||
|
// todo fix when closing drawer animation is missing because all these styles are gone
|
||||||
|
|
||||||
|
--menu-trasition-duration: .3s;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.drawer-wrapper {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
&.ready {
|
||||||
|
.drawer-container {
|
||||||
|
@starting-style {
|
||||||
|
width: 0;
|
||||||
|
display: block;
|
||||||
|
padding-inline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.drawer-container {
|
||||||
|
display: block;
|
||||||
|
z-index: 1000;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 250px;
|
||||||
|
height: 100dvh;
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
width var(--transition-duration) ease-in-out,
|
||||||
|
padding-inline var(--transition-duration) ease-in-out,
|
||||||
|
display var(--transition-duration) ease-in-out;
|
||||||
|
|
||||||
|
transition-behavior: allow-discrete;
|
||||||
|
}
|
||||||
|
.main-content-container {
|
||||||
|
.menu-button {
|
||||||
|
top: calc(5rem - 1rem);
|
||||||
|
left: calc(250px - 1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
width: 250px;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
transition:
|
||||||
|
width var(--transition-duration) ease-in-out,
|
||||||
|
display var(--transition-duration) ease-in-out;
|
||||||
|
|
||||||
|
transition-behavior: allow-discrete;
|
||||||
|
|
||||||
|
&.ready {
|
||||||
|
@starting-style {
|
||||||
|
width: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
width: 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.drawer-container {
|
.drawer-container {
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.main-content-container{
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1rem 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-container {
|
|
||||||
background-color: var(--neutral-70);
|
background-color: var(--neutral-70);
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content-container {
|
.main-content-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1rem 0 0 1rem;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.menu-button {
|
||||||
|
position: absolute;
|
||||||
|
padding: .3333333rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: 9999;
|
||||||
|
top: calc(5rem - 1rem);
|
||||||
|
left: -1rem;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
|
||||||
|
transition: top var(--menu-trasition-duration) ease-out, left var(--menu-trasition-duration) ease-out;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
top: calc(2.5rem - 1rem);
|
||||||
|
left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-symbols-outlined {
|
||||||
|
font-size: 1.3333333rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.top-nav-breadcrumb-container, .top-nav-container {
|
.top-nav-breadcrumb-container, .top-nav-container {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
@ -39,7 +159,6 @@
|
|||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,48 @@
|
|||||||
import { Component } from '@angular/core';
|
import {AfterViewInit, Component, inject, OnInit, signal} from '@angular/core';
|
||||||
import {RouterOutlet} from '@angular/router';
|
import {NavigationEnd, Router, RouterOutlet} from '@angular/router';
|
||||||
|
import {NgClass} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-drawer',
|
selector: 'app-drawer',
|
||||||
imports: [
|
imports: [
|
||||||
RouterOutlet
|
RouterOutlet,
|
||||||
|
NgClass
|
||||||
],
|
],
|
||||||
templateUrl: './drawer.component.html',
|
templateUrl: './drawer.component.html',
|
||||||
styleUrl: './drawer.component.scss'
|
styleUrl: './drawer.component.scss'
|
||||||
})
|
})
|
||||||
export class DrawerComponent {
|
export class DrawerComponent implements AfterViewInit, OnInit {
|
||||||
|
|
||||||
|
protected viewInitialized = false;
|
||||||
|
protected isCollapsed = signal<boolean>(true);
|
||||||
|
private router = inject(Router);
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.router.events.subscribe((event) => {
|
||||||
|
if (!this.isDesktop() && !this.isCollapsed() && event instanceof NavigationEnd) {
|
||||||
|
this.isCollapsed.set(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (this.isDesktop()) {
|
||||||
|
this.isCollapsed.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.viewInitialized = true;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMenuButton(_: PointerEvent) {
|
||||||
|
this.isCollapsed.update(x => !x);
|
||||||
|
}
|
||||||
|
|
||||||
|
private isDesktop(): boolean {
|
||||||
|
return window.innerWidth > 768
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,17 @@
|
|||||||
.title {
|
.title {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
transition: margin-left var(--menu-trasition-duration) ease-out;
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
margin-left: 3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
app-nav-profile {
|
app-nav-profile {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@ -21,9 +32,14 @@
|
|||||||
.logo {
|
.logo {
|
||||||
$height: 3rem;
|
$height: 3rem;
|
||||||
height: $height;
|
height: $height;
|
||||||
width: #{$height * 3.356876171875};
|
width: 100%;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: 1rem;
|
||||||
border-bottom: 1px solid var(--neutral-60);
|
border-bottom: 1px solid var(--neutral-60);
|
||||||
|
|
||||||
|
& ::ng-deep .icon {
|
||||||
|
height: $height;
|
||||||
|
width: #{$height * 3.356876171875};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-links {
|
.nav-links {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user