# Inputy i pola formularzy

## Dwa rodzaje pól

**Ustawienie szablonu** zmienia treść lub wygląd strony w kreatorze. Deklarujesz je w schema jako `text`, `range`, `color` albo inny obsługiwany typ. **Pole formularza** wypełnia odwiedzający stronę, a wartość jest wysyłana do API. Deklarujesz je w `configuration.fields` instancji `contact-form`. Te struktury nie są zamienne.

Surowe tagi `input`, `select`, `textarea` i `form` nie są obecnie renderowane z pliku Loom przez `LoomMarkup`. Nie próbuj budować działającego formularza samym takim HTML. Korzystaj z instancji formularza opisanej w [następnym rozdziale](/pl/forms/).

## Pole w ustawieniach kreatora

```json
{"type":"text","id":"title","label":"Nagłówek","default":"Porozmawiajmy"}
```

Umieść definicję w tablicy `settings` sekcji lub bloku. Odczytaj ją jako `section.settings.title` lub `block.settings.title`. Domyślna wartość wypełnia kontrolkę, gdy nie ma zapisu użytkownika. Pełne typy i ograniczenia opisuje [schema](/pl/schema/).

## Pole dla odwiedzającego

```json
{"key":"email","label":"Adres e-mail","type":"email","required":true}
```

Dodaj ten obiekt do `configuration.fields`, nie do schema Loom. `key` jest kluczem danych w wysyłce, a `label` widoczną etykietą. Etykietę można poprawiać, zachowując stabilny klucz. `required` jest wartością logiczną.

| Typ | Zastosowanie | Walidacja serwera |
| --- | --- | --- |
| `text` | Imię, firma, krótka odpowiedź | Tekst do 250 znaków |
| `textarea` | Wiadomość | Tekst do 5000 znaków |
| `email` | Adres e-mail | Poprawny e-mail, do 250 znaków |
| `tel` | Numer telefonu | Tekst do 250 znaków; bez automatycznego formatowania kraju |
| `number` | Liczba | Wartość numeryczna |
| `date` | Data | Format `YYYY-MM-DD` |
| `select` | Wybór jednej opcji | Jedna z zapisanych wartości `options` |
| `checkbox` | Potwierdzenie | Wymagany musi być zaznaczony; opcjonalny jest booleanem |

Pole `number` nie ma w aktualnym kontrakcie osobnych ustawień min/max/step. `date` nie ma definicji ograniczenia dat. Nie dopisuj tych właściwości — API odrzuca nieznane klucze konfiguracji. Zakresy `min/max/step` w schema dotyczą ustawień szablonu, nie formularzy odwiedzających.

## Lista wyboru

```json
{"key":"topic","label":"Temat","type":"select","required":true,"options":["Wycena","Wsparcie","Inne"]}
```

Opcje są tablicą tekstów, nie obiektów `value/label` jak w schema. Wyświetlany tekst jest także wysyłaną wartością. Zmiana opcji może wpłynąć na walidację nowej odpowiedzi. Publiczny wspólny renderer formularza korzysta obecnie z natywnego `select`; custom selecty panelu nie zmieniają automatycznie tego komponentu. Zmianę kontrolki publicznej należy wdrożyć we wspólnym komponencie, nie dopisać w paczce Loom.

## Klucze, limity i wartości

Formularz ma 1–30 pól. Klucz zaczyna się małą literą i zawiera do 50 znaków: małe litery, cyfry, myślniki lub podkreślenia. Musi być unikalny w formularzu. `website`, `instance_id` i `kind` są zarezerwowane. Etykieta ma maksymalnie 120 znaków. Lista zawiera 1–30 opcji, każda do 120 znaków.

Aktualna konfiguracja pola obejmuje wyłącznie `key`, `label`, `type`, `required`, `options`. Nie ma osobnego `default`, `placeholder`, treści pomocy, uploadu pliku, hasła ani radio. Odwiedzający zaczyna od pustego formularza. Placeholder istniejącego inputu jest tworzony z etykiety przez komponent, nie jest osobną konfiguracją.

## Wygląd i etykiety

Komponent opakowuje kontrolkę etykietą `label`, dzięki czemu kliknięcie nazwy przenosi fokus. Style wspólne zapewniają 8 px między etykietą a polem i 16 px między grupami. Nie zastępuj etykiety samym placeholderem.

Przykład stylowania publicznego formularza w `assets/theme.css`:

```css
.plugin-contact-form { display: grid; gap: 16px; }
.plugin-form-field { display: grid; gap: 8px; }
.plugin-form-field input:not([type="checkbox"]),
.plugin-form-field textarea,
.plugin-form-field select {
  min-height: 44px;
  padding: 12px;
  border: 1px solid #68756e;
  border-radius: 8px;
  background: #ffffff;
  color: #16221b;
}
.plugin-form-field :focus-visible { outline: 2px solid #16221b; outline-offset: 2px; }
```

