Mga preference helper

Pitong maliliit na package bawat framework, bawat isa ay may-ari ng isang trabaho ng user mula simula hanggang wakas, kasama ang isang bar na nag-aassemble ng lima sa mga ito. Nakilala mo na ang theme-picker; narito ang locale-picker, text-size-picker at motion-picker (mga preference), share-picker at search-picker (mga aksyon), date-time-picker (halaga ng form), at picker-bar.

Ang bubuuin mo

Isang settings panel kung saan pinipili ng mga user ang kanilang wika at laki ng teksto — mga pagpiling ina-apply sa buong dokumento, nananatili sa pagitan ng mga pagbisita, at nagkakahalaga lang ng dalawang component at ilang linya ng CSS. Mga 15 minuto.

Bago ka magsimula

Tapusin muna ang tutorial ng framework para sa iyong stack. Svelte ang mga sample sa ibaba; tumutugma ang mga helper ng React, Vue, Angular, HTML, Nunjucks, at Blazor kontrata-kontrata.

Ang hugis na pinagsasaluhan nila

  • Isang headless na icon button na nagbubukas ng WAI-ARIA APG listbox (o, para sa date-time-picker, isang date-picker dialog) — walang native na <select>, kaya pare-pareho ang gawi ng keyboard at mga styling hook ng bawat framework.
  • Isang class hook bawat package (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), zero CSS ang ipinapadala.
  • Ligtas sa SSR: nangyayari lang ang mga DOM write sa lifecycle ng mount/effect.
  • Malinis sa i18n: bawat string na nakikita ng user ay prop.
  • Available para sa Svelte (canonical), React, Vue, Angular, HTML custom element, Nunjucks, at Blazor — iisang kontrata sa bawat isa.

Ang theme-picker, locale-picker, at text-size-picker ay bawat isa may-ari ng isang preference ng user mula simula hanggang wakas (pagpili, aplikasyon sa DOM, opsyonal na localStorage persistence storageKey sa pamamagitan ng prop). Magkaiba ng uri ang share-picker at date-time-picker: ang share-picker ay may-ari ng isang aksyon — wala itong inilalapat sa dokumento at wala itong pinapanatili — at ang date-time-picker ay may-ari ng isang halaga ng form, dahil ang petsa sa isang form ay datos, hindi preference.

locale-picker — wika at direksyon

Hinahayaan ang user na pumili ng locale, pagkatapos ay isinusulat ang lang at dir sa root ng dokumento para sundan ito ng iyong i18n library, iyong CSS, at assistive technology. Awtomatikong natutukoy ang RTL para sa Arabic, Hebrew, at iba pang right-to-left na script. Nakatuon ito sa pagbibigay-signal lamang — ang iyong i18n library ang bahala sa pagsasalin.

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

Ang mga opsyon ay nilalagyan ng label mula sa built-in na talahanayan ng mga pangalan ng locale (maaaring i-override sa pamamagitan ng localeLabels), bawat opsyon ay may sariling lang attribute para bigkasin ng mga screen reader ang “Français” sa Pranses, at ang mga code na may underscore tulad ng en_US ay walang-pagkawalang bumabalik-balik sa BCP 47 en-US. Ikabit ang onChange (o ang bound na halaga) sa i18next, Paraglide, vue-i18n, o anuman ang ginagamit mo.

text-size-picker — laki na kontrolado ng mambabasa

Isang panalo sa accessibility na tumatagal ng ilang minuto: itinatakda ng helper ang data-text-size="{slug}" sa root ng dokumento at imamapa ng iyong CSS ang bawat halaga sa laki.

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

Sukatin ang iyong layout sa rem at susukat ang buong app ayon sa pinili ng user. Ang mga label ay ginagawang title-case mula sa mga slug (“X Large”) o ino-override gamit ang sizeLabels.

Suriin ang gawa mo: piliin ang “Large” mula sa picker, at lalaki ang teksto ng pahina. Mag-reload — malaki pa rin: nanatili ang pinili sa localStorage. Ilipat ang iyong picker ng wika sa Arabic at ang dir="rtl" ay awtomatikong mapupunta sa dokumento.

share-picker — ipadala ang pahinang ito

Isang single-glyph na button na nagbubukas ng native na share sheet ng device kung saan mayroon, at kung hindi ay bumabalik sa listahan ng mga destinasyong ibibigay mo, kasama ang aksyon ng pagkopya ng URL. Hindi ito nagpapadala ng anumang URL ng social network — kung aling mga network ang nararapat sa produkto mo ay desisyon mo, hindi ng design system.

