Pomocníci pre predvoľby

Sedem malých balíkov na framework, z ktorých každý vlastní jednu užívateľskú úlohu od začiatku do konca, plus lišta, ktorá päť z nich zostavuje. Už ste sa stretli s theme-picker; tu sú locale-picker, text-size-picker a motion-picker (predvoľby), share-picker a search-picker (akcie), date-time-picker (hodnota formulára) a picker-bar.

Čo vytvoríte

Panel nastavení, kde používatelia volia jazyk a veľkosť textu — voľby, ktoré platia pre celý dokument, pretrvávajú medzi návštevami a stoja vás dva komponenty a pár riadkov CSS. Približne 15 minút.

Skôr než začnete

Najprv dokončite návod k frameworku pre svoj stack. Ukážky nižšie sú v Svelte; pomocníci pre React, Vue, Angular, HTML, Nunjucks a Blazor im zodpovedajú zmluvu po zmluve.

Tvar, ktorý zdieľajú

  • Bezhlavé tlačidlo s ikonou, ktoré otvára listbox WAI-ARIA APG (alebo pri date-time-picker dialóg na výber dátumu) — žiadny natívny <select>, takže každý framework získa rovnaké správanie klávesnice a štýlovacie háčiky.
  • Jeden triedny háčik na balík (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), nula dodaného CSS.
  • Bezpečné pre SSR: zápisy do DOM prebiehajú len v životnom cykle mount/effect.
  • Čisté pre i18n: každý reťazec viditeľný používateľovi je prop.
  • K dispozícii pre Svelte (kanonický), React, Vue, Angular, vlastný prvok HTML, Nunjucks a Blazor — v každom rovnaká zmluva.

theme-picker, locale-picker a text-size-picker vlastnia každý jednu používateľskú predvoľbu od začiatku do konca (výber, aplikácia na DOM, voliteľné localStorage trvalé uloženie cez prop storageKey ). share-picker a date-time-picker sú iného druhu: share-picker vlastní akciu — nič nepoužíva na dokument a nič neukladá — a date-time-picker vlastní hodnotu formulára, pretože dátum vo formulári sú dáta, nie predvoľba.

locale-picker — jazyk a smer

Nechá používateľa vybrať miestne nastavenie a potom zapíše lang a dir na koreň dokumentu, aby ho nasledovala vaša knižnica i18n, vaše CSS aj asistívne technológie. RTL sa zisťuje automaticky pre arabčinu, hebrejčinu a ďalšie písma písané sprava doľava. Sústredí sa čisto na signalizáciu — preklad zabezpečuje vaša knižnica i18n.

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

Voľby sú popísané z vstavanej tabuľky názvov miestnych nastavení (možno prepísať cez localeLabels), každá voľba nesie vlastný atribút lang , aby čítačky obrazovky vyslovili „Français“ po francúzsky, a kódy s podčiarkovníkom ako en_US sa bezstratovo prevádzajú do BCP 47 a späť en-US. Pripojte onChange (alebo viazanú hodnotu) k i18next, Paraglide, vue-i18n alebo čomukoľvek, čo používate.

text-size-picker — veľkosť ovládaná čitateľom

Zisk pre prístupnosť za pár minút: pomocník nastaví data-text-size="{slug}" na koreň dokumentu a vaše CSS priradí každej hodnote veľkosť.

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

Rozmerujte rozloženie v rem a celá aplikácia sa prispôsobí voľbe používateľa. Popisy sa tvoria zo slugov s veľkým začiatočným písmenom („X Large“) alebo sa prepisujú cez sizeLabels.

Skontrolujte svoju prácu: vyberte „Large“ vo výbere a text stránky sa zväčší. Znova načítajte — stále je veľký: voľba sa trvalo uložila do localStorage. Prepnite výber jazyka na arabčinu a dir="rtl" sa na dokument nastaví automaticky.

share-picker — odoslať túto stránku

Tlačidlo s jedným glyfom, ktoré otvorí natívny zdieľací list zariadenia tam, kde existuje, a inak sa vráti k zoznamu cieľov, ktoré dodáte, plus akcii kopírovania URL. Nedodáva žiadne URL sociálnych sietí — ktoré siete patria do vášho produktu, je vaše rozhodnutie, nie rozhodnutie dizajnového systému.

