init
This commit is contained in:
@@ -1,66 +1,152 @@
|
||||
/* Verschieben Sie alle .sidebar... und .nav-item... Klassen aus styles.css hierher */
|
||||
/* Globale Variablen für einfachere Wartung */
|
||||
:host {
|
||||
display: block;
|
||||
--sidebar-width-expanded: 280px;
|
||||
--sidebar-width-collapsed: 96px;
|
||||
--sidebar-padding: 1rem;
|
||||
--sidebar-margin: 1rem;
|
||||
--transition-speed: 0.3s;
|
||||
--transition-ease: ease-in-out;
|
||||
}
|
||||
|
||||
/* 1. Der Sidebar-Container */
|
||||
.sidebar {
|
||||
width: 260px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.5rem;
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: var(--glass-backdrop-filter);
|
||||
-webkit-backdrop-filter: var(--glass-backdrop-filter);
|
||||
border-right: 1px solid var(--color-border);
|
||||
transition: background-color var(--transition-speed),
|
||||
border-color var(--transition-speed);
|
||||
gap: 2rem;
|
||||
width: var(--sidebar-width-expanded);
|
||||
height: calc(100vh - (var(--sidebar-margin) * 2));
|
||||
margin: var(--sidebar-margin);
|
||||
padding: var(--sidebar-padding);
|
||||
background-color: #fff;
|
||||
border: 1px solid #e5e7eb; /* Helle Umrandung */
|
||||
border-radius: 1rem;
|
||||
transition: width var(--transition-speed) var(--transition-ease);
|
||||
}
|
||||
|
||||
/* 2. Der Header-Bereich */
|
||||
.sidebar-header {
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem; /* Abstand zwischen Logo und Titel */
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.sidebar-logo {
|
||||
flex-shrink: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 900;
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
transition: opacity 0.2s ease-in-out,
|
||||
width 0.3s ease-in-out 0.05s,
|
||||
transform 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
/* ======================================================= */
|
||||
/* --- HIER PASSIERT DIE MAGIE FÜR DEN BUTTON --- */
|
||||
/* ======================================================= */
|
||||
.sidebar-header app-button {
|
||||
/* Weist den Button an, den gesamten verfügbaren Platz als linken Abstand zu nutzen */
|
||||
margin-left: auto;
|
||||
|
||||
/* Verhindert, dass der Button schrumpft */
|
||||
flex-shrink: 0;
|
||||
|
||||
/* Fügt eine sanfte Drehanimation hinzu */
|
||||
transition: transform var(--transition-speed) var(--transition-ease);
|
||||
transform: rotate(0deg); /* Startposition der Animation */
|
||||
}
|
||||
|
||||
/* 3. Die Navigation (angepasst an das neue Design) */
|
||||
.sidebar-nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.sidebar-footer {
|
||||
margin-top: auto;
|
||||
flex-grow: 1; /* Nimmt den restlichen vertikalen Platz ein */
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: var(--border-radius-md);
|
||||
color: var(--color-text-light);
|
||||
font-weight: 500;
|
||||
border-radius: 0.5rem;
|
||||
text-decoration: none;
|
||||
transition: all var(--transition-speed);
|
||||
}
|
||||
.nav-item app-icon {
|
||||
font-size: 20px; /* Steuert die Größe des Icons */
|
||||
transition: color var(--transition-speed);
|
||||
font-weight: 500;
|
||||
color: #4b5563;
|
||||
white-space: nowrap;
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
color: var(--color-text);
|
||||
}
|
||||
:host-context(body.dark-theme) .nav-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: #f3f4f6;
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: var(--color-primary-gradient);
|
||||
background-color: #3b82f6;
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 10px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
.nav-item.active app-icon {
|
||||
color: #fff;
|
||||
|
||||
.nav-item app-icon {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
margin-top: auto; /* Schiebt den Footer nach unten */
|
||||
}
|
||||
|
||||
/* ======================================================= */
|
||||
/* --- Stile für den eingeklappten Zustand (.collapsed) --- */
|
||||
/* ======================================================= */
|
||||
|
||||
.sidebar.collapsed {
|
||||
width: var(--sidebar-width-collapsed);
|
||||
}
|
||||
|
||||
.sidebar.collapsed .sidebar-header {
|
||||
justify-content: center; /* Zentriert das Logo, wenn der Titel weg ist */
|
||||
}
|
||||
|
||||
.sidebar.collapsed .sidebar-title {
|
||||
opacity: 0;
|
||||
width: 0; /* Wichtig: expliziter Endwert für die Breiten-Animation */
|
||||
transform: translateX(-10px); /* Leichte Bewegung nach links */
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Dreht den Button um 180 Grad, wenn die Sidebar eingeklappt ist */
|
||||
.sidebar.collapsed .sidebar-header app-button {
|
||||
transform: rotate(180deg);
|
||||
margin-left: 0; /* Setzt den Margin zurück, da 'justify-content' jetzt die Positionierung übernimmt */
|
||||
}
|
||||
|
||||
.sidebar.collapsed .nav-item {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-item span {
|
||||
white-space: nowrap;
|
||||
opacity: 1;
|
||||
|
||||
/* === NEU: Präzise Transition auch hier === */
|
||||
overflow: hidden;
|
||||
transition: opacity 0.2s ease-in-out,
|
||||
width 0.3s ease-in-out 0.05s;
|
||||
}
|
||||
|
||||
|
||||
.sidebar.collapsed .nav-item span {
|
||||
opacity: 0;
|
||||
width: 0; /* Wichtig: expliziter Endwert für die Breiten-Animation */
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -1,13 +1,33 @@
|
||||
<aside class="sidebar">
|
||||
<aside class="sidebar" [class.collapsed]="isCollapsed">
|
||||
<div class="sidebar-header">
|
||||
<h1 class="sidebar-title">CustomDash</h1>
|
||||
<div class="sidebar-logo">
|
||||
<!-- Ersetzen Sie dies durch Ihr Logo, z.B. als <img> oder <svg> -->
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
d="M24 8C19.2 8 15.2 9.4 12 11.8C15.4 12.8 18.3 15.6 19.4 19C20.6 18.6 21.8 18.4 23 18.4C24.4 18.4 25.6 18.6 26.8 19C27.9 15.6 30.8 12.8 34.2 11.8C31 9.4 27.2 8 24 8ZM11.8 12.2C8.6 14.6 6 18.2 4.6 22.4C7.8 22.8 10.6 24.6 12.4 27.2C11.4 25.4 10.8 23.2 10.6 21C9.4 17.6 10 14.4 11.8 12.2ZM36.2 12.2C38 14.4 38.6 17.6 37.4 21C37.2 23.2 36.6 25.4 35.6 27.2C37.4 24.6 40.2 22.8 43.4 22.4C42 18.2 39.4 14.6 36.2 12.2ZM4.2 24C4 25.2 4 26.4 4 27.8C4 32.8 6 37.4 9.4 40.6C10.2 37.6 12 35 14.4 33C12 30.8 10.2 28.2 9.2 25.4C7.2 25.2 5.4 24.6 4.2 24ZM20.8 27.8C18.4 29.8 16.6 32.4 15.4 35.4C17.6 38.2 20.6 40 24 40C27.4 40 30.4 38.2 32.6 35.4C31.4 32.4 29.6 29.8 27.2 27.8C25.6 29 24.2 29.2 23.2 29.2C22.4 29.2 21.4 29 20.8 27.8ZM38.8 25.4C37.8 28.2 36 30.8 33.6 33C36 35 37.8 37.6 38.6 40.6C42 37.4 44 32.8 44 27.8C44 26.4 44 25.2 43.8 24C42.6 24.6 40.8 25.2 38.8 25.4Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="sidebar-title">Wetask</h1>
|
||||
<app-button
|
||||
buttonType="icon"
|
||||
iconName="double_arrow"
|
||||
(click)="toggleSidebar()"
|
||||
></app-button>
|
||||
</div>
|
||||
|
||||
<!-- 2. Der Button zum Ein- und Ausklappen. Er ruft unsere neue Methode auf. -->
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
<a
|
||||
class="nav-item"
|
||||
[class.active]="activeRoute === 'dashboard'"
|
||||
(click)="setActive('dashboard')"
|
||||
title="Übersicht"
|
||||
>
|
||||
<app-icon name="placeholder"></app-icon>
|
||||
<span>Übersicht</span>
|
||||
@@ -17,6 +37,7 @@
|
||||
class="nav-item"
|
||||
[class.active]="activeRoute === 'analytics'"
|
||||
(click)="setActive('analytics')"
|
||||
title="Analysen"
|
||||
>
|
||||
<app-icon name="placeholder"></app-icon>
|
||||
<span>Analysen</span>
|
||||
@@ -26,6 +47,7 @@
|
||||
class="nav-item"
|
||||
[class.active]="activeRoute === 'reports'"
|
||||
(click)="setActive('reports')"
|
||||
title="Berichte"
|
||||
>
|
||||
<app-icon name="placeholder"></app-icon>
|
||||
<span>Berichte</span>
|
||||
@@ -37,6 +59,7 @@
|
||||
class="nav-item"
|
||||
[class.active]="activeRoute === 'settings'"
|
||||
(click)="setActive('settings')"
|
||||
title="Einstellungen"
|
||||
>
|
||||
<app-icon name="placeholder"></app-icon>
|
||||
<span>Einstellungen</span>
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IconComponent } from '../../ui/icon/icon.component';
|
||||
import { ButtonComponent } from '../../ui/button/button.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-sidebar',
|
||||
standalone: true,
|
||||
imports: [CommonModule, IconComponent],
|
||||
imports: [CommonModule, IconComponent,ButtonComponent],
|
||||
templateUrl: './sidebar.component.html',
|
||||
styleUrl: './sidebar.component.css'
|
||||
})
|
||||
export class SidebarComponent {
|
||||
// Wir verwalten nur noch, welcher Link aktiv ist. 'dashboard' ist der Standard.
|
||||
// Dummy-Eigenschaft für die aktive Route, damit der Code funktioniert
|
||||
activeRoute = 'dashboard';
|
||||
|
||||
// Methode, um den aktiven Link bei einem Klick zu ändern.
|
||||
// In einer echten App würde dies durch den Angular Router gesteuert werden.
|
||||
// NEU: Eigenschaft, um den Zustand der Sidebar zu speichern
|
||||
public isCollapsed = false;
|
||||
|
||||
// Dummy-Methode, damit der Code funktioniert
|
||||
setActive(route: string): void {
|
||||
this.activeRoute = route;
|
||||
}
|
||||
|
||||
// NEU: Methode, um den Zustand umzuschalten
|
||||
toggleSidebar(): void {
|
||||
this.isCollapsed = !this.isCollapsed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user