Komponenty GS Loom UI
Wspólne komponenty, warianty i style motywów.
GS Loom UI: wspólne działanie, wygląd motywu
GS Loom UI v1 to wspólna warstwa komponentów stron. Jest oddzielna od biblioteki panelu administratora i klienta. Szablon korzysta ze zwykłego HTML z data-gs-ui; GS Loom dostarcza bazowy CSS i obsługę interakcji. Motyw określa kolory, zaokrąglenia oraz własne warianty. Dotychczasowy HTML, animacje, schema i uprawnienia pluginów nadal działają.
Ta strona wyjaśnia komponenty za pomocą kodu i przykładów konfiguracji. Paczki motywów zawierają też snippets/ui-demo.html do opcjonalnych testów na prywatnej stronie developerskiej.
Kontrakt i warianty
<button type="button" data-gs-ui="button" data-variant="primary" data-size="md">
Rozpocznij
</button>
<a href="/contact" data-gs-ui="button" data-variant="outline">Kontakt</a>Do akcji używaj przycisku, do nawigacji linku. Wariant zmienia wygląd, nie semantykę. Rozmiar data-size jest niezależny od data-variant. Dotychczasowe klasy mogą pozostać obok tych atrybutów. Migracja nie wymaga wymiany wszystkich elementów ani usuwania zaczepów animacji.
| Komponent | Kontrakt HTML | Wbudowane warianty |
|---|---|---|
| Button | button lub a z data-gs-ui="button" |
primary (domyślny), secondary, outline, ghost, link, danger; rozmiary sm, md (domyślny), lg |
| Card | article lub div z data-gs-ui="card" |
surface (domyślny), outline, elevated, ghost |
| Badge | span z data-gs-ui="badge" |
primary (domyślny), secondary, outline |
| Field | wrapper z data-gs-ui="field" |
wspólne 8 px odstępu etykiety od kontrolki |
| Input / Textarea | input data-gs-ui="input" / textarea data-gs-ui="textarea" |
outline (domyślny), filled, underline |
| Select | div data-gs-ui="select" z jednym natywnym select |
outline (domyślny), filled |
| Dropdown | details data-gs-ui="dropdown", summary, wrapper zawartości |
secondary (domyślny), outline, primary |
| Tabs | div data-gs-ui="tabs", lista, przyciski i panele |
line (domyślny), pills; poziome albo pionowe |
| Accordion | details data-gs-ui="accordion" z summary |
surface (domyślny), outline, ghost |
| Modal | dialog data-gs-ui="modal" |
default, surface; rozmiary md (domyślny), lg |
Możesz dodać wariant np. brand. Samo nadanie nazwy nie tworzy nowego zachowania — zdefiniuj wygląd w CSS motywu. Wariant odpowiedni dla przycisku nie musi być odpowiedni dla inputu lub modala.
Zmienne motywu i własne warianty
Zmienne umieść w assets/ui.css. GS Loom ładuje wspólne style przed plikami motywu. W szablonie Loom poniższa reguła jest ograniczona do jego obszaru; szablony dokumentowe otrzymują ten sam CSS wewnątrz izolowanego dokumentu.
:scope {
--gs-ui-accent: #e59d02;
--gs-ui-on-accent: #161006;
--gs-ui-text: #f8f8f8;
--gs-ui-background: #040000;
--gs-ui-surface: #191715;
--gs-ui-border: #ffffff29;
--gs-ui-focus: #e59d02;
--gs-ui-radius: 20px;
--gs-ui-button-radius: 50px;
--gs-ui-shadow: 0 16px 40px #0003;
}
[data-gs-ui="button"][data-variant="brand"] {
background: #5347ce;
color: #ffffff;
border-color: #5347ce;
}Możesz także nadpisać --gs-ui-danger i --gs-ui-on-danger. Jeśli kolory są edytowalne, połącz zmienne z ustawieniami motywu. Dobieraj kolor tekstu razem z tłem i sprawdzaj kontrast. Skeleton używa żółtego akcentu na ciemnym tle, Paylio ciemnych przycisków na jasnym tle, a Victorie pomarańczowych przycisków oraz jasnych i ciemnych powierzchni. Importowany szablon korzysta z bazowych komponentów platformy; jego plik zmiennych jest częścią eksportowanej paczki.
Edytowalny wariant przycisku
Dodaj do schema bloku ustawienie select, a następnie połącz je z data-variant:
{
"type": "select",
"id": "button_variant",
"label": "Wariant przycisku",
"default": "primary",
"options": [
{"value":"primary","label":"Główny"},
{"value":"secondary","label":"Drugorzędny"},
{"value":"outline","label":"Obrys"}
]
}<a data-gs-ui="button" data-variant="[[ block.settings.button_variant ]]"
href="[[ safe_url(block.settings.url) ]]"
data-text-field="[[ block.settings_path ]].label"
gs-text="block.settings.label"></a>Istniejący blok Card w Skeleton udostępnia już takie ustawienie. Analogicznie możesz udostępnić wariant karty lub innego komponentu. select w schema konfiguruje edytor; to co innego niż komponent Select na stronie. Biblioteka UI nie dodaje automatycznie bloku do kreatora — nadal potrzebujesz schema, presetu i dopuszczenia typu przez rodzica.
Pola i Select
<div data-gs-ui="field">
<label for="contact-topic">Temat</label>
<div data-gs-ui="select" data-variant="filled">
<select id="contact-topic" name="topic" required>
<option value="">Wybierz temat</option>
<option value="sales">Sprzedaż</option>
<option value="support">Pomoc</option>
<option value="other" disabled>Niedostępne</option>
</select>
</div>
</div>Po inicjalizacji platforma pokazuje własny combobox z listą opcji. Natywny select pozostaje źródłem wartości formularza i walidacji. Strzałki przechodzą między dostępnymi opcjami, Home/End wybierają pierwszą/ostatnią, pisanie wyszukuje etykietę, Enter/Spacja zatwierdzają, Escape anuluje, a Tab zamyka listę. Kliknięcie poza kontrolką także ją zamyka. Zdarzenia change, input i reset formularza zachowują standardowe działanie. Bez JavaScript pozostaje działający natywny select. Wielokrotny wybór nie jest ulepszany w v1.
Zachowaj prawdziwą etykietę połączoną z id natywnego selecta; mechanizm przenosi dostępną nazwę na przycisk. Każda instancja potrzebuje unikalnych ID, np. opartych o block.id — nie kopiuj identycznych ID do powtarzanych bloków. Input i Textarea umieszczaj w takim samym wrapperze Field, z powiązaną etykietą. Używaj disabled, required i aria-invalid zgodnie z przeznaczeniem. Komponenty nie dostarczają endpointu wysyłki: do wysyłania i walidacji serwerowej używaj pluginu Formularze. Biblioteka nie zastępuje automatycznie pól należących do pluginu ani nie omija uprawnień.
Dropdown nawigacji i Languages
<details data-gs-ui="dropdown" data-variant="outline">
<summary>Poznaj nas</summary>
<nav data-gs-dropdown-content aria-label="Poznaj nas">
<a href="/about">O nas</a>
<a href="/contact">Kontakt</a>
</nav>
</details>Enter/Spacja otwierają natywny element rozwijany. Tab przechodzi między linkami. Escape zamyka i przywraca fokus do summary; opuszczenie kontrolki fokusem lub kliknięcie poza nią również ją zamyka. To rozwijana nawigacja z linkami, a nie ARIA menu. Nie dodawaj ról menu bez odpowiadającej im obsługi klawiatury.
<gs-languages variant="dropdown"></gs-languages> korzysta ze wspólnej obsługi dropdownu, zachowując nawigację pluginu językowego i zmianę języka w kreatorze. Każdy szablon obsługujący Languages musi dostarczyć własny wygląd przełącznika. assets/languages.css Skeleton rozszerza wspólne zmienne UI. Wariant zwykłych linków nadal jest dostępny. Szczegóły: Languages.
Tabs i Accordion
<div data-gs-ui="tabs" data-variant="pills" data-value="overview">
<div data-gs-tab-list aria-label="Informacje o produkcie">
<button data-gs-tab="overview">Przegląd</button>
<button data-gs-tab="details">Szczegóły</button>
</div>
<section data-gs-panel="overview">Treść przeglądu</section>
<section data-gs-panel="details">Szczegółowa treść</section>
</div>
<details data-gs-ui="accordion" data-variant="outline">
<summary>Jak to działa?</summary>
<p>Twoja odpowiedź.</p>
</details>Klucze zakładek odpowiadają kluczom paneli wewnątrz komponentu. Mechanizm tworzy ID, role i powiązania, ukrywa nieaktywne panele oraz zarządza fokusem klawiatury. Strzałki, Home i End automatycznie wybierają aktywną zakładkę, pomijając wyłączone. data-orientation="vertical" korzysta ze strzałek góra/dół. Definicje zakładek i paneli powinny pozostać stałe podczas życia komponentu; przy wymianie całego zestawu zamontuj go ponownie. Przed inicjalizacją JavaScript treść wszystkich paneli pozostaje czytelna.
Accordion korzysta z natywnego działania details. Dodaj open, aby początkowo rozwinąć element. Wspólna wartość name na powiązanych details pozwala utworzyć grupę z jednym otwartym elementem; nazwa grupy powinna być unikalna dla instancji bloku.
Modal
<button type="button" data-gs-ui="button" data-gs-open="shipping-dialog">Dostawa</button>
<dialog data-gs-ui="modal" data-size="lg" id="shipping-dialog" aria-labelledby="shipping-title">
<h2 id="shipping-title">Informacje o dostawie</h2>
<p>Treść wyświetlana na żądanie.</p>
<button type="button" data-gs-ui="button" data-variant="secondary" data-gs-close autofocus>Zamknij</button>
</dialog>Mechanizm otwiera natywny dialog przez showModal(): fokus pozostaje w modalu, Escape zamyka, a fokus wraca do wywołującego elementu. Zamyka także przycisk i kliknięcie poza prostokątem dialogu. Dodaj dostępną nazwę oraz widoczny przycisk zamykania. Cel jest wyszukiwany wewnątrz wrappera danego motywu; powtarzane bloki potrzebują unikalnych ID. Modal sam w sobie nie jest systemem uprawnień ani zatwierdzania i niczego nie wysyła.
Focus, active i stany nieaktywne
Fokus pozostaje widoczny bez zmiany kształtu komponentu. :active oznacza naciskanie; trwały wybór oznaczają aria-selected, aria-current lub details[open]. Natywne wyłączone przyciski nie uruchamiają akcji. Dla nieaktywnego linku użyj aria-disabled="true" i tabindex="-1"; wspólny mechanizm blokuje aktywację. Klasa wyglądająca na nieaktywną nie zastępuje kontroli dostępu. Zobacz zasady fokusu dla wyszukiwarek i dropdownów.
Migracja i sprawdzenie
Trzy dołączone motywy zawierają zmienne UI i snippet demonstracyjny. Dotychczasowe przyciski i karty Skeleton/Paylio oraz przyciski CTA Victorie korzystają ze wspólnego kontraktu, zachowując oryginalne klasy i zaczepy animacji. Wyspecjalizowana nawigacja, slidery i odtwarzacze wideo zachowują dotychczasowe działanie — nie są automatycznie zastępowane ogólnymi komponentami.
Sprawdź warianty i motywy, klawiaturę, etykiety, walidację, wyłączone opcje, reset formularza, Escape i powrót fokusu modala, dwie instancje na stronie, mobile i ograniczenie animacji. Zmiany CSS i działania UI należą do motywu/mechanizmu platformy, nie do zapisanej treści klienta. Przebuduj przez npm run loom:build; paczkę na portalu deweloperskim odświeża npm run build:developers. Nie kopiuj kodu platformy do każdej paczki — GS Loom dostarcza go w renderowaniu i podglądzie.
Równa wysokość i grow
Dodaj data-gs-equal-height do wiersza flex lub siatki grid. Każde bezpośrednie dziecko staje się kontenerem flex; karta lub przycisk wewnątrz niego otrzymuje data-gs-grow. Elementy rozciągają się do wysokości najwyższej treści w swoim wierszu, także po tłumaczeniu lub edycji na podglądzie. Szablon nadal definiuje kolumny, odstępy i breakpointy. Nie ustawiaj stałych wysokości ani pomiarów JavaScript.
<div data-gs-equal-height class="feature-grid">
<div>
<article data-gs-ui="card" data-gs-grow data-gs-stack>
<h3>Feature</h3>
<p>Short or long translated content.</p>
<div data-gs-footer>
<a data-gs-ui="button" href="/details">Details</a>
</div>
</article>
</div>
<!-- Repeat the wrapper for each card. -->
</div>.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
gap: 24px;
}data-gs-stack tworzy pionowy układ flex; data-gs-footer przesuwa akcje na dół. Zachowaj odstęp nad akcjami (np. gap lub padding stopki). data-gs-grow działa także samodzielnie wewnątrz układów flex. Na telefonie osobne wiersze zachowują naturalne wysokości. Jeśli WSZYSTKIE wiersze grid mają być równe, dodaj świadomie grid-auto-rows: 1fr do siatki. Atrybuty współpracują z każdym wariantem komponentu i nie zastępują jego kolorów, obramowania ani animacji.
Nagłówek i menu w kreatorze
Wspólny kontrakt GS Loom: data-gs-header="header" oznacza nagłówek, data-gs-logo logo, a data-gs-menu="header" lub "footer" nawigację. <gs-menu location="header"> dodaje oznaczenie automatycznie i korzysta z menu witryny. Zachowaj semantyczne header, nav i linki. Szablon odpowiada za wygląd, breakpointy oraz dropdowny.
Jeżeli nagłówek ma własne pola schematu, dodaj data-gs-header-group="header". Kliknięcie nagłówka, logo lub pozycji otwiera ustawienia tej grupy w kreatorze; zmiany zapisują się w loom.groups.header (historyczna nazwa pola danych GS Loom). Skeleton korzysta z tego wariantu, aby zachować istniejące zagnieżdżone menu i tłumaczenia. Bez tego atrybutu logo używa wspólnego edytora logo, a menu wspólnego menedżera nawigacji. Nie łącz obu źródeł danych dla tych samych pozycji. Publiczne linki zachowują normalne działanie.
Dropdown, zagnieżdżenia i megamenu
GS Loom rozdziela dane menu od wyglądu. Kreator zapisuje drzewo pozycji, <gs-menu> renderuje to drzewo, a CSS szablonu określa wygląd. Poniżej znajdują się przykłady kodu, a nie interaktywne podglądy.
1. Umieść menu w nagłówku
<gs-menu location="header" label="Main navigation"></gs-menu>Ten kod umieść w sekcji lub snippecie nagłówka szablonu. location="header" wybiera menu witryny przypisane do tej lokalizacji, a label jest nazwą dla czytników ekranu. Nie wklejaj poniższego JSON do HTML — pokazuje on dane pozycji zapisywane w menu witryny. W kreatorze użyj Nawigacja → Header, rozwiń pozycję i wybierz Dodaj pozycję podrzędną.
Edycja menu nagłówka włącza use_site_menu. Paylio korzysta ze wspólnego nagłówka; Skeleton i Victorie Vending zachowują oryginalną nawigację demonstracyjną do czasu włączenia tego ustawienia. Dla danego menu używaj jednego źródła danych, zamiast równolegle utrzymywać linki wpisane w HTML i pozycje menu witryny.
2. Dropdown z dziećmi i kolejnym poziomem
{
"id": "services",
"label": "Services",
"href": "/services",
"menu_layout": "dropdown",
"children": [
{
"id": "websites",
"label": "Websites",
"href": "/websites",
"icon": "globe",
"children": [
{
"id": "design",
"label": "Design",
"href": "/design",
"icon": "star"
},
{
"id": "development",
"label": "Development",
"href": "/development",
"icon": "code"
}
]
}
]
}Services → Websites → Design / Development tworzy trzy poziomy. Każdy obiekt w children ma ten sam format, więc dziecko może mieć własne dzieci. Pozycja bez dzieci jest zwykłym linkiem. Brak menu_layout oznacza dropdown. Ten obiekt należy do tablicy items menu nagłówka.
| Pole | Znaczenie |
|---|---|
id |
Stały identyfikator pozycji; zachowaj go przy zmianie nazwy lub kolejności. |
label |
Widoczny tekst linku lub przycisku otwierającego podmenu. |
href |
Adres docelowy. Użyj #, gdy rodzic ma wyłącznie otwierać podmenu. |
children |
Tablica dzieci; pomiń dla zwykłego linku. |
menu_layout |
dropdown tworzy listę, mega układa bezpośrednie dzieci w kolumnach. |
icon |
Klucz ikony bibliotecznej lub image:<URL>; pomiń, jeśli nie chcesz ikony. |
3. Megamenu z ikonami
{
"id": "explore",
"label": "Explore",
"href": "#",
"menu_layout": "mega",
"children": [
{
"id": "products",
"label": "Products",
"href": "/products",
"icon": "star",
"children": [
{
"id": "skeleton",
"label": "Skeleton",
"href": "/products/skeleton"
},
{
"id": "paylio",
"label": "Paylio",
"href": "/products/paylio"
}
]
},
{
"id": "support",
"label": "Support",
"href": "/support",
"icon": "image:/media/support.svg",
"children": [
{
"id": "contact",
"label": "Contact",
"href": "/contact"
},
{
"id": "docs",
"label": "Documentation",
"href": "/docs"
}
]
}
]
}Ustaw menu_layout: "mega" na rodzicu otwierającym szeroki panel. Tutaj Products i Support tworzą dwie kolumny, a ich children zawierają linki pod nagłówkami. star wybiera ikonę biblioteczną. image:/media/support.svg pokazuje własny obraz — zastąp tę ścieżkę rzeczywistym adresem z menedżera plików. Pole przyjmuje adres obrazu, a nie surowy kod SVG. Zawartość kolumn zmieniasz w danych bez przebudowy renderera.
4. Dopasuj wygląd do szablonu
[data-gs-menu="header"] {
--gs-menu-background: #17201c;
--gs-menu-color: #ffffff;
--gs-menu-border: #ffffff33;
--gs-menu-radius: 16px;
--gs-menu-gap: 24px;
}Dodaj te reguły do arkusza stylów szablonu. Selektor ogranicza tokeny do menu nagłówka. Tło, tekst, obramowanie, promień narożników i odstępy mogą być inne w każdym szablonie przy zachowaniu wspólnego działania. Zachowaj widoczny focus i dopasuj panele do szerokości ekranu.
5. Zachowanie, tłumaczenia i limity
Kliknięcie lub Enter/Spacja otwiera podmenu. Escape zamyka bieżący poziom i przywraca focus na jego przycisk. Jeżeli rodzic ma rzeczywisty URL, renderer dodaje jego link na początku panelu — samo otwarcie nie przenosi użytkownika na inną stronę. Na małych ekranach zagnieżdżenia rozwijają się pionowo. Megamenu nie jest osobną stroną ani pluginem.
Przy włączonym Languages edytuj etykiety dla poszczególnych języków w kreatorze. Zachowuj identyfikatory pozycji, aby tłumaczenia nadal dotyczyły właściwych elementów; ikony, adresy i układ są niezależne od języka. Limity: 5 poziomów łącznie z głównym, 30 pozycji w jednej gałęzi i 100 pozycji w menu. Sprawdź długie tłumaczenia, obsługę klawiatury i układ mobilny. Szczegóły danych znajdziesz w Menu, a lokalizacji w Językach.
Wizualna edycja menu w kreatorze
Kliknij nagłówek Skeleton, aby otworzyć drzewo menu. Lista zawiera istniejące pozycje; rozwiń rodzica, aby zobaczyć dzieci. Wybierz pozycję i kliknij jej nazwę, aby edytować ją bezpośrednio. Link, ikona i układ podmenu są pokazywane tylko dla wybranej pozycji. Dodawaj, usuwaj i zmieniaj kolejność bez edycji pól schematu. Zakładka Wygląd zawiera kolory tekstu, tła i aktywnej pozycji, czcionkę, rozmiar oraz odstępy. Zastosowanie zapisuje szkic i zachowuje tłumaczenia; publikacja jest osobną czynnością.