@konce-pt/angular 0.7.0 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@konce-pt/angular",
3
- "version": "0.7.0",
3
+ "version": "0.7.5",
4
4
  "description": "Open-source Angular 22 component library on Signals & Signal Forms — 70+ components, rich data table, zoneless, fully tokenized. Selektory kpt-*, klasy Kpt*.",
5
5
  "license": "MIT",
6
6
  "author": "konce.pt",
7
- "homepage": "https://gitlab.com/konce-pt/koncept-ui#readme",
7
+ "homepage": "https://ui.konce.pt/",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://gitlab.com/konce-pt/koncept-ui.git",
@@ -26,14 +26,23 @@
26
26
  "cdk",
27
27
  "data-table",
28
28
  "kpt",
29
- "koncept-ui"
29
+ "koncept-ui",
30
+ "map",
31
+ "leaflet",
32
+ "openstreetmap"
30
33
  ],
31
34
  "sideEffects": false,
32
35
  "peerDependencies": {
33
36
  "@angular/cdk": "^22.0.0",
34
37
  "@angular/common": "^22.0.0",
35
38
  "@angular/core": "^22.0.0",
36
- "@angular/forms": "^22.0.0"
39
+ "@angular/forms": "^22.0.0",
40
+ "leaflet": "^1.9.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "leaflet": {
44
+ "optional": true
45
+ }
37
46
  },
38
47
  "dependencies": {
39
48
  "tslib": "^2.3.0"
@@ -60,6 +69,10 @@
60
69
  "types": "./types/konce-pt-angular-icons.d.ts",
61
70
  "default": "./fesm2022/konce-pt-angular-icons.mjs"
62
71
  },
