ตัวช่วยการตั้งค่า
แพ็กเกจเล็ก ๆ เจ็ดตัวต่อเฟรมเวิร์ก แต่ละตัวดูแลงานของผู้ใช้หนึ่งอย่างตั้งแต่ต้นจนจบ บวกกับแถบที่รวมห้าตัวเข้าด้วยกัน คุณเคยรู้จัก theme-pickerแล้ว ต่อไปนี้คือ locale-picker, text-size-picker และ motion-picker (การตั้งค่า), share-picker และ search-picker (การกระทำ), date-time-picker (ค่าของฟอร์ม) และ picker-bar
สิ่งที่คุณจะสร้าง
แผงการตั้งค่าที่ผู้ใช้เลือกภาษาและขนาดตัวอักษร — ตัวเลือกที่ใช้กับทั้งเอกสาร คงอยู่ข้ามการเยี่ยมชม และใช้เพียงสองคอมโพเนนต์กับ CSS ไม่กี่บรรทัด ใช้เวลาประมาณ 15 นาที
ก่อนเริ่ม
ทำให้เสร็จก่อน บทเรียนเฟรมเวิร์ก สำหรับสแต็กของคุณ ตัวอย่างด้านล่างเป็น Svelte ส่วนตัวช่วยของ React, Vue, Angular, HTML, Nunjucks และ Blazor ตรงกันทีละสัญญา
รูปแบบที่ใช้ร่วมกัน
- ปุ่มไอคอนแบบ headless ที่เปิด listbox ตาม WAI-ARIA APG (หรือสำหรับ date-time-picker คือกล่องโต้ตอบเลือกวันที่) — ไม่มี
<select>แบบเนทีฟ ทุกเฟรมเวิร์กจึงได้พฤติกรรมแป้นพิมพ์และ style hook เหมือนกัน - หนึ่ง class hook ต่อแพ็กเกจ (
.locale-picker,.text-size-picker,.share-picker,.date-time-picker) ไม่มี CSS ส่งมาด้วย - ปลอดภัยสำหรับ SSR: การเขียน DOM เกิดขึ้นเฉพาะในวงจรชีวิต mount/effect
- เป็นมิตรต่อ i18n: ทุกข้อความที่ผู้ใช้เห็นเป็น prop
- ใช้ได้กับ Svelte (ตัวหลัก), React, Vue, Angular, HTML custom element, Nunjucks และ Blazor — สัญญาเดียวกันในทุกตัว
theme-picker, locale-picker และ text-size-picker แต่ละตัวดูแล
การตั้งค่า ของผู้ใช้หนึ่งอย่างตั้งแต่ต้นจนจบ (การเลือก, การนำไปใช้กับ DOM,
localStorage การเก็บค่าแบบไม่บังคับผ่าน storageKey
prop) ส่วน share-picker และ date-time-picker ต่างออกไปในประเภท: share-picker ดูแล การกระทำ — ไม่นำอะไรไปใช้กับเอกสารและไม่เก็บอะไรไว้ — และ date-time-picker ดูแล
ค่าของฟอร์มเพราะวันที่ในฟอร์มเป็นข้อมูล ไม่ใช่การตั้งค่า
locale-picker — ภาษาและทิศทาง
ให้ผู้ใช้เลือกโลแคล แล้วเขียน lang และ
dir ลงที่รากของเอกสาร เพื่อให้ไลบรารี i18n, CSS และเทคโนโลยีช่วยเหลือทั้งหมดตามไปด้วย ระบบตรวจจับ RTL ให้อัตโนมัติสำหรับภาษาอาหรับ ฮีบรู และอักษรอื่นที่เขียนจากขวาไปซ้าย มันทำหน้าที่ส่งสัญญาณเท่านั้น — ไลบรารี i18n ของคุณจัดการการแปล
<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"
/>
ป้ายกำกับของตัวเลือกมาจากตารางชื่อโลแคลที่มีมาในตัว (แทนที่ได้ผ่าน localeLabels) ตัวเลือกแต่ละอันมี
lang แอตทริบิวต์ของตัวเอง เพื่อให้โปรแกรมอ่านหน้าจอออกเสียง "Français" เป็นภาษาฝรั่งเศส และรหัสที่มีขีดล่าง เช่น en_US
แปลงไปกลับกับ BCP 47 ได้โดยไม่สูญเสีย en-USเชื่อม
onChange (หรือค่าที่ผูกไว้) เข้ากับ i18next, Paraglide, vue-i18n หรืออะไรก็ตามที่คุณใช้
text-size-picker — ขนาดที่ผู้อ่านควบคุมเอง
ชัยชนะด้านการเข้าถึงที่ใช้เวลาเพียงไม่กี่นาที: ตัวช่วยตั้งค่า
data-text-size="{slug}" ที่รากของเอกสาร และ CSS ของคุณจับคู่แต่ละค่ากับขนาด
<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%; }
กำหนดขนาดเลย์เอาต์ด้วย rem แล้วทั้งแอปจะขยายตามที่ผู้ใช้เลือก ป้ายกำกับสร้างจาก slug เป็นตัวพิมพ์ใหญ่ต้นคำ ("X Large") หรือแทนที่ด้วย sizeLabels.
ตรวจสอบงานของคุณ: เลือก "Large" จากตัวเลือก แล้วข้อความในหน้าจะใหญ่ขึ้น โหลดซ้ำ — ก็ยังใหญ่อยู่ เพราะการเลือกถูกเก็บไว้ที่
localStorageสลับตัวเลือกภาษาเป็นภาษาอาหรับ แล้ว
dir="rtl" จะถูกตั้งบนเอกสารโดยอัตโนมัติ
share-picker — ส่งหน้านี้
ปุ่มสัญลักษณ์เดียวที่เปิดชีตแชร์แบบเนทีฟของอุปกรณ์ถ้ามี และถ้าไม่มีก็จะสลับไปใช้รายการปลายทางที่คุณกำหนด พร้อมการกระทำคัดลอก URL ไม่มี URL ของโซเชียลเน็ตเวิร์กมาให้ — เครือข่ายใดเหมาะกับผลิตภัณฑ์ของคุณเป็นการตัดสินใจของคุณ ไม่ใช่ของระบบออกแบบ
<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 มีค่าเริ่มต้นเป็น location.hrefกรณีทั่วไปจึงไม่ต้องเชื่อมต่ออะไรเพิ่ม บังคับเส้นทางด้วย strategy="list" หรือ
strategy="native" เมื่อต้องการพฤติกรรมที่สม่ำเสมอข้ามแพลตฟอร์มสำหรับการทดสอบหรือภาพหน้าจอ
date-time-picker — วันที่ เวลา หรือทั้งสองอย่าง
ช่องข้อความที่พิมพ์ได้ พร้อมปุ่มไอคอนที่เปิดกล่องโต้ตอบเลือกวันที่ตาม WAI-ARIA APG ถูกต้องตามโลแคลโดยโครงสร้าง — ชื่อเดือน ชื่อวัน วันแรกของสัปดาห์ และนาฬิกา 12 หรือ 24 ชั่วโมง ล้วนมาจาก Intl — และค่าเป็นสตริง ISO ที่เรียงลำดับได้และไม่มีเขตเวลาเสมอ: "2026-03-15" สำหรับ
mode="date", "09:30" สำหรับ
mode="time", "2026-03-15T09:30" สำหรับ
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 เหมือนกับที่ <input type="date">
ส่งไปทุกประการ ดังนั้นคุณจึงสลับตัวควบคุมแบบเนทีฟเข้าหรือออกได้โดยไม่ต้องแตะแบ็กเอนด์
motion-picker — เคารพการลดการเคลื่อนไหว
ตัวช่วยตั้งค่า data-motion="{slug}" ที่รากของเอกสาร ค่าแรกมาจากการตั้งค่า
prefers-reduced-motion ของระบบปฏิบัติการของผู้เยี่ยมชม — เสมอ โดยไม่มีแฟล็กให้เลือกเปิด เพราะการเคลื่อนไหวเป็นความต้องการด้านการเข้าถึงจริง (WCAG 2.3.3) CSS และสคริปต์ของคุณเป็นผู้ตัดสินว่าจะระงับอะไร
<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 — กล่องค้นหาที่ไม่เกะกะ
ปุ่มไอคอนที่เปิดช่องค้นหา การกด Return หรือปุ่ม ⏎ ข้างช่อง จะไปยังหน้าถัดไปด้วยคำขอ GET ธรรมดาไปที่
/?<text> (ข้อความถูกตัดช่องว่างและเข้ารหัส URI คำค้นว่างจะไม่ไปไหน) ชื่อที่เข้าถึงได้สามชื่อเป็นสิ่งจำเป็น เพราะตัวช่วยไม่มีภาษาอังกฤษมาให้
<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 เปลี่ยนเส้นทาง (/search?foo) และ
navigate ทำให้การนำทางอยู่ภายในแอป หากไม่มี ตัวช่วยจะเรียก location.assign.
picker-bar — แถวส่วนหัวทั้งแถวในครั้งเดียว
picker-bar แสดงการค้นหา ธีม โลแคล ขนาดตัวอักษร และการแชร์ในแถวเดียว พร้อมชุดธีมอ้างอิงครบและสเกลขนาดตัวอักษรเจ็ดระดับที่เชื่อมไว้ล่วงหน้า ชื่อที่เข้าถึงได้ทุกชื่อส่งมาในออบเจ็กต์
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}
/>
เข้าถึงตัวเลือกที่ถูกห่อไว้ได้ด้วย searchProps,
themeProps, localeProps,
textSizeProps และ shareProps.
มีทูลทิปมาในตัว
ตัวเลือกทุกตัวแสดงป้ายกำกับในทูลทิปเมื่อตัวชี้วางอยู่บนปุ่มหรือปุ่มมีโฟกัสแป้นพิมพ์ ทูลทิปจะคงอยู่เมื่อตัวชี้เลื่อนเข้าไปบนมัน กด Escape เพื่อปิดได้ไม่ว่าโฟกัสจะอยู่ที่ใด และจะไม่แสดงเลยขณะที่ป๊อปอัปของตัวเลือกเปิดอยู่ มันใช้ข้อความเดียวกับชื่อที่เข้าถึงได้ของปุ่ม จึงไม่มีอะไรต้องตั้งค่าและไม่ต้องแปลสองครั้ง ธีมอ้างอิงเป็นผู้ใส่สไตล์ให้
แผงการตั้งค่าในที่เดียว
ตัวช่วยการตั้งค่าทั้งสี่ประกอบเข้าด้วยกันได้อย่างเป็นธรรมชาติ:
<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>
ตรวจสอบแล้ว: ตัวอย่างโค้ดของ locale-picker, text-size-picker, share-picker, date-time-picker และแผงรวม ถูกคอมไพล์ทีละตัวเทียบกับ 0.1.1 แพ็กเกจที่เผยแพร่แล้ว ผ่าน
svelte/server (2026-08-29) ส่วนตัวอย่างของ motion-picker, search-picker และ picker-bar ถูกเรนเดอร์เทียบกับคอมโพเนนต์ของแพ็กเกจเองเมื่อ 2026-10-06
หาได้ที่ไหน
# 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-
แต่ละแพ็กเกจมีสเปกของตัวเอง การทดสอบที่โยงกับข้อกำหนดของสเปก ตัวอย่างที่รันได้ (รวมถึงรูปแบบคุกกี้สำหรับ SSR) และไปป์ไลน์สำหรับบิลด์และเผยแพร่ แพ็กเกจ Svelte เป็นตัวหลัก เมื่อสงสัย ให้ถือสัญญาของมันเป็นหลัก
ขั้นต่อไป
- แคตตาล็อกคอมโพเนนต์ — เอกสารอ้างอิงครบทั้ง 571 คอมโพเนนต์
- ช่วยเหลือ — การแก้ปัญหาและคำถามที่พบบ่อย
- ทำไมต้อง Lily — และวิธีสนับสนุนโครงการ
มีคำถามระหว่างทางไหม? หน้าช่วยเหลือ เต็มไปด้วยคำตอบ — และถ้าขั้นตอนไหนทำให้ชัดเจนกว่านี้ได้ บอกเรา แล้วเรายินดีปรับปรุงบทเรียน