Ajutoare pentru preferințe
Șapte pachete mici pe framework, fiecare deținând o sarcină a utilizatorului de la cap la coadă, plus o bară care le reunește pe cinci dintre ele. Ai întâlnit deja theme-picker; iată locale-picker, text-size-picker și motion-picker (preferințe), share-picker și search-picker (acțiuni), date-time-picker (o valoare de formular) și picker-bar.
Ce vei construi
Un panou de setări în care utilizatorii aleg limba și dimensiunea textului — alegeri care se aplică întregului document, persistă între vizite și te costă două componente și câteva rânduri de CSS. Aproximativ 15 minute.
Înainte să începi
Termină mai întâi tutorialul frameworkului pentru stiva ta. Exemplele de mai jos sunt în Svelte; ajutoarele pentru React, Vue, Angular, HTML, Nunjucks și Blazor corespund contract cu contract.
Forma pe care o împart
- Un buton-pictogramă headless care deschide un listbox WAI-ARIA APG (sau, pentru date-time-picker, un dialog de alegere a datei) — fără
<select>nativ, astfel încât fiecare framework primește același comportament al tastaturii și aceleași cârlige de stil. - Un cârlig de clasă pe pachet (
.locale-picker,.text-size-picker,.share-picker,.date-time-picker), zero CSS livrat. - Sigur pentru SSR: scrierile în DOM au loc doar în ciclul de viață mount/effect.
- Curat pentru i18n: fiecare șir vizibil utilizatorului este un prop.
- Disponibil pentru Svelte (canonic), React, Vue, Angular, element personalizat HTML, Nunjucks și Blazor — același contract în fiecare.
theme-picker, locale-picker și text-size-picker dețin fiecare câte o
preferință a utilizatorului de la cap la coadă (selecție, aplicare în DOM,
localStorage persistență opțională prin prop-ul storageKey
). share-picker și date-time-picker sunt de alt fel: share-picker deține o acțiune — nu aplică nimic documentului și nu persistă nimic — iar date-time-picker deține o
valoare de formular, deoarece o dată dintr-un formular este informație, nu o preferință.
locale-picker — limbă și direcție
Lasă utilizatorul să aleagă o localizare, apoi scrie lang și
dir pe rădăcina documentului, astfel încât biblioteca ta i18n, CSS-ul tău și tehnologiile asistive să o urmeze. RTL este detectat automat pentru araba, ebraica și alte scrieri de la dreapta la stânga. Se concentrează strict pe semnalizare — biblioteca ta i18n se ocupă de traducere.
<script>
import LocalePicker from "@lilydesignsystem/svelte-locale-picker";
let locale = $state("en-US");
</script>
<LocalePicker
label="Language"
locales={["en-US", "fr", "ar", "he", "ja"]}
bind:value={locale}
storageKey="my-app-locale"
/>
Opțiunile sunt etichetate dintr-un tabel încorporat de nume de localizări (se poate suprascrie prin localeLabels), fiecare opțiune poartă propriul atribut
lang ca cititoarele de ecran să pronunțe „Français” în franceză, iar codurile cu liniuță de subliniere precum en_US
se convertesc fără pierderi în BCP 47 și înapoi en-US. Conectează
onChange (sau valoarea legată) la i18next, Paraglide, vue-i18n sau orice folosești.
text-size-picker — dimensiune controlată de cititor
Un câștig de accesibilitate care durează minute: ajutorul setează
data-text-size="{slug}" pe rădăcina documentului, iar CSS-ul tău mapează fiecare valoare la o dimensiune.
<script>
import TextSizePicker from "@lilydesignsystem/svelte-text-size-picker";
</script>
<TextSizePicker
label="Text size"
sizes={["small", "medium", "large", "x-large"]}
storageKey="my-app-text-size"
/>
:root[data-text-size="small"] { font-size: 87.5%; }
:root[data-text-size="medium"] { font-size: 100%; }
:root[data-text-size="large"] { font-size: 112.5%; }
:root[data-text-size="x-large"] { font-size: 125%; }
Dimensionează-ți aspectul în rem iar întreaga aplicație se scalează cu alegerea utilizatorului. Etichetele sunt formate din slug-uri cu majusculă inițială („X Large”) sau suprascrise cu sizeLabels.
Verifică-ți munca: alege „Large” din selector, iar textul paginii crește. Reîncarcă — tot mare e: alegerea a fost salvată persistent în
localStorage. Comută selectorul de limbă pe arabă și
dir="rtl" este setat automat pe document.
share-picker — trimite această pagină
Un buton cu un singur glif care deschide foaia de partajare nativă a dispozitivului acolo unde există, iar altfel revine la o listă de destinații pe care o furnizezi tu, plus o acțiune de copiere a URL-ului. Nu livrează niciun URL de rețea socială — ce rețele se potrivesc produsului tău este decizia ta, nu a sistemului de design.
<script>
import SharePicker from "@lilydesignsystem/svelte-share-picker";
const targets = [
{ id: "mastodon", label: "Mastodon",
href: (url, title) => `https://mastodon.social/share?text=${encodeURIComponent(title)}%20${encodeURIComponent(url)}` },
{ id: "email", label: "Email",
href: (url, title) => `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(url)}`, newTab: false },
];
</script>
<SharePicker
label="Share this page"
title="An article worth reading"
{targets}
copyLabel="Copy link"
copiedLabel="Link copied"
/>
url are valoarea implicită location.href, deci cazul obișnuit nu necesită nicio conectare. Forțează o cale cu strategy="list" sau
strategy="native" când ai nevoie de comportament consecvent între platforme pentru teste sau capturi de ecran.
date-time-picker — o dată, o oră sau ambele
Un câmp de text în care poți tasta, plus un buton-pictogramă care deschide un dialog de alegere a datei WAI-ARIA APG. Corect local prin construcție — numele lunilor, numele zilelor, prima zi a săptămânii și ceasul de 12 sau 24 de ore vin toate din Intl — iar valoarea este întotdeauna un șir ISO sortabil și fără fus orar: "2026-03-15" pentru
mode="date", "09:30" pentru
mode="time", "2026-03-15T09:30" pentru
mode="datetime".
<script>
import DateTimePicker from "@lilydesignsystem/svelte-date-time-picker";
let appointment = $state("");
</script>
<DateTimePicker
inputId="appointment"
name="appointment"
label="Choose an appointment date"
locale="en-GB"
bind:value={appointment}
labels={{
previousYear: "Previous year",
previousMonth: "Previous month",
nextMonth: "Next month",
nextYear: "Next year",
confirm: "OK",
cancel: "Cancel",
}}
/>
Valoarea ISO este identică cu ceea ce trimite <input type="date">
astfel încât poți schimba controlul nativ cu cel al bibliotecii sau invers fără a atinge backend-ul.
motion-picker — respectă mișcarea redusă
Ajutorul setează data-motion="{slug}" pe rădăcina documentului. Prima lui valoare provine din setarea
prefers-reduced-motion a sistemului de operare al vizitatorului — întotdeauna, fără indicator de activare, deoarece mișcarea este o nevoie reală de accesibilitate (WCAG 2.3.3). CSS-ul și scripturile tale decid ce se suprimă.
<script>
import MotionPicker from "@lilydesignsystem/svelte-motion-picker";
</script>
<MotionPicker
label="Motion"
motions={["no-preference", "reduce"]}
storageKey="my-app-motion"
/>
:root[data-motion="reduce"] *,
:root[data-motion="reduce"] *::before,
:root[data-motion="reduce"] *::after {
animation: none !important;
transition: none !important;
scroll-behavior: auto !important;
}
search-picker — o casetă de căutare care nu stă în cale
Un buton-pictogramă care deschide un câmp de căutare. Apăsarea tastei Return sau a butonului ⏎ de lângă câmp navighează printr-o cerere GET obișnuită către
/?<text> (textul este tăiat de spații și codat URI; o interogare goală nu duce nicăieri). Cele trei nume accesibile ale sale sunt obligatorii, deoarece ajutorul nu livrează engleză.
<script>
import SearchPicker from "@lilydesignsystem/svelte-search-picker";
import { goto } from "$app/navigation";
</script>
<SearchPicker
label="Search this site"
inputLabel="Search terms"
submitLabel="Search"
placeholder="Search…"
action="/search"
navigate={(href) => goto(href)}
/>
action schimbă calea (/search?foo), iar
navigate păstrează navigarea în aplicație; fără el ajutorul apelează location.assign.
picker-bar — tot rândul antetului deodată
picker-bar randează căutarea, tema, localizarea, dimensiunea textului și partajarea într-un singur rând, cu setul complet de teme de referință și scara de text în șapte trepte preconectate. Fiecare nume accesibil vine într-un singur obiect
labels obligatoriu.
<script>
import PickerBar from "@lilydesignsystem/svelte-picker-bar";
</script>
<PickerBar
labels={{
search: "Search", searchInput: "Search terms", searchSubmit: "Search",
theme: "Theme", locale: "Language", textSize: "Text size", share: "Share",
}}
themesUrl="/themes/"
locales={["en", "fr", "es"]}
shareTargets={targets}
/>
Ajungi la orice selector învelit cu searchProps,
themeProps, localeProps,
textSizeProps și shareProps.
Baloanele explicative vin încorporate
Fiecare selector își arată eticheta într-un balon explicativ când cursorul se oprește pe butonul său sau butonul are focalizare de tastatură. Balonul rămâne cât timp cursorul se mută pe el, Escape îl închide oriunde ar fi focalizarea și nu apare niciodată cât timp fereastra pop-up a selectorului este deschisă. Poartă același text ca numele accesibil al butonului, deci nu e nimic de configurat și nimic de tradus de două ori; temele de referință îl stilizează.
Un panou de setări într-un singur loc
Cele patru ajutoare pentru preferințe se compun firesc:
<fieldset class="fieldset">
<legend>Preferences</legend>
<ThemePicker label="Theme" themesUrl="/themes/" themes={themes} storageKey="pref-theme" />
<LocalePicker label="Language" locales={locales} storageKey="pref-locale" />
<TextSizePicker label="Text size" sizes={sizes} storageKey="pref-text-size" />
<MotionPicker label="Motion" motions={motions} storageKey="pref-motion" />
</fieldset>
Verificat: fragmentele pentru locale-picker, text-size-picker, share-picker, date-time-picker și panoul combinat au fost compilate individual față de pachetele publicate 0.1.1 , prin
svelte/server (2026-08-29); fragmentele pentru motion-picker, search-picker și picker-bar au fost randate față de componentele proprii ale pachetelor la 2026-10-06.
De unde le obții
# one directory per package in the monorepo, e.g.
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-svelte-theme-picker
# or lily-design-system-react-theme-picker, -vue- / -angular- / -html- / -web-components- / -nunjucks- / -blazor-
Fiecare pachet are propriul spec, teste asociate clauzelor spec-ului, exemple executabile (inclusiv tipare de cookie-uri pentru SSR) și o conductă de build + publicare. Pachetele Svelte sunt canonice; la îndoială, contractele lor câștigă.
Pașii următori
- Catalogul de componente — referința completă a celor 571 de componente.
- Ajutor — depanare și întrebări frecvente.
- De ce Lily — și cum sprijini proiectul.
Întrebări pe parcurs? Pagina de ajutor este plină de răspunsuri — iar dacă un pas poate fi mai clar, spune-ne și vom îmbunătăți cu plăcere tutorialul.