72
+ "./map": {
73
+ "types": "./types/konce-pt-angular-map.d.ts",
74
+ "default": "./fesm2022/konce-pt-angular-map.mjs"
75
+ },
63
76
  "./roadmap": {
64
77
  "types": "./types/konce-pt-angular-roadmap.d.ts",
65
78
  "default": "./fesm2022/konce-pt-angular-roadmap.mjs"
@@ -1,14 +1,24 @@
1
1
  # KptAppShell (kpt-app-shell)
2
2
 
3
- Szkielet aplikacji w stylu Material: toolbar u góry, panel boczny, treść.
4
- Import: `import { KptAppShell } from '@konce-pt/angular';`
3
+ Szkielet aplikacji: pasek u góry, panel boczny, treść. Responsywny bez konfiguracji.
4
+ Import: `import { KptAppShell, KptShellNavToggle } from '@konce-pt/angular';`
5
5
 
6
6
  ## Selektor
7
7
  `kpt-app-shell`
8
8
 
9
9
  ## Wejścia / wyjścia
10
- - `sidenavOpen`: model<boolean> (domyślnie true) — dwukierunkowe `[(sidenavOpen)]`
11
- - `sidenavMode`: 'side' | 'over' (domyślnie 'side'); 'over' nakłada panel ze scrimem
10
+ - `sidenavOpen`: model<boolean> (domyślnie `true`) — stan panelu ZADOKOWANEGO
11
+ (oraz wymuszonego trybu `over`); dwukierunkowe `[(sidenavOpen)]`
12
+ - `sidenavCompactOpen`: model<boolean> (domyślnie `false`) — stan NAKŁADKI w trybie `auto`
13
+ - `sidenavMode`: `'auto' | 'side' | 'over'` (domyślnie **`'auto'`**)
14
+ - `sidenavBreakpoint`: `'sm'|'md'|'lg'|'xl'|'2xl'` (domyślnie `'lg'`) — od tego progu w górę
15
+ tryb `auto` dokuje panel, poniżej robi z niego nakładkę
16
+ - `sidenavRailBreakpoint`: ten sam zbiór albo `null` (domyślnie `null`) — włącza szynę ikon
17
+ w paśmie od `sidenavBreakpoint` do tego progu; wartość musi być WYŻSZA niż `sidenavBreakpoint`
18
+ - `sidenavLabel`: string — etykieta a11y panelu; puste = `appShell.navigation` ze słownika
19
+ - `sidenavId`: readonly string — identyfikator panelu (`aria-controls`)
20
+ - `isOverlay()`, `isSidenavOpen()`: Signal<boolean> — stan efektywny dla bieżącego układu
21
+ - `toggleSidenav()`, `openSidenav()`, `closeSidenav()` — trafiają w stan właściwy dla układu
12
22
 
13
23
  ## Sloty projekcji
14
24
  - `[kptShellToolbar]` → pasek u góry
@@ -16,14 +26,64 @@ Import: `import { KptAppShell } from '@konce-pt/angular';`
16
26
  - treść domyślna → obszar główny
17
27
 
18
28
  ## Przykład
19
- <kpt-app-shell [(sidenavOpen)]="navOpen" sidenavMode="side">
20
- <kpt-toolbar kptShellToolbar>
21
- <kpt-button variant="text" (click)="navOpen.set(!navOpen())">☰</kpt-button>
29
+ <kpt-app-shell [(sidenavOpen)]="navOpen">
30
+ <kpt-toolbar kptShellToolbar elevated>
31
+ <kpt-icon-button kptShellNavToggle variant="text" ariaLabel="Menu">
32
+ <kpt-icon name="menu" />
33
+ </kpt-icon-button>
22
34
  </kpt-toolbar>
23
- <kpt-sidenav kptShellSidenav>…</kpt-sidenav>
35
+ <kpt-sidenav kptShellSidenav>
36
+ <a href="#"><kpt-icon name="list" /> <span kptNavLabel>Pulpit</span></a>
37
+ </kpt-sidenav>
24
38
  <router-outlet />
25
39
  </kpt-app-shell>
26
40
 
41
+ ## Trzy pasma trybu 'auto'
42
+ | szerokość | układ | co robi zamknięcie |
43
+ |---|---|---|
44
+ | `< sidenavBreakpoint` | nakładka + scrim | panel wyjeżdża poza krawędź (stan: `sidenavCompactOpen`) |
45
+ | `>= sidenavBreakpoint`, `< sidenavRailBreakpoint` | szyna ikon | panel zwęża się do `--kpt-sidenav-rail-width` |
46
+ | `>= sidenavRailBreakpoint` (lub brak szyny) | pełny panel | panel chowa się w całości |
47
+
48
+ ## Dlaczego DWA stany otwarcia
49
+ „Otwarty" znaczy co innego po obu stronach progu: na desktopie panel domyślnie stoi otwarty,
50
+ na telefonie domyślnie musi być schowany. Gdyby oba układy dzieliły jeden model, wejście na wąski
51
+ ekran musiałoby nadpisać stan aplikacji, a powrót na szeroki nie miałby czego przywrócić.
52
+ Rozdzielenie sprawia, że intencja z desktopu przeżywa zwężenie i rozszerzenie okna za darmo.
53
+
54
+ Przycisk `kptShellNavToggle` sam trafia we właściwy stan — nie pisz `navOpen.set(...)` ręcznie,
55
+ bo na wąskim ekranie ustawisz nie ten model.
56
+
57
+ ## Konwencja treści menu (potrzebna tylko dla szyny)
58
+ - `[kptNavLabel]` — tekst pozycji; w szynie chowany techniką „visually hidden", więc pozycja
59
+ zachowuje dostępną nazwę dla czytnika ekranu.
60
+ - `[kptNavSection]` — nagłówek grupy; chowany tak samo.
61
+
62
+ To płaskie atrybuty (jak `kptShellToolbar` czy `kptToolbarSpacer`), nie dyrektywy — nic nie trzeba
63
+ importować. Bez nich szyna pokaże ucięty tekst zamiast ikony. W szynie warto opatrzyć pozycje
64
+ `kptTooltip`, bo widać sam znak.
65
+
27
66
  ## Zachowanie
28
- - 'side': zamknięty panel chowa się (ujemny margines) i rozpycha treść.
29
- - 'over': panel absolutny z `translateX`, klik w scrim zamyka. Szerokość: `--kpt-sidenav-width`.
67
+ - O układzie decyduje wyłącznie CSS (`@media`), więc nic nie migocze przed hydracją i całość
68
+ działa na SSR. JavaScript odpowiada tylko za to, który stan przełącza przycisk.
69
+ - Zamknięty panel wypada z kolejki Tab przez `visibility: hidden` (nie `inert`) — jest poprawny
70
+ już na pierwszej klatce.
71
+ - Otwarta nakładka nakłada `inert` na treść (`<main>`), więc Tab nie wchodzi pod scrim.
72
+ - `Escape` zamyka nakładkę; klik w scrim też.
73
+ - Kierunek wysuwu idzie za `dir` (RTL wyjeżdża z prawej).
74
+ - Wysokość: `100dvh` z fallbackiem `100vh`.
75
+ - **Nie** zamyka menu po nawigacji — shell nie wie, co w danej aplikacji nią jest.
76
+ Zrób to sam: `if (shell.isOverlay()) shell.closeSidenav();`.
77
+
78
+ ## Tryby wymuszone (zgodność wsteczna)
79
+ `sidenavMode="side"` i `"over"` ignorują szerokość okna i czytają `sidenavOpen`, dokładnie jak
80
+ przed wprowadzeniem `auto`. Ustaw `"side"`, jeśli aplikacja sama zarządza responsywnością —
81
+ inaczej dostaniesz dwie warstwy tej samej logiki.
82
+
83
+ ## Tokeny
84
+ `--kpt-sidenav-width` (16rem), `--kpt-sidenav-rail-width` (4rem), `--kpt-z-overlay`,
85
+ `--kpt-color-overlay-scrim`, `--kpt-elevation-3`, `--kpt-motion-duration-base`.
86
+
87
+ ## Odłożone
88
+ Focus trap i zwrot fokusu do przycisku po zamknięciu (spójnie z `kpt-drawer`, który też ich
89
+ nie ma — to osobne zadanie dla całego repo). `<aside>` ma już `tabindex="-1"`.
@@ -0,0 +1,45 @@
1
+ # KptBreakpointObserver
2
+
3
+ Serwis (root) zamieniający media query na sygnały. Jedyny w bibliotece sposób na zapytanie
4
+ „jak szerokie jest okno" z poziomu TypeScriptu.
5
+
6
+ ## API
7
+
8
+ inject(KptBreakpointObserver)
9
+
10
+ - `up(bp: KptBreakpoint): Signal<boolean>` — `(min-width: <próg>px)`, mobile-first.
11
+ - `down(bp: KptBreakpoint): Signal<boolean>` — `(max-width: <próg - 0.02>px)`; odjęcie 0.02px
12
+ sprawia, że pasma `up`/`down` nie nakładają się na ułamkowych szerokościach (zoom, DPI).
13
+ - `matches(query: string): Signal<boolean>` — dowolne media query.
14
+
15
+ `KptBreakpoint` = `'sm' | 'md' | 'lg' | 'xl' | '2xl'`; progi w `KPT_BREAKPOINTS`
16
+ (640 / 768 / 1024 / 1280 / 1536 px).
17
+
18
+ ## Skąd biorą się wartości
19
+
20
+ Z tokenów: `packages/tokens/tokens/primitives/breakpoint.json` → `scripts/gen-tokens.mjs`
21
+ generuje `breakpoint/breakpoints.generated.ts` (dla JS) i `styles/_breakpoints.generated.scss`
22
+ (dla `@media` w SCSS komponentów). Oba pliki są commitowane i **nie edytuje się ich ręcznie** —
23
+ zmiana progu idzie przez token i `pnpm nx build angular`. Dzięki jednemu źródłu CSS biblioteki
24
+ i jej JavaScript nie mogą rozjechać się cicho.
25
+
26
+ ## SSR
27
+
28
+ Poza przeglądarką każdy sygnał to stałe `false`. Nie buduj na nim układu strony — od tego jest
29
+ CSS (`@media`), inaczej dostaniesz migotanie przed hydracją. Serwis służy do zachowań:
30
+ w którą stronę ma zadziałać przycisk, czy zamykać panel po nawigacji, co odłożyć na później.
31
+
32
+ ## Przykład
33
+
34
+ @Component({ /* … */ })
35
+ export class Header {
36
+ private readonly breakpoints = inject(KptBreakpointObserver);
37
+ readonly isDesktop = this.breakpoints.up('lg');
38
+ readonly isCompact = this.breakpoints.down('md');
39
+ }
40
+
41
+ ## Uwagi
42
+
43
+ - Zapytania są memoizowane per string — `up('lg')` w dziesięciu komponentach to jeden
44
+ `MediaQueryList` i jeden nasłuch; nie trzeba tego cache'ować u siebie.
45
+ - Sprzątanie idzie przez `DestroyRef` root injectora, więc nie ma czego odsubskrybować.
@@ -23,6 +23,9 @@ Import: `import { KptDatepicker } from '@konce-pt/angular';`
23
23
  - `monthDisplay`: 'long' | 'number' (domyślnie 'long') — w trybie 'month' i etykietach miesięcy: słownie (styczeń) lub liczbą (01)
24
24
  - `displayFormat`: 'pl' | 'iso' (domyślnie 'pl') — format wyświetlania i domyślnego placeholdera
25
25
  - `disabled`/`invalid`/`touched`: boolean; output `touch`.
26
+ - `ariaLabel`: string|null — nazwa dostępna, gdy pola nie opisuje `<label for>`
27
+ (np. dwie godziny w jednym wierszu edytora). Bez niej czytnik ekranu ogłasza samą wartość.
28
+ - Ikona w polu: kalendarz, a w trybie 'time' zegar.
26
29
  - Panel: nawigacja (‹ ›) miesięcy/lat/dekad wg trybu; tarcza zegara z „Gotowe"; przycisk czyszczenia (×).
27
30
 
28
31
  ## i18n
@@ -1,27 +1,68 @@
1
- # KptDialog (kpt-dialog)
1
+ # KptDialog (kpt-dialog)
2
+
3
+ Okno modalne na natywnym `<dialog>` (focus trap, Esc, backdrop w standardzie).
4
+ Import: `import { KptDialog } from '@konce-pt/angular';`
5
+
6
+ ## Selektor
7
+ `kpt-dialog`
8
+
9
+ ## Wejścia
10
+ - `open`: model<boolean> — dwukierunkowe `[(open)]`
11
+ - `header`: string; `dismissible`: boolean (Esc/× zamyka; domyślnie true)
12
+
13
+ ## Sloty
14
+ - treść domyślna → body; element z atrybutem `kptDialogFooter` → stopka
15
+
16
+ ## Przykład
17
+ <kpt-dialog [(open)]="confirmOpen" header="Usunąć?">
18
+ Nieodwracalne.
19
+ <div kptDialogFooter>
20
+ <kpt-button variant="text" (click)="confirmOpen.set(false)">Anuluj</kpt-button>
21
+ <kpt-button variant="danger" (click)="remove()">Usuń</kpt-button>
22
+ </div>
23
+ </kpt-dialog>
24
+
25
+ ## Tokeny
26
+ `--kpt-color-surface-raised`, `--kpt-color-overlay-scrim` (::backdrop), `--kpt-elevation-4`.
27
+ Uwaga: globalny reset zeruje margin — komponent przywraca `margin:auto` (centrowanie).
28
+
29
+ ## Kontrolki na CDK Overlay w środku okna
30
+
31
+ `kpt-dialog` stoi na natywnym `<dialog>` i otwiera się przez `showModal()`, co wynosi je
32
+ do **warstwy szczytowej** przeglądarki — a ta jest ponad całym drzewem dokumentu i żaden
33
+ `z-index` jej nie przebije. Kontener CDK Overlay wisi domyślnie na `<body>`, więc panele
34
+ `kpt-select`, `kpt-datepicker`, `kpt-autocomplete` i `kpt-menu` otwierałyby się w środku
35
+ okna NIEWIDOCZNE, schowane za jego tłem.
36
+
37
+ Dlatego `kpt-dialog` na czas otwarcia przenosi kontener overlayów do wnętrza `<dialog>`
38
+ i oddaje go na miejsce przy zamknięciu (również gdy komponent zostanie zniszczony
39
+ z otwartym oknem). Nie trzeba nic konfigurować — kontrolki overlayowe działają w oknie
40
+ tak samo jak poza nim.
2
41
 
3
- Okno modalne na natywnym `<dialog>` (focus trap, Esc, backdrop w standardzie).
4
- Import: `import { KptDialog } from '@konce-pt/angular';`
42
+ ## Układ i przewijanie
5
43
 
6
- ## Selektor
7
- `kpt-dialog`
44
+ Otwarte okno jest kolumną flex: nagłówek (`.kpt-dialog__header`) i stopka
45
+ (`[kptDialogFooter]`) stoją nieruchomo, a przewija się wyłącznie `.kpt-dialog__body`.
46
+ Pasek przewijania biegnie więc tylko wzdłuż treści, nie wzdłuż całego okna.
8
47
 
9
- ## Wejścia
10
- - `open`: model<boolean> — dwukierunkowe `[(open)]`
11
- - `header`: string; `dismissible`: boolean (Esc/× zamyka; domyślnie true)
48
+ Treść dostaje `flex: 0 1 auto` (domyślne) + `min-height: 0`, celowo **nie** `flex: 1`
49
+ jak w `kpt-drawer`. Szuflada wypełnia wysokość ekranu, okno ma kurczyć się do treści:
50
+ krótkie (`kpt-confirm` — dwa zdania i dwa przyciski) zostaje krótkie, długie zatrzymuje się
51
+ na `max-height: calc(100vh - 4rem)` i przewija samą treść.
12
52
 
13
- ## Sloty
14
- - treść domyślna → body; element z atrybutem `kptDialogFooter` → stopka
53
+ Deklaracja `display: flex` jest scopowana `&[open]` i musi taka zostać. Regułę
54
+ `dialog:not([open]) { display: none }` daje arkusz przeglądarki, a każda deklaracja
55
+ autorska ją bije — także z `@layer`. Niescopowane `display: flex` zostawiłoby wszystkie
56
+ zamknięte okna widoczne na stronie.
15
57
 
16
- ## Przykład
17
- <kpt-dialog [(open)]="confirmOpen" header="Usunąć?">
18
- Nieodwracalne.
19
- <div kptDialogFooter>
20
- <kpt-button variant="text" (click)="confirmOpen.set(false)">Anuluj</kpt-button>
21
- <kpt-button variant="danger" (click)="remove()">Usuń</kpt-button>
22
- </div>
23
- </kpt-dialog>
58
+ `.kpt-dialog` nie dostaje `overflow: hidden` — kontener CDK Overlay jest na czas otwarcia
59
+ przeniesiony do wnętrza `<dialog>` (patrz sekcja wyżej), więc przycięcie okna ucięłoby
60
+ panele `kpt-select` czy `kpt-datepicker`. Do samego przewijania nie jest potrzebne:
61
+ po przejściu na flex nic nie wystaje poza okno.
24
62
 
25
- ## Tokeny
26
- `--kpt-color-surface-raised`, `--kpt-color-overlay-scrim` (::backdrop), `--kpt-elevation-4`.
27
- Uwaga: globalny reset zeruje margin — komponent przywraca `margin:auto` (centrowanie).
63
+ Przypięty pasek akcji wewnątrz treści (np. „Anuluj / Zapisz" w `kpt-map-create-dialog`)
64
+ robi się przez `position: sticky` — kontenerem przewijania jest `.kpt-dialog__body`.
65
+ Ujemne marginesy boczne muszą zgadzać się z jego paddingiem (`--kpt-space-6`),
66
+ a przesunięcie `bottom` musi być lustrem ujemnego marginesu dolnego
67
+ (`bottom: calc(var(--kpt-space-6) * -1)`) — przyklejanie liczy się dla marginesowego
68
+ pudełka, więc przy `bottom: 0` pod paskiem przesuwałby się skrawek treści.
@@ -24,12 +24,30 @@ Import: `import { KptFormField } from '@konce-pt/angular';`
24
24
  Warianty float mają animowane przejście etykiety (pozycja spoczynkowa w miejscu placeholdera →
25
25
  uniesiona). Uniesienie następuje przy focusie kontrolki **lub** gdy pole ma wartość. Wykrywanie
26
26
  wypełnienia jest po stronie komponentu (zdarzenia `input`/`change` + wartość początkowa) — **nie**
27
- wymaga ustawiania placeholdera na kontrolce. Uwaga: wzorzec działa dla kontrolek `input`/`textarea`.
27
+ wymaga ustawiania placeholdera na kontrolce.
28
28
 
29
29
  <kpt-form-field label="E-mail" labelType="over">
30
30
  <kpt-input />
31
31
  </kpt-form-field>
32
32
 
33
+ ### Kontrolki bez natywnego `input`/`textarea`
34
+
35
+ Wartości `kpt-select` nie da się odczytać z DOM (panel żyje w overlayu), więc taka kontrolka
36
+ zgłasza wypełnienie sama — dostarcza token `KPT_FORM_FIELD_CONTROL` z sygnałem `filled`.
37
+ `kpt-select` robi to z pudełka; własna kontrolka wymaga:
38
+
39
+ import { KPT_FORM_FIELD_CONTROL, type KptFormFieldControl } from '@konce-pt/angular';
40
+
41
+ @Component({
42
+ providers: [{ provide: KPT_FORM_FIELD_CONTROL, useExisting: forwardRef(() => MyControl) }],
43
+ })
44
+ export class MyControl implements KptFormFieldControl {
45
+ readonly filled = computed(() => this.value() != null);
46
+ }
47
+
48
+ Gdy kontrolka dostarczy token, `kpt-form-field` przestaje zaglądać do DOM i ufa wyłącznie
49
+ sygnałowi `filled` — dlatego etykieta unosi się natychmiast po zmianie wartości.
50
+
33
51
  ## Projekcja
34
52
  Kontrolkę umieszcza się w treści (ng-content):
35
53
 
@@ -14,7 +14,8 @@ kolor z `currentColor`. Import: `import { KptIcon } from '@konce-pt/angular';`
14
14
  menu, x, chevron-up, chevron-down, chevron-left, chevron-right, check, search,
15
15
  grip-vertical, info, alert-triangle, circle-check, circle-x, calendar, copy, link, code,
16
16
  star, phone, map-pin, world, clock, align-left, align-center, align-right, align-justified,
17
- palette, highlight, clipboard, clipboard-text, table (pełna lista w `icons.ts`).
17
+ palette, highlight, clipboard, clipboard-text, table, mail, share, external-link, crosshair
18
+ (pełna lista w `icons.ts`).
18
19
 
19
20
  ## Pełny zestaw (5130 ikon Tabler)
20
21
  Opcjonalny entry point `@konce-pt/angular/icons` (pobierany tylko przy imporcie):
@@ -28,7 +28,7 @@ Nie warunkuj walidatorów przez `when: state.touched()` — psuje to `valid()`.
28
28
  Pełny przepływ: sekcja `## Formularz od zera (Signal Forms)` w głównym llms.txt.
29
29
 
30
30
  ## Wejścia prezentacyjne
31
- - `type`: 'text'|'email'|'password'|'number'|'search'|'tel'|'url' (domyślnie 'text')
31
+ - `type`: 'text'|'email'|'password'|'number'|'search'|'tel'|'url'|'time' (domyślnie 'text')
32
32
  - `placeholder`: string
33
33
  - `id`: string — trafia na wewnętrzny `<input>` (do `label[for]`); host go nie nosi
34
34
  - `ariaLabel`: string | null
@@ -18,6 +18,15 @@ Wymaga stylów overlay CDK w aplikacji: `import '@angular/cdk/overlay-prebuilt.c
18
18
  - `disabled`/`invalid`/`touched`: boolean; output `touch`.
19
19
  - Klawiatura: Enter/↓ otwiera, ↑/↓ nawigacja, Enter wybiera, Esc zamyka.
20
20
 
21
+ ## Float Label
22
+ W `kpt-form-field` z `labelType` `over`/`in`/`on` etykieta unosi się także po wybraniu opcji —
23
+ select dostarcza token `KPT_FORM_FIELD_CONTROL` z sygnałem `filled` (wartości w overlayu nie da
24
+ się odczytać z DOM). Nic nie trzeba konfigurować:
25
+
26
+ <kpt-form-field label="Kraj" labelType="on">
27
+ <kpt-select [formField]="f.country" [options]="countries" />
28
+ </kpt-form-field>
29
+
21
30
  ## i18n
22
31
  Etykiety „Szukaj…", „Brak wyników" i aria usuwania chipa z i18n (namespace `select`).
23
32
  Domyślnie EN; konfiguracja przez `provideKptI18n` — patrz `i18n/llms.txt`.
@@ -1,20 +1,29 @@
1
- # KptSidenav (kpt-sidenav)
2
-
3
- Panel boczny — stylowany kontener nawigacji, zwykle w slocie `kptShellSidenav`
4
- komponentu `kpt-app-shell`. Import: `import { KptSidenav } from '@konce-pt/angular';`
5
-
6
- ## Selektor
7
- `kpt-sidenav`
8
-
9
- ## Treść
10
- Dowolna zawartość (ng-content). Elementy `<a>` mają wbudowane style pozycji nawigacji
11
- (hover z `--kpt-color-muted`).
12
-
13
- ## Przykład
14
- <kpt-sidenav kptShellSidenav>
15
- <a href="#">Pulpit</a>
16
- <a href="#">Ustawienia</a>
17
- </kpt-sidenav>
18
-
19
- ## Tokeny
20
- `--kpt-sidenav-{bg,fg,border,width}` (szerokość ustawia `kpt-app-shell`).
1
+ # KptSidenav (kpt-sidenav)
2
+
3
+ Panel boczny — stylowany kontener nawigacji, zwykle w slocie `kptShellSidenav`
4
+ komponentu `kpt-app-shell`. Import: `import { KptSidenav } from '@konce-pt/angular';`
5
+
6
+ ## Selektor
7
+ `kpt-sidenav`
8
+
9
+ ## Treść
10
+ Dowolna zawartość (ng-content). Elementy `<a>` mają wbudowane style pozycji nawigacji
11
+ (hover z `--kpt-color-muted`).
12
+
13
+ ## Przykład
14
+ <kpt-sidenav kptShellSidenav>
15
+ <a href="#">Pulpit</a>
16
+ <a href="#">Ustawienia</a>
17
+ </kpt-sidenav>
18
+
19
+ ## Szyna ikon (kpt-app-shell)
20
+ Jeśli shell ma włączone `sidenavRailBreakpoint`, opatrz tekst pozycji atrybutem `kptNavLabel`,
21
+ a nagłówek grupy `kptNavSection` — w zwiniętej szynie zostaje sama ikona, a etykieta jest
22
+ chowana technicznie (visually hidden), więc czytnik ekranu wciąż zna nazwę pozycji:
23
+
24
+ <a href="#"><kpt-icon name="list" /> <span kptNavLabel>Pulpit</span></a>
25
+
26
+ To płaskie atrybuty, nie dyrektywy — nic nie trzeba importować. Bez ikony szyna będzie pusta.
27
+
28
+ ## Tokeny
29
+ `--kpt-sidenav-{bg,fg,border,width,rail-width}` (szerokość ustawia `kpt-app-shell`).
@@ -1,23 +1,31 @@
1
- # KptToolbar (kpt-toolbar)
2
-
3
- Górny pasek (toolbar) — pozioma belka na treść aplikacji.
4
- Import: `import { KptToolbar } from '@konce-pt/angular';`
5
-
6
- ## Selektor
7
- `kpt-toolbar`
8
-
9
- ## Wejścia
10
- - `elevated`: boolean — cień pod paskiem
11
-
12
- ## Odstęp
13
- Element z atrybutem `kptToolbarSpacer` dostaje `flex: 1` i rozpycha zawartość.
14
-
15
- ## Przykład
16
- <kpt-toolbar elevated>
17
- <strong>Koncept UI</strong>
18
- <span kptToolbarSpacer></span>
19
- <kpt-button variant="text">Wyloguj</kpt-button>
20
- </kpt-toolbar>
21
-
22
- ## Tokeny
23
- `--kpt-toolbar-{bg,fg,border,height}`.
1
+ # KptToolbar (kpt-toolbar)
2
+
3
+ Górny pasek (toolbar) — pozioma belka na treść aplikacji.
4
+ Import: `import { KptToolbar } from '@konce-pt/angular';`
5
+
6
+ ## Selektor
7
+ `kpt-toolbar`
8
+
9
+ ## Wejścia
10
+ - `elevated`: boolean — cień pod paskiem
11
+ - `wrap`: boolean — pozwala zawartości zawinąć się do kolejnych wierszy. Opcjonalne, bo
12
+ zawijanie zmienia zachowanie `kptToolbarSpacer`: w jednowierszowym pasku rozpycha on treść,
13
+ a w zawijanym potrafi zepchnąć resztę akcji do nowego wiersza.
14
+
15
+ ## Odstęp
16
+ Element z atrybutem `kptToolbarSpacer` dostaje `flex: 1` i rozpycha zawartość.
17
+
18
+ ## Przykład
19
+ <kpt-toolbar elevated>
20
+ <strong>Koncept UI</strong>
21
+ <span kptToolbarSpacer></span>
22
+ <kpt-button variant="text">Wyloguj</kpt-button>
23
+ </kpt-toolbar>
24
+
25
+ ## Responsywność
26
+ Poniżej breakpointa `sm` pasek sam zbiega się do `--kpt-toolbar-height-compact` i węższych
27
+ marginesów. Do chowania fragmentów zawartości na wąskim ekranie użyj klas `@konce-pt/grid`,
28
+ np. `class="kpt-hide kpt-display-sm-inline"` na podtytule.
29
+
30
+ ## Tokeny
31
+ `--kpt-toolbar-{bg,fg,border,height,height-compact}`.