Preferenču palīgi

Septiņas mazas paketes katram ietvaram, katra no kurām pārvalda vienu lietotāja uzdevumu no sākuma līdz beigām, plus josla, kas apvieno piecas no tām. Jūs jau esat saticis theme-picker; lūk locale-picker, text-size-picker un motion-picker (preferences), share-picker un search-picker (darbības), date-time-picker (veidlapas vērtība) un picker-bar.

Ko jūs izveidosiet

Iestatījumu panelis, kurā lietotāji izvēlas valodu un teksta izmēru — izvēles, kas attiecas uz visu dokumentu, saglabājas starp apmeklējumiem un jums izmaksā divas komponentes un dažas CSS rindiņas. Apmēram 15 minūtes.

Pirms sākat

Vispirms pabeidziet ietvara apmācību savam stekam. Tālāk redzamie paraugi ir Svelte; React, Vue, Angular, HTML, Nunjucks un Blazor palīgi tiem atbilst līgums pēc līguma.

Forma, ko tie dala

  • Bezgalvas ikonas poga, kas atver WAI-ARIA APG listbox (vai date-time-picker gadījumā datuma izvēles dialogu) — bez vietējā <select>, tāpēc katrs ietvars iegūst vienādu tastatūras uzvedību un stila āķus.
  • Viens klases āķis uz paketi (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), nulle piegādāta CSS.
  • Drošs SSR: DOM rakstīšana notiek tikai mount/effect dzīves ciklā.
  • Tīrs i18n ziņā: katra lietotājam redzamā virkne ir prop.
  • Pieejams Svelte (kanoniskais), React, Vue, Angular, HTML pielāgotam elementam, Nunjucks un Blazor — katrā tas pats līgums.

theme-picker, locale-picker un text-size-picker katrs pārvalda vienu lietotāja preferenci no sākuma līdz beigām (izvēle, pielietošana DOM, neobligāta localStorage saglabāšana ar storageKey propu). share-picker un date-time-picker ir cita veida: share-picker pārvalda darbību — tas neko nepielieto dokumentam un neko nesaglabā — bet date-time-picker pārvalda veidlapas vērtību, jo datums veidlapā ir dati, nevis preference.

locale-picker — valoda un virziens

Ļauj lietotājam izvēlēties lokāli, pēc tam ieraksta lang un dir dokumenta saknē, lai jūsu i18n bibliotēka, CSS un atbalsta tehnoloģijas tai visas sekotu. RTL tiek noteikts automātiski arābu, ivrita un citām no labās uz kreiso rakstāmām rakstībām. Tas pievēršas tikai signalizēšanai — tulkošanu veic jūsu i18n bibliotēka.

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

Opcijas tiek apzīmētas no iebūvētas lokāļu nosaukumu tabulas (var pārrakstīt ar localeLabels), katra opcija nes savu lang atribūtu, lai ekrāna lasītāji izrunātu „Français” franču valodā, un kodi ar pasvītru, piemēram, en_US tiek bez zudumiem konvertēti uz BCP 47 un atpakaļ en-US. Savienojiet onChange (vai saistīto vērtību) ar i18next, Paraglide, vue-i18n vai ko vien izmantojat.

text-size-picker — izmērs, ko kontrolē lasītājs

Pieejamības uzvara, kas aizņem minūtes: palīgs iestata data-text-size="{slug}" dokumenta saknē, un jūsu CSS katru vērtību piesaista izmēram.

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

Izmērojiet savu izkārtojumu rem un visa lietotne mērogojas līdz ar lietotāja izvēli. Iezīmes veido no slug’iem ar lielo sākumburtu („X Large”) vai pārraksta ar sizeLabels.

Pārbaudiet savu darbu: izvēlieties „Large” izvēlnē, un lapas teksts pieaug. Pārlādējiet — tas joprojām ir liels: izvēle tika saglabāta localStorage. Pārslēdziet valodas izvēli uz arābu, un dir="rtl" tiek automātiski iestatīts dokumentā.

share-picker — nosūtiet šo lapu

Viena glifa poga, kas atver ierīces vietējo kopīgošanas lapu, kur tāda ir, un citādi atkāpjas uz jūsu norādīto galamērķu sarakstu, plus URL kopēšanas darbību. Tā nepiegādā nevienu sociālo tīklu URL — kuri tīkli pieder jūsu produktam, ir jūsu, nevis dizaina sistēmas lēmums.

