Pomoćnici za postavke

Sedam malih paketa po frameworku, svaki posjeduje jedan korisnički zadatak od početka do kraja, plus traka koja okuplja pet njih. Već ste upoznali theme-picker; evo locale-picker, text-size-picker i motion-picker (postavke), share-picker i search-picker (radnje), date-time-picker (vrijednost obrasca) te picker-bar.

Što ćete izraditi

Ploča postavki na kojoj korisnici biraju jezik i veličinu teksta — izbori koji vrijede za cijeli dokument, ostaju između posjeta i koštaju vas dvije komponente i nekoliko redaka CSS-a. Otprilike 15 minuta.

Prije nego počnete

Najprije dovršite vodič za framework za svoj stog. Primjeri u nastavku su u Svelteu; pomoćnici za React, Vue, Angular, HTML, Nunjucks i Blazor odgovaraju im ugovor po ugovor.

Oblik koji dijele

  • Headless gumb-ikona koji otvara WAI-ARIA APG listbox (ili, za date-time-picker, dijalog za odabir datuma) — bez izvornog <select>, pa svaki framework dobiva isto ponašanje tipkovnice i stilske kuke.
  • Jedna klasna kuka po paketu (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), nula isporučenog CSS-a.
  • Siguran za SSR: zapisi u DOM događaju se samo u životnom ciklusu mount/effect.
  • Čist za i18n: svaki niz vidljiv korisniku je prop.
  • Dostupno za Svelte (kanonski), React, Vue, Angular, HTML prilagođeni element, Nunjucks i Blazor — isti ugovor u svakom.

theme-picker, locale-picker i text-size-picker posjeduju svaki jednu korisničku postavku od početka do kraja (odabir, primjena na DOM, neobvezna localStorage trajnost preko propa storageKey ). share-picker i date-time-picker razlikuju se po vrsti: share-picker posjeduje radnju — ne primjenjuje ništa na dokument i ništa ne pohranjuje — a date-time-picker posjeduje vrijednost obrasca, jer je datum u obrascu podatak, a ne postavka.

locale-picker — jezik i smjer

Dopušta korisniku da odabere lokalizaciju, a zatim zapisuje lang i dir na korijen dokumenta kako bi je slijedili vaša i18n biblioteka, vaš CSS i pomoćne tehnologije. RTL se otkriva automatski za arapski, hebrejski i druga pisma zdesna nalijevo. Usredotočen je isključivo na signaliziranje — prijevod obavlja vaša i18n biblioteka.

<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"
/>

Opcije se označavaju iz ugrađene tablice naziva lokalizacija (može se nadjačati preko localeLabels), svaka opcija nosi vlastiti atribut lang kako bi čitači zaslona izgovarali „Français“ na francuskom, a kodovi s podvlakom poput en_US pretvaraju se bez gubitaka u BCP 47 i natrag en-US. Povežite onChange (ili vezanu vrijednost) s i18next, Paraglideom, vue-i18n ili čime god koristite.

text-size-picker — veličina koju kontrolira čitatelj

Dobitak za pristupačnost koji traje minute: pomoćnik postavlja data-text-size="{slug}" na korijen dokumenta, a vaš CSS preslikava svaku vrijednost u veličinu.

<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%; }

Dimenzionirajte raspored u rem i cijela se aplikacija skalira s korisnikovim izborom. Oznake se tvore iz slugova s velikim početnim slovom („X Large“) ili nadjačavaju preko sizeLabels.

Provjerite svoj rad: odaberite „Large“ u biraču i tekst stranice raste. Ponovno učitajte — i dalje je velik: izbor je trajno spremljen u localStorage. Prebacite birač jezika na arapski i dir="rtl" se automatski postavlja na dokument.

share-picker — pošaljite ovu stranicu

Gumb s jednim glifom koji otvara izvorni list za dijeljenje uređaja gdje postoji, a inače se vraća na popis odredišta koja vi dostavite, plus radnju kopiranja URL-a. Ne isporučuje nijedan URL društvenih mreža — koje mreže pripadaju vašem proizvodu vaša je odluka, a ne dizajnerskog sustava.