<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 predvolene location.href, takže bežný prípad nepotrebuje žiadne zapojenie. Vynúťte cestu pomocou strategy="list" alebo strategy="native" keď potrebujete konzistentné správanie naprieč platformami pre testy alebo snímky obrazovky.

date-time-picker — dátum, čas alebo oboje

Textové pole, do ktorého možno písať, plus tlačidlo s ikonou, ktoré otvorí dialóg na výber dátumu WAI-ARIA APG. Správne pre dané prostredie už z konštrukcie — názvy mesiacov, názvy dní, prvý deň týždňa a 12- či 24-hodinové hodiny pochádzajú z Intl — a hodnota je vždy zoraditeľný reťazec ISO bez časového pásma: "2026-03-15" pre mode="date", "09:30" pre mode="time", "2026-03-15T09:30" pre 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",
  }}
/>

Hodnota ISO je zhodná s tým, čo <input type="date"> odosiela, takže natívny ovládací prvok môžete vymeniť dovnútra aj von bez zásahu do backendu.

motion-picker — rešpektujte obmedzený pohyb

Pomocník nastaví data-motion="{slug}" na koreň dokumentu. Jeho prvá hodnota pochádza z nastavenia prefers-reduced-motion operačného systému návštevníka — vždy, bez príznaku na aktiváciu, pretože pohyb je skutočná potreba prístupnosti (WCAG 2.3.3). Vaše CSS a skripty rozhodujú, čo sa potlačí.

<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 — vyhľadávacie pole, ktoré neprekáža

Tlačidlo s ikonou, ktoré otvorí vyhľadávacie pole. Stlačenie Return alebo tlačidla ⏎ vedľa poľa prejde obyčajnou požiadavkou GET na /?<text> (text sa orezá a zakóduje ako URI; prázdny dotaz nevedie nikam). Jeho tri prístupné názvy sú povinné, pretože pomocník nedodáva angličtinu.

<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 mení cestu (/search?foo) a navigate drží navigáciu v aplikácii; bez neho pomocník volá location.assign.

picker-bar — celý riadok hlavičky naraz

picker-bar vykresľuje vyhľadávanie, tému, miestne nastavenie, veľkosť textu a zdieľanie v jednom riadku, s úplnou sadou referenčných tém a sedemstupňovou škálou textu vopred zapojenými. Každý prístupný názov prichádza v jednom povinnom objekte labels .

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

Dostanete sa k ľubovoľnému obalenému výberu cez searchProps, themeProps, localeProps, textSizeProps a shareProps.

Popisky sú vstavané

Každý výber zobrazí svoj popis v popisku, keď ukazovateľ spočinie na jeho tlačidle alebo má tlačidlo fokus klávesnice. Popisok zostane, keď ukazovateľ prejde na neho, Escape ho zavrie, nech je fokus kdekoľvek, a nikdy sa nezobrazí, kým je otvorené kontextové okno výberu. Nesie rovnaký text ako prístupný názov tlačidla, takže nie je čo konfigurovať ani dvakrát prekladať; referenčné témy ho ostylujú.

Panel nastavení na jednom mieste

Štyria pomocníci pre predvoľby sa prirodzene skladajú:

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

Overené: ukážky pre locale-picker, text-size-picker, share-picker, date-time-picker a kombinovaný panel boli skompilované jednotlivo proti publikovaným 0.1.1 balíkom cez svelte/server (2026-08-29); ukážky pre motion-picker, search-picker a picker-bar boli vykreslené proti vlastným komponentom balíkov 2026-10-06.

Kde ich získať

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

Každý balík má vlastný spec, testy naviazané na klauzuly specu, spustiteľné príklady (vrátane vzorov cookies pre SSR) a pipeline na zostavenie a publikovanie. Balíky Svelte sú kanonické; v prípade pochybností vyhrávajú ich zmluvy.

Ďalšie kroky

Otázky po ceste? Stránka pomocníka je plná odpovedí — a ak by niektorý krok mohol byť jasnejší, dajte nám vedieť a návod radi vylepšíme.