<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 noklusējums ir location.hreftāpēc parastajam gadījumam nav vajadzīga nekāda savienošana. Piespiediet ceļu ar strategy="list" vai strategy="native" kad nepieciešama konsekventa uzvedība starp platformām testiem vai ekrānuzņēmumiem.

date-time-picker — datums, laiks vai abi

Teksta lauks, kurā var rakstīt, plus ikonas poga, kas atver WAI-ARIA APG datuma izvēles dialogu. Pareizs lokālei pēc konstrukcijas — mēnešu nosaukumi, nedēļas dienu nosaukumi, nedēļas pirmā diena un 12 vai 24 stundu pulkstenis visi nāk no Intl — un vērtība vienmēr ir kārtojama ISO virkne bez laika joslas: "2026-03-15" elementam mode="date", "09:30" elementam mode="time", "2026-03-15T09:30" elementam 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 vērtība ir identiska tai, ko <input type="date"> nosūta, tāpēc vietējo vadīklu varat ievietot vai izņemt, nepieskaroties aizmugursistēmai.

motion-picker — ievērojiet samazinātu kustību

Palīgs iestata data-motion="{slug}" dokumenta saknē. Tā pirmā vērtība nāk no apmeklētāja operētājsistēmas prefers-reduced-motion iestatījuma — vienmēr, bez ieslēgšanas karoga, jo kustība ir īsta pieejamības vajadzība (WCAG 2.3.3). Jūsu CSS un skripti izlemj, kas tiek nomākts.

<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 — meklēšanas lodziņš, kas netraucē

Ikonas poga, kas atver meklēšanas lauku. Nospiežot Return vai pogu ⏎ blakus laukam, tiek pārvietots ar vienkāršu GET pieprasījumu uz /?<text> (teksts tiek apgriezts un kodēts kā URI; tukšs vaicājums nekur neved). Tā trīs pieejamie nosaukumi ir obligāti, jo palīgs nepiegādā angļu valodu.

<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 maina ceļu (/search?foo), un navigate notur navigāciju lietotnes iekšienē; bez tā palīgs izsauc location.assign.

picker-bar — visa galvenes rinda uzreiz

picker-bar attēlo meklēšanu, motīvu, lokāli, teksta izmēru un kopīgošanu vienā rindā, ar pilnu atsauces motīvu kopu un septiņpakāpju teksta skalu iepriekš savienotiem. Katrs pieejamais nosaukums nāk vienā obligātā labels objektā.

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

Sasniedziet jebkuru ietītu izvēlni ar searchProps, themeProps, localeProps, textSizeProps un shareProps.

Rīka padomi ir iebūvēti

Katra izvēlne rāda savu iezīmi rīka padomā, kad rādītājs atrodas uz tās pogas vai pogai ir tastatūras fokuss. Rīka padoms paliek, kamēr rādītājs pārvietojas uz to, Escape to aizver, kur vien atrastos fokuss, un tas nekad netiek rādīts, kamēr izvēlnes uznirstošais logs ir atvērts. Tas nes to pašu tekstu kā pogas pieejamais nosaukums, tāpēc nav ko konfigurēt vai tulkot divreiz; atsauces motīvi to noformē.

Iestatījumu panelis vienuviet

Četri preferenču palīgi dabiski saliekas kopā:

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

Pārbaudīts: locale-picker, text-size-picker, share-picker, date-time-picker un apvienotā paneļa fragmenti tika sakompilēti atsevišķi pret publicētajām 0.1.1 paketēm, izmantojot svelte/server (2026-08-29); motion-picker, search-picker un picker-bar fragmenti tika attēloti pret pašu paku komponentēm 2026-10-06.

Kur tos iegūt

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

Katrai paketei ir savs spec, testi, kas piesaistīti spec klauzulām, izpildāmi piemēri (ieskaitot SSR sīkdatņu modeļus) un būvēšanas un publicēšanas cauruļvads. Svelte paketes ir kanoniskās; šaubu gadījumā to līgumi uzvar.

Nākamie soļi

Jautājumi pa ceļam? Palīdzības lapa ir pilna atbilžu — un, ja kāds solis varētu būt skaidrāks, pastāstiet mums un mēs labprāt uzlabosim apmācību.