<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 je prema zadanom location.hrefpa uobičajeni slučaj ne treba nikakvo ožičenje. Prisilite putanju pomoću strategy="list" ili strategy="native" kada trebate dosljedno ponašanje na različitim platformama za testove ili snimke zaslona.

date-time-picker — datum, vrijeme ili oboje

Tekstno polje u koje možete tipkati, plus gumb-ikona koji otvara dijalog za odabir datuma WAI-ARIA APG. Ispravan za lokalizaciju po konstrukciji — nazivi mjeseci, nazivi dana, prvi dan tjedna i 12- ili 24-satni sat dolaze iz Intl — a vrijednost je uvijek sortirljiv ISO niz bez vremenske zone: "2026-03-15" za mode="date", "09:30" za mode="time", "2026-03-15T09:30" za 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",
  }}
/>

ISO vrijednost jednaka je onome što <input type="date"> šalje, pa izvornu kontrolu možete zamijeniti unutra ili van bez diranja pozadinskog sustava.

motion-picker — poštujte smanjeno kretanje

Pomoćnik postavlja data-motion="{slug}" na korijen dokumenta. Njegova prva vrijednost dolazi iz postavke prefers-reduced-motion operacijskog sustava posjetitelja — uvijek, bez zastavice za uključivanje, jer je kretanje stvarna potreba pristupačnosti (WCAG 2.3.3). Vaš CSS i skripte odlučuju što se potiskuje.

<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 — okvir za pretraživanje koji ne smeta

Gumb-ikona koji otvara polje za pretraživanje. Pritisak na Return ili gumb ⏎ pored polja navigira običnim GET zahtjevom na /?<text> (tekst se obrezuje i URI-kodira; prazan upit ne vodi nikamo). Njegova tri pristupačna naziva obavezna su jer pomoćnik ne isporučuje engleski.

<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 mijenja putanju (/search?foo), a navigate zadržava navigaciju unutar aplikacije; bez njega pomoćnik poziva location.assign.

picker-bar — cijeli redak zaglavlja odjednom

picker-bar iscrtava pretraživanje, temu, lokalizaciju, veličinu teksta i dijeljenje u jednom retku, s cjelovitim skupom referentnih tema i sedmostupanjskom ljestvicom teksta unaprijed spojenima. Svaki pristupačni naziv dolazi u jednom obaveznom labels objektu.

<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}
/>

Do bilo kojeg omotanog birača dođite preko searchProps, themeProps, localeProps, textSizeProps i shareProps.

Opisi alata ugrađeni su

Svaki birač prikazuje svoju oznaku u opisu alata kada pokazivač miruje na njegovu gumbu ili gumb ima fokus tipkovnice. Opis alata ostaje dok se pokazivač pomiče na njega, Escape ga zatvara gdje god fokus bio, a nikad se ne prikazuje dok je skočni prozor birača otvoren. Nosi isti tekst kao pristupačni naziv gumba, pa nema što konfigurirati ni dvaput prevoditi; referentne teme ga stiliziraju.

Ploča postavki na jednom mjestu

Četiri pomoćnika za postavke prirodno se slažu:

<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>

Provjereno: isječci za locale-picker, text-size-picker, share-picker, date-time-picker i kombiniranu ploču kompilirani su pojedinačno prema objavljenim 0.1.1 paketima, preko svelte/server (2026-08-29); isječci za motion-picker, search-picker i picker-bar iscrtani su prema vlastitim komponentama paketa 2026-10-06.

Gdje ih nabaviti

# 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-

Svaki paket ima vlastiti spec, testove povezane s klauzulama specifikacije, izvršive primjere (uključujući SSR uzorke s kolačićima) te cjevovod za izradu i objavu. Svelte paketi su kanonski; u slučaju sumnje, njihovi ugovori pobjeđuju.

Sljedeći koraci

Pitanja usput? Stranica pomoći puna je odgovora — a ako neki korak može biti jasniji, javite nam i rado ćemo poboljšati vodič.