Část III · Enum sloupce
8.2. Prezentační rozhraní case
Enum smí implementovat čtyři rozhraní – HasIcon, HasColor,
HasBadge a HasShort. Sloupec se přidává pořád stejným
addEnum(); jak bude vypadat, rozhoduje sám enum.
Ukázka
Stav a Platba mají ikonu, barvu i pilulku, Doprava jen barvu
a zkratku. V columns() se ty tři sloupce neliší jediným znakem.
Zdrojový kód
php
app/Modules/AdminModule/Components/Docs/Columns/EnumPresentationGridControl/EnumPresentationGridControl.php
<?php
declare(strict_types=1);
namespace App\Components\Docs\Columns\EnumPresentationGridControl;
use App\Enum\OrderPayment;
use App\Enum\OrderShipping;
use App\Enum\OrderStatus;
use Xart\Grid\Button\ButtonManager;
use Xart\Grid\Column\ColumnManager;
use Xart\Grid\Control\GridControl;
use Xart\Grid\DataOutput\Row;
use Xart\Grid\DataSource\DataSource;
use Xart\Grid\DataSource\SQL\SQLDataSource;
/**
* Dokumentace, kapitola 8.2 – Prezentační rozhraní case.
*
* Tři enumy, každý s jinou sadou rozhraní: Stav a Platba mají ikonu, barvu i pilulku, Doprava jen
* barvu a zkratku. V columns() se přitom neliší jediným znakem – všechno rozhoduje enum sám.
*/
class EnumPresentationGridControl extends GridControl
{
public function createDataSource(): DataSource
{
return new SQLDataSource(__DIR__ . '/EnumPresentationGridControl.sql');
}
public function columns(ColumnManager $cm): void
{
$cm->add('number', 'Číslo');
// OrderStatus: HasIcon, HasColor, HasBadge – v buňce ikona v barevné pilulce.
$cm->addEnum('status', 'Stav', OrderStatus::class);
// OrderPayment: totéž, jen s jinými barvami.
$cm->addEnum('payment', 'Platba', OrderPayment::class);
// OrderShipping: HasColor a HasShort – barevný podklad a místo popisku zkratka.
$cm->addEnum('shipping', 'Doprava', OrderShipping::class);
$cm->addNumber('total_price', 'Celkem', 2, 'Kč');
}
public function buttons(ButtonManager $bm): void
{
}
public function rows(Row $row): void
{
}
public function render(): void
{
$this->template->render(__DIR__ . '/EnumPresentationGridControl.latte');
}
}
php
app/Enum/OrderStatus.php
<?php
declare(strict_types=1);
namespace App\Enum;
use Xart\Grid\Color\Color;
use Xart\Grid\Column\Enum\HasBadge;
use Xart\Grid\Column\Enum\HasColor;
use Xart\Grid\Column\Enum\HasIcon;
enum OrderStatus: string implements HasIcon, HasColor, HasBadge
{
case new = 'Nová';
case confirmed = 'Potvrzená';
case shipped = 'Odeslaná';
case delivered = 'Doručená';
case cancelled = 'Stornovaná';
public function icon(): ?string
{
return match ($this) {
self::new => 'ti ti-sparkles',
self::confirmed => 'ti ti-checkbox',
self::shipped => 'ti ti-truck-delivery',
self::delivered => 'ti ti-home-check',
self::cancelled => 'ti ti-ban',
};
}
public function color(): Color|string|null
{
return match ($this) {
self::new => '#b091ff',
self::confirmed => '#74c0fc',
self::shipped => '#ffd43b',
self::delivered => '#40c057',
self::cancelled => '#fa5252',
};
}
public function badge(): Color|string|null
{
return match ($this) {
self::new => new Color('#9e3bdb', '#edf2ff'),
self::confirmed => new Color('#1c7ed6', '#e7f5ff'),
self::shipped => new Color('#d9480f', '#fff9db'),
self::delivered => new Color('#2b8a3e', '#ebfbee'),
self::cancelled => new Color('#c92a2a', '#fff5f5'),
};
}
}
php
app/Enum/OrderShipping.php
<?php
declare(strict_types=1);
namespace App\Enum;
use Xart\Grid\Color\Color;
use Xart\Grid\Color\ColorScheme;
use Xart\Grid\Column\Enum\HasColor;
use Xart\Grid\Column\Enum\HasShort;
enum OrderShipping: string implements HasColor, HasShort
{
case ppl = 'PPL';
case dpd = 'DPD';
case zasilkovna = 'Zásilkovna';
case post = 'Česká pošta';
case pickup = 'Osobní odběr';
public function color(): Color|string|null
{
return match ($this) {
self::ppl => ColorScheme::purple()->subtle(),
self::dpd => ColorScheme::orange()->subtle(),
self::zasilkovna => ColorScheme::red()->subtle(),
self::post => ColorScheme::yellow()->subtle(),
self::pickup => ColorScheme::green()->subtle()
};
}
public function short(): string
{
return match ($this) {
self::zasilkovna => 'ZAS',
self::post => 'ČP',
self::pickup => 'OS',
default => $this->value
};
}
}
Čtyři rozhraní
| Rozhraní | Metoda | Co přidá |
|---|---|---|
HasIcon |
icon(): ?string |
CSS třídy ikony (ti ti-truck) – vždy před textem. Hodnota jde
rovnou do atributu class, takže se při definici gridu ověří proti
^[a-zA-Z0-9 _-]+$. |
HasColor |
color(): Color|string|null |
Barevný podklad přes celou plochu buňky. Řetězec je zkratka za
new Color($barva) – barva textu se dopočítá tak, aby byla čitelná. |
HasBadge |
badge(): Color|string|null |
Barevná pilulka kolem ikony a textu – tedy jen kus buňky, ne celá. |
HasShort |
short(): ?string |
Zkratka místo plného popisku (ČP). Do exportu jde vždycky plný
popisek – zkratku by v CSV nikdo nevysvětlil. |
Rozhraní se implementují po jednom, jak se hodí. Case, který v match vrátí
null, prostě tu část nemá – ostatní case v témže enumu ji mít můžou.
Kam se prezentace propíše
- Buňka – vykreslí se vše, co case umí (doladit jde v kapitole 8.3).
- Nabídka filtru – tytéž části kreslí frontend, jen barva se v ní vejde pouze na chip položky.
- Export – vždy plný popisek. Barva podkladu se propíše jako pozadí buňky tam, kde to formát umí (XLSX, PDF); pilulka ne, ta je prvek uvnitř buňky, ne barva buňky.
- Přístupnost – plný popisek zůstává v
titlebuňky, a když je v ní jen ikona nebo barva, ještě varia-label.
Barvy
color() i badge() berou Color, nebo rovnou hex jako
řetězec. Pojmenovanou paletu má ColorScheme (ColorScheme::blue(),
->subtle() pro světlejší odstín), vlastní dvojici podklad + text zapíšete
new Color('#c92a2a', '#fff5f5'). Celá paleta má svou kapitolu 16.