Add Navigation Menu Component

This commit is contained in:
copecone committed 2026-05-05 15:17:52 +09:00
1 parent 7363684b2f
commit 25a9bca291
7 files changed
+136 -3

No files matched your search

+1 -1
View File
@@ -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;
+11 -2
View File
@@ -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);
}
}
+1
View File
@@ -23,6 +23,7 @@
flex-direction: column;
gap: 16px;
padding-top: 4px;
padding-bottom: 12px;
}