diff --git a/_authors/wkulczak.md b/_authors/wkulczak.md
new file mode 100644
index 000000000..fe1f19893
--- /dev/null
+++ b/_authors/wkulczak.md
@@ -0,0 +1,8 @@
+---
+name: Wojciech Kulczak
+title: Wojciech Kulczak
+short_name: wkulczak
+github: wkulczi
+bio: Jestem programistą z kilkuletnim doświadczeniem i zażyłością do frameworków frontendowych. Lubię poznawać nowe technologie i eksperymentować z istniejącymi rozwiązaniami kod. Po godzinach gotuję, dbam o ogród, poszukuję idealnej kawy i winyli a czasem postrzelam z łuku.
+image: wkulczak.webp
+---
diff --git a/_posts/pl/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms.md b/_posts/pl/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms.md
new file mode 100644
index 000000000..38e412ba4
--- /dev/null
+++ b/_posts/pl/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms.md
@@ -0,0 +1,268 @@
+---
+layout: post
+title: "Czy wiesz, że Angular 21 rozszerza API formularzy o Signal Forms?"
+description: Wraz z publikacją Angulara w wersji 21 opracowano nowy system definicji formularzy za pomocą sygnałów.
+date: 2026-04-24T08:00:00+01:00
+published: true
+didyouknow: false
+lang: pl
+author: wkulczak
+image: /assets/img/posts/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms/thumbnail.webp
+tags:
+- angular
+- signals
+---
+
+Wraz z publikacją Angulara w wersji 21 opracowano nowy system definicji formularzy za pomocą sygnałów,
+dostępny w pakiecie @angular/forms/signals. Choć jest to obecnie funkcja eksperymentalna,
+wyraźnie wyznacza przyszły kierunek rozwoju frameworka.
+
+To rozwiązanie pozwala na scentralizowany kod, lepsze wsparcie typowania, prostsze definicje własnych komponentów i przejrzystą walidację.
+
+## Dlaczego Signal Forms? Różnica w podejściu do danych
+Signal Forms stanowią zmianę paradygmatu w porównaniu do Template-Driven Forms i Reactive Forms. Kluczowe zasady to:
+
+1. **Model jako źródło prawdy**: Zamiast wydobywać dane z wewnętrznych struktur frameworka, to Ty dostarczasz własny sygnał, który formularz jedynie odzwierciedla i synchronizuje
+2. **Deklaratywna logika**: Logika walidacji jest opisywana w schemacie.
+3. **Strukturalne mapowanie**: Struktura pól odzwierciedla model danych w stosunku 1:1, a struktura formularza jest automatycznie wyprowadzana z modelu danych.
+W tym podejściu formularz to hierarchia pól, z której automatycznie **wyprowadzany jest stan** (błędy, stan disabled, touched itp.).
+**Kluczowa Różnica**: W Signal Forms model formularza jest **źródłem prawdy** (source of truth), a nie **wynikiem/wyjściem** (output).
+
+**Korzyści w pigułce**:
+- **Brak boilerplate'u**: Drastyczna redukcja kodu.
+- **Silne typowanie**: Wyprowadzane jest z modelu.
+- **Automatyczne dwukierunkowe wiązanie**: Za pomocą dyrektywy `[field]`.
+- **Brak subskrypcji**: Wykorzystanie wbudowanej reaktywności sygnałów.
+
+## Tworzenie Formularza
+Rekomendowanym sposobem definicji formularza jest związanie go z dedykowanym interfejsem.
+
+```typescript
+export interface UserAccountRegistration {
+ email: string;
+ password: {
+ pw1: string;
+ pw2: string;
+ }
+}
+```
+
+```typescript
+protected readonly userAccountRegistration = signal(userAccountRegistrationInitValue) // Źródło prawdy
+protected readonly userAccountRegistrationForm = form(this.userAccountRegistration, registrationValidationSchema);
+```
+
+Metoda `form(model, schema)` tworzy `FieldTree` (drzewo pól), które odzwierciedla model danych.
+Aby uzyskać aktualny stan i wartość danego pola, wywołujemy je jako funkcję, otrzymując `FieldState` (np. `form.email().value()`).
+
+### Komponenty w Szablonie
+Do połączenia pól formularza z szablonem używamy dyrektywy **Field**.
+
+```html
+
+```
+
+### Komponenty Formularza (Custom Controls)
+Tworzenie własnych komponentów formularza jest znacząco przyjemniejsze do implementacji niż w Reactive Forms, gdzie wymagany był `ControlValueAccessor`.
+
+Aby tworzony komponent mógł być użyty jako pole formularza z dyrektywą `[field]`, należy zaimplementować jeden z dedykowanych interfejsów:
+
+1. `FormValueControl`: Dla większości pól edytujących pojedynczą wartość (np. pole tekstowe, wybór daty).
+2. `FormCheckboxControl`: Dla kontrolek typu checkbox lub toggle, które reprezentują stan boolean (w tym przypadku wymagana jest właściwość checked zamiast value).
+Oba interfejsy dziedziczą z `FormUiControl` i wymagają jedynie, aby komponent udostępniał właściwość **value** (lub checked) jako `ModelSignal`.
+
+```typescript
+@Component({
+ selector: 'app-password-strength',
+ // ...
+})
+// Wymagana jest implementacja FormValueControl
+export class PasswordStrength implements FormValueControl {
+ // Właściwość 'value' musi być model signal. Model signal to połączenie input i output.
+ readonly value = model('');
+ // Opcjonalne: synchronizacja stanu formularza
+ readonly invalid = input(false);
+ readonly touched = model(false);
+ readonly label = input('Password');
+
+ protected changeInput(input: Event) {
+ const target = input.target as HTMLInputElement;
+ // Zmiana wartości poprzez set() automatycznie synchronizuje stan z modelem formularza.
+ this.value.set(target.value);
+ }
+
+ protected markAsTouched() {
+ this.touched.set(true);
+ }
+}
+```
+
+Dyrektywa `[field]` automatycznie łączy ten model z modelem formularza i przekazuje stany takie jak disabled, invalid,
+required i errors jako opcjonalne sygnały `input()` do komponentu.
+
+## Walidacje: Schemat Deklaratywny
+
+Walidacje tworzone są za pomocą metody schema, a następnie przekazywane do metody form. Schemat jest definiowany deklaratywnie w jednym miejscu.
+
+Biblioteka wyposażona jest w szereg wbudowanych funkcji walidacyjnych, takich jak `email`, `required`, `minLength`, `maxLength`, `min`, `max` i `pattern`.
+
+```typescript
+export const registrationValidationSchema = schema((schemaPath) => {
+ required(schemaPath.email, {message: 'Email is required'});
+ email(schemaPath.email, {message: 'Invalid email address'});
+ required(schemaPath.password.pw1, {message: 'Password is required'});
+ minLength(schemaPath.password.pw1, 4, {message: 'Password must be at least 4 characters long'})...
+}
+```
+
+### Walidacja Międzypolowa (validateTree)
+
+Możliwe jest powiązanie walidatorów z innymi polami formularza, co jest niezbędne np. do sprawdzania zgodności haseł. Używamy do tego funkcji `validateTree()`.
+
+```typescript
+validateTree(schemaPath.password, (ctx) => {
+ return ctx.value().pw2 === ctx.value().pw1
+ ? undefined
+ : {
+ field: ctx.field.pw2, // Przypisanie błędu do konkretnego pola
+ kind: 'confirmationPassword',
+ message: 'Entered password must match with the one specified above'
+ }
+});
+```
+
+### Walidacja Asynchroniczna (validateAsync)
+
+Signal Forms wspierają walidację asynchroniczną (np. sprawdzanie dostępności nazwy użytkownika lub e-maila na serwerze) za pomocą `validateAsync`.
+
+```typescript
+export const registrationValidationSchema= schema((schemaPath) => {
+ ...
+ // Przykład walidacji asynchronicznej
+ validateAsync(schemaPath.email, {
+ params: ({value}) => value(),
+ factory: (params) => {
+ const registrationService = inject(RegistrationService);
+ return resource({
+ params,
+ loader: async({params}) => {
+ return await registrationService.checkEmailTaken(params)
+ }
+ });
+ },
+ onSuccess: (result) => {
+ return result ? {
+ kind: 'mailTaken',
+ message: 'Mail address is already taken. Please choose another one.'
+ } : undefined
+ },
+ onError: () => undefined
+ });
+});
+```
+
+Podczas oczekiwania na wynik walidacji asynchronicznej pole ma ustawiony stan `pending()` na true, co można wykorzystać do wyświetlania informacji zwrotnej w UI.
+
+### Walidacja Warunkowa i Kontrola Stanu
+
+Możemy warunkowo stosować schematy lub kontrolować stan pól (`disabled`, `hidden`, `readonly`) w oparciu o inne wartości w formularzu, używając `applyWhenValue` lub `applyWhen`.
+
+Przykłady kontroli stanu pól:
+
+- Wyłączanie (Disabling):
+```typescript
+disabled(schemaPath.newsletterTopics, (ctx) => !ctx.valueOf(schemaPath.newsletter));
+```
+Warto dodać, że w Signal Forms możemy zwracać powód wyłączenia. Powody te są dostępne przez sygnał `disabledReasons()`.
+
+- Ukrywanie (Hiding):
+```typescript
+hidden(schemaPath.someField, (ctx) => !ctx.valueOf(schemaPath.otherField));
+```
+
+Przykładowe użycie:
+```typescript
+applyWhen(schemaPath, (ctx) => ctx.value().newsletter, (schemaPathWhenTrue) => {
+ required(schemaPathWhenTrue.newsletterFrequency, {message: 'Select a frequency'});
+})
+```
+
+### Debouncing (Opóźnianie Aktualizacji)
+
+Aby zapobiec nadmiernej liczbie wywołań API podczas szybkiego wpisywania (np. w walidacji asynchronicznej), możemy łatwo zastosować debouncing za pomocą funkcji `debounce()`:
+
+```typescript
+// Opóźnienie aktualizacji wartości pola email o 500ms
+debounce(schemaPath.email, 500);
+validateAsync(schemaPath.email, { ... });
+```
+
+Dzięki temu aktualizacje do modelu i walidatory asynchroniczne są uruchamiane dopiero po ustaniu pisania na dany czas.
+
+### Integracja z Zewnętrznymi Schematami
+
+Zespół Angular umożliwił również walidację za pomocą zewnętrznych bibliotek implementujących reguły walidacyjne za pomocą **Standard Schema** (np. Zod, czy Valibot). Odbywa się to za pomocą helpera `validateStandardSchema`.
+
+```typescript
+import {z} from 'zod';
+validateStandardSchema(schemaPath.phoneNumber, z.e164("Not a phone number!"))
+```
+
+## Zarządzanie Stanem Wysyłania i Błędami Serwera
+
+Do obsługi wysyłania formularza (szczególnie operacji asynchronicznych) zaleca się użycie dedykowanej funkcji `submit()`.
+
+Funkcja `submit()` automatycznie zarządza stanem `submitting()` (dostępnym jako sygnał: `form().submitting()`).
+
+Jeśli podczas zapisu wystąpią błędy serwera, możemy je przypisać z powrotem do konkretnych pól formularza lub do całego formularza, zwracając tablicę obiektów `ValidationErrorWithField`.
+
+```typescript
+protected submitForm() {
+ submit(this.registrationForm, async (form) => {
+ const errors: ValidationErrorWithField[] = [];
+ try {
+ await this.#registrationService.registerUser(form().value);
+ } catch (e) {
+ // Przypisanie błędu do konkretnego pola
+ errors.push({
+ field: form.username,
+ kind: 'serverValidation',
+ message: 'Username is not available.'
+ });
+ }
+ return errors; // Zwrócone błędy serwera są automatycznie dodawane do stanu formularza.
+ });
+ return false;
+}
+```
+
+Dzięki Signal Forms w o wiele prostszy sposób można, implementować złożone reguły walidacyjne (np. asynchroniczne czy między polowe) w jednym, centralnym schemacie.
+
+Ten nowy, reaktywny model znacząco redukuje boilerplate i gwarantuje silne typowanie-cechy, których brakowało w tradycyjnych Reactive Forms.
+Choć Signal Forms pozostają funkcją eksperymentalną w Angular v21, stanowią optymalny wybór dla nowych projektów opartych na sygnałach,
+oferując lepsze doświadczenie deweloperskie i fine-grained reactivity.
+
+## Stan Signal Forms i Podsumowanie
+Signal Forms (dostępne w @angular/forms/signals) zostały wprowadzone w Angular v21 jako funkcja eksperymentalna.
+Oznacza to, że API i funkcjonalność mogą ulec zmianie w przyszłych wydaniach, zanim zostaną ustabilizowane.
+
+Zespół Angulara rekomenduje Signal Forms do nowych projektów, pamiętając jednak, że to wciąż funkcja eksperymentalna,
+która może ulec zmianie przed stabilizacją.
+
+Mimo to, nowy model reaktywny z Signal Forms rozwiązuje wiele problemów związanych z Reactive Forms:
+
+| Obszar | Reactive Forms | Signal Forms |
+|---------------------|--------------------------------------------|---------------------------------------------|
+| **Boilerplate** | Duży (FormGroup, FormControl, FormBuilder) | Bardzo niski (Czysty model + schema) |
+| **Typowanie** | Wymaga jawnych typów lub Typed Forms | Silne, wyprowadzane z modelu |
+| **Reaktywność** | Oparta na Observables (subskrypcje) | Oparta na Signals (Fine-grained reactivity) |
+| **Custom Controls** | Wymaga ControlValueAccessor | Wymaga FormValueControl (znacznie prostsze) |
+| **Źródło Prawdy** | Hierarchia FormControl/FormGroup | Writable Signal Model (dane użytkownika) |
+
+
+Signal Forms demonstrują, w jakim kierunku ewoluuje Angular.
+Po Template-Driven Forms i Reactive Forms, Signal Forms są **trzecim głównym podejściem** do obsługi formularzy w Angularze,
+które ma na celu uczynienie ich bardziej **bezpiecznymi pod kątem typowania, reaktywnymi i deklaratywnymi.**
+
+
+CodeSandbox: https://codesandbox.io/p/github/wkulczi/ngsignals/master
\ No newline at end of file
diff --git a/assets/img/authors/wkulczak.webp b/assets/img/authors/wkulczak.webp
new file mode 100644
index 000000000..10cd8804b
Binary files /dev/null and b/assets/img/authors/wkulczak.webp differ
diff --git a/assets/img/posts/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms/thumbnail.webp b/assets/img/posts/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms/thumbnail.webp
new file mode 100644
index 000000000..095819f84
Binary files /dev/null and b/assets/img/posts/2026-04-24-czy-wiesz-ze-angular-21-rozszerza-api-formularzy-o-signal-forms/thumbnail.webp differ