Add Navigation Menu Component
This commit is contained in:
1 parent
7363684b2f
commit
25a9bca291
7 files changed
+136
-3
No files matched your search
@@ -37,7 +37,7 @@ $default_animation_duration: 0.2s;
|
||||
animation: popup-enter var(--animation-duration) $animation_timing;
|
||||
|
||||
outline: light-dark(oklch(0 0 0 / 20%), oklch(1 0 0 / 20%)) 2px solid;
|
||||
gap: 16px;
|
||||
gap: 12px;
|
||||
|
||||
&.variant-glass {
|
||||
background-color: light-dark(oklch(1 0 0 / 60%), oklch(0 0 0 / 60%));
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
|
||||
&.nav-link {
|
||||
font-weight: 700;
|
||||
|
||||
@@ -2,17 +2,18 @@ import {
|
||||
afterNextRender,
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
effect,
|
||||
ElementRef,
|
||||
inject,
|
||||
NgZone,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
signal,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { PopupService } from '../../services/popup.service';
|
||||
import { SettingsPopup } from '../settings/settings';
|
||||
import { NavigationMenu } from './navigation-menu';
|
||||
import { TranslationService } from '../../services/translation.service';
|
||||
import { SettingsService } from '../../services/settings.service';
|
||||
|
||||
@@ -57,6 +58,12 @@ export class HeaderMenu implements OnDestroy {
|
||||
private element: ElementRef,
|
||||
private ngZone: NgZone,
|
||||
) {
|
||||
effect(() => {
|
||||
if (this.expandStage() > 0) {
|
||||
this.popupService.close(NavigationMenu);
|
||||
}
|
||||
});
|
||||
|
||||
afterNextRender(() => {
|
||||
this.ngZone.runOutsideAngular(() => {
|
||||
this.resizeObserver = new ResizeObserver((entries) => {
|
||||
@@ -147,7 +154,9 @@ export class HeaderMenu implements OnDestroy {
|
||||
}
|
||||
|
||||
onHamburgerClick(): void {
|
||||
|
||||
this.popupService.open(NavigationMenu, {
|
||||
position: { top: '84px', right: '20px' },
|
||||
});
|
||||
}
|
||||
|
||||
onSettingsClick() {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<app-popup [position]="position()" (closeRequest)="close()">
|
||||
<div header-left class="menu-header-title">
|
||||
<span class="material-symbols-outlined">menu</span>
|
||||
<span>{{ translation.menu.menu }}</span>
|
||||
</div>
|
||||
|
||||
<div class="menu-content">
|
||||
<div class="menu-section">
|
||||
<a class="menu-item nav-link" [routerLink]="['/levels']" (click)="close()">{{ translation.menu.levels }}</a>
|
||||
<span class="menu-item dummy-link">{{ translation.menu.community }}</span>
|
||||
<span class="menu-item dummy-link">{{ translation.menu.leaderboard }}</span>
|
||||
<span class="menu-item dummy-link">{{ translation.menu.about }}</span>
|
||||
</div>
|
||||
|
||||
<hr class="menu-divider" />
|
||||
|
||||
<div class="menu-section">
|
||||
<a class="menu-item nav-link" [routerLink]="['/known-issues']" (click)="close()">{{ translation.menu.knownIssues }}</a>
|
||||
<span class="menu-item dummy-link"><strong>{{ translation.menu.login }}</strong></span>
|
||||
<span class="menu-item dummy-link">{{ translation.menu.signup }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</app-popup>
|
||||
@@ -0,0 +1,73 @@
|
||||
:host {
|
||||
display: block;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.menu-header-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 18px;
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 276px;
|
||||
padding-bottom: 12px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.menu-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.menu-divider {
|
||||
height: 1px;
|
||||
border: none;
|
||||
background-color: light-dark(oklch(0 0 0 / 20%), oklch(1 0 0 / 20%));
|
||||
margin: 0 6px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
height: 40px;
|
||||
padding-left: 12px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
transition: background-color 0.2s;
|
||||
border-radius: 4px;
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-size: 24px;
|
||||
color: light-dark(oklch(0.4 0 0), oklch(0.8 0 0));
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&.nav-link {
|
||||
font-weight: 700;
|
||||
color: oklch(0.6 0.15 250);
|
||||
transition: opacity 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
&.dummy-link {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Component, inject, input } from '@angular/core';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { PopupComponent, PopupPosition } from '../../components/popup/popup';
|
||||
import { PopupService } from '../../services/popup.service';
|
||||
import { TranslationService } from '../../services/translation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'navigation-menu',
|
||||
standalone: true,
|
||||
imports: [PopupComponent, RouterLink],
|
||||
templateUrl: './navigation-menu.html',
|
||||
styleUrl: './navigation-menu.scss',
|
||||
})
|
||||
export class NavigationMenu {
|
||||
private popupService = inject(PopupService);
|
||||
protected translation = inject(TranslationService).translation;
|
||||
|
||||
/**
|
||||
* 팝업의 위치
|
||||
*/
|
||||
position = input<PopupPosition | 'center'>('center');
|
||||
|
||||
close() {
|
||||
this.popupService.close(NavigationMenu);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
padding-top: 4px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user