वरीयता सहायक

हर फ़्रेमवर्क के लिए सात छोटे पैकेज, हर एक उपयोगकर्ता के एक काम का शुरू से अंत तक स्वामी है, साथ में एक पट्टी जो उनमें से पाँच को जोड़ती है। आप पहले ही मिल चुके हैं 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 सहायक अनुबंध-दर-अनुबंध मेल खाते हैं।

वह आकार जो वे साझा करते हैं

  • एक हेडलेस आइकन बटन जो WAI-ARIA APG लिस्टबॉक्स खोलता है (या date-time-picker के लिए तिथि-चयन संवाद) — कोई मूल <select>नहीं, ताकि हर फ़्रेमवर्क को समान कीबोर्ड व्यवहार और स्टाइलिंग हुक मिलें।
  • प्रति पैकेज एक क्लास हुक (.locale-picker, .text-size-picker, .share-picker, .date-time-picker), शून्य CSS भेजा जाता है।
  • SSR-सुरक्षित: DOM लिखाई केवल mount/effect जीवनचक्र में होती है।
  • i18n-स्वच्छ: उपयोगकर्ता को दिखने वाली हर स्ट्रिंग एक prop है।
  • Svelte (मानक), React, Vue, Angular, HTML कस्टम तत्व, 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-

हर पैकेज का अपना spec, spec धाराओं से जुड़े परीक्षण, चलाए जा सकने वाले उदाहरण (SSR कुकी पैटर्न सहित) और बिल्ड + प्रकाशन पाइपलाइन है। Svelte पैकेज मानक हैं; संदेह में उनके अनुबंध जीतते हैं।

अगले चरण

रास्ते में सवाल हैं? सहायता पृष्ठ उत्तरों से भरा है — और अगर कोई चरण और स्पष्ट हो सकता है, हमें बताएँ और हम खुशी से ट्यूटोरियल सुधारेंगे।