Pembantu preferensi

Pitu paket cilik saben kerangka, saben siji nduwèni siji tugas pangguna saka wiwitan nganti pungkasan, ditambah bar sing nglumpukaké lima saka kuwi. Sampeyan wis kenalan karo theme-picker; iki locale-picker, text-size-picker lan motion-picker (preferensi), share-picker lan search-picker (tumindak), date-time-picker (nilai formulir) lan picker-bar.

Apa sing bakal sampeyan gawé

Panèl setelan ing ngendi pangguna milih basa lan ukuran teks — pilihan sing ditrapaké ing kabèh dokumen, tetep ing antarané kunjungan lan regané mung rong komponen lan sawetara baris CSS. Kira-kira 15 menit.

Sadurunge miwiti

Rampungna dhisik tutorial kerangka kanggo tumpukan sampeyan. Conto ing ngisor iku Svelte; pembantu React, Vue, Angular, HTML, Nunjucks lan Blazor cocog kontrak mawon.

Wujud sing dienggo bareng

  • Tombol ikon headless sing mbukak listbox WAI-ARIA APG (utawa, kanggo date-time-picker, dialog pamilih tanggal) — ora ana <select>asli, supaya saben kerangka olèh prilaku keyboard lan pancingan gaya sing padha.
  • Siji pancingan kelas saben paket (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), nol CSS dikirim.
  • Aman kanggo SSR: panulisan DOM mung kedadean ing siklus urip mount/effect.
  • Resik kanggo i18n: saben string sing katon pangguna iku prop.
  • Kasedhiya kanggo Svelte (kanonik), React, Vue, Angular, unsur kustom HTML, Nunjucks lan Blazor — kontrak sing padha ing saben-saben.

theme-picker, locale-picker lan text-size-picker saben-saben nduwèni siji preferensi pangguna saka wiwitan nganti pungkasan (pilihan, panrapan ing DOM, opsional localStorage pangeling liwat prop storageKey ). share-picker lan date-time-picker beda jinisé: share-picker nduwèni tumindak — ora nrapaké apa-apa ing dokumen lan ora nyimpen apa-apa — lan date-time-picker nduwèni nilai formulir, amarga tanggal ing formulir iku data, dudu preferensi.

locale-picker — basa lan arah

Ngidini pangguna milih lokal, banjur nulis lang lan dir ing oyod dokumen supaya pustaka i18n, CSS lan teknologi bantuan sampeyan kabèh ngetutaké. RTL dideteksi otomatis kanggo Arab, Ibrani lan aksara liyané saka tengen menyang kiwa. Fokusé mung menèhi sinyal — pustaka i18n sampeyan sing ngurus terjemahan.

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

Pilihan dilabeli saka tabel jeneng lokal sing wis ana (bisa ditimpa liwat localeLabels), saben pilihan nggawa atribut lang dhéwé supaya pamaca layar ngucapaké "Français" nganggo basa Prancis, lan kode nganggo garis ngisor kaya en_US diowahi tanpa mundhut menyang BCP 47 lan bali en-US. Sambungna onChange (utawa nilai sing diikat) menyang i18next, Paraglide, vue-i18n utawa apa wae sing sampeyan enggo.

text-size-picker — ukuran sing dikontrol pamaca

Kamenangan aksesibilitas sing mung butuh menit: pembantu nyetel data-text-size="{slug}" ing oyod dokumen lan CSS sampeyan mapaké saben nilai menyang ukuran.

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

Ukuren tata letak sampeyan nganggo rem lan kabèh aplikasi ngukur miturut pilihan pangguna. Label digawé saka slug nganggo aksara kapital ("X Large") utawa ditimpa nganggo sizeLabels.

Priksa pagawéan sampeyan: pilih "Large" saka pamilih, lan teks kaca dadi gedhé. Muat maneh — isih gedhé: pilihan disimpen ing localStorage. Ganti pamilih basa menyang Arab lan dir="rtl" disetel ing dokumen kanthi otomatis.

share-picker — kirimna kaca iki

Tombol siji glif sing mbukak lembar nuduhaké asli piranti yèn ana, lan yèn ora bali menyang dhaptar tujuan sing sampeyan sediakaké, ditambah tumindak nyalin URL. Ora ngirim URL jaringan sosial apa wae — jaringan endi sing cocog karo produk sampeyan iku kaputusan sampeyan, dudu kaputusan sistem desain.