Style paczki są ograniczone do jej obszaru. Formularz musi być wewnątrz tego obszaru, aby dziedziczyć te reguły. To styl wyglądu, nie zmiana sposobu walidacji lub wysyłania. Nie ukrywaj informacji o błędzie kolorem tła.

## Focus, active i własne dropdowny

Każdy motyw musi zapewniać widoczny fokus klawiatury i stany interakcji dla kontrolek, także wyszukiwarki pluginu, formularza komentarzy, przełącznika języka i własnych dropdownów. Użyj kolorów i kształtów motywu. `:focus-visible` oznacza fokus klawiatury, `:focus-within` wyróżnia złożoną kontrolkę, gdy jej element ma fokus, a `:active` oznacza wyłącznie moment naciskania. Dla trwałych stanów używaj zgodnie z semantyką komponentu `aria-current`, `aria-selected`, `aria-expanded` lub `details[open]`; nie oznaczaj wybranej opcji przez `:active`.

Jeśli input wyszukiwarki znajduje się w zaokrąglonej obudowie, narysuj jedną obwódkę wokół obudowy zamiast prostokątnej ramki wokół wewnętrznego inputu:

```css
.blog-section .blog-search:focus-within {
  outline: 2px solid var(--site-accent, currentColor);
  outline-offset: 0;
}
.blog-section .blog-search input:focus {
  outline: none;
  box-shadow: none;
}
.blog-section .blog-search button:focus-visible {
  outline: 2px solid var(--site-accent, currentColor);
  outline-offset: 3px;
}
```

Usunięcie obwódki inputu jest tutaj dopuszczalne tylko dlatego, że obudowa zapewnia widoczny zamiennik. Nie stosuj globalnego `outline: none`. Zachowaj osobny fokus klawiatury przycisku wysyłania, aby było wiadomo, jaka akcja zostanie uruchomiona. Dopasuj zaokrąglenia pól, unikaj przycinania obwódek i sprawdź kontrast względem pola oraz strony. Sugestie autouzupełniania przeglądarki są jej interfejsem; CSS motywu nie styluje tego popupu.

GrowSite Skeleton używa żółtego akcentu, Paylio swojego skonfigurowanego akcentu, a Victorie Vending pomarańczowego fokusu w obu wariantach kolorystycznych. Naciśnięty przycisk delikatnie zmienia jasność. Style specyficzne dla motywu są częścią jego paczki i muszą obejmować również bloki pluginów dodane przez klienta.

Własny dropdown musi mieć dostępny przycisk otwierający, widoczny fokus, stan otwarcia, obsługę klawiatury i listę mieszczącą się na ekranie. Dropdown nawigacji zawiera linki; kontrolka wyboru wartości wymaga odpowiedniej semantyki i obsługi wyboru klawiaturą. Nie dodawaj `role="menu"` ani `role="listbox"` bez implementacji ich obsługi klawiatury. Ostyluj przycisk, listę, opcje, bieżący wybór, hover, stan nieaktywny i fokus. Korzystając ze wspólnej kontrolki formularza, zachowaj walidację aplikacji i zapis wartości.

Dla Languages użyj `<gs-languages variant="dropdown"></gs-languages>`. Motyw odpowiada za style `.gs-language-dropdown`, `summary` i `.gs-language-switch`. Bieżący język ma `aria-current="true"`, a `details[open]` oznacza otwartą listę. Kontrolka obsługuje Enter/Spację na przycisku, Tab między linkami i Escape do zamknięcia. Zobacz [wymagania przełącznika języka](/pl/locales/) z opisem integracji i przykładami paczek.

Sprawdź Tab, Shift+Tab, Enter, Spację i Escape; kliknięcia; stany wybrane i nieaktywne; długie etykiety opcji; wiele języków oraz ekrany mobilne. Upewnij się, że fokus pozostaje widoczny i nie powoduje poziomego przewijania strony.

## Sprawdzenie

Kliknij etykietę, przejdź klawiaturą przez pola, sprawdź pustą wartość wymaganą, błędny e-mail i wartość spoza opcji. Checkbox opcjonalny powinien wysyłać `false`, gdy nie jest zaznaczony. Przetestuj długie etykiety na telefonie. Weryfikację serwerową wykonuj na testowej, opublikowanej witrynie.


Zobacz [komponenty GS Loom UI](/pl/components/): wspólny kontrakt HTML, warianty komponentów, tokeny motywu i działające przykłady.
