styles
This commit is contained in:
@@ -16,19 +16,28 @@
|
||||
border-radius: 50%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
background-color: var(--color-surface);
|
||||
}
|
||||
|
||||
.kpi-icon ::ng-deep svg {
|
||||
.kpi-icon app-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icon-sales { background: linear-gradient(135deg, #2ecc71, #27ae60); }
|
||||
.icon-users { background: linear-gradient(135deg, #3498db, #2980b9); }
|
||||
.icon-orders { background: linear-gradient(135deg, #f39c12, #f1c40f); }
|
||||
.icon-performance { background: linear-gradient(135deg, #9b59b6, #8e44ad); }
|
||||
.icon-blue {
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
}
|
||||
.icon-green {
|
||||
background: linear-gradient(135deg, #2ecc71, #27ae60);
|
||||
}
|
||||
.icon-orange {
|
||||
background: linear-gradient(135deg, #f39c12, #f1c40f);
|
||||
}
|
||||
.icon-purple {
|
||||
background: linear-gradient(135deg, #9b59b6, #8e44ad);
|
||||
}
|
||||
|
||||
.kpi-content {
|
||||
display: flex;
|
||||
@@ -44,4 +53,4 @@
|
||||
.kpi-label {
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-light);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<div class="card kpi-card">
|
||||
<div
|
||||
<div
|
||||
class="kpi-icon"
|
||||
[class.icon-sales]="color === 'sales'"
|
||||
[class.icon-users]="color === 'users'"
|
||||
[class.icon-orders]="color === 'orders'"
|
||||
[class.icon-performance]="color === 'performance'">
|
||||
<!-- ng-content erlaubt es, ein spezifisches SVG-Icon von außen einzufügen -->
|
||||
<ng-content></ng-content>
|
||||
[class.icon-blue]="color === 'blue'"
|
||||
[class.icon-green]="color === 'green'"
|
||||
[class.icon-orange]="color === 'orange'"
|
||||
[class.icon-purple]="color === 'purple'"
|
||||
>
|
||||
<app-icon
|
||||
*ngIf="iconName"
|
||||
[name]="iconName"
|
||||
[svgColor]="svgColor"
|
||||
></app-icon>
|
||||
</div>
|
||||
<div class="kpi-content">
|
||||
<span class="kpi-value">{{ value }}</span>
|
||||
<span class="kpi-label">{{ label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IconComponent } from '../../ui/icon/icon.component';
|
||||
|
||||
type KpiColor = 'sales' | 'users' | 'orders' | 'performance';
|
||||
type KpiColor = 'blue' | 'green' | 'orange' | 'purple';
|
||||
|
||||
@Component({
|
||||
selector: 'app-kpi-card',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
imports: [CommonModule, IconComponent],
|
||||
templateUrl: './kpi-card.component.html',
|
||||
styleUrl: './kpi-card.component.css'
|
||||
styleUrl: './kpi-card.component.css',
|
||||
})
|
||||
export class KpiCardComponent {
|
||||
@Input() value: string = '';
|
||||
@Input() label: string = '';
|
||||
@Input() color: KpiColor = 'users';
|
||||
@Input() color: KpiColor = 'blue';
|
||||
@Input() iconName: string | null = null;
|
||||
@Input() svgColor: string | null = null;
|
||||
}
|
||||
@@ -9,8 +9,9 @@
|
||||
[class.btn-icon]="color === 'icon' || color === 'icon-danger'"
|
||||
[class.btn-icon-danger]="color === 'icon-danger'"
|
||||
[class.btn-full-width]="fullWidth"
|
||||
[attr.data-tooltip]="tooltip">
|
||||
|
||||
<!-- ng-content erlaubt es, Text oder SVGs von außen in den Button einzufügen -->
|
||||
[attr.data-tooltip]="tooltip"
|
||||
>
|
||||
<!-- HIER IST DIE KORREKTUR: Binding an [svgColor] statt [iconColor] -->
|
||||
<app-icon *ngIf="iconName" [name]="iconName" [svgColor]="svgColor"></app-icon>
|
||||
<ng-content></ng-content>
|
||||
</button>
|
||||
@@ -1,13 +1,16 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IconComponent } from '../icon/icon.component';
|
||||
|
||||
// Definiert die erlaubten Varianten für den Button
|
||||
type ButtonColor = 'primary' | 'secondary' | 'stroked' | 'flat' | 'icon' | 'icon-danger';
|
||||
|
||||
@Component({
|
||||
selector: 'app-button',
|
||||
|
||||
imports: [CommonModule],
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
IconComponent
|
||||
],
|
||||
templateUrl: './button.component.html',
|
||||
styleUrl: './button.component.css'
|
||||
})
|
||||
@@ -17,6 +20,8 @@ export class ButtonComponent {
|
||||
@Input() disabled = false;
|
||||
@Input() fullWidth = false;
|
||||
|
||||
// Ein spezieller Input für Tooltips
|
||||
@Input() tooltip: string | null = null;
|
||||
@Input() iconName: string | null = null;
|
||||
// --- HIER IST DIE KORREKTUR: Umbenennung zu svgColor ---
|
||||
@Input() svgColor: string | null = null; // Farbe des SVG-Inhalts im Button
|
||||
}
|
||||
@@ -3,12 +3,16 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1em; /* Passt sich an die Schriftgröße des Elternelements an */
|
||||
height: 1em;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
color: inherit; /* Wichtig, damit currentColor vom Elternelement übernommen wird */
|
||||
}
|
||||
|
||||
/* Wir verwenden ::ng-deep, da das SVG-Element dynamisch eingefügt wird */
|
||||
::ng-deep .icon-svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
stroke: currentColor;
|
||||
/* HIER IST DIE KORREKTUR: fill muss ein gültiger CSS-Wert sein */
|
||||
stroke: currentColor;
|
||||
fill: currentColor;
|
||||
}
|
||||
@@ -1,35 +1,89 @@
|
||||
import { Component, Input, OnChanges, SimpleChanges, ElementRef, Renderer2 } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {
|
||||
Component,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
ElementRef,
|
||||
Renderer2,
|
||||
Inject,
|
||||
PLATFORM_ID,
|
||||
TransferState,
|
||||
makeStateKey,
|
||||
StateKey
|
||||
} from '@angular/core';
|
||||
|
||||
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
const ICON_SVG_KEY_PREFIX = 'icon-svg-';
|
||||
|
||||
@Component({
|
||||
selector: 'app-icon',
|
||||
standalone: true,
|
||||
standalone: true,
|
||||
imports: [CommonModule, HttpClientModule],
|
||||
template: '<ng-content></ng-content>', // Leeres Template, da wir das SVG direkt einfügen
|
||||
template: '',
|
||||
styleUrl: './icon.component.css'
|
||||
})
|
||||
export class IconComponent implements OnChanges {
|
||||
@Input() name: string = '';
|
||||
// --- HIER IST DIE KORREKTUR: Umbenennung zu svgColor ---
|
||||
@Input() svgColor: string | null = null; // Farbe des SVG-Inhalts (Füllung/Linie)
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private el: ElementRef,
|
||||
private renderer: Renderer2
|
||||
private renderer: Renderer2,
|
||||
private transferState: TransferState,
|
||||
@Inject(PLATFORM_ID) private platformId: Object
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['name'] && this.name) {
|
||||
// Lädt das SVG aus dem assets-Ordner und fügt es in die Komponente ein
|
||||
this.http.get(`assets/icons/${this.name}.svg`, { responseType: 'text' })
|
||||
// Überprüfe Änderungen an 'name' ODER 'svgColor'
|
||||
if ((changes['name'] && this.name) || (changes['svgColor'] && this.name)) {
|
||||
this.loadSvg();
|
||||
}
|
||||
}
|
||||
|
||||
private loadSvg(): void {
|
||||
const svgStateKey: StateKey<string> = makeStateKey<string>(ICON_SVG_KEY_PREFIX + this.name);
|
||||
const cachedSvg = this.transferState.get(svgStateKey, null);
|
||||
|
||||
this.el.nativeElement.innerHTML = '';
|
||||
|
||||
if (cachedSvg) {
|
||||
this.setSvg(cachedSvg);
|
||||
} else {
|
||||
this.http.get(`icons/${this.name}.svg`, { responseType: 'text' })
|
||||
.pipe(
|
||||
tap(svg => {
|
||||
if (!isPlatformBrowser(this.platformId)) {
|
||||
this.transferState.set(svgStateKey, svg);
|
||||
}
|
||||
})
|
||||
)
|
||||
.subscribe(svg => {
|
||||
this.el.nativeElement.innerHTML = svg;
|
||||
// Optional: Fügt dem <svg>-Element selbst eine Klasse hinzu
|
||||
const svgElement = this.el.nativeElement.querySelector('svg');
|
||||
if (svgElement) {
|
||||
this.renderer.addClass(svgElement, 'icon-svg');
|
||||
}
|
||||
this.setSvg(svg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private setSvg(svgContent: string): void {
|
||||
this.el.nativeElement.innerHTML = svgContent;
|
||||
const svgElement = this.el.nativeElement.querySelector('svg');
|
||||
if (svgElement) {
|
||||
this.renderer.addClass(svgElement, 'icon-svg');
|
||||
|
||||
// --- HIER IST DIE KORREKTUR: svgColor anwenden ---
|
||||
if (this.svgColor) {
|
||||
this.renderer.setStyle(svgElement, 'fill', this.svgColor); // Füllfarbe
|
||||
this.renderer.setStyle(svgElement, 'stroke', this.svgColor); // Linienfarbe
|
||||
} else {
|
||||
// Fallback zu currentColor, wenn keine Farbe übergeben wird
|
||||
this.renderer.setStyle(svgElement, 'fill', 'currentColor');
|
||||
this.renderer.setStyle(svgElement, 'stroke', 'currentColor');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user