<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 bawan-é yaiku location.hrefmula kasus umum ora butuh kabel apa-apa. Meksa dalan nganggo strategy="list" utawa strategy="native" nalika butuh prilaku konsisten ing antarané platform kanggo tes utawa gambar layar.

date-time-picker — tanggal, wektu, utawa loro-lorone

Kolom teks sing bisa diketik, ditambah tombol ikon sing mbukak dialog pamilih tanggal WAI-ARIA APG. Bener kanggo lokal saka rancangan — jeneng sasi, jeneng dina, dina pisanan minggu lan jam 12 utawa 24 jam kabèh asalé saka Intl — lan nilai tansah string ISO sing bisa diurutaké lan tanpa zona wektu: "2026-03-15" kanggo mode="date", "09:30" kanggo mode="time", "2026-03-15T09:30" kanggo 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",
  }}
/>

Nilai ISO padha karo apa sing dikirim <input type="date"> mula sampeyan bisa ngganti kontrol asli mlebu utawa metu tanpa nyenggol backend sampeyan.

motion-picker — ngajèni obah sing dikurangi

Pembantu nyetel data-motion="{slug}" ing oyod dokumen. Nilai pisanané asalé saka setelan prefers-reduced-motion sistem operasi pengunjung — tansah, tanpa gendéra opt-in, amarga obah iku kabutuhan aksesibilitas sing nyata (WCAG 2.3.3). CSS lan skrip sampeyan sing mutusaké apa sing ditindhes.

<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 — kothak panggolèkan sing ora ngalang-alangi

Tombol ikon sing mbukak kolom panggolèkan. Mencet Return, utawa tombol ⏎ ing jejeré kolom, navigasi nganggo panjalukan GET prasaja menyang /?<text> (teks dipotong lan dienkode URI; pitakon kosong ora menyang ngendi-ngendi). Telung jeneng sing bisa diakses iku wajib, amarga pembantu ora ngirim basa Inggris.

<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 ngowahi dalan (/search?foo), lan navigate njaga navigasi ing jero aplikasi; tanpa iku pembantu nundhang location.assign.

picker-bar — kabèh baris header sekaligus

picker-bar nampilaké panggolèkan, tema, lokal, ukuran teks lan nuduhaké ing siji baris, kanthi set tema rujukan lengkap lan skala teks pitung undhak sing wis disambungaké. Saben jeneng sing bisa diakses teka ing siji obyèk wajib 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}
/>

Jangkau pamilih sing dibungkus nganggo searchProps, themeProps, localeProps, textSizeProps lan shareProps.

Tooltip wis ana ing njero

Saben pamilih nampilaké labelé ing tooltip nalika penunjuk ngaso ing tombolé utawa tombol duwé fokus keyboard. Tooltip tetep nalika penunjuk pindhah menyang, Escape nutup ing ngendi wae fokusé, lan ora tau katon nalika popup pamilih mbukak. Isiné teks sing padha karo jeneng sing bisa diakses tombol, mula ora ana sing kudu dikonfigurasi utawa diterjemahaké kaping pindho; tema rujukan sing nata.

Panèl setelan ing siji panggonan

Papat pembantu preferensi gampang digabung:

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

Dikonfirmasi: potongan locale-picker, text-size-picker, share-picker, date-time-picker lan panèl gabungan dikompilasi siji-siji nglawan paket 0.1.1 sing wis diterbitaké, liwat svelte/server (2026-08-29); potongan motion-picker, search-picker lan picker-bar dirender nglawan komponen paket dhéwé ing 2026-10-06.

Ngendi olèhé

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

Saben paket nduwé spec dhéwé, tes sing dipetakaké menyang klausa spec, conto sing bisa dijalanaké (kalebu pola cookie SSR) lan pipa pambangunan + panerbitan. Paket Svelte iku kanonik; yèn mamang, kontrak-é sing menang.

Langkah sabanjuré

Ana pitakon ing dalan? Kaca pitulung kebak wangsulan — lan menawa ana langkah sing bisa luwih cetha, kandhanana kita lan kita bakal seneng nyaosi tutorial luwih apik.