Einstellungs-Helper
Sieben kleine Pakete pro Framework, jedes besitzt eine Aufgabe der Nutzenden von Anfang bis Ende, plus eine Leiste, die fünf davon zusammenfasst. Du kennst theme-pickerschon; hier sind locale-picker, text-size-picker und motion-picker (Einstellungen), share-picker und search-picker (Aktionen), date-time-picker (ein Formularwert) und picker-bar.
Was du baust
Ein Einstellungsbereich, in dem Nutzende Sprache und Textgröße wählen — Entscheidungen, die für das ganze Dokument gelten, über Besuche hinweg bestehen bleiben und dich zwei Komponenten und ein paar Zeilen CSS kosten. Etwa 15 Minuten.
Bevor du anfängst
Schließe zuerst das Framework-Tutorial für deinen Stack ab. Die Beispiele unten sind Svelte; die Helper für React, Vue, Angular, HTML, Nunjucks und Blazor entsprechen ihnen Vertrag für Vertrag.
Die gemeinsame Form
- Ein Headless-Icon-Button, der eine WAI-ARIA-APG-Listbox öffnet (oder, bei date-time-picker, einen Datumsauswahl-Dialog) — kein natives
<select>, sodass jedes Framework dasselbe Tastaturverhalten und dieselben Styling-Hooks bekommt. - Ein Klassen-Hook pro Paket (
.locale-picker,.text-size-picker,.share-picker,.date-time-picker), null ausgeliefertes CSS. - SSR-sicher: DOM-Schreibzugriffe passieren nur im Mount-/Effect-Lebenszyklus.
- i18n-sauber: Jeder für Nutzende sichtbare Text ist eine Prop.
- Verfügbar für Svelte (kanonisch), React, Vue, Angular, HTML-Custom-Element, Nunjucks und Blazor — in jedem derselbe Vertrag.
theme-picker, locale-picker und text-size-picker besitzen jeweils eine
Einstellung der Nutzenden von Anfang bis Ende (Auswahl, Anwendung im DOM, optionale
localStorage Persistenz über die storageKey
-Prop). share-picker und date-time-picker sind anders geartet: share-picker besitzt eine Aktion — sie wendet nichts auf das Dokument an und speichert nichts — und date-time-picker besitzt einen
Formularwert, denn ein Datum in einem Formular sind Daten, keine Einstellung.
locale-picker — Sprache und Richtung
Lässt die Nutzenden ein Gebietsschema wählen und schreibt dann lang und
dir auf die Dokumentwurzel, damit deine i18n-Bibliothek, dein CSS und Hilfstechnologien alle folgen. RTL wird für Arabisch, Hebräisch und andere Schriften von rechts nach links automatisch erkannt. Er konzentriert sich rein aufs Signalisieren — die Übersetzung übernimmt deine i18n-Bibliothek.
<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"
/>
Die Optionen werden aus einer eingebauten Tabelle von Gebietsschemanamen beschriftet (überschreibbar über localeLabels), jede Option trägt ihr eigenes
lang -Attribut, damit Screenreader „Français“ französisch aussprechen, und Codes mit Unterstrich wie en_US
werden verlustfrei nach BCP 47 und zurück umgewandelt en-US. Schließe
onChange (oder den gebundenen Wert) an i18next, Paraglide, vue-i18n oder was auch immer du nutzt an.
text-size-picker — von der lesenden Person gesteuerte Größe
Ein Barrierefreiheits-Gewinn in Minuten: Der Helper setzt
data-text-size="{slug}" auf der Dokumentwurzel, und dein CSS ordnet jeden Wert einer Größe zu.
<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%; }
Lege dein Layout in rem aus, und die ganze App skaliert mit der Wahl der Nutzenden. Labels werden aus den Slugs in Titelschreibweise gebildet („X Large“) oder mit sizeLabels.
Prüfe deine Arbeit: überschrieben. Wähle „Large“ im Picker, und der Seitentext wird größer. Neu laden — er ist immer noch groß: Die Wahl wurde dauerhaft gespeichert in
localStorage. Stelle deinen Sprach-Picker auf Arabisch um, und
dir="rtl" wird automatisch auf das Dokument gesetzt.
share-picker — diese Seite senden
Ein Ein-Glyphen-Button, der das native Teilen-Menü des Geräts öffnet, wo es eines gibt, und sonst auf eine Liste von dir gelieferter Ziele zurückfällt, plus eine Aktion zum Kopieren der URL. Er liefert keine Social-Network-URLs mit — welche Netzwerke in dein Produkt gehören, entscheidest du, nicht das Designsystem.
<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 ist standardmäßig location.href, daher braucht der Normalfall keine Verdrahtung. Erzwinge einen Pfad mit strategy="list" oder
strategy="native" , wenn du für Tests oder Screenshots konsistentes Verhalten über Plattformen hinweg brauchst.
date-time-picker — ein Datum, eine Uhrzeit oder beides
Ein Textfeld, in das du tippen kannst, plus ein Icon-Button, der einen WAI-ARIA-APG-Datumsauswahl-Dialog öffnet. Von Grund auf lokalisierungsrichtig — Monatsnamen, Wochentagsnamen, erster Wochentag und 12- oder 24-Stunden-Uhr kommen alle aus Intl — und der Wert ist immer ein sortierbarer, zeitzonenfreier ISO-String: "2026-03-15" für
mode="date", "09:30" für
mode="time", "2026-03-15T09:30" für
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",
}}
/>
Der ISO-Wert ist identisch mit dem, was <input type="date">
abschickt, sodass du das native Bedienelement ein- oder austauschen kannst, ohne dein Backend anzufassen.
motion-picker — reduzierte Bewegung respektieren
Der Helper setzt data-motion="{slug}" auf der Dokumentwurzel. Sein erster Wert kommt aus der
prefers-reduced-motion -Einstellung des Betriebssystems der besuchenden Person — immer, ohne Opt-in-Flag, weil Bewegung ein echtes Barrierefreiheitsbedürfnis ist (WCAG 2.3.3). Dein CSS und deine Skripte entscheiden, was unterdrückt wird.
<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 — ein Suchfeld, das nicht im Weg ist
Ein Icon-Button, der ein Suchfeld öffnet. Drücken von Return oder der ⏎-Button neben dem Feld navigiert mit einer einfachen GET-Anfrage zu
/?<text> (der Text wird getrimmt und URI-kodiert; eine leere Anfrage führt nirgendwohin). Seine drei zugänglichen Namen sind Pflicht, weil der Helper kein Englisch mitliefert.
<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 ändert den Pfad (/search?foo), und
navigate hält die Navigation in der App; ohne ihn ruft der Helper location.assign.
picker-bar — die ganze Kopfzeile auf einmal
picker-bar rendert Suche, Theme, Sprache, Textgröße und Teilen in einer Zeile, mit dem vollständigen Satz an Referenz-Themes und der siebenstufigen Textskala bereits verdrahtet. Jeder zugängliche Name kommt in einem einzigen erforderlichen
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}
/>
Erreiche jeden eingebetteten Picker mit searchProps,
themeProps, localeProps,
textSizeProps und shareProps.
Tooltips sind eingebaut
Jeder Picker zeigt sein Label in einem Tooltip, wenn der Zeiger auf seinem Button ruht oder der Button Tastaturfokus hat. Der Tooltip bleibt stehen, während der Zeiger auf ihn wandert, Escape schließt ihn, wo auch immer der Fokus ist, und er erscheint nie, solange das Popup des Pickers offen ist. Er trägt denselben Text wie der zugängliche Name des Buttons, also gibt es nichts zu konfigurieren und nichts doppelt zu übersetzen; die Referenz-Themes gestalten ihn.
Ein Einstellungsbereich an einem Ort
Die vier Einstellungs-Helper lassen sich ganz natürlich kombinieren:
<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>
Geprüft: Die Snippets für locale-picker, text-size-picker, share-picker, date-time-picker und den kombinierten Bereich wurden einzeln gegen die veröffentlichten 0.1.1 -Pakete kompiliert, über
svelte/server (2026-08-29); die Snippets für motion-picker, search-picker und picker-bar wurden am 2026-10-06 gegen die eigenen Komponenten der Pakete gerendert.
Wo du sie bekommst
# 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-
Jedes Paket hat seine eigene Spec, Tests, die den Spec-Klauseln zugeordnet sind, lauffähige Beispiele (einschließlich SSR-Cookie-Mustern) und eine Build- und Veröffentlichungs-Pipeline. Die Svelte-Pakete sind kanonisch; im Zweifel gelten ihre Verträge.
Nächste Schritte
- Komponentenkatalog — die vollständige Referenz der 571 Komponenten.
- Hilfe — Fehlerbehebung und FAQ.
- Warum Lily — und wie du das Projekt unterstützen kannst.
Fragen unterwegs? Die Hilfeseite steckt voller Antworten — und wenn ein Schritt klarer sein könnte, sag es uns und wir verbessern das Tutorial gern.