Pembantu keutamaan

Tujuh pakej kecil bagi setiap rangka kerja, masing-masing memiliki satu tugas pengguna dari awal hingga akhir, ditambah bar yang menghimpunkan lima daripadanya. Anda sudah mengenali theme-picker; ini pula locale-picker, text-size-picker dan motion-picker (keutamaan), share-picker dan search-picker (tindakan), date-time-picker (nilai borang), dan picker-bar.

Apa yang akan anda bina

Panel tetapan di mana pengguna memilih bahasa dan saiz teks mereka — pilihan yang digunakan pada seluruh dokumen, kekal antara lawatan dan hanya menelan dua komponen serta beberapa baris CSS. Kira-kira 15 minit.

Sebelum anda bermula

Selesaikan tutorial rangka kerja untuk tindanan anda. Sampel di bawah ialah Svelte; pembantu React, Vue, Angular, HTML, Nunjucks dan Blazor sepadan kontrak demi kontrak.

Bentuk yang mereka kongsi

  • Butang ikon tanpa kepala yang membuka kotak senarai WAI-ARIA APG (atau, bagi date-time-picker, dialog pemilih tarikh) — tiada natif <select>, jadi setiap rangka kerja mendapat tingkah laku papan kekunci dan cangkuk penggayaan yang sama.
  • Satu cangkuk kelas bagi setiap pakej (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), sifar CSS dihantar.
  • Selamat untuk SSR: penulisan DOM berlaku hanya dalam kitaran hayat mount/effect.
  • Bersih i18n: setiap rentetan yang dilihat pengguna ialah prop.
  • Tersedia untuk Svelte (kanonik), React, Vue, Angular, elemen tersuai HTML, Nunjucks dan Blazor — kontrak yang sama dalam setiap satu.

theme-picker, locale-picker dan text-size-picker masing-masing memiliki satu keutamaan pengguna dari awal hingga akhir (pemilihan, penggunaan DOM, localStorage kegigihan storageKey pilihan melalui prop). share-picker dan date-time-picker berbeza jenis: share-picker memiliki satu tindakan — ia tidak menggunakan apa-apa pada dokumen dan tidak menyimpan apa-apa — dan date-time-picker memiliki satu nilai borang, kerana tarikh dalam borang ialah data dan bukan keutamaan.

locale-picker — bahasa dan arah

Membenarkan pengguna memilih lokal, kemudian menulis lang dan dir pada akar dokumen supaya perpustakaan i18n anda, CSS anda dan teknologi bantuan semuanya mengikut. RTL dikesan secara automatik untuk Arab, Ibrani dan tulisan kanan-ke-kiri yang lain. Ia hanya memberi tumpuan kepada isyarat — perpustakaan i18n anda mengendalikan 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 dilabel daripada jadual terbina dalam nama lokal (boleh diganti melalui localeLabels), setiap pilihan membawa atribut lang sendiri supaya pembaca skrin menyebut “Français” dalam bahasa Perancis, dan kod bergaris bawah seperti en_US berulang-alik tanpa kehilangan kepada BCP 47 en-US. Sambungkan onChange (atau nilai terikat) ke i18next, Paraglide, vue-i18n atau apa sahaja yang anda gunakan.

text-size-picker — saiz dikawal pembaca

Kemenangan kebolehcapaian yang mengambil masa beberapa minit: pembantu menetapkan data-text-size="{slug}" pada akar dokumen dan CSS anda memetakan setiap nilai kepada saiz.

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

Saizkan susun atur anda dalam rem dan seluruh aplikasi berskala mengikut pilihan pengguna. Label dihuruf besarkan daripada slug (“X Large”) atau diganti dengan sizeLabels.

Semak kerja anda: pilih “Large” daripada pemilih, dan teks halaman membesar. Muat semula — ia masih besar: pilihan itu disimpan ke localStorage. Tukar pemilih bahasa anda kepada Arab dan dir="rtl" mendarat pada dokumen secara automatik.

share-picker — hantar halaman ini

Butang satu glif yang membuka helaian kongsi natif peranti di mana ada, dan jika tidak kembali kepada senarai destinasi yang anda bekalkan, serta tindakan salin-URL. Ia tidak menghantar URL rangkaian sosial — rangkaian mana yang sesuai dalam produk anda adalah keputusan anda, bukan sistem reka bentuk.

