Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

Návrh je jedna deklarace a každý povrch je její projekce

Návrh je jedna deklarace a každý povrch je její projekce

majordomus://adr/adr-0031přijato designuiprojectionsodvozeno

odkazuje na

odkazuje na něj

Nic ve vrstvě to nejmenuje. Zpětné odkazy se odvozují, takže prázdný seznam je odpověď, ne opomenutí.

31. Design je jedna deklarace a každý povrch je její projekce

Kontext

Čtyři povrchy tohoto repozitáře staví HTML před člověka: web publikovaný na GitHub Pages, Cockpit, stránky, které vykresluje sám spustitelný soubor — jeho domovská stránka a každý generovaný report — a obal Swagger UI nad dokumentem OpenAPI.

Každý nesl svůj vlastní návrh.

Web byl výchozí motiv Flowbite nad paletou Tailwindu a na prvním místě zásobníku písem uváděl Inter, který nikdy nenačetl. Cockpit byl druhý vstupní bod Tailwindu s vlastním @theme — stejná myšlenka, znovu — a pod ním druhá paleta povrchů v --mj-*, jejíž tmavá polovina byla ručně vybrána v jiném odstínu než cokoli jiného v repozitáři. Stránky reportů nesly sedm hexadecimálních literálů v bloku <style> a přepínaly podle prefers-color-scheme, zatímco každý jiný povrch přepínal podle třídy. Shell Swaggeru zdědil, co třetí strana ten týden vydala.

To byl stav, který mohl vidět kdokoli. Psaní kontroly našlo další tři. cockpit.js nesl hexadecimální záložní hodnoty pro tokeny, které čte ze stránky. site/graph.js četl sedm vlastností --mj-graph-*, které žádná stylesheet nikdy nedeklarovala, takže každé vyhledání minulo a každý výkres byl vybarven z literálů v jeho vlastní záložní tabulce — pod komentářem „Palette read from the page, not duplicated here“. site/diagrams.js držel světlé a tmavé téma Mermaid, dalších šestnáct literálů, plus třetí zopakování sady písem.

Sedm palet. Ani jedna z nich nebyla návrhem, který by někdo zvolil dvakrát; každá byla týmž návrhem rozhodnutým znovu tím, kdo ho zrovna potřeboval, a rozešly se přesně tak daleko, jak by předpověděl každý, kdo se nedíval.

S kódem nebylo nic špatně. Vadou bylo, že hodnota návrhu neměla kanonický domov, takže ji každý povrch, který ji potřeboval, musel vymyslet, a žádná kontrola nerozlišila povrch, který se řídí návrhem, od povrchu s vlastním návrhem.

Rozhodnutí

Hodnota designu se volí jednou v share/design/tokens.yaml a každá stylesheet je její projekcí.

scripts/design-tokens zapisuje z onoho jednoho souboru tři projekce:

  • share/design/theme.css, Tailwind @theme — importované vstupním bodem webu i Cockpitu, po tématu Flowbite, takže ty dva buildy Tailwindu nemohou rozlišit jiný typ písma ani jiný akcent.
  • share/design/surface.css, sémantický povrch ve vrstvě a pod selektorem, proti kterému je psán stylesheet Cockpitu, nesoucí jména --mj-* a --mj-graph-* jako aliasy kanonických vlastností. Alias nemá vlastní hodnotu, takže se nemůže rozejít; je to synonymum, nikdy druhé rozhodnutí.
  • apps/majordomus-cli/src/web/tokens.css, tytéž hodnoty jako prosté vlastní vlastnosti, zkompilované do spustitelného souboru pomocí include_str! pro stránky, které nemají Tailwind a nestahují žádný asset. Žije uvnitř crate, takže se crate stále sestaví, i když se balí samostatně.

scripts/ci/design-check je kontrola a klade dvě otázky. Jsou tři projekce aktuální? A jmenuje nějaký soubor, který může dostat barvu na obrazovku, barvu mimo kanonickou deklaraci? Sledovaný zdroj s hexadecimálním literálem, rgb(), hsl() nebo oklch() selže, pokud není jednou ze čtyř uvedených výjimek — samotné generované projekce, bajty třetích stran, SVG ikona, kterou prohlížeč vykresluje mimo jakýkoli dokument, a aritmetika barev v knihovně kontrastu, která hledá mezi čistě černou a čistě bílou a nic nemaluje. Každá výjimka je důvod. Přidaná cesta bez něj je selhání, které toto nahrazuje.