<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 ay default sa location.hrefkaya hindi na kailangan ng wiring sa karaniwang kaso. Pilitin ang isang path gamit ang strategy="list" o strategy="native" kapag kailangan mo ng pare-parehong gawi sa lahat ng platform para sa pagsusuri o mga screenshot.

date-time-picker — petsa, oras, o pareho

Isang text field na maaari mong i-type, kasama ang isang icon button na nagbubukas ng WAI-ARIA APG date-picker dialog. Tama sa locale sa disenyo — ang mga pangalan ng buwan, pangalan ng araw ng linggo, unang araw ng linggo, at 12- o 24-oras na orasan ay lahat nanggagaling sa Intl — at ang halaga ay palaging isang masusuri at walang-timezone na ISO string: "2026-03-15" para sa mode="date", "09:30" para sa mode="time", "2026-03-15T09:30" para sa 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",
  }}
/>

Kapareho ang halagang ISO ng ipinopost ng <input type="date"> , kaya maaari mong ipasok o alisin ang native na kontrol nang hindi ginagalaw ang backend mo.

motion-picker — igalang ang nabawasang galaw

Itinatakda ng helper ang data-motion="{slug}" sa root ng dokumento. Ang unang halaga nito ay nanggagaling sa setting ng operating system ng bisita prefers-reduced-motion — palagi, nang walang opt-in na flag, dahil tunay na pangangailangan sa accessibility ang galaw (WCAG 2.3.3). Ang iyong CSS at mga script ang magpapasya kung ano ang pipigilan.

<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 — isang search box na umiiwas sa daan

Isang icon button na nagbubukas ng search field. Ang pagpindot sa Return, o ang ⏎ na button sa tabi ng field, ay nagna-navigate gamit ang payak na GET request sa /?<text> (tinatanggalan ng sobra ang teksto at URI-encoded; ang walang-lamang query ay hindi pumupunta saanman). Kinakailangan ang tatlong accessible na pangalan nito, dahil hindi nagpapadala ng Ingles ang helper.

<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 ay nagbabago ng path (/search?foo), at navigate ay pinananatili ang navigation sa loob ng app; kung wala ito, tinatawag ng helper ang location.assign.

picker-bar — ang buong header row nang sabay-sabay

picker-bar ay nagre-render ng search, tema, locale, laki ng teksto at pagbabahagi sa isang row, na may buong hanay ng mga reference na tema at pitong-hakbang na text scale na naka-wire na. Dumarating ang bawat accessible na pangalan sa isang kinakailangang labels object.

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

Abutin ang anumang nakabalot na picker gamit ang searchProps, themeProps, localeProps, textSizeProps at shareProps.

Kasama na ang mga tooltip

Ipinapakita ng bawat picker ang label nito sa isang tooltip kapag nakapatong ang pointer sa button nito o may keyboard focus ang button. Nananatili ang tooltip habang lumilipat ang pointer papunta rito, ibinababa ito ng Escape saanman naroon ang focus, at hindi ito kailanman lumilitaw habang bukas ang popup ng picker. Dala nito ang parehong teksto ng accessible na pangalan ng button, kaya walang kailangang i-configure at walang isasaling dalawang beses; ang mga reference na tema ang nagbibigay ng istilo nito.

Isang settings panel sa isang lugar

Natural na nagsasama ang apat na preference helper:

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

Napatunayan: ang mga snippet ng locale-picker, text-size-picker, share-picker, date-time-picker at pinagsamang panel ay isa-isang na-compile laban sa nailathalang 0.1.1 mga package sa pamamagitan ng svelte/server (2026-08-29); ang mga snippet ng motion-picker, search-picker at picker-bar ay na-render laban sa sariling mga component ng mga package noong 2026-10-06.

Saan ito makukuha

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

Bawat package ay may sariling spec, mga pagsusuring nakamapa sa mga clause ng spec, mga halimbawang maaaring patakbuhin (kasama ang mga SSR cookie pattern), at build + publish pipeline. Canonical ang mga Svelte package; kapag may pagdududa, nananaig ang kanilang mga kontrata.

Mga susunod na hakbang

May mga tanong habang nasa daan? Ang pahina ng tulong ay puno ng mga sagot — at kung maaaring maging mas malinaw ang isang hakbang, sabihin sa amin at masaya naming pagbubutihin ang tutorial.