This commit is contained in:
Michał Sieciechowicz 2025-08-03 11:14:26 +02:00
parent 678ce12de4
commit efb94f14da
13 changed files with 412 additions and 4 deletions

View File

@ -264,6 +264,75 @@ export class AppComponent {
}
```
### Card Components
**Selectors:** `ui-card`, `ui-card-title`, `ui-card-menu`, `ui-card-footer`
**Description:** Zestaw komponentów do tworzenia kart z opcjonalnym nagłówkiem, menu i stopką.
**CardComponent (`ui-card`) Properties:**
- `title?: string` - Tytuł karty wyświetlany w nagłówku
- `margin: 0.5rem` - Domyślny margin karty
- Kolory jak ui-menu (--ui-color-menu-bg, --ui-color-menu-text)
**Standalone Components:**
- `ui-card-title` - Tytuł karty z własnymi stylami
- `ui-card-menu` - Menu/przyciski w nagłówku
- `ui-card-footer` - Stopka karty z własnymi stylami
**Usage:**
```html
<!-- Podstawowe użycie -->
<ui-card title="Tytuł karty">
<p>Zawartość karty</p>
</ui-card>
<!-- Pełne użycie z wszystkimi slotami -->
<ui-card title="Statystyki">
<ui-card-menu>
<button class="btn btn-sm">Edytuj</button>
<button class="btn btn-sm">Usuń</button>
</ui-card-menu>
<div class="stats">
<div class="stat-item">
<span class="value">123</span>
<span class="label">Użytkownicy</span>
</div>
</div>
<ui-card-footer>
<small class="text-muted">Ostatnia aktualizacja: dziś</small>
</ui-card-footer>
</ui-card>
<!-- Niestandardowy tytuł -->
<ui-card>
<ui-card-title>
<div class="d-flex align-items-center">
<i class="icon-chart"></i>
<span>Raporty sprzedaży</span>
</div>
</ui-card-title>
<ui-card-menu>
<span class="text-success">+12%</span>
</ui-card-menu>
<div class="chart-container">
<!-- wykres -->
</div>
</ui-card>
```
**CSS Variables:**
- `--ui-color-card-bg` - tło karty
- `--ui-color-card-border` - kolor obramowania
- `--ui-color-card-title` - kolor tytułu
- `--ui-color-card-text` - kolor tekstu
- `--ui-color-card-footer-bg` - tło stopki
- `--ui-shadow-card` - standardowy cień karty
- `--ui-shadow-card-hover` - cień przy hover
## Development
### Building

View File

@ -0,0 +1,186 @@
# Card Components
Zestaw komponentów do tworzenia kart z opcjonalnym nagłówkiem, menu i stopką.
## Komponenty
- `ui-card` - główny kontener karty
- `ui-card-title` - tytuł karty (standalone komponent)
- `ui-card-menu` - menu/przyciski w nagłówku (standalone komponent)
- `ui-card-footer` - stopka karty (standalone komponent)
## Użycie
### Podstawowe użycie z tytułem jako Input
```html
<ui-card title="Tytuł karty">
<p>Zawartość karty</p>
</ui-card>
```
### Użycie z komponentem ui-card-title
```html
<ui-card>
<ui-card-title>
<h2>Niestandardowy tytuł</h2>
<span class="badge">Nowy</span>
</ui-card-title>
<p>Zawartość karty</p>
</ui-card>
```
### Pełne użycie z wszystkimi komponentami
```html
<ui-card title="Statystyki">
<ui-card-menu>
<button class="btn btn-sm">Edytuj</button>
<button class="btn btn-sm">Usuń</button>
</ui-card-menu>
<div class="stats">
<div class="stat-item">
<span class="value">123</span>
<span class="label">Użytkownicy</span>
</div>
<div class="stat-item">
<span class="value">456</span>
<span class="label">Zamówienia</span>
</div>
</div>
<ui-card-footer>
<small class="text-muted">Ostatnia aktualizacja: dziś</small>
</ui-card-footer>
</ui-card>
```
### Użycie z komponentami ui-card-title i ui-card-menu
```html
<ui-card>
<ui-card-title>
<div class="d-flex align-items-center">
<i class="icon-chart"></i>
<span>Raporty sprzedaży</span>
</div>
</ui-card-title>
<ui-card-menu>
<div class="stats-mini">
<span class="text-success">+12%</span>
</div>
<button class="btn btn-outline-primary btn-sm">Szczegóły</button>
</ui-card-menu>
<div class="chart-container">
<!-- wykres -->
</div>
<ui-card-footer>
<div class="d-flex justify-content-between">
<span>Okres: ostatnie 30 dni</span>
<a href="#" class="text-primary">Zobacz więcej</a>
</div>
</ui-card-footer>
</ui-card>
```
## API
### CardComponent (`ui-card`)
**Inputs:**
| Właściwość | Typ | Domyślna | Opis |
|------------|-----|----------|------|
| `title` | `string` | `undefined` | Tytuł karty wyświetlany w nagłówku |
**Content Projection:**
| Selektor | Opis |
|----------|------|
| `ui-card-title` | Komponent tytułu karty |
| `ui-card-menu` | Komponent menu w nagłówku |
| (default) | Główna zawartość karty |
| `ui-card-footer` | Komponent stopki karty |
### CardTitleComponent (`ui-card-title`)
**Opis:** Standalone komponent do wyświetlania tytułu karty z własnymi stylami.
### CardMenuComponent (`ui-card-menu`)
**Opis:** Standalone komponent do wyświetlania menu/przycisków w nagłówku karty.
### CardFooterComponent (`ui-card-footer`)
**Opis:** Standalone komponent do wyświetlania stopki karty z własnymi stylami.
## Zmienne CSS
Komponent używa następujących zmiennych CSS z systemu motywów:
### Kolory
- `--ui-color-card-bg` - tło karty
- `--ui-color-card-border` - kolor obramowania
- `--ui-color-card-title` - kolor tytułu
- `--ui-color-card-text` - kolor tekstu
- `--ui-color-card-footer-bg` - tło stopki
### Spacing
- `--ui-spacing-xs` (4px) - małe odstępy
- `--ui-spacing-sm` (8px) - średnie odstępy
- `--ui-spacing-md` (16px) - standardowe padding
- `--ui-spacing-lg` (24px) - duże odstępy
### Layout
- `--ui-border-radius` (8px) - zaokrąglenie rogów
- `--ui-font-size-lg` (18px) - rozmiar czcionki tytułu
- `--ui-font-weight-semibold` (600) - grubość czcionki tytułu
- `--ui-card-header-min-height` (40px) - minimalna wysokość nagłówka
### Cienie
- `--ui-shadow-card` - standardowy cień karty
- `--ui-shadow-card-hover` - cień przy hover
## Responsywność
Na urządzeniach mobilnych (max-width: 768px):
- Nagłówek karty zmienia się na układ kolumnowy
- Menu wyrównuje się do prawej strony
- Zachowane są wszystkie funkcjonalności
## Przykłady stylizacji
### Karta z kolorowym nagłówkiem
```scss
.custom-card {
.ui-card-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
margin: -16px -16px 0;
padding: 16px;
}
.ui-card-title {
color: white;
}
}
```
### Karta z ikoną
```html
<ui-card>
<ui-card-title>
<div class="d-flex align-items-center gap-2">
<i class="icon-settings"></i>
<span>Ustawienia</span>
</div>
</ui-card-title>
<!-- zawartość -->
</ui-card>
```

View File

@ -0,0 +1,11 @@
:host {
display: block;
padding: 0 var(--ui-spacing-md, 16px) var(--ui-spacing-md, 16px);
border-top: 1px solid var(--ui-color-menu-border, #d0d0d0);
background: var(--ui-color-menu-active, rgba(0, 0, 0, 0.1));
color: var(--ui-color-menu-text, #ffffff);
&:empty {
display: none;
}
}

View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
@Component({
selector: 'ui-card-footer',
standalone: true,
imports: [],
template: '<ng-content />',
styleUrl: './card-footer.component.scss'
})
export class CardFooterComponent {
}

View File

@ -0,0 +1,7 @@
:host {
display: flex;
gap: var(--ui-spacing-sm, 8px);
align-items: flex-start;
flex-shrink: 0;
padding: 1rem;
}

View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
@Component({
selector: 'ui-card-menu',
standalone: true,
imports: [],
template: '<ng-content />',
styleUrl: './card-menu.component.scss'
})
export class CardMenuComponent {
}

View File

@ -0,0 +1,9 @@
:host {
display: block;
margin: 0;
font-size: var(--ui-font-size-lg, 18px);
font-weight: var(--ui-font-weight-semibold, 600);
color: var(--ui-color-menu-text, #ffffff);
line-height: 1.2;
padding: 1rem;
}

View File

@ -0,0 +1,12 @@
import { Component } from '@angular/core';
@Component({
selector: 'ui-card-title',
standalone: true,
imports: [],
template: `<ng-content />`,
styleUrl: './card-title.component.scss'
})
export class CardTitleComponent {
}

View File

@ -1 +1,15 @@
<p>card works!</p>
<div class="header">
@if (title) {
<div class="title">{{ title }}</div>
} @else {
<ng-content select="ui-card-title"></ng-content>
}
<ng-content select="ui-card-menu"></ng-content>
</div>
<div class="content">
<ng-content></ng-content>
</div>
<ng-content select="ui-card-footer"></ng-content>

View File

@ -0,0 +1,23 @@
:host {
display: block;
margin: var(--ui-spacing-sm, 0.5rem);
background: var(--ui-color-menu-bg, #343a40);
border: 1px solid var(--ui-color-menu-border, #d0d0d0);
border-radius: var(--ui-border-radius, 8px);
box-shadow: var(--ui-shadow-card, 0 2px 4px rgba(0, 0, 0, 0.1));
overflow: hidden;
transition: box-shadow 0.2s ease;
}
.content {
padding: var(--ui-spacing-md, 16px);
color: var(--ui-color-menu-text, #ffffff);
line-height: 1.5;
}
.header{
display: flex;
.title,
::ng-deep ui-card-title{
flex-grow: 1;
}
}

View File

@ -1,11 +1,13 @@
import { Component } from '@angular/core';
import { Component, Input } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'ui-card',
imports: [],
standalone: true,
imports: [CommonModule],
templateUrl: './card.component.html',
styleUrl: './card.component.scss'
})
export class CardComponent {
@Input() title?: string;
}

View File

@ -41,6 +41,27 @@
--ui-color-icon-primary: #{$primary};
--ui-color-icon-secondary: #{$secondary};
--ui-color-icon-muted: color-mix(in srgb, #{$text} 60%, transparent 40%);
/* Card component variables */
--ui-color-card-bg: #{if($background == #343a40, #ffffff, color-mix(in srgb, #{$background} 95%, white 5%))};
--ui-color-card-border: #{$border};
--ui-color-card-title: #{$primary};
--ui-color-card-text: #{if($text == #ffffff, #333333, $text)};
--ui-color-card-footer-bg: #{if($background == #343a40, #f8f9fa, color-mix(in srgb, #{$background} 90%, white 10%))};
/* Card spacing and layout variables */
--ui-spacing-xs: 4px;
--ui-spacing-sm: 8px;
--ui-spacing-md: 16px;
--ui-spacing-lg: 24px;
--ui-border-radius: 8px;
--ui-font-size-lg: 18px;
--ui-font-weight-semibold: 600;
--ui-card-header-min-height: 40px;
/* Card shadows */
--ui-shadow-card: 0 2px 4px rgba(0, 0, 0, 0.1);
--ui-shadow-card-hover: 0 4px 8px rgba(0, 0, 0, 0.15);
}
/**
@ -83,4 +104,31 @@
}
}
/**
* Mixin that applies theme-aware styles to card components
*/
@mixin ui-card-theme() {
background: var(--ui-color-card-bg);
border: 1px solid var(--ui-color-card-border);
border-radius: var(--ui-border-radius);
box-shadow: var(--ui-shadow-card);
&:hover {
box-shadow: var(--ui-shadow-card-hover);
}
.ui-card-title {
color: var(--ui-color-card-title);
}
.ui-card-content {
color: var(--ui-color-card-text);
}
.ui-card-footer {
background: var(--ui-color-card-footer-bg);
border-top-color: var(--ui-color-card-border);
}
}

View File

@ -17,3 +17,6 @@ export * from './lib/modules/form/components/input/input.component';
// Components
export * from './lib/components/button/button.component';
export * from './lib/components/card/card.component';
export * from './lib/components/card/card-title/card-title.component';
export * from './lib/components/card/card-menu/card-menu.component';
export * from './lib/components/card/card-footer/card-footer.component';