@konce-pt/angular 0.7.9 → 0.7.11
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/CHANGELOG.md +63 -0
- package/fesm2022/konce-pt-angular-charts.mjs +8 -8
- package/fesm2022/konce-pt-angular-charts.mjs.map +1 -1
- package/fesm2022/konce-pt-angular.mjs +1680 -587
- package/fesm2022/konce-pt-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/auth/llms.txt +104 -0
- package/src/lib/context-menu/llms.txt +2 -2
- package/src/lib/i18n/llms.txt +2 -2
- package/src/lib/input/llms.txt +2 -0
- package/src/lib/megamenu/llms.txt +1 -1
- package/src/lib/menu/llms.txt +2 -2
- package/src/lib/menubar/llms.txt +2 -2
- package/src/lib/password/llms.txt +3 -0
- package/src/lib/rich-text/llms.txt +20 -1
- package/src/lib/speed-dial/llms.txt +2 -2
- package/src/lib/split-button/llms.txt +2 -2
- package/types/konce-pt-angular.d.ts +367 -38
- package/types/konce-pt-angular.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konce-pt/angular",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.11",
|
|
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",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# KptAuth (kpt-auth)
|
|
2
|
+
|
|
3
|
+
Ekran uwierzytelniania: logowanie, rejestracja i odzyskiwanie hasła w jednym komponencie,
|
|
4
|
+
z panelem promocyjnym i listą dostawców zewnętrznych (OAuth/SSO). Signal Forms.
|
|
5
|
+
Komponent jest **prezentacyjny** — nie woła API i nie nawiguje; robi to aplikacja w handlerach.
|
|
6
|
+
Import: `import { KptAuth, KptAuthProviderDef } from '@konce-pt/angular';`
|
|
7
|
+
|
|
8
|
+
## Selektor
|
|
9
|
+
`kpt-auth`
|
|
10
|
+
|
|
11
|
+
## Wejścia
|
|
12
|
+
- `mode`: model<'signIn' | 'signUp' | 'forgot'> = 'signIn' — dwukierunkowy (aplikacja może wymusić tryb)
|
|
13
|
+
- `layout`: 'slider' | 'split' = 'slider' — panel promocyjny przejeżdża na drugą stronę / stoi w miejscu
|
|
14
|
+
- `providers`: KptAuthProvider[] = [] — `{ id, label, icon?, iconUrl?, description? }`
|
|
15
|
+
- `providerLayout`: 'list' | 'grid' = 'list' — lista pełnej szerokości / siatka ikon z podpisami
|
|
16
|
+
- `showName`, `requireTerms`, `showRemember`: boolean = true — obecność pól
|
|
17
|
+
- `busy`: boolean — przyciski w stanie ładowania, dostawcy zablokowani
|
|
18
|
+
- `error` / `notice`: string | null — komunikat serwera (kpt-alert `danger` / `success`)
|
|
19
|
+
- `promoTitle` / `promoText`: string | null — `null` = tekst z i18n zależny od trybu,
|
|
20
|
+
`''` = ukryj (miejsce na slot `[kptAuthPromo]`)
|
|
21
|
+
- `animated`: boolean = true; `animationDuration`: number = 320 (ms)
|
|
22
|
+
|
|
23
|
+
## Wyjścia
|
|
24
|
+
- `signIn`: { email, password, remember }
|
|
25
|
+
- `signUp`: { name, email, password, terms }
|
|
26
|
+
- `resetPassword`: { email }
|
|
27
|
+
- `providerSelect`: KptAuthProvider — wybrany dostawca (pełny obiekt, nie samo `id`)
|
|
28
|
+
- `modeChange` — z `model` `mode`
|
|
29
|
+
|
|
30
|
+
## Projekcja
|
|
31
|
+
- `[kptAuthBrand]` — logo/nazwa nad nagłówkiem
|
|
32
|
+
- `[kptAuthPromo]` — treść panelu promocyjnego (pod tytułem/tekstem, nad CTA)
|
|
33
|
+
- `[kptAuthSso]` — przycisk logowania firmowego **nad** separatorem dostawców
|
|
34
|
+
- `[kptAuthFields]` — dodatkowe pola wewnątrz `<form>` (logowanie i rejestracja)
|
|
35
|
+
- `[kptAuthFooter]` — stopka (regulamin, prawa autorskie)
|
|
36
|
+
- `ng-template[kptAuthProvider]="id"` (`KptAuthProviderDef`) — własny markup jednego dostawcy;
|
|
37
|
+
kontekst: `$implicit` = dostawca, `select` = funkcja zgłaszająca wybór
|
|
38
|
+
|
|
39
|
+
**Pola ze slotu `[kptAuthFields]` nie wchodzą do modelu komponentu.** Konsument wiąże je do
|
|
40
|
+
własnego formularza i czyta w handlerze `signIn`/`signUp` — w emitowanej wartości ich nie ma.
|
|
41
|
+
|
|
42
|
+
## Walidacja
|
|
43
|
+
Trzy niezależne formularze (po jednym na tryb), walidatory bezwarunkowe: e-mail wymagany
|
|
44
|
+
i poprawny, hasło wymagane (rejestracja: min. 8 znaków), zgodność hasła i powtórzenia
|
|
45
|
+
(`validateTree`), zgoda wymagana gdy `requireTerms`. Komunikaty składane są z `kind` błędu
|
|
46
|
+
w czasie renderowania, więc **zmiana języka w runtime przerysowuje je** (walidatory tworzą się raz).
|
|
47
|
+
Błąd pokazuje się dopiero po dotknięciu pola; `submit()` sam oznacza całe drzewo jako dotknięte.
|
|
48
|
+
|
|
49
|
+
## Ikony dostawców
|
|
50
|
+
Rdzeń nie zawiera ikon marek. Trzy drogi:
|
|
51
|
+
1. `provideKptTablerIcons()` z `@konce-pt/angular/icons` → `icon: 'brand-google'`,
|
|
52
|
+
`'brand-facebook'`, `'brand-linkedin'`, `'brand-windows'`, `'brand-apple'`, `'brand-github'`, `'key'`.
|
|
53
|
+
2. `KptIconRegistry.register({ google: '<path …/>' })` — uwaga: sanityzator przepuszcza
|
|
54
|
+
`fill`/`stroke`/`opacity`, ale wycina `defs`/gradienty i `fill-rule`, a `viewBox` jest ustalony
|
|
55
|
+
na `0 0 24 24`. Wielokolorowe logo wymaga jawnego `fill` na każdej ścieżce.
|
|
56
|
+
3. `iconUrl` (zwykły `<img alt="">`) albo szablon `kptAuthProvider` — dla logo z gradientem.
|
|
57
|
+
|
|
58
|
+
Ikona jest dekoracyjna (`kpt-icon` ma `aria-hidden`), więc nazwa dostępna przycisku zawsze
|
|
59
|
+
pochodzi z `label`.
|
|
60
|
+
|
|
61
|
+
## Dostępność
|
|
62
|
+
- W drzewie żyje **wyłącznie formularz aktywnego trybu** — nie ma elementów niewidocznych,
|
|
63
|
+
ale wciąż fokusowalnych.
|
|
64
|
+
- Nagłówek panelu ma `tabindex="-1"` i dostaje fokus po zmianie trybu (inaczej zmiana nie
|
|
65
|
+
zostaje ogłoszona, a fokus zostaje na przycisku, który zjechał z ekranu).
|
|
66
|
+
- Etykiety przez `kpt-form-field` + `controlId`; `autocomplete`: `email`, `current-password`,
|
|
67
|
+
`new-password`, `name`.
|
|
68
|
+
- Przełączniki trybu to `<button>` z tekstem, nie `<a href="#">`.
|
|
69
|
+
- `prefers-reduced-motion` wyłącza przejazdy i wjazd treści.
|
|
70
|
+
|
|
71
|
+
## Stylowanie
|
|
72
|
+
Publiczne zmienne: `--kpt-auth-width` (64rem), `--kpt-auth-card-height` (34rem),
|
|
73
|
+
`--kpt-auth-min-height` (100dvh), `--kpt-auth-promo-bg` (własny gradient marki),
|
|
74
|
+
`--kpt-auth-padding`, `--kpt-auth-card-radius` / `--kpt-auth-card-border` / `--kpt-auth-card-shadow`.
|
|
75
|
+
Wariant na całe okno (karta bez ramki, od krawędzi do krawędzi):
|
|
76
|
+
|
|
77
|
+
kpt-auth {
|
|
78
|
+
--kpt-auth-padding: 0;
|
|
79
|
+
--kpt-auth-width: 100%;
|
|
80
|
+
--kpt-auth-card-height: 100dvh;
|
|
81
|
+
--kpt-auth-card-radius: 0;
|
|
82
|
+
--kpt-auth-card-border: 0;
|
|
83
|
+
--kpt-auth-card-shadow: none;
|
|
84
|
+
}
|
|
85
|
+
Poniżej breakpointu `md` układ schodzi do jednej kolumny (promo nad formularzem, bez przejazdu).
|
|
86
|
+
|
|
87
|
+
## Przykład
|
|
88
|
+
<kpt-auth
|
|
89
|
+
[providers]="[{ id: 'google', label: 'Google', icon: 'brand-google' }]"
|
|
90
|
+
[busy]="loading()"
|
|
91
|
+
[error]="serverError()"
|
|
92
|
+
(signIn)="login($event)"
|
|
93
|
+
(signUp)="register($event)"
|
|
94
|
+
(resetPassword)="sendLink($event.email)"
|
|
95
|
+
(providerSelect)="oauth($event.id)"
|
|
96
|
+
>
|
|
97
|
+
<img kptAuthBrand src="/logo.svg" alt="Konce" />
|
|
98
|
+
<small kptAuthFooter>© 2026 Konce</small>
|
|
99
|
+
</kpt-auth>
|
|
100
|
+
|
|
101
|
+
## i18n
|
|
102
|
+
Wszystkie napisy pochodzą z namespace `auth` (EN/PL), w tym `auth.promo.*` i interpolacje
|
|
103
|
+
`auth.continueWith` ({provider}), `auth.passwordHint` / `auth.errorMinLength` ({min}).
|
|
104
|
+
Patrz `i18n/llms.txt`.
|
|
@@ -7,11 +7,11 @@ Import: `import { KptContextMenu } from '@konce-pt/angular';`
|
|
|
7
7
|
- `items`: KptMenuItem<T>[] — { label, icon?, danger?, disabled?, separator? }
|
|
8
8
|
Honoruje też `header` (nieklikalny wiersz z `avatar`/`label`/`description`), `description`
|
|
9
9
|
(druga linia) i `badge` + `badgeVariant` (odznaka po prawej) — pełny opis w menu/llms.txt.
|
|
10
|
-
- `
|
|
10
|
+
- `selected`: KptMenuItem<T> — wybór pozycji
|
|
11
11
|
- Obszar reagujący na PPM przez projekcję `<ng-content>`.
|
|
12
12
|
|
|
13
13
|
## Przykład
|
|
14
|
-
<kpt-context-menu [items]="items" (
|
|
14
|
+
<kpt-context-menu [items]="items" (selected)="onSelect($event)">
|
|
15
15
|
<div class="obszar">Kliknij prawym przyciskiem</div>
|
|
16
16
|
</kpt-context-menu>
|
|
17
17
|
|
package/src/lib/i18n/llms.txt
CHANGED
|
@@ -27,8 +27,8 @@ Import: `import { provideKptI18n, KptI18n } from '@konce-pt/angular';`
|
|
|
27
27
|
Namespace'y: `common` (close/remove/previous/next/clear/done/all), `paginator` (rowsPerPage/range/prevPage/nextPage),
|
|
28
28
|
`select`, `listbox`, `dataView`, `dataTable`, `confirm`, `fileUpload`, `chipsInput`, `dateRange`, `datepicker`,
|
|
29
29
|
`pickList`, `orderList`, `inputNumber`, `password`, `spinner`, `speedDial`, `scrollTop`, `splitButton`, `panel`,
|
|
30
|
-
`breadcrumb`, `richText
|
|
31
|
-
`richText.styleHeading` ({level}). Nazwy dni/miesięcy w kalendarzach są wyliczane z `Intl` wg locale (nie ze słownika).
|
|
30
|
+
`breadcrumb`, `richText`, `auth` (w tym `auth.promo.*`). Interpolacje: `paginator.range` ({start},{end},{total}), `dataTable.filter*` ({column}),
|
|
31
|
+
`richText.styleHeading` ({level}), `auth.continueWith` ({provider}), `auth.passwordHint` i `auth.errorMinLength` ({min}). Nazwy dni/miesięcy w kalendarzach są wyliczane z `Intl` wg locale (nie ze słownika).
|
|
32
32
|
|
|
33
33
|
## Uwaga
|
|
34
34
|
Pojedyncze etykiety można też nadpisać per-komponent przez odpowiedni `input()` (np. `emptyMessage`, `acceptLabel`) —
|
package/src/lib/input/llms.txt
CHANGED
|
@@ -32,6 +32,8 @@ Pełny przepływ: sekcja `## Formularz od zera (Signal Forms)` w głównym llms.
|
|
|
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
|
|
35
|
+
- `autocomplete`: string | null — podpowiedź dla przeglądarki i menedżera haseł
|
|
36
|
+
(np. `email`, `username`, `one-time-code`); bez niej autouzupełnianie nie działa
|
|
35
37
|
|
|
36
38
|
## Stan wiązany automatycznie przez FormField
|
|
37
39
|
`value` (model, wymagane), `disabled`, `readonly`, `required`, `invalid`, `errors`,
|
|
@@ -8,7 +8,7 @@ Import: `import { KptMegamenu } from '@konce-pt/angular';`
|
|
|
8
8
|
|
|
9
9
|
## Wejścia / wyjścia
|
|
10
10
|
- `items`: KptMenuItem<T>[] (3 poziomy: top → kolumny → linki)
|
|
11
|
-
- `
|
|
11
|
+
- `selected`: KptMenuItem<T> (kliknięty odnośnik)
|
|
12
12
|
|
|
13
13
|
## Przykład
|
|
14
14
|
items = [{
|
package/src/lib/menu/llms.txt
CHANGED
|
@@ -6,7 +6,7 @@ Import: `import { KptMenu, KptMenuItem } from '@konce-pt/angular';`
|
|
|
6
6
|
|
|
7
7
|
## Wejścia / wyjścia
|
|
8
8
|
- `items`: KptMenuItem[]
|
|
9
|
-
- `
|
|
9
|
+
- `selected`: output<KptMenuItem> — emitowany tylko dla zwykłych pozycji (nie dla nagłówków)
|
|
10
10
|
|
|
11
11
|
## KptMenuItem
|
|
12
12
|
- `label?`, `value?`, `icon?`, `disabled?`, `danger?`, `separator?`
|
|
@@ -23,7 +23,7 @@ Import: `import { KptMenu, KptMenuItem } from '@konce-pt/angular';`
|
|
|
23
23
|
Pola `header`, `description`, `badge` i `avatar` honorują też `kpt-context-menu` i `kpt-split-button`.
|
|
24
24
|
|
|
25
25
|
## Przykład
|
|
26
|
-
<kpt-menu [items]="items" (
|
|
26
|
+
<kpt-menu [items]="items" (selected)="onSelect($event)">
|
|
27
27
|
<kpt-avatar name="Anna Kowalska" />
|
|
28
28
|
</kpt-menu>
|
|
29
29
|
|
package/src/lib/menubar/llms.txt
CHANGED
|
@@ -7,10 +7,10 @@ Import: `import { KptMenubar } from '@konce-pt/angular';`
|
|
|
7
7
|
|
|
8
8
|
## Wejścia / wyjścia
|
|
9
9
|
- `items`: KptMenuItem<T>[] — pozycje górne; pod-menu w `items?` każdej pozycji
|
|
10
|
-
- `
|
|
10
|
+
- `selected`: KptMenuItem<T>
|
|
11
11
|
|
|
12
12
|
## Przykład
|
|
13
|
-
<kpt-menubar [items]="items" (
|
|
13
|
+
<kpt-menubar [items]="items" (selected)="onSelect($event)" />
|
|
14
14
|
|
|
15
15
|
items: KptMenuItem[] = [
|
|
16
16
|
{ label: 'Plik', items: [{ label: 'Nowy' }, { separator: true }, { label: 'Zamknij', danger: true }] },
|
|
@@ -7,6 +7,9 @@ Import: `import { KptPassword } from '@konce-pt/angular';`
|
|
|
7
7
|
- `value`: model<string> (lub `formField`)
|
|
8
8
|
- `feedback`: boolean — pokazuje miernik siły (4 paski + etykieta)
|
|
9
9
|
- `placeholder`: string
|
|
10
|
+
- `id`: string — id natywnego pola; wiąże etykietę z `kpt-form-field [controlId]`
|
|
11
|
+
- `autocomplete`: string | null = 'current-password' — w rejestracji i resecie ustaw
|
|
12
|
+
`new-password`, inaczej menedżer haseł podstawi stare hasło zamiast zaproponować nowe
|
|
10
13
|
- `disabled`/`invalid`/`touched`: boolean; `touch`: output
|
|
11
14
|
|
|
12
15
|
## Siła hasła
|
|
@@ -10,11 +10,20 @@ Import: `import { KptRichText, KptRichTool, KptRichToolbar } from '@konce-pt/ang
|
|
|
10
10
|
- `toolbar`: KptRichToolbar = KptRichTool[] | KptRichTool[][] (płaska lista lub grupy=sekcje).
|
|
11
11
|
Pominięcie narzędzia/grupy je wyłącza; między grupami separator. Domyślnie pełny pasek w 5 sekcjach.
|
|
12
12
|
- `placeholder`: string; `disabled`/`invalid`/`touched`: boolean; `touch`: output
|
|
13
|
+
- `maxListLevel`: number = 6 — maksymalna głębokość zagnieżdżenia list. Limit dotyczy interakcji
|
|
14
|
+
(Tab i narzędzia `indent`/`outdent`); wklejonej treści nie spłaszczamy, żeby nie gubić danych.
|
|
13
15
|
|
|
14
16
|
## Narzędzia (KptRichTool)
|
|
15
17
|
- Schowek: `copy`, `paste` (z formatowaniem, oczyszczone), `pasteText` (bez formatowania)
|
|
16
18
|
- Styl: `heading` (select: Normalny/paragraf + Nagłówek 1–6)
|
|
17
19
|
- Format: `bold`, `italic`, `underline`, `strike`, `ul`, `ol`
|
|
20
|
+
- Wcięcia list: `indent` (dodaj wcięcie), `outdent` (usuń wcięcie) — działają wyłącznie w `li`,
|
|
21
|
+
zagnieżdżają zgodnie ze specyfikacją (`li > ul/ol > li`, podlista dziedziczy typ listy rodzica).
|
|
22
|
+
Aktywne tylko tam, gdzie coś zrobią (poza listą i przy limicie przycisk jest wyszarzony).
|
|
23
|
+
Znaczniki poziomów cyklują co 3 (jak w edytorach tekstu): `ol` 1. → a. → i., `ul` • → ○ → ▪.
|
|
24
|
+
Reguły `list-style-type` obowiązują w widoku edytora (`.kpt-rich-text__editor`) do 6. poziomu.
|
|
25
|
+
Zapisany HTML nie niesie klas — renderując `value` poza edytorem opakuj go w `.kpt-rich-content`
|
|
26
|
+
z `@konce-pt/styles`, żeby listy wyglądały tak samo.
|
|
18
27
|
- Kolory: `foreColor` (kolor tekstu), `backColor` (kolor tła) — popover z próbkami + `input type=color`
|
|
19
28
|
- Wyrównanie: `alignLeft`, `alignCenter`, `alignRight`, `alignJustify`
|
|
20
29
|
- `table` (wstaw tabelę: popover z siatką NxM). W komórce prawy klik = menu kontekstowe
|
|
@@ -26,6 +35,15 @@ Import: `import { KptRichText, KptRichTool, KptRichToolbar } from '@konce-pt/ang
|
|
|
26
35
|
Odłożone: selekcja nieregularna, Ctrl+Backspace, zbiorcze formatowanie z górnego paska.
|
|
27
36
|
- `link` (prompt URL), `clear` (usuń formatowanie), `html` (przełącznik podglądu źródła HTML — edycja surowego HTML)
|
|
28
37
|
|
|
38
|
+
## Klawiatura
|
|
39
|
+
- Tab / Shift+Tab w punkcie listy = wcięcie / poziom wyżej (to samo co `indent`/`outdent`).
|
|
40
|
+
- Tab / Shift+Tab w komórce tabeli = następna / poprzednia komórka (z zaznaczeniem jej treści).
|
|
41
|
+
Lista wewnątrz komórki ma pierwszeństwo — dopiero gdy nie da się już wciąć, Tab zmienia komórkę.
|
|
42
|
+
- Wszędzie indziej — a także na pierwszym punkcie listy, na poziomie najwyższym, przy `maxListLevel`
|
|
43
|
+
i w ostatniej komórce tabeli — Tab zostaje **natywny** i wyprowadza fokus z edytora. To celowe:
|
|
44
|
+
edytor nie może być pułapką klawiaturową (WCAG 2.1.2), więc `preventDefault()` wołamy wyłącznie
|
|
45
|
+
wtedy, gdy operacja faktycznie zmieniła treść.
|
|
46
|
+
|
|
29
47
|
## Przykład
|
|
30
48
|
<kpt-rich-text [formField]="f.body" /> <!-- pełny pasek -->
|
|
31
49
|
<kpt-rich-text [(value)]="v" [toolbar]="[['bold','italic'],['ul','ol'],['link']]" />
|
|
@@ -42,4 +60,5 @@ Sanityzacja obejmuje **każdy** zapis do DOM edytora, nie tylko paste — w tym
|
|
|
42
60
|
zewnątrz (`[(value)]`/`formField` z aplikacji, tryb źródła HTML). Traktuj `value` na wejściu jako
|
|
43
61
|
potencjalnie niezaufane (DB, inny użytkownik, CMS); na wyjściu z komponentu jest sanityzowane.
|
|
44
62
|
Schowek „wklej"/„wklej bez formatowania" używa async Clipboard API (wymaga uprawnień przeglądarki).
|
|
45
|
-
|
|
63
|
+
Wyjątek od execCommand: wcięcia list robimy własnym kodem na DOM — `execCommand('indent')` produkuje
|
|
64
|
+
w Chrome niepoprawne `ul > ul` (albo `blockquote` z marginesem, który i tak zdjąłby sanityzator).
|
|
@@ -7,10 +7,10 @@ Import: `import { KptSpeedDial } from '@konce-pt/angular';`
|
|
|
7
7
|
- `items`: KptMenuItem<T>[] — akcje (label, icon)
|
|
8
8
|
- `direction`: 'up' | 'down' | 'left' | 'right' (KptSpeedDialDirection)
|
|
9
9
|
- `icon`: string (domyślnie 'plus', obraca się o 45° po otwarciu); `ariaLabel`: string
|
|
10
|
-
- `
|
|
10
|
+
- `selected`: KptMenuItem<T>
|
|
11
11
|
|
|
12
12
|
## Przykład
|
|
13
|
-
<kpt-speed-dial [items]="actions" direction="up" (
|
|
13
|
+
<kpt-speed-dial [items]="actions" direction="up" (selected)="onAction($event)" />
|
|
14
14
|
|
|
15
15
|
## Tokeny
|
|
16
16
|
FAB główny z `kpt-fab`; akcje `--kpt-color-surface-raised`, `--kpt-elevation-2`.
|
|
@@ -13,10 +13,10 @@ Wymaga `import '@angular/cdk/overlay-prebuilt.css';`
|
|
|
13
13
|
|
|
14
14
|
## Wyjścia
|
|
15
15
|
- `primaryClick`: void — klik przycisku głównego
|
|
16
|
-
- `
|
|
16
|
+
- `selected`: KptMenuItem<T> — wybór pozycji z menu
|
|
17
17
|
|
|
18
18
|
## Przykład
|
|
19
|
-
<kpt-split-button [items]="items" (primaryClick)="save()" (
|
|
19
|
+
<kpt-split-button [items]="items" (primaryClick)="save()" (selected)="onItem($event)">Zapisz</kpt-split-button>
|
|
20
20
|
|
|
21
21
|
items: KptMenuItem[] = [
|
|
22
22
|
{ label: 'Zapisz jako szkic', value: 'draft' },
|