Core
Schema
Sdílený slovník pro rozvržení obsahu: jedno uspořádané pole komponent, které konzumují formuláře, infolisty i modaly akcí.
Na této stránce
Schema je uspořádané pole komponent předané do ->schema([...]). Je to
sdílený slovník pro uspořádání obsahu a stejné komponenty se vykreslují
napříč povrchy — formuláře, infolisty i action modaly konzumují schema.
use NyonCode\WireCore\Foundation\Schema\Grid;use NyonCode\WireCore\Foundation\Schema\Section; Section::make('profile') ->label('Profile') ->schema([ Grid::make()->columns(2)->schema([ TextInput::make('first_name'), TextInput::make('last_name'), ]), ])
Jak to funguje
Schema je strom komponent. Ten strom tvoří dva druhy:
- Pole nesou hodnotu a state path —
TextInput,Select,Toggle, … Váží se na váš model/stav a účastní se validace. Viz reference Formuláře → Pole. - Layoutové a schema komponenty nenesou vlastní stav; uspořádávají své
potomky.
Grid,Section,Tabs,Wizarda spol. každá bere svou vlastní->schema([...]), takže se layouty vnořují libovolně hluboko.
Při renderu hostitel prochází strom do hloubky: každá komponenta vyresolvuje svou vlastní konfiguraci (popisky, viditelnost, sloupce) a vykreslí svůj Blade pohled, rekurzivně do dětských schémat. Protože layoutové komponenty nedrží hodnotu, lze je přidávat, odebírat nebo přeřazovat volně bez zásahu do vašich dat — na stav se mapují jen pole.
Všechny schema komponenty žijí pod NyonCode\WireCore\Foundation\Schema a rozšiřují
sdílený základ LayoutComponent, což je důvod, proč identický Grid nebo Section
funguje ve formuláři, infolistu i modalu.
Rozpětí sloupců
Jakýkoli potomek layoutu založeného na sloupcích (Grid, Section, Fieldset, Tab, Step)
řídí svou vlastní šířku:
TextInput::make('bio')->columnSpan(2); // rozpětí dvou sloupcůTextInput::make('notes')->columnSpanFull(); // rozpětí celého řádku
Rozpětí se řeší proti mřížce, ve které komponenta skutečně skončí — na každé
šířce. Mřížka je responzivní: columns(3) je na telefonu jeden sloupec a na
desktopu tři, takže rozpětí není jedna třída, ale žebřík. columnSpan(3)
v třísloupcovém Gridu je md:col-span-3, totéž rozpětí ve Fieldsetu (který má
dva sloupce už od sm) je sm:col-span-2 md:col-span-3. Píšeš číslo, breakpointy
si doplní mřížka.
Rozpětí nikdy nemůže být širší než jeho mřížka. Požádat o víc neznamená
oříznutou dlaždici — CSS Grid chybějící sloupec přidá, čímž přeskládá celý
layout a ostatní potomky zmáčkne do zbytku. Rozpětí širší než deklarovaný počet
se proto vykreslí jako celá šířka mřížky: columnSpan(4) ve dvousloupcové sekci
jsou dva sloupce, všude.
Mřížka svým potomkům řekne, ve které mřížce jsou. Komponenta se nikdy neptá,
kde sedí — dozví se to na vstupu a svůj žebřík si spočítá z toho, co jí bylo
řečeno. Všechny dodávané layouty to za tebe dělají, takže tohle je potřeba jen
když si píšeš vlastní layoutovou komponentu: předej stejný počet sloupců metodě
ResponsiveGrid::cols() pro mřížku a metodě inGridOf() každého potomka, a
rozpětí uvnitř se pak posouvají s mřížkou, ne mimo ni.
@php use NyonCode\WireCore\Foundation\Support\ResponsiveGrid; $columns = $layout->getColumns();@endphp <div class="grid gap-4 {{ ResponsiveGrid::cols($columns) }}"> @foreach ($layout->getSchema() as $component) @if ($component->isVisible()) {{ $component->inGridOf($columns) }} {{-- [tl! focus] --}} @endif @endforeach</div>
Potomek, kterému to nikdo neřekl, předpokládá mřížku přesně tak širokou, jaké
rozpětí si vyžádal. To je nejužší předpoklad, který nikdy nemůže vymyslet sloupec
— a zároveň to není mřížka, kterou jsi nakreslil, takže columnSpan(2) ve tvém
vlastním třísloupcovém layoutu by se přeskládalo na špatné šířce a nikdo by to
nenahlásil.
Společné API layoutů
Každá layoutová komponenta — Grid, Flex, Section, Fieldset, Tab, Step,
Tabs, Wizard — dědí ze stejné báze LayoutComponent, takže tenhle povrch mají
všechny stejný a stránky jednotlivých komponent uvádějí jen to, co která přidává.
Vytvoří ji Component::make(?string $name = null). Jméno je volitelné a není
state path: layout nenese hodnotu, takže jméno jen pojmenovává.
->label(string|Closure|null $label) // text nadpisu; fallback je Str::headline() jména->hiddenLabel(bool $condition = true) // komponentu zachová, nadpis nevykreslí->schema(array $components) // děti, v pořadí vykreslení->statePath(?string $path) // přepne kořen state path pro všechno pod ní->columnSpan(int|string $span) // 2|3|4|'full' — kolik z RODIČOVSKÉHO gridu zabere->columnSpanFull() // zkratka pro 'full'->inGridOf(int|array $columns) // mřížka, ve které se komponenta kreslí; layout to řekne každému potomkovi->visible(bool|Closure $condition = true)->hidden(bool|Closure $condition = true)->visibleWhen(string $field, mixed $value = true) // vidět, dokud se jiné pole rovná $value->hiddenWhen(string $field, mixed $value = true)->disabled(bool|Closure $condition = true) // vypne každé pole pod sebou->disabledWhen(string $field, mixed $value = true)->livewire(mixed $livewire) // host; nastaví se sám, když formulář připravuje děti->getName(): string->getLabel(): ?string->getSchema(): array->getColumnSpan(): int|string|null->isVisible(): bool->isHidden(): bool->isDisabled(): bool
Tři z nich si zaslouží větu, protože právě na ně lidi narazí jako na překvapení:
columnSpan()je o rodiči, ne o dítěti. Říká, kolik z gridu, který tuhle komponentu obsahuje, zabere — omezené tím, co ta mřížka má:columnSpan(5)ve čtyřsloupcové mřížce jsou čtyři sloupce, ve dvousloupcové dva.columnSpanFull()je celý řádek, ať už je řádek jakýkoli.visible()bere closure a vyhodnocuje se při každém renderu, takže layout může přicházet a mizet podle stavu formuláře.visibleWhen('type', 'company')je totéž napsané pro ten obvyklý případ.disabled()se propisuje dolů. Vypnutí sekce vypne každé pole uvnitř, což je jedna podmínka místo téže podmínky na každém poli.
Layoutové komponenty
| Komponenta | Účel |
|---|---|
| Grid | Responzivní vícesloupcový layout |
| Flex | Uspořádat potomky na jedné vodorovné (flexbox) ose |
| Section | Seskupit komponenty pod nadpisem, volitelně sbalitelné |
| Fieldset | Seskupit související komponenty s ohraničenou legendou |
| Tabs | Client-side záložkové panely (všechny panely validují společně) |
| Wizard | Client-side vícekrokový layout s indikátorem kroků |
Prime komponenty
Statické, ne-vstupní komponenty, které zobrazují obsah:
| Komponenta | Účel |
|---|---|
| Callout | Jemný, barevný upozorňovací box s nadpisem a ikonou |
| Empty State | Vycentrovaný placeholder zobrazený, když není co zobrazit |
Kde se schémata používají
Protože tyto komponenty žijí v core Foundation\Schema, konzumuje je víc
než jen formuláře:
- Formuláře staví své tělo ze schématu, a to přímo z těchhle tříd. Tenké
podtřídy
NyonCode\WireForms\Components\Layout\*, které vyměňovaly form-specifický markup, byly ve 2.0 odstraněny: jejich kopie views zaostaly za originály, takže sekce ve formuláři vykreslila míň než sekce v infolistu postavená ze stejné třídy. - Infolisty znovupoužívají stejný layout slovník pro read-only detailní pohledy.
- Action modaly používají Wizard pro vícekrokové toky — viz Modaly → Vícekrokový wizard.