style(navigation): implement basic navigation bar

This commit is contained in:
2025-08-21 04:03:53 +02:00
parent ebb45d2ea0
commit 3406450eba
16 changed files with 2319 additions and 262 deletions

View File

@@ -0,0 +1,73 @@
<nav class="sticky top-0 p-[30px] flex flex-row justify-between relative z-5000">
<div class="logo grid place-items-center">
<span class="font-semibold text-3xl">BH</span>
</div>
<div class="navigation grid place-items-center">
@if (themeSwitchService.darkMode()) {
<ul class="relative hidden items-center space-x-1 rounded-full border border-black/10 bg-black/5 px-1.5 py-1 backdrop-blur-md md:flex border-white/10 bg-white/10">
<li class="relative list-none">
<a class="block px-4 py-1.5 text-sm font-light text-black transition hover:text-black/80 text-white/70 hover:text-white" routerLink="/">
Home
</a>
@if (isActive('/')) {
<ng-container *ngTemplateOutlet="activeNavItem"/>
}
</li>
<li class="relative list-none">
<a class="block px-4 py-1.5 text-sm font-light text-black transition hover:text-black/80 text-white/70 hover:text-white" routerLink="/about">
About
</a>
@if (isActive('/about')) {
<ng-container *ngTemplateOutlet="activeNavItem"/>
}
</li>
</ul>
<ng-template #activeNavItem>
<span class="bg-white/5 absolute inset-0 -z-5000 w-full rounded-full">
<div class="bg-white absolute -top-[9px] left-1/2 h-1 w-8 -translate-x-1/2 rounded-t-full">
<div class="bg-white/20 absolute -top-2 -left-2 h-6 w-12 rounded-full blur-md"></div>
<div class="bg-white/20 absolute -top-1 h-6 w-8 rounded-full blur-md"></div>
<div class="bg-white/20 absolute top-0 left-2 h-4 w-4 rounded-full blur-sm"></div>
</div>
</span>
</ng-template>
} @else {
<ul class="relative hidden items-center space-x-1 rounded-full border border-black/10 bg-black/5 px-1.5 py-1 backdrop-blur-md md:flex">
<li class="relative list-none">
<a class="block px-4 py-1.5 text-sm font-light text-black transition hover:text-black/80" routerLink="/">
Home
</a>
@if (isActive('/')) {
<ng-container *ngTemplateOutlet="activeNavItem"/>
}
</li>
<li class="relative list-none">
<a class="block px-4 py-1.5 text-sm font-light text-black transition hover:text-black/80" routerLink="/about">
About
</a>
@if (isActive('/about')) {
<ng-container *ngTemplateOutlet="activeNavItem"/>
}
</li>
</ul>
<ng-template #activeNavItem>
<span class="bg-black/5 absolute inset-0 -z-5000 w-full rounded-full">
<div class="bg-black absolute -top-[9px] left-1/2 h-1 w-8 -translate-x-1/2 rounded-t-full">
<div class="bg-black/20 absolute -top-2 -left-2 h-6 w-12 rounded-full blur-md"></div>
<div class="bg-black/20 absolute -top-1 h-6 w-8 rounded-full blur-md"></div>
<div class="bg-black/20 absolute top-0 left-2 h-4 w-4 rounded-full blur-sm"></div>
</div>
</span>
</ng-template>
}
</div>
<div class="options flex flex-row gap-[10px]">
<div class="dark-mode size-[50px]">
<fa-icon [icon]="faMoon"/>
</div>
<div class="language size-[50px]">EN</div>
</div>
</nav>
<div class="blur blur1"></div>
<div class="blur blur2"></div>

View File

@@ -0,0 +1,41 @@
nav {
.options > div {
display: grid;
place-items: center;
cursor: pointer;
border-radius: 50%;
border: 1px solid transparent;
transition: border .5s ease;
&:hover {
border-color: var(--surface-100);
}
&:active {
border-color: var(--surface-500);
}
}
}
.blur {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 120px;
pointer-events: none;
}
.blur1 {
z-index: 10;
backdrop-filter: blur(3px);
mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 1) 70%, rgba(0, 0, 0, 0) 100%);
-webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 1) 70%, rgba(0, 0, 0, 0) 100%);
}
.blur2 {
z-index: 20;
backdrop-filter: blur(5px);
mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 1) 85%, rgba(0, 0, 0, 1) 100%);
-webkit-mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 1) 85%, rgba(0, 0, 0, 1) 100%);
}

View File

@@ -0,0 +1,29 @@
import { NgTemplateOutlet } from '@angular/common';
import { Component } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { faMoon } from '@fortawesome/free-solid-svg-icons';
import { faSun } from '@fortawesome/free-solid-svg-icons';
import { ThemeSwitchService } from '../../service/theme-switch.service';
@Component({
selector: 'app-navigation-bar',
imports: [FontAwesomeModule, RouterLink, NgTemplateOutlet ],
templateUrl: './navigation-bar.html',
styleUrl: './navigation-bar.scss'
})
export class NavigationBar {
constructor(
private router: Router,
protected themeSwitchService: ThemeSwitchService,
) {}
isActive(route: string): boolean {
return this.router.url === route;
}
faMoon = faMoon;
faSun = faSun;
}

View File

@@ -1,4 +1,4 @@
import {effect, Injectable, signal, WritableSignal} from '@angular/core';
import {computed, effect, Injectable, signal, WritableSignal} from '@angular/core';
import {Theme} from "../models/theme";
@Injectable({
@@ -8,6 +8,9 @@ export class ThemeSwitchService {
private readonly THEME_KEY = 'app-theme-mode';
public theme: WritableSignal<Theme> = signal(Theme.DEFAULT_THEME);
public darkMode = computed(() => {
return this.theme().code === 'dark' || (this.theme().code === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
});
constructor() {
effect(() => {
@@ -49,8 +52,4 @@ export class ThemeSwitchService {
console.info(`switching to theme: ${theme.name}`);
this.theme.set(theme);
}
isDarkMode(): boolean {
return this.theme().code === 'dark' || (this.theme().code === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
}
}