Hodnoty byly zvoleny tak, aby se publikovaný web nezměnil. Světlý motiv je gray z Tailwindu, na který se motiv webu už rozlišoval. Sada písem je ta, ve které se web vždy vykresloval, protože Inter byl jmenován a nikdy nenačten. Tmavý je z Cockpitu, ponechaný, protože byl zvolen pro hustou řídicí rovinu čtenou celé hodiny. Konvergence šla k tomu, co tam už bylo, ne k novému názoru.

Důsledky

Zkompilovaný stylesheet Cockpitu se překompiloval bajt po bajtu identicky, když byl jeho vlastní @theme smazán a nahrazen sdíleným importem. To je důkaz, že první krok byl refaktoring a ne redesign.

Hodnota změněná v tokens.yaml a nepřegenerovaná nemůže přistát: kontrola selže. Nemůže přistát ani povrch, který si vypěstuje vlastní paletu. Čtyři povrchy jsou nyní jedním návrhem v jediném smyslu, který přežije rok úprav — existuje jedno místo ke změně a stroj si všimne, když vznikne druhé.

Generátor ověřuje, co vypisuje, dříve než to zapíše. Není to defenzivní programování; je to chyba, kterou tento generátor měl. Nevyvážená uvozovka vytvořila --font-sans: ...Emoji; — deklaraci, kterou parser CSS tiše zahodí, takže sestavení uspělo, kontrola driftu prošla, každá kontrola zůstala zelená a jeden povrch přišel o svou sadu písem. test/cases/107_design_tokens.sh drží tuto mutaci i druhou, kde odstraňovač komentářů snědl #fff a zapsal vlastní vlastnost bez jakékoli hodnoty.

Kontrola klade třetí otázku, kterou první verze neměla: je každý token --mj-, který povrch čte, takový, který něco deklaruje? Okamžitě našla --mj-text-faint — čtený stylopisem Cockpitu od dne jeho napsání, nikde nedeklarovaný, a tudíž se vždy rozlišující na svou záložní hodnotu. Je to totéž selhání jako site/graph.js, o jeden jmenný prostor vedle, a je z principu neviditelné: nedeklarovaná vlastní vlastnost je prázdný řetězec, nikdy chyba, takže build ani prohlížeč nemají co hlásit.

Co to nedělá: nepřestylizuje vnitřek Swagger UI. Rám stránky — její písmo, akcent, odkazy — je nyní tohoto repozitáře; bloky operací a tabulky schémat jsou stylopis třetí strany v připnuté verzi a přeskinování cizího stromu komponent je údržbová faktura, kterou tato stránka nepotřebuje. Stránka se připne na světlý režim, protože Swagger UI 5 nedodává tmavé téma a tmavý rám kolem trvale světlého widgetu je horší než světlý.

Dvě věci jsou záměrně ponechány na později a jmenovány, ne skryty. Assety Swagger UI se stále stahují z CDN unpkg, což je jediná část projekce HTTP, která není dostupná offline — jejich vendorování je samostatné rozhodnutí o velikosti distribuce, ne o návrhu. A scripts/ui stále objevuje jen povrchy static-directory, takže Cockpit, domovská stránka a shell Swaggeru jsou mimo audit prohlížeče, i když už sdílejí návrh; sada stránek auditu pochází ze souborového systému a routa vykreslená při požadavku soubor nemá. Rozšíření by způsobilo, že záruka z ADR 0022 dosáhne každého povrchu, a ne většiny.

Odkud to pochází

kanonický soubor
.ai/repo/adrs/0031-the-design-is-one-declaration-and-every-surface-is-a-project.md
identity
adr-0031
dostupné také jako
Zdroj MCP majordomus://adr/adr-0031 · majordomus entity show adr/adr-0031 · GET /api/v1/entity?uri=majordomus://adr/adr-0031
v Cockpitu
/cockpit/objects/adr/adr-0031

Tato stránka je generována z výše uvedeného souboru pomocí scripts/generate-site-data; úprava stránky nic nemění, úprava souboru změní všechna rozhraní. Výše uvedené vztahy jsou hrany docs/generated/graph.json, které spustitelný program zapisuje ze stejného indexu.

Prohledává názvy a popisy všech stránek, které tento web publikuje.