<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 lalai kepada location.hrefjadi kes biasa tidak memerlukan pendawaian. Paksa laluan dengan strategy="list" atau strategy="native" apabila anda memerlukan tingkah laku konsisten merentas platform untuk ujian atau tangkapan skrin.

date-time-picker — tarikh, masa, atau kedua-duanya

Medan teks yang boleh anda taip, ditambah butang ikon yang membuka dialog pemilih tarikh WAI-ARIA APG. Betul mengikut lokal mengikut reka bentuk — nama bulan, nama hari minggu, hari pertama minggu dan jam 12 atau 24 jam semuanya datang daripada Intl — dan nilainya sentiasa rentetan ISO yang boleh diisih tanpa zon masa: "2026-03-15" untuk mode="date", "09:30" untuk mode="time", "2026-03-15T09:30" untuk 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 sama dengan apa yang dihantar oleh <input type="date"> , jadi anda boleh menukar kawalan natif masuk atau keluar tanpa menyentuh bahagian belakang anda.

motion-picker — hormati gerakan dikurangkan

Pembantu menetapkan data-motion="{slug}" pada akar dokumen. Nilai pertamanya datang daripada tetapan sistem pengendalian pelawat prefers-reduced-motion — sentiasa, tanpa bendera pilih masuk, kerana gerakan ialah keperluan kebolehcapaian sebenar (WCAG 2.3.3). CSS dan skrip anda memutuskan apa yang ditindas.

<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 — kotak carian yang tidak menghalang

Butang ikon yang membuka medan carian. Menekan Return, atau butang ⏎ di sebelah medan, menavigasi dengan permintaan GET biasa ke /?<text> (teks dipangkas dan dikod URI; pertanyaan kosong tidak ke mana-mana). Tiga nama boleh diaksesnya diperlukan, kerana pembantu tidak menghantar bahasa Inggeris.

<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 menukar laluan (/search?foo), dan navigate mengekalkan navigasi dalam aplikasi; tanpanya pembantu memanggil location.assign.

picker-bar — seluruh baris pengepala sekaligus

picker-bar memaparkan carian, tema, lokal, saiz teks dan perkongsian dalam satu baris, dengan set penuh tema rujukan dan skala teks tujuh langkah yang sudah disambungkan. Setiap nama boleh diakses tiba dalam satu labels objek wajib.

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

Capai mana-mana pemilih terbalut dengan searchProps, themeProps, localeProps, textSizeProps dan shareProps.

Tip alat sudah terbina dalam

Setiap pemilih menunjukkan labelnya dalam tip alat apabila penuding berehat pada butangnya atau butang mempunyai fokus papan kekunci. Tip alat kekal semasa penuding bergerak ke atasnya, Escape menolaknya di mana-mana fokus berada, dan ia tidak pernah dipaparkan semasa popup pemilih terbuka. Ia membawa teks yang sama dengan nama boleh akses butang, jadi tiada apa untuk dikonfigurasi dan tiada apa untuk diterjemah dua kali; tema rujukan menggayakannya.

Panel tetapan di satu tempat

Empat pembantu keutamaan bergubah dengan semula jadi:

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

Disahkan: serpihan locale-picker, text-size-picker, share-picker, date-time-picker dan panel gabungan dikompil secara berasingan terhadap 0.1.1 pakej yang diterbitkan melalui svelte/server (2026-08-29); serpihan motion-picker, search-picker dan picker-bar dipaparkan terhadap komponen pakej itu sendiri pada 2026-10-06.

Di mana untuk mendapatkannya

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

Setiap pakej mempunyai spec sendiri, ujian yang dipetakan kepada klausa spec, contoh boleh dijalankan (termasuk corak kuki SSR) dan saluran binaan + penerbitan. Pakej Svelte ialah kanonik; apabila ragu, kontrak mereka menang.

Langkah seterusnya

Ada soalan di sepanjang jalan? halaman bantuan penuh dengan jawapan — dan jika sesuatu langkah boleh dijelaskan lagi, beritahu kami dan kami dengan senang hati akan memperbaiki tutorial.