सीधे मुख्य कॉन्टेंट पर जाएँ
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
शुरुआत करेंWebReactSwiftUIJetpack ComposeFlutterReact Nativeप्रीसेटआपका अपना डिज़ाइन सिस्टमAI एजेंट के साथ Tanrei का इस्तेमालब्रांडडिज़ाइन टोकनडिज़ाइन सिस्टम और कस्टमाइज़ेशनTheme Studioरंगटाइपोग्राफ़ीआइकनशेपएलिवेशनमोशनइंटरैक्शन स्टेटव्यवहारलेआउटसुलभताशब्दकलर टोकनटाइप स्केल टोकनशेप टोकनएलिवेशन टोकनमोशन टोकनस्टेट टोकनस्पेस और माप के टोकनकंपोनेंटबटनमुख्य ऐक्शन बटनसेगमेंटेड बटनबटन ग्रुपमेन्यू वाला बटनटूलबारकॉपी बटनचेकबॉक्सरेडियो बटनस्विचचिपमेन्यूस्लाइडरस्लाइडर फ़ील्डकैलेंडरDateTimePickerफ़ील्ड ग्रुपरेडियो ग्रुपचेकबॉक्स ग्रुपसिलेक्टसिलेक्ट फ़ील्डमेन्यू बारफ़ाइल अपलोडफ़ाइल पिकर उन्नतड्रॉप ज़ोनटेक्स्ट इनपुट उन्नतटेक्स्ट फ़ील्डचिप फ़ील्डफ़ील्डकॉम्बोबॉक्स उन्नतकॉम्बोबॉक्स फ़ील्डनंबर इनपुट उन्नतनंबर फ़ील्डकलर इनपुट उन्नतकलर फ़ील्डवन-टाइम कोड इनपुट उन्नतवन-टाइम कोड फ़ील्डएम्बेडेड टेक्स्ट इनपुट उन्नतचैट कंपोज़रकार्डडिवाइडरमोडल लेयर उन्नतडायलॉगलिस्टलिस्ट पंक्तिबॉटम शीटसाइड शीटकैरसेलकोड ब्लॉकटेबलपॉपओवरचरणअकॉर्डियनडिस्क्रिप्शन लिस्टफ़िगरऐप शेलपेज हेडरट्री व्यूटाइमलाइनइमेज प्रीव्यूसाइज़ हैंडलसाइज़ बदलने वाला फ़्रेमस्क्रॉल एरियाबैजप्रोग्रेस इंडिकेटरमीटरनंबर टिकरलोडिंग इंडिकेटरस्नैकबारटूलटिपकीबोर्ड शॉर्टकटटैगइनलाइन कोडकॉलआउटअवतारख़ाली स्टेटटैग ग्रुपस्केलेटनफ़ाइल आइटमस्वॉचमार्की टेक्स्टटैबटैब व्यूऐप बारनेविगेशन बारनेविगेशन ड्रॉअरखोजलिंकपेजिनेशनपिछला और अगला लिंकस्टेपरब्रेडक्रंबविषय सूचीलिंक कार्डFAB मेन्यूस्थितिTanrei कैसे बनता हैयोगदानलाइसेंस और श्रेय
होमकंपोनेंटखोज

खोज

एक खोज बार, या उसका एक छोटा ट्रिगर, जो लोगों के टाइप करते समय सुझाव और नतीजे पेश करता है — बार के नीचे डॉक किए हुए व्यू में, डायलॉग में या पूरी स्क्रीन पर।

content_copyMarkdown में देखें
श्रेणी
नेविगेशन
टोकन
comp.search
स्तर
फ़ीचर
इनसे बना है
Modal layer

अवलोकन

Web
tanrei-search
schedule
SwiftUI
TanreiSearch
schedule
Jetpack Compose
TanreiSearch
schedule
Flutter
TanreiSearch
schedule
React Native
Search
schedule

इससे जनरेट किया गया: docs/status/status.json, specs/search.spec.json

संशोधित स्पेक, जो अभी हर प्लैटफ़ॉर्म पर नहीं है

यह पेज खोज को वैसा बताता है जैसा स्पेक में वह अभी है, साइट खोज भी: बार की जगह एक ट्रिगर, डायलॉग व्यू, ऐसे नतीजे जो लिंक हैं, स्थिति पंक्ति और शॉर्टकट। वेब कंपोनेंट यह सब करता है, और डेमो भी। SwiftUI, Compose, Flutter और React Native ऊपर “पीछे” के रूप में चिह्नित हैं: जब तक वे बराबरी पर नहीं आते, वे पिछला संशोधन देते हैं — अपने इनपुट वाला बार, डॉक्ड और फ़ुल-स्क्रीन व्यू, और सुझाव — और उनके उदाहरण वही संशोधन दिखाते हैं।

ख़ाली, क्वेरी के साथ, और आइकन बटन के साथ

menumicaccount_circle

साइट खोज: अपने शॉर्टकट के साथ बटन ट्रिगर, आइकन ट्रिगर, और अपना शॉर्टकट दिखाने वाला बार। किसी ट्रिगर को दबाकर उसका व्यू खोलें

क्वेरी वाली पंक्ति के नीचे सुझाव, और इनलाइन कम्प्लीशन। बिल टाइप करें, फिर ऐरो कुंजियों से आगे-पीछे जाएँ

इस्तेमाल

खोज एक बार और एक व्यू है। बार में खोज का ग्लिफ़, इनपुट, क्वेरी होने पर मिटाने का बटन, और अंत में आपके अपने अधिकतम दो आइकन बटन रहते हैं, जैसे बोलकर इनपुट या खाता। leading स्लॉट में आपका अपना मेन्यू या पीछे जाने का बटन ग्लिफ़ की जगह ले सकता है। व्यू तब खुलता है जब व्यक्ति खोजता है, और उसमें ऊपर से नीचे तक सुझाव, स्थिति पंक्ति, नतीजे, और फिर आपका अपना कोई भी कॉन्टेंट रहता है।

बार या ट्रिगर। bar बताता है कि जहाँ खोज रखी गई है, वहाँ क्या रहता है:

  • field (डिफ़ॉल्ट): अपने इनपुट वाला बार।
  • button: बार के आकार का ट्रिगर, जिसमें इनपुट नहीं होता, सिर्फ़ खोज का ग्लिफ़, प्लेसहोल्डर और शॉर्टकट का संकेत होता है। इसे उस हेडर में इस्तेमाल करें जिसमें जगह हो।
  • icon: सिर्फ़ आइकन वाला बटन, जो खोज का ग्लिफ़ दिखाता है। इसे उस हेडर में इस्तेमाल करें जिसमें जगह न हो।

ट्रिगर एक मोडल व्यू खोलता है, डायलॉग या फ़ुल-स्क्रीन व्यू, और इनपुट उस व्यू के हेडर में होता है। एक ही प्रॉडक्ट चौड़ी विंडो पर button और सँकरी विंडो पर icon इस्तेमाल करता है।

तीन प्रस्तुतियाँ। presentation बताता है कि व्यू कहाँ खुलता है:

  • docked (डिफ़ॉल्ट): बार के ठीक नीचे, उतनी ही चौड़ी एक सरफ़ेस, प्लैटफ़ॉर्म की ओवरले लेयर में, जैसे मेन्यू अपने ऐंकर के नीचे खुलता है। फ़ोकस बार के इनपुट में रहता है, इसलिए सुझाव बदलते रहने पर भी व्यक्ति टाइप करता रहता है। अगर नीचे काफ़ी जगह न हो, तो व्यू बार के ऊपर खुलता है।
  • dialog: विंडो के ऊपरी हिस्से के पास, स्क्रिम के ऊपर एक मोडल सरफ़ेस, जिसके हेडर में पीछे जाने का बटन, इनपुट और मिटाने का बटन रहते हैं। यह बड़ी विंडो के लिए है, और ट्रिगर से खोला जाता है। स्क्रिम को दबाने पर यह बंद हो जाता है।
  • full-screen: पूरी विंडो के ऊपर एक मोडल व्यू, उसी हेडर के साथ। यह फ़ोकस लेता है, उसे अपने भीतर रखता है, और बंद होने पर उसे बार या ट्रिगर पर लौटा देता है।

बड़ी विंडो पर डॉक्ड या डायलॉग इस्तेमाल करें और छोटी विंडो पर फ़ुल-स्क्रीन। खोज आपके लिए नहीं चुनती: presentation को अपने ब्रेकपॉइंट से सेट करें। docked वाला ट्रिगर डायलॉग खोलता है, क्योंकि डॉक्ड व्यू के पास अपना कोई इनपुट नहीं होता, और डीबग बिल्ड इसकी रिपोर्ट करते हैं।

सुझाव आइटम का एक प्रकार हैं: वे क्वेरी जो व्यक्ति शायद खोजना चाहे, जैसे कोई पिछली क्वेरी या टाइप किए गए टेक्स्ट को पूरा करने वाली क्वेरी। हर सुझाव में एक value, एक headline, और वैकल्पिक रूप से supportingText और एक leadingIcon होता है, जैसे पिछली क्वेरी के लिए history। मौजूदा क्वेरी के लिए सुझाव आप देते हैं; खोज उन्हें बनाती है और फ़िल्टर नहीं करती। जो सुझाव क्वेरी से शुरू होता है, उसका जोड़ा हुआ हिस्सा वेब सर्च की तरह ज़्यादा गाढ़ा दिखता है। किसी सुझाव को चुनने पर उसके मान के साथ select एमिट होता है। खोज ख़ुद कभी क्वेरी नहीं बदलती, इसलिए चुनाव का क्या मतलब है, यह आप तय करते हैं: आम तौर पर, सुझाव को बार में डालकर उसे खोजना।

क्वेरी वाली पंक्ति। जब सुझाव दिखते हैं, तो पहली पंक्ति वही क्वेरी होती है जो टाइप की गई है: खोज का ग्लिफ़ और क्वेरी, और अगर आप queryRowText दें तो उसके नीचे वह (“सारी मेल में खोजें”)। सुझाव दिखते ही यह पंक्ति सक्रिय होती है, इसलिए Enter हमेशा वही खोजता है जो टाइप किया गया है, जैसे ब्राउज़र के एड्रेस बार की पहली पंक्ति; Down Arrow सुझावों पर ले जाती है। इस पंक्ति को किसी शब्द की ज़रूरत नहीं: ग्लिफ़ और क्वेरी अपने-आप में पूरी पंक्ति हैं। दूसरा आम रूप, यानी वेब सर्च पेज वाला, चाहिए तो queryRow को none करें: तब ऐसी कोई पंक्ति नहीं होती, व्यक्ति के आगे बढ़ने तक कुछ भी सक्रिय नहीं होता, और तब तक Enter वही खोजता है जो टाइप किया गया है।

पंक्तियों में आगे-पीछे जाना। ऐरो कुंजियाँ क्रम से क्वेरी वाली पंक्ति, सुझावों और फिर नतीजों पर जाती हैं। जिस सुझाव पर वे पहुँचती हैं, वह क्वेरी बदले बिना इनपुट में दिखता है, इसलिए Enter वही चुनता है जो इनपुट में दिख रहा है; क्वेरी वाली पंक्ति पर लौटने पर टाइप की गई क्वेरी वापस आ जाती है। सिरों पर कुंजियाँ घूमकर आती हैं: आख़िरी पंक्ति पर Down Arrow पहली पर ले जाती है, और पहली पर Up Arrow आख़िरी पर। उन्हें सिरों पर रोकना हो, तो wrap को false करें।

इनलाइन कम्प्लीशन। inlineCompletion एड्रेस बार की तरह, क्वेरी से शुरू होने वाले पहले सुझाव से इनपुट में क्वेरी पूरी करता है, और जोड़ा हुआ हिस्सा कैरेट के बाद चुना हुआ दिखता है। कैरेट हिलाने से कम्प्लीशन स्वीकार होता है, Backspace उसे हटा देता है, और Enter उसे स्वीकार करके खोजता है। मिटाने या पेस्ट करने के ठीक बाद, इनपुट मेथड के कंपोज़ करते समय, या ऑन-स्क्रीन कीबोर्ड पर यह कभी पूरा नहीं करता। डिफ़ॉल्ट रूप से यह बंद रहता है।

नतीजे आइटम का दूसरा प्रकार हैं, उन चीज़ों के लिए जो खोज को मिलीं: कोई पेज, कोई सेक्शन, कोई संदेश। नतीजे में एक value, एक headline, एक excerpt और वैकल्पिक रूप से एक leadingIcon होता है, और वह कहीं ले जाता है: href के साथ उसकी पंक्ति एक असली लिंक है, जिसे प्लैटफ़ॉर्म वैसे ही खोलता है जैसे किसी भी लिंक को — मॉडिफ़ायर कुंजी के साथ नए टैब में, अपने कॉन्टेक्स्ट मेन्यू के साथ। href के बिना पंक्ति एक बटन है, और select ही अकेला संकेत है। नतीजों का ग्रुप नतीजों को एक हेडिंग के नीचे रखता है: “संदेश” जैसा कोई हल्का शीर्षक, या, अपने href के साथ, वह पेज जिसके सेक्शन ये नतीजे हैं। अंश वह टुकड़ा है जिसमें आप चिह्नित करते हैं कि क्या मेल खाया; खोज टेक्स्ट में क्वेरी को नहीं ढूँढती। वेब पर अंश एलिमेंट का अपना कॉन्टेंट है, जिसमें मेल खाने वाले हिस्सों के चारों ओर <mark> होता है, या excerpt के टुकड़े, जिनमें हर दूसरा टुकड़ा मेल खाने वाला हिस्सा है।

स्थिति। खोज कभी क्वेरी नहीं चलाती, इंतज़ार नहीं करती और फ़िल्टर नहीं करती: वह हर बदलाव पर input एमिट करती है और जो आप देते हैं उसे बनाती है। status (idle, loading या error) और statusText से उसे बताएँ कि आपकी खोज क्या कर रही है: गिनती (“टोकन के लिए 12 नतीजे”), कि कुछ नहीं मिला, या विफलता। स्थिति पंक्ति टेक्स्ट दिखाती है और उसके बदलने पर उसे पढ़कर सुनाती है, और लोड होते समय वह थोड़ी देरी के बाद लोडिंग इंडिकेटर दिखाती है।

शॉर्टकट। shortcut उन कुंजियों का नाम देता है जो खोज खोलती हैं, कीबोर्ड शॉर्टकट के कुंजी-नामों में (mod+k, /)। खोज उन्हें एक संकेत के रूप में लिखती है, व्यक्ति के कीबोर्ड के हिसाब से टेक्स्ट की एक पंक्ति: बटन ट्रिगर के अंत में, और बार में तब, जब वह ख़ाली हो और उस पर फ़ोकस न हो। वह उन्हें ट्रिगर या इनपुट के कीबोर्ड शॉर्टकट के रूप में देती है। कुंजियाँ सिर्फ़ तब काम करती हैं जब आप उन्हें बाइंड करें, या bindShortcut सेट करें: तब खोज, जब तक वह दिखती है और सक्षम है, पूरी विंडो में सुनती है, उन कुंजियों पर खुलती है और दोबारा उन्हीं पर बंद होती है।

खुलना और बंद होना। बार को दबाने, टाइप करने, या इनपुट में Down Arrow दबाने से व्यू खुलता है। सिर्फ़ फ़ोकस से वह कभी नहीं खुलता: Tab से बार पर आने पर, या फ़ुल-स्क्रीन व्यू से फ़ोकस लौटने पर, वह बंद ही रहता है। खोज toggle से खुलने या बंद होने का अनुरोध करती है, जो नया स्टेट साथ लाता है और, बंद होते समय, कारण भी: escape, back, select, submit, outside, tab, focus-out या shortcut। व्यू बंद होने पर क्वेरी जैसी है वैसी रहती है। जब सुझाव दिखते हैं, तो क्वेरी वाली पंक्ति पर Enter टाइप की गई क्वेरी के साथ submit एमिट करता है; सुझाव न हों और नतीजे हों, तो Enter पहला नतीजा खोलता है, जैसे डॉक्यूमेंटेशन की खोज में। submit के बाद व्यू, जब तक वह नतीजे या कोई स्थिति दिखाता है, खुला रहता है, ताकि व्यक्ति उन तक जा सके। वेब पर एलिमेंट अपना expanded ख़ुद सेट करता है, और SwiftUI और Flutter पर बाइंडिंग या कंट्रोलर बदलता है। Compose और React Native पर आप कॉलबैक से expanded सेट करते हैं, जैसे मेन्यू के लिए।

<tanrei-search name="q" label="मेल खोजें" placeholder="मेल खोजें" clear-label="खोज मिटाएँ" query-row-text="सारी मेल में खोजें">
  <tanrei-button variant="text" slot="trailing" label="बोलकर खोजें"><span slot="icon">mic</span></tanrei-button>
  <tanrei-search-suggestion value="invoices" headline="इनवॉइस" leading-icon="history"></tanrei-search-suggestion>
  <tanrei-search-suggestion value="folder:invoices" headline="इनवॉइस"
    supporting-text="फ़ोल्डर · 24 संदेश" leading-icon="folder"></tanrei-search-suggestion>
  <!-- बाक़ी चाइल्ड व्यू में आपका अपना कॉन्टेंट हैं, सुझावों के बाद। -->
</tanrei-search>

<!-- वेब सर्च पेज वाला रूप: क्वेरी वाली पंक्ति नहीं, आगे बढ़ने तक कुछ सक्रिय नहीं; ऐरो कुंजियाँ सिरों पर रुकती हैं। -->
<tanrei-search label="वेब पर खोजें" placeholder="खोजें" query-row="none" no-wrap></tanrei-search>

<!-- एड्रेस बार वाला रूप: क्वेरी से शुरू होने वाले पहले सुझाव से इनपुट में क्वेरी पूरी होती है। -->
<tanrei-search label="खोजें या पता टाइप करें" inline-completion></tanrei-search>

<!-- छोटी विंडो पर: व्यू पूरी विंडो को ढकता है और उसमें पीछे जाने का बटन होता है। -->
<tanrei-search presentation="full-screen" label="मेल खोजें" placeholder="मेल खोजें"
  clear-label="खोज मिटाएँ" back-label="पीछे"></tanrei-search>

<!-- साइट खोज: अपने शॉर्टकट के साथ ट्रिगर, डायलॉग व्यू, और ऐसे नतीजे जो लिंक हैं। -->
<tanrei-search id="docs-search" bar="button" presentation="dialog" label="दस्तावेज़ खोजें" placeholder="खोजें"
  shortcut="mod+k" bind-shortcut clear-label="खोज मिटाएँ" back-label="पीछे">
  <!-- href वाला ग्रुप पेज है; उसके नतीजे उसमें मिले सेक्शन हैं। -->
  <tanrei-search-result-group value="/tokens/" headline="डिज़ाइन टोकन" href="/tokens/" leading-icon="article">
    रंग, साइज़ और मोशन, <mark>टोकन</mark> के रूप में, तीन स्तरों में।
    <tanrei-search-result value="/tokens/#layers" headline="लेयर" href="/tokens/#layers" leading-icon="tag">
      लेयर किसी <mark>टोकन</mark> का मान बदलती है और अपने टोकन जोड़ सकती है।
    </tanrei-search-result>
  </tanrei-search-result-group>
  <!-- बाक़ी चाइल्ड आपका अपना कॉन्टेंट हैं, नतीजों के बाद। -->
  <tanrei-button variant="text">और नतीजे लोड करें</tanrei-button>
</tanrei-search>

<script type="module">
  import '@tanrei/web/components/search';
  import '@tanrei/web/components/button';
  const search = document.querySelector('[name="q"]');
  search.addEventListener('input', () => showSuggestionsFor(search.value));
  search.addEventListener('submit', () => runSearch(search.value)); // रद्द किया जा सकता है; फ़ॉर्म के भीतर यह फिर फ़ॉर्म सबमिट करता है
  search.addEventListener('select', (e) => openSuggestion(e.detail.value));
  // एलिमेंट toggle फ़ायर करने से पहले अपना expanded ख़ुद सेट करता है।
  search.addEventListener('toggle', (e) => log(e.detail.expanded, e.detail.reason));

  // खोज कभी क्वेरी नहीं चलाती, इंतज़ार नहीं करती और डिबाउंस नहीं करती: यह आपका काम है।
  const docs = document.querySelector('#docs-search');
  let asked = 0;
  docs.addEventListener('input', async () => {
    const mine = ++asked;
    docs.status = 'loading';
    docs.statusText = 'खोज रहे हैं';
    const found = await query(docs.value);
    if (mine !== asked) return; // कोई नया सवाल पूछा जा चुका है: यह जवाब छोड़ दें
    show(found); // <tanrei-search-result> चाइल्ड बदलें
    docs.status = 'idle';
    docs.statusText = `${docs.value} के लिए ${found.length} नतीजे`; // हर जवाब पर एक बार सेट करें: इसे पढ़कर सुनाया जाता है
  });
  // कोई नतीजा अपनी जगह पर सक्रिय किया गया। लिंक को अपने राउटर को सौंपने के लिए इवेंट रद्द करें।
  docs.addEventListener('select', (e) => { /* e.preventDefault(); router.push(e.detail.value); */ });
</script>
import { Button, Search, SearchResult, SearchResultGroup, SearchSuggestion } from '@tanrei/react';

<Search
  label="मेल खोजें"
  placeholder="मेल खोजें"
  clearLabel="खोज मिटाएँ"
  value={query}
  onInput={(e) => setQuery(e.currentTarget.value)}
  onSubmit={() => runSearch(query)}
  onSelect={(e) => openSuggestion(e.detail.value)}
>
  <Button variant="text" slot="trailing" label="बोलकर खोजें" onClick={dictate}><span slot="icon">mic</span></Button>
  {suggestions.map((s) => (
    <SearchSuggestion key={s.value} value={s.value} headline={s.headline} supportingText={s.detail} leadingIcon={s.icon} />
  ))}
</Search>

// साइट खोज: अपने शॉर्टकट के साथ ट्रिगर, डायलॉग व्यू, और ऐसे नतीजे जो लिंक हैं।
// excerpt टेक्स्ट के टुकड़े हैं: हर दूसरा टुकड़ा मेल खाने वाला हिस्सा है।
<Search
  bar="button"
  presentation="dialog"
  label="दस्तावेज़ खोजें"
  placeholder="खोजें"
  shortcut={['mod+k']}
  bindShortcut
  clearLabel="खोज मिटाएँ"
  backLabel="पीछे"
  status={status}
  statusText={statusText}
  onInput={(e) => runQuery(e.currentTarget.value)}
  onSelect={(e) => { e.preventDefault(); router.push(e.detail.value); }}
>
  {pages.map((page) => (
    <SearchResultGroup key={page.url} value={page.url} headline={page.title} href={page.url} leadingIcon="article" excerpt={page.excerpt}>
      {page.sections.map((s) => (
        <SearchResult key={s.url} value={s.url} headline={s.title} href={s.url} leadingIcon="tag" excerpt={s.excerpt} />
      ))}
    </SearchResultGroup>
  ))}
</Search>
import Tanrei

// हर संपादन text लिखता है; खुलना और बंद होना isExpanded लिखते हैं।
TanreiSearch("मेल खोजें", text: $query, isExpanded: $isSearching,
             prompt: Text("मेल खोजें"), clearLabel: "खोज मिटाएँ",
             onSubmit: { value in runSearch(value) },
             onSelect: { value in openSuggestion(value) }) {
    TanreiSearchSuggestion("इनवॉइस", leadingIcon: "history", value: "invoices")
    TanreiSearchSuggestion("इनवॉइस", supportingText: "फ़ोल्डर · 24 संदेश", leadingIcon: "folder", value: "folder:invoices")
}
import io.github.chnotchy.tanrei.components.TanreiSearch
import io.github.chnotchy.tanrei.components.TanreiSearchSuggestion

// स्टेट होइस्टिंग: value और expanded आप रखते हैं, और उन्हें कॉलबैक से बदलते हैं।
TanreiSearch(
    value = query,
    onValueChange = { query = it },
    expanded = expanded,
    onExpandedChange = { open, _ -> expanded = open }, // दूसरा आर्ग्युमेंट कारण है
    label = "मेल खोजें",
    placeholder = "मेल खोजें",
    clearLabel = "खोज मिटाएँ",
    onSearch = { runSearch(query) },
    onSelect = { openSuggestion(it) },
) {
    TanreiSearchSuggestion(value = "invoices", headline = "इनवॉइस", leadingIcon = "history")
    TanreiSearchSuggestion(value = "folder:invoices", headline = "इनवॉइस", supportingText = "फ़ोल्डर · 24 संदेश", leadingIcon = "folder")
}
import 'package:tanrei/tanrei.dart';

// TanreiSearchController एक TextEditingController है जो isExpanded भी रखता है।
final TanreiSearchController search = TanreiSearchController();

TanreiSearch(
  controller: search,
  semanticLabel: 'मेल खोजें',
  hintText: 'मेल खोजें',
  clearLabel: 'खोज मिटाएँ',
  onChanged: showSuggestionsFor,
  onSubmitted: runSearch,
  onSelected: openSuggestion,
  suggestions: const <TanreiSearchSuggestion>[
    TanreiSearchSuggestion(value: 'invoices', headline: 'इनवॉइस', leadingIcon: 'history'),
    TanreiSearchSuggestion(value: 'folder:invoices', headline: 'इनवॉइस', supportingText: 'फ़ोल्डर · 24 संदेश', leadingIcon: 'folder'),
  ],
);
import { Search } from '@tanrei/react-native';

// कंट्रोल्ड: value और expanded को आप onChangeText और onExpandedChange से बदलते हैं।
<Search
  value={query}
  onChangeText={setQuery}
  expanded={expanded}
  onExpandedChange={(next) => setExpanded(next)}
  accessibilityLabel="मेल खोजें"
  placeholder="मेल खोजें"
  clearLabel="खोज मिटाएँ"
  onSubmitEditing={() => runSearch(query)}
  onSelect={openSuggestion}
  suggestions={[
    { value: 'invoices', headline: 'इनवॉइस', leadingIcon: 'history' },
    { value: 'folder:invoices', headline: 'इनवॉइस', supportingText: 'फ़ोल्डर · 24 संदेश', leadingIcon: 'folder' },
  ]}
/>

// छोटी विंडो पर: presentation="full-screen" और backLabel="पीछे"। Android का बैक बटन व्यू को बंद करता है।

स्पेक

एक सुझाव, स्थिति पंक्ति और ग्रुप किए हुए नतीजों वाला डॉक्ड व्यू, अपनी जगह पर बना हुआ

अक्षम, और खुला हुआ डॉक्ड व्यू

संरचना

प्रॉपर्टी

प्रॉपर्टी टाइप डिफ़ॉल्ट विवरण
presentation docked | dialog | full-screen "docked" Where the view opens: docked under the bar, without taking focus from it; dialog, a modal surface near the top of the window with its own header (a large screen, opened from a trigger); or full-screen, over the whole window with its own header (a small screen). One product uses more than one and switches by window size.
bar field | button | icon "field" What stands where the search is placed. field: the bar with its input, as before. button: a trigger shaped like the bar that holds no input — the search glyph, the placeholder and the shortcut hint — for an app bar with room. icon: an icon-only Button showing the search glyph, for an app bar without. A trigger opens a modal view (dialog or full-screen), where the input is. One product uses button on a wide window and icon on a narrow one.
value string "" The query.
label string "" Names the search field, the trigger, the view, the suggestions and the results for assistive technology ("Search mail"). Drawn only as a button trigger's text while placeholder is empty. Required.
placeholder string "" A hint shown while the value is empty, and the text of a button trigger. Never a replacement for label.
expanded boolean false Whether the view is open. The search asks to open and close it with toggle (SRC-5, SRC-6, SRC-36, SRC-38).
disabled boolean false Prevents focus, editing and opening the view.
clearLabel string "" The clear button's accessible name, in the product's language ("Clear search"). Required while the clear button can show.
backLabel string "" The accessible name of the back button in a modal view's header ("Back"). Required for full-screen and for dialog.
shortcut strings The keyboard shortcut that opens the search, in the keyboard shortcut component's key names: one chord per string, pressed in order (["mod+k"], ["/"]). The search writes it as a hint, a line of text with no keycaps (SRC-37), and exposes it as the keyboard shortcut of its trigger or input. It makes the keys work only while bindShortcut is true (SRC-38); otherwise the product binds them.
bindShortcut boolean false Makes the search itself listen for shortcut, anywhere in the window, for as long as it is shown and enabled: the keys open it, and close it again while it is open (SRC-38). Off by default: a component listens outside itself only where the product asks it to.
status idle | loading | error "idle" What the product's search is doing, which the product sets: idle (nothing is awaited: results, or none, are final), loading (a query is running: the status row shows a loading indicator after its delay) or error (the query failed: statusText is drawn as an error and announced at once). The search never runs a query itself (SRC-51).
statusText string "" The status row's text, in the product's language, announced to assistive technology when it changes: the count ("12 results for tokens"), that nothing was found ("No results for tokne"), the failure ("Search is unavailable"); while loading, the loading indicator's name ("Searching"). Empty draws no status row unless status is loading.
queryRow first | none "first" Where the query as typed stands among the suggestions, which are queries. first: a row of its own above them — the search glyph and the value, with queryRowText under it — drawn while the view shows suggestions and the value is not empty, and active from the moment they show, so that the action key always searches for what was typed, as the first row of a browser's address bar does (SRC-57). none: no such row: no suggestion is active until the person moves to one, so that the action key searches for what was typed until then, as a web search page does, and the input itself is the place before the first suggestion in the arrow keys' cycle (SRC-14).
queryRowText string "" What the query row says beside the query, in the product's language, drawn as its supporting text and read as its description ("Search all mail", "Ask the assistant"). Empty draws the search glyph and the query alone: the row needs no words. Ignored while queryRow is none.
inlineCompletion boolean false Completes the query in the input while the person types, from the first suggestion whose headline begins with it: the rest of that headline is written after the caret, selected, and the query row shows the completed query (SRC-55). A completion of the beginning only; never after a deletion or a paste, during an input-method composition or on an on-screen keyboard; moving the caret accepts it, Backspace takes it away. Off by default: an address bar completes, a search page does not. Ignored while queryRow is none.
wrap boolean true Whether the arrow keys go round at the ends of the view's rows: Down Arrow on the last to the first, Up Arrow on the first to the last — with queryRow none, through the input's own place before the first suggestion (SRC-14, SRC-49). False stops them at the ends.
iconSpace auto | always | never "auto" Whether a row of the view — a suggestion, a result, a result group's linked heading — keeps the room of the leading icon column where it has no icon, so that the headlines of the view start on one line. auto: every row keeps the column while any suggestion or result of the view has a leading icon, and none while none has. always: every row keeps it. never: only a row that has an icon has the column. The view is decided as a whole. The menu's iconSpace, with the same values and default (SRC-52).
density regular | compact "regular" How much room a row of the view takes — a suggestion, a result, a result group's linked heading —: its least height, its paddings, the gap after its icon column and the size of its glyph, and never its text style. regular (a 56 row in the default system) is for a product used by touch as well as by pointer; compact (a 32 row with a 20 glyph, the tree view's compact row) is for a tool used with a pointer, a command palette looked through with the keyboard. For touch a row is never lower than the touch target in either (SRC-16). The bar, the trigger and the view's header are not changed. A design system may add values.

स्लॉट

स्लॉट विवरण
leading An icon-only Button at the bar's start (a menu or back button), drawn in place of the search glyph.
trailing Up to two icon-only Buttons at the bar's end, after the clear button (voice input, account).
default The product's own content in the view, after the suggestions, the status row and the results: a button that loads more results, a link to the full results page, or richer content for an empty query.

इवेंट

इवेंट विवरण
input The person changed the value (typing, deleting, pasting, dictating, the clear button, Escape); carries the new value. Not emitted when the product sets value. It is the product's cue to run its query; the search does not delay or drop it (SRC-51).
submit The person pressed the keyboard's action key (Enter, Search) with no suggestion active and no result current; carries the value.
select The person chose a suggestion, or activated a result in place (without a modifier key, in the same window); carries its value. For a result with an href it is emitted before the platform follows the link, and on the web cancelling it keeps the link from being followed, so that a router can take it.
toggle The search asks to open or close its view; carries the new expanded value and, when closing, the reason: escape, back, select, submit, outside, tab, focus-out or shortcut (in the platform's casing).

आइटम

वे आइटम के प्रकार जिन्हें कंपोनेंट दोहराता है। फ़िक्स्चर अपने आइटम क्रम से सूचीबद्ध करता है; हर प्लैटफ़ॉर्म हर प्रकार को अपने तरीक़े से नाम देता है।

suggestion

A choice that completes or replaces the query while the person types: a query they searched before, or a completion. Choosing it emits select and the product sets the value. A thing the product opens is a result.

प्रॉपर्टी टाइप डिफ़ॉल्ट विवरण
value string "" Identifies the suggestion; select carries it. Unique among the suggestions.
headline string "" The suggestion's text, and its accessible name.
supportingText string "" A second line under the headline ("Folder · 24 messages"), and its description.
leadingIcon string "" The name of a glyph at the row's start (history for a past query, a folder for a result). Empty draws none.
स्पेक Web SwiftUI Jetpack Compose Flutter React Native
आइटम tanrei-search-suggestion TanreiSearchSuggestion TanreiSearchSuggestion TanreiSearchSuggestion SearchSuggestion
value · प्रॉपर्टी value value value value value
headline · प्रॉपर्टी headline headline headline headline headline
supportingText · प्रॉपर्टी supportingText supportingText supportingText supportingText supportingText
leadingIcon · प्रॉपर्टी leadingIcon leadingIcon leadingIcon leadingIcon leadingIcon
टिप्पणियाँ A child element with value, headline, supporting-text and leading-icon attributes, as <option> in a <datalist>. TanreiSearchSuggestion(_ headline:, supportingText:, leadingIcon:, value:) in the suggestions view builder. TanreiSearchSuggestion(value, headline, supportingText, leadingIcon) called in the search's content lambda, before the product's own content. TanreiSearchSuggestion(value:, headline:, supportingText:, leadingIcon:) in the search's suggestions: list. The element type of the suggestions array: { value, headline, supportingText?, leadingIcon? }.

result

A thing the search found that the person can go to: a page, a section of a page, a message, a file. It is a link, not an option.

प्रॉपर्टी टाइप डिफ़ॉल्ट विवरण
value string "" Identifies the result; select carries it. Unique among the suggestions, results and result groups.
headline string "" The result's title, and its accessible name.
excerpt strings A passage of the thing found, as runs of text in order: the first, third, fifth… run is plain text and the second, fourth… is a match, drawn marked (SRC-43). ["Tokens are ", "design", " decisions"] marks design; a passage that begins with a match begins with an empty run; one run alone is a passage without marks. The product's search decides what matched; the search component does not look for the query in the text.
leadingIcon string "" The name of a glyph at the row's start (article for a page, tag for a section). Empty draws none.
href string "" Where the result goes: an address as the platform's links take one (a URL; on the web a path or a fragment as well), in the prop set every control with a destination takes. Not empty, it makes the row a link, opened by the platform as its own links are (SRC-45). Empty makes the row a button: select is then the only signal, and the product opens the thing.
target same | new "same" Where the destination opens. same: where the person is. new: a new context — a new tab or window on the web, outside the current screen elsewhere — which targetLabel says. Ignored without href.
targetLabel string "" What assistive technology reads after the result's name while target is new ("opens in a new tab"), in the product's language. Required while target is new; ignored otherwise.
स्पेक Web SwiftUI Jetpack Compose Flutter React Native
आइटम tanrei-search-result TanreiSearchResult TanreiSearchResult TanreiSearchResult SearchResult
value · प्रॉपर्टी value value value value value
headline · प्रॉपर्टी headline headline headline headline headline
excerpt · प्रॉपर्टी excerpt excerpt excerpt excerpt excerpt
leadingIcon · प्रॉपर्टी leadingIcon leadingIcon leadingIcon leadingIcon leadingIcon
href · प्रॉपर्टी href destination href href href
target · प्रॉपर्टी target target target target target
targetLabel · प्रॉपर्टी targetLabel targetLabel targetLabel targetLabel targetLabel
टिप्पणियाँ A child element whose link is an <a href> (a <button> without href) it keeps as its own first child in the light DOM, drawn as nothing and slotted over the row it draws in its shadow root, so that the search's input can name it as its active descendant (SRC-50); a page's rules for anchors and buttons neither move nor paint it. The excerpt is its child content: text with <mark> elements for the matches, which is what search engines hand back, styled through ::slotted(mark); the excerpt property (an array of runs) is used while it has no child content. Inserting an engine's HTML is the product's act: the element never parses a string as markup. rel and download are forwarded to the anchor, as every link form forwards them; target="new" is target="_blank" with noopener in rel. Not built on this platform yet. TanreiSearchResult(_ headline:, excerpt: [String], leadingIcon:, value:, destination: URL?); with a destination it opens through the environment's openURL and has the .isLink trait. target and targetLabel as the platform's link forms map them. Not built on this platform yet. TanreiSearchResult(value, headline, excerpt: List<String>, leadingIcon, href); with an href it opens through LocalUriHandler. target and targetLabel as the platform's link forms map them. Not built on this platform yet. TanreiSearchResult(value:, headline:, excerpt: [...], leadingIcon:, href: Uri?, target:, targetSemanticLabel:) in the search's results: list, with Semantics(link: true). Not built on this platform yet. An element type of the results array: { value, headline, excerpt?, leadingIcon?, href? }, with accessibilityRole="link"; an href opens through Linking. target and targetLabel as the platform's link forms map them.

result-group · ग्रुप — इसमें आइटम होते हैं

Results that belong together, under one heading: the sections found in one page, or the results of one kind. With an href its heading is itself a result (the page), and its results are drawn under it as its parts; without one its heading is a title.

प्रॉपर्टी टाइप डिफ़ॉल्ट विवरण
headline string "" The group's heading: the page's title, or the name of the kind ("Pages"). It names the group for assistive technology.
value string "" Identifies the heading as a result while href is not empty; select carries it.
excerpt strings While href is not empty, the heading's own excerpt, in the runs a result's excerpt has. Ignored without href.
leadingIcon string "" While href is not empty, the name of a glyph at the heading row's start. Ignored without href.
href string "" Where the heading goes. With it the heading is a result's row and a link (SRC-44, SRC-45); empty makes it a title that takes no input.
target same | new "same" Where the destination opens. same: where the person is. new: a new context — a new tab or window on the web, outside the current screen elsewhere — which targetLabel says. Ignored without href.
targetLabel string "" What assistive technology reads after the result's name while target is new ("opens in a new tab"), in the product's language. Required while target is new; ignored otherwise.
स्पेक Web SwiftUI Jetpack Compose Flutter React Native
आइटम tanrei-search-result-group TanreiSearchResultGroup TanreiSearchResultGroup TanreiSearchResultGroup SearchResultGroup
headline · प्रॉपर्टी headline headline headline headline headline
value · प्रॉपर्टी value value value value value
excerpt · प्रॉपर्टी excerpt excerpt excerpt excerpt excerpt
leadingIcon · प्रॉपर्टी leadingIcon leadingIcon leadingIcon leadingIcon leadingIcon
href · प्रॉपर्टी href destination href href href
target · प्रॉपर्टी target target target target target
targetLabel · प्रॉपर्टी targetLabel targetLabel targetLabel targetLabel targetLabel
टिप्पणियाँ A child element holding <tanrei-search-result> children; with href its own heading's link is an <a> it keeps as its own child, as a result does, and its excerpt is the content of its excerpt slot, with <mark> as in a result. Not built on this platform yet. TanreiSearchResultGroup(_ headline:, destination:, …) { results }. Not built on this platform yet. TanreiSearchResultGroup(headline, href, …) { results }. Not built on this platform yet. TanreiSearchResultGroup(headline:, href:, results: [...]). Not built on this platform yet. The other element type of results: { headline, href?, …, results: [...] }.

स्टेट

व्यवहार

EARS रूप में लिखी गई आवश्यकताएँ। हर प्लैटफ़ॉर्म के इम्प्लीमेंटेशन को इन ID के आधार पर टेस्ट किया जाता है। आवश्यकताओं का पाठ स्पेक फ़ाइल से ज्यों का त्यों, अंग्रेज़ी में दिखाया गया है।

ID आवश्यकता
SRC-1 THE search SHALL draw its bar as wide as its layout gives it and at least comp.search.container.height high, filled with comp.search.standard.container.color, raised by comp.search.standard.container.elevation and rounded by comp.search.container.shape, and SHALL lay out in one row, each element vertically centered and comp.search.container.gap from the next, except that its action buttons — the clear button and the icon-only Buttons of the trailing slot — stand comp.search.container.button-gap from one another (SRC-34): the search glyph comp.search.container.padding-inline from the start edge (or, WHILE the leading slot is filled, the product's icon-only Button comp.search.container.padding-inline-with-button from it, in place of the glyph), the input taking the remaining width, the clear button WHILE it is shown (SRC-10), and the icon-only Buttons of the trailing slot; the last element SHALL end comp.search.container.padding-inline-with-button from the end edge when it is an icon-only Button, and comp.search.container.padding-inline when it is the input. Right-to-left layouts SHALL mirror the row.
SRC-2 THE search SHALL draw the glyph search of the system's icon set at comp.search.leading-icon.size in comp.search.standard.leading-icon.color with the family and fill of an unselected icon, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, SHALL NOT mirror it when the layout direction is right-to-left, and SHALL hide it from assistive technology. THE search SHALL draw no mark of its own (no path, shape or character of its own) for this glyph or for the glyphs of its clear and back buttons (SRC-10, SRC-11).
SRC-3 THE search SHALL draw the value on one line in comp.search.input.typescale and comp.search.standard.input.color, scrolling it sideways inside the input when it is longer, and WHILE the value is empty the placeholder in the same text style in comp.search.standard.placeholder.color; it SHALL draw the caret in comp.search.standard.caret.color and highlight selected text in comp.input-box.selection.color, drawing it in comp.input-box.selection.content.color: the product's one selection pair for text entry.
SRC-4 THE search SHALL edit its value in the platform's native text element and SHALL follow the text field's rules for it: TXI-1 (input once per change, and none when the product sets value), TXI-4 (input-method composition), TXI-20 for the search type (a general keyboard whose action key reads as search) and TXI-24 (the typed text's own direction); it SHALL hide a clear or cancel button that the platform draws inside its native element (the web's search cancel button), because it draws its own (SRC-10).
SRC-5 WHILE collapsed and bar is field, WHEN the person presses the bar outside its slot elements and the clear button, types into the input, or presses Down Arrow in it, THE search SHALL focus the input and emit toggle once with expanded true; focus that reaches the input by Tab, or returns to it when the view closes, SHALL NOT expand it. The Down Arrow that opens the view SHALL only open it: the row the action key takes is then the one SRC-14 and SRC-49 make current as the view opens, made current by an arrow key and so announced at once (SRC-24). THE search SHALL become expanded through its binding or controller where expanded is one (SwiftUI, Flutter) and by setting its own property on the web, and by the product setting expanded to true on Compose and React Native. WHILE bar is button or icon the trigger's activation is what expands the search (SRC-36), and the product's shortcut where the search binds it (SRC-38).
SRC-6 WHILE expanded, WHEN the person presses Escape or the platform's back, activates the back button (SRC-11), chooses a suggestion (SRC-15), activates a result in place (SRC-45), submits where submitting closes (SRC-13) or presses the shortcut the search binds (SRC-38), or, WHILE presentation is dialog, presses the scrim (a modal view answers Escape, back and the scrim as its modal layer does, MDL-6), or, WHILE presentation is docked, presses outside the bar and the view, presses Tab or Shift+Tab, or moves focus out of the search, THE search SHALL emit toggle once with expanded false and that reason (escape, back, select, submit, shortcut, outside, tab or focus-out) and SHALL be collapsed as SRC-5 says it is expanded; the value SHALL stay as it is. Tab and Shift+Tab SHALL then move focus on from the input as they would have, and whether a press outside also reaches the element under it SHALL follow the platform and be stated in its README, as for the menu (MNU-5). Focus that moves between the bar's input and a result of the docked view (SRC-49) has not left the search.
SRC-7 WHILE expanded, presentation is docked and bar is field and the view has content (a suggestion, a status row, a result, a result group, or content in the default slot), THE search SHALL present the view in the platform's overlay layer, the one the menu's surface uses (MNU-1), comp.search.view.offset below the bar, as wide as the bar and aligned with it; WHERE the room below, within comp.search.view.viewport-margin of the viewport's edge and of the on-screen keyboard, is less than the view needs and the room above is more, it SHALL place the view above the bar instead; it SHALL limit the view's height to the room left and scroll its content beyond it, and keep following the bar while it moves. It SHALL fill the view with comp.search.view.container.color, raise it by comp.search.view.container.elevation, round it by comp.search.view.container.shape, clip the content to that shape and inset it by comp.search.view.padding-block and comp.search.view.padding-inline. WHILE the view has no content THE search SHALL draw no view and stay expanded.
SRC-8 WHILE presentation is docked THE search SHALL keep focus in the bar's input while the view is open, because the view is an operated overlay whose focus is the input it belongs to: it SHALL NOT move focus into the view when it opens, trap focus, make anything inert or draw a scrim; a press on a suggestion, on the status row or on the view's surface SHALL NOT take focus from the input; a result is a link and takes focus when the person presses it or reaches it by Down Arrow (SRC-49), which is still focus inside the search; and the search SHALL leave focus where the person put it when the view closes.
SRC-9 WHEN expanded becomes true WHILE presentation is full-screen THE search SHALL present the view over the whole window as a modal overlay on its modal layer without the layer's scrim (MDL-1 WHILE scrim is false, the view filling the window), filled with comp.search.view.container.color to every edge of the window and under every system inset, with its content inside the safe area and above the on-screen keyboard: at its top a header at least comp.search.header.height high holding the back button (SRC-11) comp.search.header.padding-inline from the start edge, the input with the same value, and the clear button WHILE it is shown, the last of them comp.search.header.padding-inline from the end edge, comp.search.container.gap apart and vertically centered; under the header a line of comp.search.divider.thickness in comp.search.divider.color across the window; under that the view's content in the order SRC-46 gives, scrolling. It SHALL move focus to the header's input with the caret at the end of the value, keep focus inside the view, and make everything outside it inert and hidden from assistive technology, as its modal layer does (MDL-2, MDL-4); WHEN the view closes THE search SHALL return focus to the bar's input without expanding it again (SRC-5), or to the trigger WHILE bar is button or icon.
SRC-10 WHILE value is not empty and disabled is false THE search SHALL show a clear button: an icon-only Tanrei Button of the text variant showing the glyph close of the system's icon set, not mirrored, named by clearLabel, of size small in the bar and medium in the full-screen header. WHEN it is activated THE search SHALL set value to empty, emit input once with the empty value and move focus to the input it belongs to, and SHALL NOT expand or collapse. WHILE clearLabel is empty THE search SHALL still show the button, and in debug builds report that it has no accessible name.
SRC-11 WHILE the full-screen view is open THE search SHALL draw a back button at the start of its header: an icon-only Tanrei Button of the text variant and the medium size showing the glyph arrow_back of the system's icon set, mirrored in right-to-left layouts by the icon helper, as the icon set marks it (SRC-32), named by backLabel; WHEN it is activated THE search SHALL collapse with the reason back (SRC-6). WHILE backLabel is empty THE search SHALL still draw it, and in debug builds report that it has no accessible name.
SRC-12 WHILE collapsed and the input has focus, WHEN the person presses Escape with a value that is not empty THE search SHALL set value to empty and emit input once, as a native search input does; with an empty value Escape SHALL do nothing and pass on to the enclosing element.
SRC-13 WHEN the person presses the keyboard's action key (Enter, Search, Go) in the input while the query row is active or no row is (SRC-14, SRC-57), no result is current (SRC-49) and no input method is composing, or presses the query row by pointer or touch, THE search SHALL, WHILE an inline completion is shown, first accept it (SRC-55), and SHALL emit submit once with the value and then, WHILE expanded and the view shows no result, no result group and no status row, collapse with the reason submit (SRC-6), so that toggle follows submit; WHILE the view shows one of them it SHALL stay expanded, because what the person asked for is already in front of them, and the product closes the view where its submit goes elsewhere; on the web, inside a form, it SHALL then request the form's submission unless submit was cancelled, as a native input does. The submission SHALL be requested through the form's default button (BTN-30): WHILE the form has a submit button — the platform's own or a Button of type submit — the first of them in document order SHALL be pressed, so that its click is emitted and its name and value are sent, and WHILE that button is disabled nothing SHALL be submitted; only a form with no submit button is asked directly.
SRC-14 WHILE expanded and the view holds suggestions THE search SHALL keep focus in the input, so that typing goes on editing the value, and SHALL make at most one of its rows current without moving focus, as an editable combobox with list autocomplete does. The rows the arrow keys go through are, in this order: the query row WHILE it is drawn (queryRow first and a value that is not empty, SRC-57), and otherwise the input's own place, which stands for the value as typed and makes no row current; then the suggestions, in the product's order; then the results (SRC-49). WHEN the input has focus and the view comes to show suggestions — it opens with them, the product gives or replaces them, or focus comes back to the input — and WHEN the person types, deletes or pastes, THE search SHALL make the first of those places current automatically: the query row, active, or the input's place, no row being active — either way the action key searches for the value as typed (SRC-13). Down Arrow SHALL make the next row current and Up Arrow the previous one, Down Arrow from the input's place going to the first suggestion and Up Arrow on the first suggestion back to the input's place; WHILE wrap is true Down Arrow on the last row SHALL go to the first place and Up Arrow on the first place to the last row, and WHILE wrap is false they SHALL do nothing at the ends. WHEN a suggestion becomes active by an arrow key THE search SHALL show its headline in the input in place of the value, the caret at its end, without changing value or emitting input, so that the action key chooses what the input shows (SRC-15); WHEN the query row or the input's place becomes current again, or a result takes focus, THE search SHALL show the value as typed again (and its inline completion, SRC-55); WHEN the person types, deletes or pastes while a suggestion's headline is shown, that text, edited, SHALL become the value (input, SRC-4); and WHEN the view closes or the input loses focus without a choice THE search SHALL show the value as typed. Moving the caret SHALL leave the current row as it is, except that it accepts an inline completion (SRC-55). WHILE the person types on an on-screen keyboard THE search SHALL make no row current by itself — neither as the suggestions show nor as the person types — so that the keyboard's action key (Search, Go) submits the value as typed (SRC-13), as a search field on a phone does, and the person chooses a suggestion by touching it. The person types on an on-screen keyboard from the moment the input takes focus from a touch or a pen (or a touch or a pen presses the focused input), and no longer once they press Down Arrow, Up Arrow or a key that moves the caret — keys only a hardware keyboard has — or a mouse presses the input, which make the first place current as after typing: whether a device has a touch screen, or a coarse primary pointer, does not tell which keyboard is in use on a laptop with a touch screen or a tablet with a keyboard attached. WHILE no row is current because of an on-screen keyboard, Down Arrow SHALL make the first row current (the query row, or the first suggestion where the input's place comes first) and Up Arrow the last row WHILE wrap is true. WHILE an input method is composing no row SHALL be current and Enter, Escape and the arrow keys SHALL be the input method's (TXI-4), so that the Enter that confirms a conversion chooses nothing; WHEN the composition ends THE search SHALL make the first place current as after typing. WHILE the input does not have focus no row SHALL be current. WHEN a row becomes current while part of it is scrolled out of view THE search SHALL scroll it into view. Enter with an active suggestion SHALL choose it (SRC-15). A row made current automatically is announced once typing pauses, and one an arrow key moves to at once (SRC-24).
SRC-15 WHEN the person activates a suggestion (by pointer or touch, or by Enter while it is active) THE search SHALL emit select once with the suggestion's value and then collapse with the reason select (SRC-6), so that toggle follows select; it SHALL NOT change value itself: the product sets the value it wants, the suggestion's text for a query. The query row is not a suggestion: activating it submits the value (SRC-13, SRC-57).
SRC-16 THE search SHALL lay out each suggestion as one row, at least comp.search.suggestion.container.height.regular tall and at least sys.target.touch tall for touch input, in both densities, and for fine pointers at least sys.target.pointer tall WHILE density is regular and as tall as its density gives WHILE density is compact (SRC-53) (rows that touch cannot extend a hit area over each other): comp.search.suggestion.container.padding-inline.regular from each edge, the leading icon column as SRC-52 says, then the headline with the supporting text under it, comp.search.suggestion.container.gap.regular after the icon column, padded by comp.search.suggestion.container.padding-block.regular above and below. It SHALL draw the headline in comp.search.suggestion.headline.typescale and the supporting text in comp.search.suggestion.supporting-text.typescale, both wrapping and growing the row rather than being cut; the leading icon at comp.search.suggestion.leading-icon.size.regular with the family and fill of an unselected icon, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max; and the row's highlight rounded by comp.search.suggestion.container.shape. Right-to-left layouts SHALL mirror the row, and the whole row SHALL be the suggestion's hit area.
SRC-17 WHILE a suggestion — the query row included — is hovered, active or pressed THE search SHALL render its container, leading icon, headline, supporting text and opacity from the component tokens of its highest-precedence state, with precedence pressed over active over hovered and the active suggestion taking the focused tokens; WHEN a suggestion becomes active THE search SHALL show the focus ring inside its row without animation, whether an arrow key or the search made it active. A pointer over a suggestion SHALL NOT make it active.
SRC-18 WHILE the bar is hovered, focused or pressed THE search SHALL render its container, outline, outline width, glyph, input, placeholder, caret and opacity from the component tokens of the highest-precedence active state, with precedence pressed over focused over hovered; unlike a button, focus gained by pointer or touch SHALL select the focused state, because a field shows where typing will go however it was focused. THE search SHALL show the bar's focus by its focused outline, drawn inside the bar's edge, and SHALL NOT draw the focus ring around the bar; WHERE sys.behavior.focus-style is glow it SHALL also draw the glow around the bar while it is focused. WHEN colors or widths change between states THE search SHALL animate them over comp.search.motion.state-duration with comp.search.motion.state-easing, and at once where motion is reduced.
SRC-19 WHEN the bar is pressed by pointer or touch, or a suggestion by pointer, touch or Enter, THE search SHALL show that element's pressed state without delay and SHALL keep it visible for at least sys.motion.duration.press-hold, even when the press ends sooner.
SRC-20 WHILE pressed THE search SHALL answer as sys.behavior.pressed-feedback names: overlay applies the pressed tokens to the whole container at once; ripple grows the pressed state layer from the point of contact (from the center for keyboard activation); dim applies the pressed opacity to the whole control and draws no state layer; none draws no answer to the press. Under ripple and dim only the container color stays with the state under the press; outline, glyph, input, placeholder, caret, leading icon, headline, supporting text, opacity and shape still come from the pressed tokens. Under none every part stays with the state under the press. The ripple grows over comp.search.motion.feedback-duration with comp.search.motion.state-easing, fades over comp.search.motion.state-duration with comp.search.motion.state-easing once the press has ended and press-hold has passed, and appears whole where motion is reduced. The container is the bar for a press on the bar and the row for a press on a suggestion; the control a dim applies to is the bar or the row.
SRC-21 THE search SHALL ease its bar, view and suggestion corners by sys.shape.corner-smoothing (0 is a quarter circle, 0.6 the iOS continuous corner; a platform with only the OS curve draws it for any amount above 0) and show its keyboard focus as sys.behavior.focus-style names (ring or glow); a platform that cannot draw a choice SHALL fall back to the first value and state that in its README.
SRC-22 WHERE the bar is shorter than the minimum target THE search SHALL extend its hit area vertically to sys.target.touch for touch input and sys.target.pointer for fine pointers, without changing its visual size; a platform that cannot tell the input type SHALL use sys.target.touch.
SRC-23 WHEN the view opens THE search SHALL fade it in over comp.search.motion.open-duration with comp.search.motion.open-easing, a docked view also growing from its edge that faces the bar, and WHEN it closes SHALL fade it out over comp.search.motion.close-duration with comp.search.motion.close-easing; WHERE motion is reduced it SHALL appear and disappear at once. Focus SHALL move (SRC-9) when the view opens or closes, not when the motion ends.
SRC-24 THE search SHALL expose its input as a search field named by label and never by placeholder, with the platform's search role where it has one (a search box, the search-field trait, the search input type); WHILE the view shows suggestions, the web's input SHALL be a combobox with aria-autocomplete list (both WHILE an inline completion can be shown, SRC-55), aria-expanded true and aria-controls naming the suggestions' listbox. THE search SHALL announce the active row, as the input's active descendant on the web: at once WHEN an arrow key makes it active; and WHEN the search made it active automatically (the query row, SRC-14) only once it has stayed active for 500 milliseconds with nothing typed, each edit taking the active descendant away until then, as React Aria's autocomplete does, so that a screen reader reads the character typed first and then what the action key takes, and not a row after every key. The active option SHALL be selected (aria-selected true) and every other one not, from the moment it is active. THE search SHALL expose the suggestions on the web as a listbox named by label whose options — the query row first where it is drawn (SRC-57), then the suggestions — are named by their headline and described by their supporting text, and on the other platforms as buttons named and described the same way, with their position in the list; icons and the divider SHALL be hidden; WHILE the view shows no suggestion the web's input SHALL be a search box without the combobox role, whatever else the view holds; results SHALL never be options (SRC-50); the dialog and full-screen views SHALL each be exposed as their modal layer's modal dialog (MDL-10) named by label; the clear and back buttons SHALL be named by clearLabel and backLabel.
SRC-25 THE search SHALL NOT restyle the icon-only Buttons in its leading and trailing slots: each SHALL render from its own tokens and keep its own semantics and its own focus stop in reading order (the leading one before the input, the trailing ones after the clear button), and the search SHALL draw neither slot in the full-screen header. The hit areas of two neighbouring elements of the bar or the full-screen header SHALL stop at the middle of comp.search.container.gap, those of two neighbouring action buttons where the lengths SRC-34 keeps for them meet, and an icon-only Button's at the bar's edge. The gap, the length of SRC-34 and comp.search.container.padding-inline-with-button are what keep each icon-only Button's target whole: under the default system every icon-only Button of the bar and the header, the small clear button included, keeps a target at least sys.target.touch wide; a layer that narrows the gap or the padding narrows those targets.
SRC-26 WHILE disabled is true THE search SHALL NOT be focusable, editable or expandable, SHALL NOT emit input, submit, select or toggle, SHALL hide the clear button, SHALL expose the disabled state to assistive technology, and SHALL render the bar's container, outline, glyph, input, placeholder and opacity from the disabled component tokens; the slot icon-only Buttons keep their own state.
SRC-27 WHILE label is not empty THE search SHALL expose it as its accessible name, over a name the product gives it on the element (aria-label or aria-labelledby); WHILE label is empty and the product gives the search a name of its own on the element — aria-label, or aria-labelledby naming an element — THE search SHALL expose that name as its accessible name; WHILE label is empty and the product gives it none THE search SHALL still render, and in debug builds report that it has no accessible name; WHEN presentation, bar or status names a value the component does not define THE search SHALL render as docked, field or idle and in debug builds report the value; WHEN a result's headline is empty, or a result's or linked group heading's value is empty or repeats that of another suggestion, result or group, or a result group holds anything but results, THE search SHALL still render what it can and in debug builds report it; WHEN a suggestion's value is empty or repeats another's, or its headline is empty, THE search SHALL still render it and in debug builds report it; IF the trailing slot holds more than two elements THE search SHALL still lay them out and in debug builds report it.
SRC-28 WHILE the text size is enlarged THE search SHALL grow the bar and the full-screen header to hold one line of the input (their heights are minimums) and keep the value on one line, SHALL let suggestion rows grow and wrap, and SHALL NOT scale the icon-only Buttons it holds.
SRC-29 THE search SHALL hand the default slot's content comp.search.standard.suggestion.headline.color as the platform's inherited foreground (the web's inherited color, SwiftUI's foreground style, Compose's content color, Flutter's default text and icon style, React Native's Tanrei text context), inset by comp.search.suggestion.container.padding-inline.regular at the sides, and plain text given as that content, where the platform must style it, SHALL take sys.typescale.body.
SRC-30 IF the icon set cannot draw a glyph of the search yet (search, close or arrow_back; its font is still loading or failed to load) THE search SHALL draw nothing in that glyph's place, never the glyph's name as text, SHALL keep the glyph's box so that the bar's layout does not change, SHALL keep the clear and back buttons operable and named by clearLabel and backLabel, and SHALL draw the glyph once the icon set can.
SRC-31 THE search SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the search is shown THE search SHALL draw itself for the new direction at once, without a motion of its own, keeping its value, whether it is expanded, and its focus.
SRC-32 WHERE the layout direction is right-to-left THE search SHALL draw a suggestion's leading icon and the arrow_back of its back button (SRC-11) mirrored left to right exactly when the system's icon set marks that glyph's name as mirrored or the product forces mirroring for that use, and unmirrored when the product forbids it: the icon helper mirrors the glyph inside its own box, about the box's vertical centre line, changing neither its place, size, color and fill nor the order SRC-1 and SRC-16 gives. THE search SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as an image or a view of its own rather than by a glyph's name. The search glyph and the clear button's close are not marked and are never mirrored (SRC-2, SRC-10); the icon-only Buttons of the leading and trailing slots mirror their own glyphs (BTN-19).
SRC-33 THE search SHALL lay out its placeholder and a suggestion's headline and supporting text as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE search SHALL still place each and align its lines by the layout direction, not by the text's own.
SRC-34 THE search SHALL lay out the bar's action buttons — the clear button WHILE it is shown (SRC-10) and the icon-only Buttons of the trailing slot — comp.search.container.button-gap from one another, measured between their visible bounds, and SHALL move two of them further apart only as far as each needs in order to keep, centred on itself, a length of sys.target.touch along the row that its neighbour's does not reach into, because buttons that stand this close cannot extend a hit area over each other (as BGR-3): where the token is 0, as in the default system, a button at least sys.target.touch wide touches its neighbour, and a narrower one stands half of what it lacks away from it. The first action button SHALL still stand comp.search.container.gap after the input and the last comp.search.container.padding-inline-with-button from the bar's end edge (SRC-1). THE search SHALL NOT widen, resize or restyle a button to do so (SRC-25), and SHALL space the buttons the same whatever the input type, so that the bar does not change with the pointer.
SRC-35 WHILE bar is button THE search SHALL draw a trigger in place of the bar of SRC-1: one button as wide as its layout gives it and at least comp.search.trigger.container.height high, filled, raised and rounded as the bar is (comp.search.standard.container.color, comp.search.standard.container.elevation, comp.search.container.shape), holding in one row, vertically centered and comp.search.trigger.container.gap apart, the glyph search drawn as SRC-2 says at comp.search.trigger.leading-icon.size, comp.search.trigger.container.padding-inline from the start edge; then the placeholder — or the label WHILE placeholder is empty — on one line in comp.search.trigger.label.typescale and comp.search.standard.placeholder.color, taking the remaining width and cut at its own end where it does not fit (SRC-33); then the shortcut hint WHILE shortcut is not empty (SRC-37); the last of them ending comp.search.trigger.container.padding-inline from the end edge. WHILE bar is icon THE search SHALL draw in the bar's place one icon-only Tanrei Button of the text variant and the medium size showing the glyph search of the system's icon set, rendered from the Button's own tokens, and no hint. In either form THE search SHALL draw no input, no clear button and neither slot in the trigger, and SHALL NOT show the value while collapsed. Right-to-left layouts SHALL mirror the row.
SRC-36 WHILE bar is button or icon THE search SHALL treat its trigger as a button: WHEN it is activated by pointer, touch, Enter or Space THE search SHALL emit toggle once with expanded true and become expanded as SRC-5 says, presenting its view as a modal one — dialog WHILE presentation is dialog or docked, and full-screen WHILE it is full-screen — and in debug builds SHALL report presentation docked with a trigger, because a docked view has no input of its own. WHILE the button trigger is hovered, keyboard-focused or pressed THE search SHALL render its container, outline, outline width, glyph, text and opacity from the bar's component tokens of the highest-precedence state, with precedence pressed over focused over hovered, showing keyboard focus by the focused outline as the bar does (SRC-18); focus gained by pointer or touch SHALL NOT select the focused state, as for a Button; a press SHALL be answered as SRC-19 and SRC-20 say for the bar, and its hit area extended on both axes as SRC-22 says. THE search SHALL expose the trigger as a button named by label that opens a dialog, with whether its view is open (aria-haspopup with the value dialog and aria-expanded on the web), and with the search glyph hidden; WHILE disabled is true the trigger SHALL NOT be focusable or pressable, SHALL expose the disabled state and SHALL render from the disabled tokens (SRC-26).
SRC-37 WHILE shortcut is not empty THE search SHALL draw it with the keyboard shortcut component, hosted as KBS-13 says: in its plain form, at size small, with convention auto, disabled while the search is disabled, its legends and separators in comp.search.shortcut.typescale and comp.search.shortcut.color; it SHALL draw no cap, fill or edge (KBS-7), because the bar's fill may be the cap's own. It SHALL draw the hint at the end of a button trigger (SRC-35) and, WHILE bar is field, after the bar's input and comp.search.container.gap from it, only while the value is empty and the input does not have focus; it SHALL NOT draw it WHILE bar is icon, nor in a view's header. THE search SHALL expose the shortcut as the keyboard shortcut of its trigger, or of its input WHILE bar is field, in the platform's form (KBS-12: aria-keyshortcuts on the web), SHALL hide the drawn keys from assistive technology, and SHALL give the hint no press of its own: a press on it is a press on the trigger or the bar.
SRC-38 WHILE bindShortcut is true, shortcut holds exactly one chord and disabled is false, WHEN the person presses that chord anywhere in the window (read as KBS-1 reads it: mod is Command on Apple platforms and Control elsewhere) THE search SHALL, WHILE collapsed, open as an activation of its trigger does (SRC-36) or, WHILE bar is field, focus its input and expand (SRC-5), and WHILE expanded SHALL collapse with the reason shortcut (SRC-6); and it SHALL keep that press from doing anything else. THE search SHALL NOT act on a press that something else has already taken (a cancelled key event on the web), on a key repeating while held, during an input-method composition, or — for a chord without mod, ctrl or alt — while focus is in an element that takes text, its own input included, so that such a key types there. THE search SHALL listen only while it is part of what is shown (connected to the document, in the view tree) and SHALL stop when it is removed, disabled, or bindShortcut becomes false.
SRC-39 WHILE bindShortcut is false THE search SHALL NOT listen for any key outside itself: the hint and the exposed shortcut say what the product has bound, and the product opens the search by setting expanded. IF bindShortcut is true while shortcut is empty or holds more than one chord, or while another shown search binds the same chord, THE search SHALL bind nothing for itself — the search shown first keeps a chord two of them name — and in debug builds SHALL report it.
SRC-40 WHEN expanded becomes true WHILE presentation is dialog THE search SHALL present the view as a modal overlay on its modal layer (MDL-1, MDL-2, MDL-4): the layer's scrim in comp.search.view.scrim.color and comp.search.view.scrim.blur over the whole window, and above it a container centered between the window's side edges, its top comp.search.view.dialog.offset below the top of the safe area, as wide as the window allows up to comp.search.view.dialog.max-width while keeping comp.search.view.viewport-margin from each side edge, and as tall as its content up to the room left above comp.search.view.viewport-margin from the bottom of the safe area or from the on-screen keyboard; WHERE the window is too short to keep the offset and one row of content, it SHALL give up the offset down to comp.search.view.viewport-margin. It SHALL fill the container with comp.search.view.container.color, raise it by comp.search.view.container.elevation, round it by comp.search.view.container.shape and clip its content to that shape. At the container's top it SHALL draw a header at least comp.search.header.height high: the back button the full-screen view's header draws, drawn, mirrored, named by backLabel, reported and answered as SRC-11 says, comp.search.header.padding-inline from the start edge, where the full-screen header has it and in the search glyph's place, the input with the same value, and the clear button WHILE it is shown (SRC-10, at the medium size), comp.search.container.gap apart and vertically centered, the last ending comp.search.header.padding-inline from the end edge when it is the clear button and comp.search.container.padding-inline when it is the input; it SHALL draw no search glyph in the header. The back button SHALL be a stop of the view's focus order, so that a person can leave the view without Escape, a pointer or the scrim. WHILE the view has content under the header THE search SHALL draw a line of comp.search.divider.thickness in comp.search.divider.color across the container under it, then the content in the order SRC-46 gives, inset by comp.search.view.padding-block and comp.search.view.padding-inline and scrolling under the header when it is taller than the room. It SHALL move focus, keep it inside, make everything outside inert and hidden from assistive technology, and return focus when the view closes, all as SRC-9 says for the full-screen view; and it SHALL keep the container's top where it is while its content changes, so that the input does not move under the person's typing.
SRC-41 WHEN the dialog view opens THE search SHALL fade its scrim and its container in together (MDL-7, with the search's own motion, which its docked view shares) over comp.search.motion.open-duration with comp.search.motion.open-easing, and WHEN it closes SHALL fade both out over comp.search.motion.close-duration with comp.search.motion.close-easing, as SRC-23 says of the other views; WHEN the container's height changes with its content THE search SHALL draw the new height at once, without a motion of its own.
SRC-42 THE search SHALL lay out a result as a suggestion's row is laid out (SRC-16), from the same tokens: the leading icon column, then the headline in comp.search.suggestion.headline.typescale with the excerpt under it in comp.search.suggestion.supporting-text.typescale, both wrapping and growing the row rather than being cut, the row at least comp.search.suggestion.container.height.regular tall and at least the minimum target, and the whole row the result's hit area. The leading icon column SHALL be kept as SRC-52 says, the suggestions and the results of the view decided together, so that they align. WHILE a result is hovered, focused, current (SRC-49) or pressed THE search SHALL render its row from the suggestion tokens of that state (comp.search.standard.suggestion.container.color and the leading icon, headline and supporting-text colors, the excerpt taking the supporting-text color) with the precedence, the focus ring inside the row and the press answer that SRC-17, SRC-19 and SRC-20 give a suggestion, focused and current standing where active stands there.
SRC-43 THE search SHALL read an excerpt as runs of text in order, the second, fourth and every further even run being a match, SHALL draw the runs as one continuous text that wraps as one, and SHALL draw each match in comp.search.result.mark.color with its weight raised by comp.search.result.mark.emphasis, over a fill of comp.search.result.mark.container.color that covers the match's own line boxes, with square corners and no padding, so that the fill moves no text. A match SHALL be told from the excerpt around it by all three — color, weight and fill — because a match must not depend on color alone, and the reader's font, which the product does not choose, may have no weight between regular and bold, so that the raised weight draws as the regular one (an Arabic font often has none); the fill shows a match in every script, as the platform's own marked text is filled. A result is a destination, so what is marked in it is what matched; a query suggestion marks what it adds (SRC-56). THE search SHALL NOT look for the query in a result's text, mark a result's headline, or change, trim or shorten an excerpt: what matched and how long the passage is are the product's. It SHALL expose the excerpt to assistive technology as one text, the result's description, read without a pause or an announcement at a mark, and SHALL lay the whole excerpt out as text of its own direction (SRC-33).
SRC-44 THE search SHALL draw a result group as its heading followed by its results in order, comp.search.group.gap below whatever stands above it in the view and above whatever follows it. WHILE the group's href is empty its heading SHALL be the headline in comp.search.group-title.typescale and comp.search.group-title.color, wrapping, inset by comp.search.suggestion.container.padding-inline.regular at the sides and padded by comp.search.suggestion.container.padding-block.regular above and below, taking no input and no state. WHILE href is not empty the heading SHALL be a result's row (SRC-42, SRC-45) made of the group's headline, excerpt and leading icon, and the group's results SHALL be inset at the start by comp.search.group.indent, their hit areas and highlights with them, so that they read as parts of it. A group SHALL hold results only, and SHALL NOT hold a group. Right-to-left layouts SHALL mirror the inset.
SRC-45 THE search SHALL make each result, and each group heading, whose href is not empty a link and not an option or a button: the platform's own link to href (the web's anchor element; elsewhere an element with the platform's link semantics whose address the platform's opener opens), so that whatever the platform gives a link — on the web following it by Enter or a press, opening it in a new tab by a modifier key or the middle button, its context menu, dragging and copying its address, the address shown before it is followed — is the platform's and not the search's to imitate; it SHALL activate a link by pointer, touch or Enter and not by Space, SHALL open it in a new context WHILE target is new (on the web one that is given no handle to the page that opened it) and expose targetLabel as its description after the excerpt, and SHALL draw no mark of its own for a new context. WHEN a result is activated in place (by Enter, touch or a primary press, without a modifier key, target being same) THE search SHALL emit select once with the result's value and then let the platform open href, unless the product cancelled that select, in which case it SHALL open nothing because the product's router has taken it; and SHALL then collapse with the reason select (SRC-6), so that toggle follows select. WHEN a result is opened any other way (a modifier key, the middle button, the context menu, target new) THE search SHALL emit nothing and stay expanded, so that a person can open several results from one search. WHILE a result's href is empty, or names a script rather than a place, it SHALL be a button, activated by pointer, touch, Enter or Space, for which select is all that happens.
SRC-46 WHILE expanded THE search SHALL lay out the content of its view from top to bottom in this order: the suggestions, the status row (SRC-47), the results and result groups in the order the product gives them, and the default slot's content; a part that is absent takes no room.
SRC-47 WHILE statusText is not empty or status is loading THE search SHALL draw a status row: inset by comp.search.suggestion.container.padding-inline.regular at the sides and padded by comp.search.suggestion.container.padding-block.regular above and below, taking no input and no state. WHILE status is idle it SHALL draw statusText, wrapping, in comp.search.status.typescale and comp.search.status.color; WHILE status is error it SHALL draw it in comp.search.status.error.color; WHILE status is loading it SHALL draw, in the text's place and at the row's start, one Tanrei loading indicator of size small named by statusText, which waits its own show delay and enters as the loading indicator does (LDG-11 to LDG-14), and no text, and the row SHALL keep the height of one line of text whether or not the indicator is shown yet. The results the product leaves in the view WHILE status is loading SHALL stay drawn and usable.
SRC-48 THE search SHALL expose the status row as a live region that is present from the moment the view opens: WHILE status is idle, WHEN statusText changes THE search SHALL have assistive technology read the new text politely, after what it is saying (the status role on the web); WHILE status is error it SHALL have it read at once (the alert role); WHILE status is loading it SHALL announce nothing — the loading indicator does not announce itself (LDG-6) — and SHALL mark the results as busy (aria-busy on the web) until status leaves loading. THE search SHALL NOT compose, count or translate the text: the number of results and the words around it are the product's.
SRC-49 WHILE expanded, the input has focus and the view holds a result and no suggestion THE search SHALL make the first result current automatically, focus staying in the input, as SRC-14 makes its first place current and, as there, not WHILE the person types on an on-screen keyboard or an input method is composing: WHEN the view comes to show results — it opens with them, the product gives or replaces them, or focus comes back to the input — and WHEN the person types, deletes or pastes. It SHALL draw the current result as a focused one (SRC-42), and the action key in the input SHALL activate it as Enter on it does (SRC-45), so that one press of Enter goes to what the search found first, as a documentation search does. With the modifier that opens a link elsewhere — Command under the Apple keyboard convention and Control under the others for a new tab, Shift for a new window — the action key in the input SHALL open the current result's destination there, as that press on the link does: nothing emitted and the view kept open (SRC-45); a current result without a destination takes no such press. WHILE the input does not have focus no result SHALL be current. The results SHALL be the last rows of the arrow keys' cycle (SRC-14), in view order, across groups, a linked group heading counting as a result and a title not, and an arrow key that reaches a result SHALL move focus to it: WHEN the person presses Down Arrow in the input while the first result is current THE search SHALL move focus to the second result, and to the first WHILE no result is current and there is no suggestion to go to (none in the view, or the last one active). WHILE a result has focus THE search SHALL move focus to the next result with Down Arrow and to the previous one with Up Arrow; Up Arrow on the first SHALL go back to the input with the last suggestion active, where the view holds suggestions; and at the ends of the cycle, WHILE wrap is true, Down Arrow on the last result SHALL go to the first place of the cycle — focus going back to the input, to the query row or the input's place, or, with no suggestion, to the first result — and, with no suggestion in the view, Up Arrow on the first result, whether it has focus or is current in the input, SHALL move focus to the last result; WHILE wrap is false they SHALL do nothing there. WHEN a result takes focus or becomes current while part of it is scrolled out of view THE search SHALL scroll it into view, and SHALL show the focus ring inside its row (SRC-42). WHILE a result has focus, WHEN the person types a character, deletes or pastes THE search SHALL move focus to the input so that the key edits the value there, and Escape SHALL close the view as from the input (SRC-6). Tab and Shift+Tab SHALL move through the results as through any links WHILE the view is modal, and SHALL leave the search and close the view WHILE it is docked (SRC-6). A pointer over a result SHALL NOT move focus, and the arrows SHALL NOT reach the status row or the default slot's content.
SRC-50 THE search SHALL expose its results as links in a list, outside the suggestions' listbox: one list named by label holding the results in order, each result a link named by its headline and described by its excerpt, with its position in the list where the platform gives one; a result group as a group named by its headline holding its own list of its results, and a linked heading as a link before that list; a result without href as a button in the same place. A result SHALL never carry the option role: an option cannot be a link, and a result must be one. The result current while focus stays in the input (SRC-49) SHALL be announced as the query row is (SRC-24) — on the web the input names the result's link as its active descendant once it has stayed current for 500 milliseconds with nothing typed —, the input staying a search box; what the search found is also said by the status row (SRC-48), and the result takes real focus as soon as the person moves to it. On the platforms without a link element THE search SHALL expose a result as a button with the link trait or role where the platform has one, named and described the same way. Leading icons SHALL be hidden, and the status row is exposed as SRC-48 says.
SRC-51 THE search SHALL NOT run a query, fetch, wait, debounce, cache, sort or filter anything itself: it emits input once per change (SRC-4) and draws the suggestions, the results, the status and the statusText the product gives it, replacing them when the product does, at once and without a motion of its own. WHEN the result that has focus is removed or replaced, or the product replaces its content whole so that the element that held the focus goes with it, THE search SHALL move focus to the input rather than let it fall out of the view; WHEN the product sets results or status while the view is collapsed THE search SHALL keep them for the next time it opens and SHALL NOT expand.
SRC-52 THE search SHALL decide the leading icon column for its view as a whole — its suggestions, its query row, its results and the linked headings of its result groups (SRC-16, SRC-42, SRC-44, SRC-57) — as iconSpace says. WHILE iconSpace is auto every row SHALL keep the column, empty where it has no icon, WHERE any suggestion or result of the view has a leading icon — the query row, drawn with the search glyph, counting as one that has —, so that the headlines of the view start on one line, and no row SHALL keep it WHERE none has one; WHILE iconSpace is always every row SHALL keep it, whether or not any has an icon; WHILE iconSpace is never a row SHALL have the column only where it has a leading icon itself. The column kept is comp.search.suggestion.leading-icon.size.regular wide with comp.search.suggestion.container.gap.regular after it, draws nothing and is nothing to assistive technology. WHEN a suggestion or a result is added or removed, or its leadingIcon changes, or the query row is drawn or taken away, THE search SHALL decide again; WHEN iconSpace names a value the search does not define THE search SHALL treat it as auto and in debug builds report the unknown value.
SRC-53 THE search SHALL draw every row of its view — a suggestion, a result, a result group's linked heading — at its density. WHILE density is regular a row SHALL take the regular value of every token of the density axis this spec names (comp.search.suggestion.container.height.regular, comp.search.suggestion.container.padding-block.regular, comp.search.suggestion.container.padding-inline.regular, comp.search.suggestion.container.gap.regular, comp.search.suggestion.leading-icon.size.regular); WHILE density is compact it SHALL take the compact value of each in its place (comp.search.suggestion.container.height.compact, comp.search.suggestion.container.padding-block.compact, comp.search.suggestion.container.padding-inline.compact, comp.search.suggestion.container.gap.compact, comp.search.suggestion.leading-icon.size.compact), so that a compact row is lower, set in less from its edges and draws a smaller glyph, the room kept for an empty leading icon column (SRC-52) shrinking with it. The text styles, the group titles, the status row, the view's surface, its header and the bar SHALL be the same in both. WHEN density names a value the active design system does not have THE search SHALL draw the default density's rows and in debug builds report the unknown value; a density a design system added SHALL be drawn from that density's tokens, as the core values are. WHEN density changes while the view is shown THE search SHALL draw the new rows at once, without a motion, keeping the active row.
SRC-54 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE search SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the search is invalid — except those the search owns (aria-haspopup, aria-expanded, aria-controls, aria-keyshortcuts, aria-disabled), which it SHALL move and not expose. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE search SHALL take it off that element. WHEN the product sets an aria- attribute the search owns THE search SHALL report it in debug builds.
SRC-55 WHILE inlineCompletion is true and the query row is drawn (SRC-57), WHEN the person inserts text at the end of the value — by typing, or as an input method commits its composition — or the product gives or replaces the suggestions after such an insertion, THE search SHALL complete the value in the input from the first suggestion, in the product's order, whose headline begins with the value and is longer than it, compared as the combobox compares a label with what was typed (CMB-25): it SHALL write the rest of that headline after the value, selected, with the caret before it, without changing value or emitting input, and the query row SHALL show the completed text and stay active. THE search SHALL NOT complete after the person deleted (Backspace, Delete, a cut) or pasted, until they insert text again; WHILE an input method is composing; WHILE the person types on an on-screen keyboard (SRC-14); WHILE the caret is not at the end of the value or the person has selected text; or WHERE no suggestion's headline begins with the value. WHEN the person moves the caret or the selection — an arrow key, Home, End, a press in the input — THE search SHALL accept the completion: the completed text SHALL become the value, input SHALL be emitted once, and the caret SHALL move as the key or the press moves it. WHEN the person presses Backspace or Delete while a completion is shown THE search SHALL take the completion away and nothing else: the value stays as typed, no input is emitted, and nothing is completed again until the person inserts text. Typing a character SHALL replace the completion and go on from the value as typed, which may be completed again; WHEN an input method begins to compose while a completion is shown, its first inserted text SHALL replace the completion as a typed character does, and WHEN the composition is cancelled before it inserted anything THE search SHALL take the completion away as Backspace does: the value stays as typed and no input is emitted. The action key SHALL accept the completion and then submit (SRC-13). WHEN an arrow key makes a suggestion active the input SHALL show that suggestion (SRC-14), and WHEN the query row becomes current again THE search SHALL show the completion again as it was. WHEN the view closes or the input loses focus THE search SHALL take an unaccepted completion away. WHILE inlineCompletion is false or queryRow is none THE search SHALL complete nothing.
SRC-56 WHILE the value is not empty THE search SHALL draw, in the headline of each suggestion that begins with the value — compared as SRC-55 compares —, the rest of the headline, its completion, with its weight raised by comp.search.suggestion.completion.emphasis over the weight of comp.search.suggestion.headline.typescale, in the headline's own color and with no fill, as a web search draws what each suggestion would add to what was typed: the person knows what they typed, and tells the suggestions apart by what each adds. A headline that does not begin with the value SHALL be drawn without emphasis; the query row's headline is the value itself, and only an inline completion shown after it is emphasised (SRC-57, SRC-55). The completion SHALL wrap with the headline as one text, move no letter of it, and be read as part of the headline, without a pause or an announcement. THE search SHALL NOT emphasise anything in a suggestion's supporting text, and the excerpt of a result marks what matched instead (SRC-43).
SRC-57 WHILE queryRow is first, the view shows suggestions and the value is not empty THE search SHALL draw a query row above the first suggestion: a suggestion's row (SRC-16, SRC-17, SRC-19, SRC-20, SRC-53), drawn from the suggestion tokens, holding in its leading icon column the glyph search of the system's icon set, drawn as a suggestion's leading icon and never mirrored (SRC-2), the value as typed as its headline — followed by the inline completion WHILE one is shown, emphasised as SRC-56 says —, and queryRowText as its supporting text WHILE queryRowText is not empty. It is the search's own row and holds no word of the search's own: what it says beside the query is the product's, and the glyph and the query alone are a whole row. It SHALL be the row the search makes active automatically (SRC-14), so that the action key always searches for the value as typed (SRC-13), as the first row of a browser's address bar does; WHEN the person presses it by pointer or touch, or presses the action key while it is active, THE search SHALL submit as SRC-13 says, focus staying in the input, and SHALL NOT emit select. It is never a query of its own to fill the input with: WHEN it becomes current again the input shows the value as typed (SRC-14). THE search SHALL expose it as the first option of the suggestions' listbox, named by its headline and described by queryRowText, counted in the options' positions. WHILE queryRow is none THE search SHALL draw no query row; WHEN queryRow names a value the search does not define THE search SHALL draw the query row as for first and in debug builds report the value.

प्लैटफ़ॉर्म के अनुसार नामों का मिलान

पैरिटी का मतलब एक जैसे API नहीं है। हर प्लैटफ़ॉर्म एक ही कॉन्ट्रैक्ट को अपने तरीक़े से व्यक्त करता है।

स्पेक Web SwiftUI Jetpack Compose Flutter React Native
कंपोनेंट tanrei-search TanreiSearch TanreiSearch TanreiSearch Search
presentation · प्रॉपर्टी presentation presentation presentation presentation presentation
bar · प्रॉपर्टी bar bar bar bar bar
value · प्रॉपर्टी value text value controller value
label · प्रॉपर्टी label label label semanticLabel accessibilityLabel
placeholder · प्रॉपर्टी placeholder prompt placeholder hintText placeholder
expanded · प्रॉपर्टी expanded isExpanded expanded controller expanded
disabled · प्रॉपर्टी disabled disabled enabled enabled disabled
clearLabel · प्रॉपर्टी clearLabel clearLabel clearLabel clearLabel clearLabel
backLabel · प्रॉपर्टी backLabel backLabel backLabel backLabel backLabel
shortcut · प्रॉपर्टी shortcut shortcut shortcut shortcut shortcut
bindShortcut · प्रॉपर्टी bindShortcut bindsShortcut bindShortcut bindShortcut bindShortcut
status · प्रॉपर्टी status status status status status
statusText · प्रॉपर्टी statusText statusText statusText statusText statusText
queryRow · प्रॉपर्टी queryRow queryRow queryRow queryRow queryRow
queryRowText · प्रॉपर्टी queryRowText queryRowText queryRowText queryRowText queryRowText
inlineCompletion · प्रॉपर्टी inlineCompletion inlineCompletion inlineCompletion inlineCompletion inlineCompletion
wrap · प्रॉपर्टी wrap wrap wrap wrap wrap
iconSpace · प्रॉपर्टी iconSpace iconSpace iconSpace iconSpace iconSpace
density · प्रॉपर्टी density density density density density
input · इवेंट input text onValueChange onChanged onChangeText
submit · इवेंट submit onSubmit onSearch onSubmitted onSubmitEditing
select · इवेंट select onSelect onSelect onSelected onSelect
toggle · इवेंट toggle isExpanded onExpandedChange onExpandedChanged onExpandedChange
टिप्पणियाँ A form-associated custom element, as the text field is: it takes name and submits its value. It renders an <input type="search" enterkeyhint="search"> in its shadow root, with the web's own cancel button hidden. Attributes are kebab-case (clear-label, back-label, query-row, query-row-text, inline-completion); wrap defaults to true, so its attribute is the inverse, no-wrap, as a boolean attribute cannot default to true. The suggestions are <tanrei-search-suggestion> children; the leading and trailing slots are named slots, and other children are the view's default content. The docked view is a manual popover in the top layer, placed with CSS anchor positioning and a script fallback, with the search's own light dismiss so that toggle carries a reason; a press outside also reaches the element under it. The full-screen view is a <dialog> opened with showModal(). The element sets its own expanded before firing toggle, which is a CustomEvent whose detail holds expanded and reason; submit is cancelable. The inline attribute, for tests, draws the open view in place. The leading glyph is the icon helper's search; the clear and back buttons show close and arrow_back (SRC-2, SRC-10, SRC-11). Not built yet: bar="button" and bar="icon" render a <button> (the icon form a <tanrei-button icon-only>) with aria-haspopup="dialog", aria-expanded and aria-keyshortcuts; the dialog view is a <dialog> opened with showModal(), its scrim the ::backdrop, a press on which closes it with the reason outside; shortcut is an attribute of chords separated by spaces, as the keyboard shortcut's keys; bind-shortcut adds one keydown listener on the window while the element is connected. The status row is a role="status" element that exists from the first render (role="alert" while status="error"). Results are <tanrei-search-result> and <tanrei-search-result-group> children; focus moves to their anchors with focus(), and select on a result is cancelable. The query row is an option of the search's own in its shadow root, first in the listbox (id="query-row"). A suggestion an arrow key reaches is written into the input element without setting value or firing input; the element is written back from value when the person returns. The inline completion is a selection range after the typed text; the input a Backspace fires to take it away, which changes no value, is stopped in the shadow root. An automatic row is named by aria-activedescendant 500 ms after it became current, from a timer each edit restarts and clears. A result's link is its own light-DOM child (the <a>, or the <button> without href), slotted over the row the result draws in its shadow root and drawn as nothing itself, so that the input reaches it as its active descendant by element reflection (ariaActiveDescendantElement): an id cannot cross a shadow root, and reflection reaches out into the document, never into another shadow root. An on-screen keyboard (SRC-14) is told by the pointerType of the press that focused the input — touch or pen — and a hardware keyboard by its arrow and caret keys; (pointer: coarse) describes only the primary pointer, and the VirtualKeyboard API is Chromium's alone. TanreiSearch(_ label:, text: Binding<String>, isExpanded: Binding<Bool>, presentation:, prompt:, clearLabel:, backLabel:, onSubmit:, onSelect:) { suggestions } leading: { … } trailing: { … } content: { … }. Every edit writes the text binding, which is the input event; opening and closing write isExpanded, which is toggle (the reason is passed to an optional onToggle). SwiftUI's .searchable is not used: its field and suggestions cannot take the tokens. The docked view is drawn in an overlay above the window's content, anchored to the bar, not with .popover, which is modal at compact widths and would take focus from the field (SRC-8). The full-screen view is presented with .fullScreenCover, with the system transition off, as the dialog is. The input has the search-field trait. disabled follows .disabled(_:). Snapshot harness: renders the bar and the open view in place, as the menu and the dialog do. Without an installed icon font it strokes the search and back glyphs as shapes of its own (TanreiSearchMagnifierShape, TanreiSearchBackArrowShape) instead of drawing nothing (SRC-2, SRC-30). Not built on this platform yet: queryRow, queryRowText, inlineCompletion and wrap (it draws no query row, completes nothing and stops the arrow keys at the ends), bar, the dialog presentation, shortcut (where bindsShortcut would be .keyboardShortcut on the trigger), status, statusText, iconSpace (SRC-52: it keeps the leading icon column in every row while any suggestion has an icon) and the result kinds. Compose idiom, as Material's SearchBar with its input field: TanreiSearch(value, onValueChange, expanded, onExpandedChange, label, modifier, presentation, placeholder, enabled, clearLabel, backLabel, onSearch, onSelect, leading, trailing) { suggestions and content }. State hoisting: the caller keeps value and expanded and moves them from onValueChange and onExpandedChange, which receives the new value and the reason. enabled is the inverse flag. Built on BasicTextField with the search IME action. The docked view is a Popup that does not take focus; the full-screen view is a Dialog window with usePlatformDefaultWidth = false and the window's own dim off, as the dialog's. Compose has no combobox or listbox role: the suggestions are buttons in a column with collection semantics. Snapshot harness: renders the bar and the open view in place. Without an installed icon font it strokes the clear button's close as a vector of its own (TanreiDrawnGlyph), and draws search and arrow_back as their names in the platform font, clipped to the box (TanreiNamedGlyph), instead of drawing nothing (SRC-2, SRC-30). Not built on this platform yet: queryRow, queryRowText, inlineCompletion and wrap (it draws no query row, completes nothing and stops the arrow keys at the ends), bar, the dialog presentation, shortcut, bindShortcut (a key handler on the window's root, where a hardware keyboard exists), status, statusText, iconSpace (SRC-52: it keeps the leading icon column in every row while any suggestion has an icon) and the result kinds. Flutter idiom, as Material's SearchAnchor and SearchController but without Material: TanreiSearch(controller: TanreiSearchController, semanticLabel:, presentation:, hintText:, enabled:, clearLabel:, backLabel:, onChanged:, onSubmitted:, onSelected:, onExpandedChanged:, leading:, trailing: [...], suggestions: [...], child:). TanreiSearchController is a TextEditingController that also holds isExpanded with expand() and collapse(); the search updates it itself and calls onExpandedChanged with the value and the reason. The input is EditableText with TextInputAction.search and SemanticsInputType.search (Flutter 3.32, the oldest version supported, asserts on SemanticsRole.searchBox). The docked view is drawn through an OverlayPortal; the full-screen view is a modal route that scopes semantics, as the dialog's. Snapshot harness: a golden of the bar and the open view. Lagging behind SRC-30: it writes the built-in glyphs as Material Symbols code points (tanreiSearchGlyph, tanreiCloseGlyph, tanreiArrowBackGlyph), and without the icon font it draws whatever the fallback face has at those code points instead of nothing. Not built on this platform yet: queryRow, queryRowText, inlineCompletion and wrap (it draws no query row, completes nothing and stops the arrow keys at the ends), bar, the dialog presentation, shortcut, bindShortcut (a HardwareKeyboard handler), status, statusText, iconSpace (SRC-52: it keeps the leading icon column in every row while any suggestion has an icon) and the result kinds. Controlled, in TextInput's idiom: <Search value onChangeText expanded onExpandedChange accessibilityLabel placeholder presentation clearLabel backLabel onSubmitEditing onSelect suggestions={[…]} leading trailing insets>{content}</Search>; the caller moves value and expanded from onChangeText and onExpandedChange, which receives the new value and the reason. The input is a TextInput with returnKeyType="search" and accessibilityRole="search". The docked view is on the overlay layer that TanreiProvider renders, not a Modal (which would take focus from the field); the full-screen view is a transparent Modal with statusBarTranslucent and navigationBarTranslucent, its insets from the insets prop or TanreiProvider's. Android's back button (BackHandler) closes the view. Snapshot harness: renders the bar and the open view in place. Lagging behind SRC-30: without the icon font the built-in glyphs print their ligature names. Not built on this platform yet: queryRow, queryRowText, inlineCompletion and wrap (it draws no query row, completes nothing and stops the arrow keys at the ends), bar, the dialog presentation, shortcut, status, statusText, iconSpace (SRC-52: it keeps the leading icon column in every row while any suggestion has an icon) and the result kinds; bindShortcut does nothing where there is no hardware keyboard event to listen to, and the README says so.

टोकन

टोकन किसका एलियास रिज़ॉल्व किया गया मान (लाइट)
--tanrei-comp-search-container-button-gap sys.space.space0 0px
--tanrei-comp-search-container-gap — 16px
--tanrei-comp-search-container-height — 56px
--tanrei-comp-search-container-padding-inline sys.space.space200 16px
--tanrei-comp-search-container-padding-inline-with-button sys.space.space100 8px
--tanrei-comp-search-container-shape sys.shape.corner.full 9999px
--tanrei-comp-search-disabled-opacity — 1
--tanrei-comp-search-disabled-outline-width — 1px
--tanrei-comp-search-divider-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-search-divider-thickness sys.border.hairline 1px
--tanrei-comp-search-focused-opacity — 1
--tanrei-comp-search-focused-outline-width — 2px
--tanrei-comp-search-group-title-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-group-gap sys.space.space100 8px
--tanrei-comp-search-group-indent sys.space.space300 24px
--tanrei-comp-search-header-height — 72px
--tanrei-comp-search-header-padding-inline sys.space.space100 8px
--tanrei-comp-search-hovered-opacity — 1
--tanrei-comp-search-hovered-outline-width — 1px
--tanrei-comp-search-leading-icon-size sys.icon.medium 24px
--tanrei-comp-search-motion-close-duration sys.motion.role.appear.anchored.exit 250ms
--tanrei-comp-search-motion-close-easing sys.motion.easing.exit cubic-bezier(0.3, 0, 1, 1)
--tanrei-comp-search-motion-feedback-duration sys.motion.role.feedback 450ms
--tanrei-comp-search-motion-open-duration sys.motion.role.appear.anchored.enter 300ms
--tanrei-comp-search-motion-open-easing sys.motion.easing.enter cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-search-motion-state-duration sys.motion.role.state.default 250ms
--tanrei-comp-search-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-search-outline-width sys.border.hairline 1px
--tanrei-comp-search-pressed-opacity — 1
--tanrei-comp-search-pressed-outline-width — 1px
--tanrei-comp-search-result-mark-color sys.color.on-surface #1b1b1b
--tanrei-comp-search-result-mark-container-color sys.color.secondary-container #eeeeee
--tanrei-comp-search-result-mark-emphasis sys.typescale.emphasis.body 100
--tanrei-comp-search-shortcut-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-standard-caret-color sys.color.primary #1b1b1b
--tanrei-comp-search-standard-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-search-standard-container-elevation sys.elevation.level0
--tanrei-comp-search-standard-disabled-caret-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-container-color — #eeeeee
--tanrei-comp-search-standard-disabled-container-elevation —
--tanrei-comp-search-standard-disabled-input-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-outline-color — #000000 · 0%
--tanrei-comp-search-standard-disabled-placeholder-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-suggestion-container-color — #000000 · 0%
--tanrei-comp-search-standard-disabled-suggestion-headline-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-suggestion-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-suggestion-state-layer-color — #1b1b1b · 38%
--tanrei-comp-search-standard-disabled-suggestion-supporting-text-color — #1b1b1b · 38%
--tanrei-comp-search-standard-focused-caret-color — #1b1b1b
--tanrei-comp-search-standard-focused-container-color — #eeeeee
--tanrei-comp-search-standard-focused-container-elevation —
--tanrei-comp-search-standard-focused-input-color — #1b1b1b
--tanrei-comp-search-standard-focused-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-focused-outline-color — #0070ac
--tanrei-comp-search-standard-focused-placeholder-color — #4b4b4b
--tanrei-comp-search-standard-focused-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-focused-suggestion-container-color — #1b1b1b · 10%
--tanrei-comp-search-standard-focused-suggestion-headline-color — #1b1b1b
--tanrei-comp-search-standard-focused-suggestion-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-focused-suggestion-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-focused-suggestion-supporting-text-color — #4b4b4b
--tanrei-comp-search-standard-hovered-caret-color — #1b1b1b
--tanrei-comp-search-standard-hovered-container-color — #dddddd
--tanrei-comp-search-standard-hovered-container-elevation —
--tanrei-comp-search-standard-hovered-input-color — #1b1b1b
--tanrei-comp-search-standard-hovered-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-hovered-outline-color — #000000 · 0%
--tanrei-comp-search-standard-hovered-placeholder-color — #4b4b4b
--tanrei-comp-search-standard-hovered-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-hovered-suggestion-container-color — #1b1b1b · 8%
--tanrei-comp-search-standard-hovered-suggestion-headline-color — #1b1b1b
--tanrei-comp-search-standard-hovered-suggestion-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-hovered-suggestion-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-hovered-suggestion-supporting-text-color — #4b4b4b
--tanrei-comp-search-standard-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-search-standard-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-standard-outline-color — #000000 · 0%
--tanrei-comp-search-standard-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-standard-pressed-caret-color — #1b1b1b
--tanrei-comp-search-standard-pressed-container-color — #d9d9d9
--tanrei-comp-search-standard-pressed-container-elevation —
--tanrei-comp-search-standard-pressed-input-color — #1b1b1b
--tanrei-comp-search-standard-pressed-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-pressed-outline-color — #000000 · 0%
--tanrei-comp-search-standard-pressed-placeholder-color — #4b4b4b
--tanrei-comp-search-standard-pressed-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-pressed-suggestion-container-color — #1b1b1b · 10%
--tanrei-comp-search-standard-pressed-suggestion-headline-color — #1b1b1b
--tanrei-comp-search-standard-pressed-suggestion-leading-icon-color — #4b4b4b
--tanrei-comp-search-standard-pressed-suggestion-state-layer-color — #1b1b1b
--tanrei-comp-search-standard-pressed-suggestion-supporting-text-color — #4b4b4b
--tanrei-comp-search-standard-state-layer-color comp.search.standard.input.color #1b1b1b
--tanrei-comp-search-standard-suggestion-container-color — #000000 · 0%
--tanrei-comp-search-standard-suggestion-headline-color sys.color.on-surface #1b1b1b
--tanrei-comp-search-standard-suggestion-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-standard-suggestion-state-layer-color comp.search.standard.suggestion.headline.color #1b1b1b
--tanrei-comp-search-standard-suggestion-supporting-text-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-status-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-search-status-error-color sys.color.error #cd262f
--tanrei-comp-search-suggestion-completion-emphasis — 300
--tanrei-comp-search-suggestion-container-gap-compact comp.tree-view.container.gap.compact 8px
--tanrei-comp-search-suggestion-container-gap-regular sys.space.space200 16px
--tanrei-comp-search-suggestion-container-height-compact comp.tree-view.container.height.compact 32px
--tanrei-comp-search-suggestion-container-height-regular — 56px
--tanrei-comp-search-suggestion-container-padding-block-compact — 4px
--tanrei-comp-search-suggestion-container-padding-block-regular — 8px
--tanrei-comp-search-suggestion-container-padding-inline-compact comp.tree-view.container.padding-inline.compact 8px
--tanrei-comp-search-suggestion-container-padding-inline-regular sys.space.space200 16px
--tanrei-comp-search-suggestion-container-shape — 4px
--tanrei-comp-search-suggestion-leading-icon-size-compact sys.icon.small 20px
--tanrei-comp-search-suggestion-leading-icon-size-regular sys.icon.medium 24px
--tanrei-comp-search-trigger-container-gap sys.space.space100 8px
--tanrei-comp-search-trigger-container-height — 40px
--tanrei-comp-search-trigger-container-padding-inline sys.space.space150 12px
--tanrei-comp-search-trigger-leading-icon-size sys.icon.small 20px
--tanrei-comp-search-view-container-color sys.color.surface-bright #ffffff
--tanrei-comp-search-view-container-elevation sys.elevation.level2 0px 0px 0px 1px rgb(0 0 0 / 0.08), 0px 1px 2px 0px rgb(0 0 0 / 0.04)
--tanrei-comp-search-view-container-shape sys.shape.corner.medium 8px
--tanrei-comp-search-view-dialog-max-width — 640px
--tanrei-comp-search-view-dialog-offset sys.space.space800 64px
--tanrei-comp-search-view-offset sys.space.space50 4px
--tanrei-comp-search-view-padding-block sys.space.space50 4px
--tanrei-comp-search-view-padding-inline sys.space.space50 4px
--tanrei-comp-search-view-scrim-blur comp.modal-layer.scrim.blur 0px
--tanrei-comp-search-view-scrim-color comp.modal-layer.scrim.color #000000 · 40%
--tanrei-comp-search-view-viewport-margin sys.space.space100 8px
--tanrei-comp-search-group-title-typescale sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-search-input-typescale sys.typescale.body-large 400 16px/1.625
--tanrei-comp-search-shortcut-typescale sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-search-status-typescale sys.typescale.body-small 400 13px/1.5385
--tanrei-comp-search-suggestion-headline-typescale sys.typescale.body 400 14px/1.5714
--tanrei-comp-search-suggestion-supporting-text-typescale sys.typescale.body-small 400 13px/1.5385
--tanrei-comp-search-trigger-label-typescale sys.typescale.body 400 14px/1.5714

फ़िक्स्चर

मानक रेंडरिंग। हर प्लैटफ़ॉर्म हर फ़िक्स्चर का स्नैपशॉट एक ही ID से लेता है, ताकि नतीजों की तुलना की जा सके।

इससे जनरेट किया गया: specs/search.spec.json, tokens/comp/search.tokens.json, design/tokens/

दिशानिर्देश

कब इस्तेमाल करें

खोज तब इस्तेमाल करें जब खोजना प्रॉडक्ट के कॉन्टेंट तक पहुँचने का एक मुख्य रास्ता हो, जैसे मेल, फ़ाइलें, संपर्क या सेटिंग, और सुझाव लोगों को वहाँ जल्दी पहुँचने में मदद करें। इसे स्क्रीन के ऊपर रखें, या उस पेज के ऊपर जिसमें यह खोजती है।

इसे साइट खोज के रूप में भी इस्तेमाल करें: हेडर में एक ट्रिगर जो डायलॉग खोलता है, जिसमें मिले हुए पेज और सेक्शन लिंक के रूप में होते हैं।

स्क्रीन पर पहले से मौजूद छोटी लिस्ट को फ़िल्टर करने के लिए, या फ़ॉर्म में खोज का शब्द दर्ज करने के लिए, search type वाला टेक्स्ट फ़ील्ड काफ़ी है। किसी तय लिस्ट में से एक मान चुनना मेन्यू या लिस्ट का काम है, खोज का नहीं।

बार या ट्रिगर

bar पेज में क्या रहता है क्या खोलता है किसके लिए
field (डिफ़ॉल्ट) अपने इनपुट वाला बार कोई भी प्रस्तुति वह प्रॉडक्ट जिसमें खोज एक मुख्य रास्ता है, और बार की अपनी जगह है
button बार के आकार का ट्रिगर: ग्लिफ़, प्लेसहोल्डर और शॉर्टकट का संकेत एक मोडल व्यू: डायलॉग या फ़ुल-स्क्रीन जगह वाला हेडर, जहाँ खोज कई चीज़ों में से एक है
icon खोज के ग्लिफ़ वाला, सिर्फ़ आइकन वाला बटन एक मोडल व्यू: डायलॉग या फ़ुल-स्क्रीन बिना जगह वाला हेडर, जैसे सँकरी विंडो

ट्रिगर का नाम label से आता है, और बटन ट्रिगर प्लेसहोल्डर दिखाता है, या जहाँ प्लेसहोल्डर न हो वहाँ लेबल। जब उसका व्यू बंद होता है, तो फ़ोकस ट्रिगर पर लौटता है।

डॉक्ड, डायलॉग या फ़ुल-स्क्रीन

प्रस्तुति व्यू कहाँ खुलता है फ़ोकस किसके लिए
डॉक्ड (डिफ़ॉल्ट) बार के नीचे, उतना ही चौड़ा, कॉन्टेंट के ऊपर बार के इनपुट में रहता है। और कुछ भी निष्क्रिय नहीं होता, और कोई स्क्रिम नहीं होता बड़ी विंडो, जहाँ व्यू पूरी स्क्रीन को छिपाए बिना खुल सकता है
डायलॉग विंडो के ऊपरी हिस्से के पास, बीच में, एक अधिकतम चौड़ाई तक, स्क्रिम के ऊपर। कॉन्टेंट बदलने पर उसका ऊपरी सिरा अपनी जगह रहता है हेडर के इनपुट पर जाता है, व्यू के भीतर रहता है, और बंद होने पर ट्रिगर या बार पर लौट आता है बड़ी विंडो, ट्रिगर से खोला गया: साइट खोज
फ़ुल-स्क्रीन पूरी विंडो के ऊपर, अपने हेडर, पीछे जाने के बटन और डिवाइडर के साथ हेडर के इनपुट पर जाता है, व्यू के भीतर रहता है, और बंद होने पर बार या ट्रिगर पर लौट आता है छोटी विंडो, जहाँ सुझाव और ऑन-स्क्रीन कीबोर्ड किसी और चीज़ के लिए जगह नहीं छोड़ते

क्वेरी तीनों में एक ही रहती है। किसी ब्रेकपॉइंट पर presentation बदलने से वह नहीं बदलती।

मिटाने और पीछे जाने के बटन

दोनों पहले से बने हैं, क्योंकि उनका व्यवहार खोज का अपना है: मिटाने का बटन क्वेरी को ख़ाली करता है और व्यू और फ़ोकस को वहीं रखता है जहाँ वे हैं, और पीछे जाने का बटन फ़ुल-स्क्रीन व्यू को बंद करता है। उनके नाम आपके प्रॉडक्ट की भाषा में होने चाहिए, इसलिए उन्हें आप देते हैं: clearLabel (“खोज मिटाएँ”) और, डायलॉग और फ़ुल-स्क्रीन के लिए, backLabel (“पीछे”)। iOS पर पीछे जाने का बटन फ़ुल-स्क्रीन व्यू से बाहर निकलने का अकेला रास्ता है। डायलॉग के हेडर में भी पीछे जाने का बटन होता है, ताकि जिस व्यक्ति के पास न Escape है, न पॉइंटर, वह भी उससे बाहर निकल सके।

सुझाव, नतीजे और आपका कॉन्टेंट

  • सुझाव एक क्वेरी है; नतीजा जाने की जगह है। सुझाव क्वेरी पूरी करने में मदद करता है, और ऐरो कुंजियाँ उसे सक्रिय बनाती हैं जबकि फ़ोकस इनपुट में रहता है। नतीजा वह चीज़ है जो आपकी खोज को मिली: एक लिंक, जो ख़ुद फ़ोकस लेता है।
  • टाइप की गई क्वेरी को अपने सुझावों में न जोड़ें: वह काम क्वेरी वाली पंक्ति का है। अगर पंक्ति को बताना हो कि Enter क्या करेगा, तो अपने प्रोडक्ट की भाषा में queryRowText दें (“सारी मेल में खोजें”, “असिस्टेंट से पूछें”)।
  • रूप इस आधार पर चुनें कि खोज किस काम की है। जहाँ Enter को हमेशा टाइप किया गया टेक्स्ट ही खोजना चाहिए, जैसे एड्रेस बार या मेल की खोज में, वहाँ क्वेरी वाली पंक्ति (डिफ़ॉल्ट) रहने दें। जिस खोज पेज पर सुझाव फ़ील्ड के नीचे आते हैं, जैसे वेब सर्च पेज पर, वहाँ queryRow="none" इस्तेमाल करें। जिस खोज की सारी पंक्तियाँ नतीजे हों, जैसे डॉक्यूमेंटेशन की खोज, उसे दोनों में से किसी की ज़रूरत नहीं: Enter उसका पहला नतीजा खोलता है।
  • inlineCompletion सिर्फ़ वहाँ इस्तेमाल करें जहाँ लोग जानी-पहचानी चीज़ें, जैसे पते या नाम, पूरे टाइप करते हैं और कम्प्लीशन से उनकी कुंजियाँ बचती हैं। खोज पेज फ़ील्ड के भीतर पूरा नहीं करते।
  • प्रकारों में फ़र्क़ बताने के लिए शुरुआती आइकन इस्तेमाल करें: पिछली क्वेरी के लिए history, कोई फ़ोल्डर, कोई पेज, कोई सेक्शन।
  • जब सिर्फ़ कुछ पंक्तियों में आइकन हो, तो iconSpace तय करता है कि बाक़ी पंक्तियाँ अपनी हेडलाइन कहाँ से शुरू करें। auto (डिफ़ॉल्ट) तब तक व्यू की हर पंक्ति में आइकन की जगह ख़ाली रखता है जब तक किसी सुझाव या नतीजे में आइकन हो, ताकि हेडलाइनें एक सीध में रहें; always उसे हर पंक्ति में रखता है, और never सिर्फ़ उस पंक्ति में जिसमें आइकन हो। मेन्यू में भी यही iconSpace है, उन्हीं मानों और उसी डिफ़ॉल्ट के साथ।
  • density तय करता है कि व्यू की एक पंक्ति कितनी जगह लेती है: regular (डिफ़ॉल्ट, 56 ऊँची) या compact (32 ऊँची, 20 का ग्लिफ़), कमांड पैलेट या माउस और कीबोर्ड से इस्तेमाल होने वाले टूल के लिए। न बार बदलता है, न टेक्स्ट। छूने पर पंक्ति कभी टच टारगेट से नीची नहीं होती।
  • हेडलाइन छोटी रखें और ब्योरा सहायक टेक्स्ट या अंश में रखें: “इनवॉइस”, फिर “फ़ोल्डर · 24 संदेश”। वे काटे नहीं जाते, अगली पंक्ति में चले जाते हैं।
  • अंश में चिह्नित करें कि क्या मेल खाया। निशान सिस्टम का है, एक रंग, ज़्यादा भारी वेट और मेल खाए हिस्से के पीछे हल्की भराई, इसलिए मेल खाने वाले हिस्से हर जगह एक जैसे दिखते हैं और हर लिपि में मिल जाते हैं, उस फ़ॉन्ट में भी जिसमें सामान्य और बोल्ड के बीच कोई वेट नहीं होता।
  • नतीजों को तब ग्रुप करें जब वे साथ के हों: सेक्शन अपने पेज के नीचे, संदेश “संदेश” के नीचे। जब ग्रुप ख़ुद एक जगह हो, तो उसकी हेडिंग एक लिंक होती है।
  • जब भी किसी नतीजे का कोई पता हो, उसे href दें। तब व्यक्ति उसे नए टैब में खोल सकता है, उसका पता कॉपी कर सकता है और देख सकता है कि वह कहाँ ले जाता है। href के बिना select सिर्फ़ उस नतीजे के लिए इस्तेमाल करें जिसे आपका प्रॉडक्ट ख़ुद खोलता है।
  • व्यू का क्रम तय है: सुझाव, स्थिति पंक्ति, नतीजे, फिर आपका अपना कॉन्टेंट, जैसे “और नतीजे लोड करें” बटन या नतीजों के पूरे पेज का लिंक।
  • जिस डॉक्ड व्यू के पास दिखाने को कुछ नहीं है, वह कुछ नहीं बनाता, और खोज खुली रहती है, इसलिए जैसे ही कुछ होता है वह फिर दिख जाता है।

स्थिति

  • हर जवाब के लिए statusText एक बार सेट करें: “टोकन के लिए 12 नतीजे”, “टोकेन के लिए कोई नतीजा नहीं”। बदलने पर इसे पढ़कर सुनाया जाता है, इसलिए हर कीस्ट्रोक पर इसे बदलना शोर होगा।
  • जब तक क्वेरी चल रही है, status को loading सेट करें। लोडिंग इंडिकेटर थोड़ी देरी के बाद ही दिखता है, इसलिए तेज़ जवाब में वह दिखता ही नहीं।
  • status को error सेट करें, ऐसे टेक्स्ट के साथ जो बताए कि क्या हुआ। इसे त्रुटि के रूप में बनाया जाता है और तुरंत पढ़कर सुनाया जाता है।
  • जो जवाब क्रम से बाहर पहुँचते हैं, उन्हें छोड़ दें। खोज वही बनाती है जो आपने सबसे आख़िर में सेट किया।

शॉर्टकट

  • ऐसा शॉर्टकट इस्तेमाल करें जिसे लोग आपकी तरह के प्रॉडक्ट में खोज के लिए पहले से जानते हैं, और उसे mod के साथ लिखें, ताकि वह हर कीबोर्ड पर सही हो।
  • bindShortcut एक स्क्रीन की एक ही खोज पर सेट करें। एक ही कुंजियाँ बाइंड करने वाली दो खोजों में से, जो पहले दिखाई गई वह उन्हें रखती है, और डीबग बिल्ड दूसरी की रिपोर्ट करते हैं।
  • बिना मॉडिफ़ायर वाला शॉर्टकट, जैसे /, तब अनदेखा किया जाता है जब फ़ोकस किसी टेक्स्ट इनपुट में हो, ताकि व्यक्ति वह अक्षर टाइप कर सके।
  • अगर आप बिना मॉडिफ़ायर वाली एक अक्षर की कुंजी, जैसे /, बाइंड करते हैं, तो लोगों को उसे बंद करने या बदलने का तरीक़ा दें (WCAG 2.1.4, कैरेक्टर की शॉर्टकट)। bindShortcut डिफ़ॉल्ट रूप से बंद रहता है।
  • bindShortcut के बिना संकेत सिर्फ़ कुंजियाँ दिखाता है: उन्हें ख़ुद बाइंड करें, या shortcut को ख़ाली छोड़ दें।

करें

  • ऐसा प्लेसहोल्डर लिखें जो बताए कि क्या खोजा जा सकता है: “मेल खोजें”। label भी सेट करें: प्लेसहोल्डर कभी नाम नहीं होता।
  • क्वेरी बदलने के साथ सुझाव अपडेट करें, और जब व्यक्ति उनमें एक से दूसरे पर जा रहा हो, तो उनका क्रम न बदलें। सबसे मेल खाने वाला सुझाव सबसे ऊपर रखें: एक Down Arrow उस तक पहुँचती है, और inlineCompletion के साथ क्वेरी उसी से पूरी होती है।
  • select पर वही करें जिसका वादा सुझाव करता है: कोई नतीजा खोलें, या बार में क्वेरी रखकर उसे चलाएँ।
  • अंतिम स्लॉट में अधिकतम दो आइकन बटन रखें।
  • जिस नतीजे का target new हो, उसे targetLabel (“नए टैब में खुलता है”) दें।

न करें

  • बार पर सिर्फ़ फ़ोकस आने से व्यू न खोलें। खोज पहले से इससे बचती है; इसे ख़ुद वापस न जोड़ें।
  • डॉक्ड व्यू में ऐसे कंट्रोल न रखें जिन्हें अपना फ़ोकस चाहिए, जैसे टेक्स्ट फ़ील्ड। डॉक्ड व्यू को दबाने पर फ़ोकस इनपुट में ही रहता है।
  • किसी सुझाव के सक्रिय होने पर क्वेरी न बदलें। खोज उसे value बदले और input एमिट किए बिना इनपुट में दिखाती है; क्वेरी सिर्फ़ कोई चुनाव (select), व्यक्ति का टाइप करना या स्वीकार किया गया कम्प्लीशन बदलता है।
  • फ़ॉर्म में कोई मान चुनने के लिए खोज इस्तेमाल न करें।
  • नतीजे का पता सिर्फ़ select में न रखें। href के बिना पंक्ति एक बटन है, और व्यक्ति उसे नए टैब में नहीं खोल सकता।
  • मेल खाने वाले हिस्सों को ख़ुद सिर्फ़ रंग से चिह्नित न करें, और अंश में अनजान स्रोत का मार्कअप न रखें। वेब पर अंश का कॉन्टेंट आपका है: आप वहाँ जो रखते हैं, वह जैसा है वैसा दिखाया जाता है।

सुलभता

रोल
searchbox
लेबलिंग
label names the search field, the trigger, the suggestions' list, the results' list and the modal views; it is never the placeholder. A suggestion is named by its headline and described by its supporting text; a result by its headline and its excerpt, read as one text with no mention of the marks; a result group by its headline. The status text is announced when it changes, and the loading indicator is named by it. The clear and back buttons are named by clearLabel and backLabel; the slots' icon-only Buttons by their own labels. The search glyph, the leading icons, the drawn shortcut keys, the scrim and the divider are decorative; the shortcut is exposed as the trigger's or the input's keyboard shortcut.
न्यूनतम टार्गेट
दिखने वाला आकार छोटा होने पर भी हिट एरिया न्यूनतम टार्गेट साइज़ को पूरा करता है। minimum 32px · pointer 44px · spacing 8px · touch 48px

कीबोर्ड

कुंजियाँ क्रिया
Tab / Shift+Tab Moves focus to the leading icon-only Button, the input, the clear button and the trailing icon-only Buttons in turn, or to the trigger. With the docked view open, leaves the search and closes the view. In a modal view (dialog, full-screen) focus stays inside it and Tab goes through the header's controls, the results and the product's own content.
Enter / Space on the trigger Opens the modal view and moves focus to its input.
The shortcut Where the search binds it (bindShortcut): opens the search from anywhere in the window, and closes it again while it is open.
Typing Edits the value and opens the view while it is closed. With suggestions, the first row is the one Enter takes: the query row — the query as typed, so that Enter searches for it — or, with queryRow none, no row, so that Enter does the same. With results and no suggestions, the first result is current, so that Enter opens it. On an on-screen keyboard (the input focused by a touch or a pen) nothing is, so that its Search or Go key submits the query as typed. With inlineCompletion, the query is completed in the input from the first suggestion that begins with it. While a result has focus, returns focus to the input and edits there.
Down Arrow / Up Arrow Opens the view while it is closed. While it is open, moves through the rows in order: the query row (with queryRow none, the input's own place), the suggestions, then the results, across groups; on a suggestion focus stays in the input, and a result takes focus. Down Arrow goes on from the row Enter takes now, so the first press reaches the second row. A suggestion an arrow key reaches is shown in the input without changing the query, and the query as typed comes back on the query row or the input's place. At the ends they go round — Down on the last row to the first, Up on the first to the last — unless wrap is false, which stops them. The row an arrow key moves to is read out at once; a row the search made current is read once typing pauses for half a second.
Left Arrow, Right Arrow, Home, End Move the caret, and leave the row Enter takes as it is. With an inline completion shown, accept it: the completed query becomes the value.
Backspace / Delete, an inline completion shown Takes the completion away and leaves the query as typed; nothing is completed again until the person types.
Enter In the input: chooses the active suggestion (select) or opens the current result; on the query row, or with no row active, submits the value (submit) — completed first where an inline completion is shown — which closes the view unless it shows results or a status. On an on-screen keyboard nothing is made current by itself, so its Search or Go key submits the value as typed. While an input method is composing, Enter confirms the conversion and does nothing else. With Command (Control off Apple keyboards) or Shift, Enter in the input opens the current result in a new tab or a new window, as the link would with that modifier: nothing is emitted and the view stays. On a result: follows the link, as the platform does, modifier keys included.
Enter / Space on the back button Closes the modal view (dialog, full-screen) and returns focus to the bar's input or the trigger: the way out for a person who has neither Escape nor a pointer.
Escape Closes the view and returns focus to the bar's input or the trigger; while the view is closed, clears the value.

टिप्पणियाँ

  • Two patterns, by what a row is. Suggestions are queries, in the WAI-ARIA combobox pattern with a listbox popup on the web, in every view: focus stays in the input, and the query as typed is always what Enter takes until the person moves. By default (queryRow first) it is a row of its own, first and active, as the first row of a browser's address bar is (list autocomplete with automatic selection); with queryRow none the input itself is that place and nothing is active, as on a web search page (list autocomplete with manual selection). The arrow keys move through the suggestions and show each in the input without changing the query, and go round at the ends unless wrap is false. inlineCompletion completes the query in the input from a suggestion that begins with it, as an address bar does (list and inline autocomplete). A query suggestion draws what it adds to the query heavier; a result marks what matched. Results are destinations: links in a list, never options, in every view: an option cannot be a link, and a result has to be one (open in a new tab, copy the address, the visited color). Where the view holds results and no suggestion, the first result is current while focus stays in the input, drawn as focused and opened by Enter, as a documentation search does; a result takes real focus once the person moves to it, and the input is a combobox only while the view shows suggestions. A row the search made current by itself — the query row, the first result — is announced once typing pauses for half a second, as React Aria's autocomplete does, so that a screen reader reads the typed character first and then what Enter takes, and not a row after every key; a row an arrow key moves to is announced at once. The dialog and full-screen views are modal dialogs that hold the search field and those links, the pattern of a site search; the docked view with suggestions only is the combobox it was. SwiftUI, Compose, Flutter and React Native have no combobox role: their input is a search field, suggestions are buttons and results are buttons with the link trait or role, each with its position in its list.
  • Overlays: the docked view is an operated overlay that is not modal, and its focus is the input it belongs to until an arrow key takes it to a result; the dialog and full-screen views are modal overlays that take focus, keep it and return it to the bar's input or the trigger.
  • The search never runs a query (SRC-51). The product listens to input, waits as long as its index needs before asking (nothing for an index in memory; a few hundred milliseconds for one over the network), drops an answer that arrives after a newer question, sets status to loading only while it truly waits, and sets statusText once per answer, so that the count is announced once.
  • A shortcut is the product's unless bindShortcut is true. The keyboard shortcut component never listens (KBS-14); the search may, because the command the keys perform is its own: open me.
  • Who closes the view: the search emits toggle; where expanded is a binding or controller (SwiftUI, Flutter) or the element's own property (the web) the search closes it itself, and on Compose and React Native the product sets expanded from toggle, as for the menu.
  • The input edits text as the text field does (TXI-1, TXI-4, TXI-20, TXI-24), and its selection is the text field's pair: comp.input-box.selection.color behind the text, comp.input-box.selection.content.color for it.
  • Heights are minimums: at 200% text size the bar and the header grow, the value stays on one line, and suggestion rows wrap.
  • How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
  • WCAG 2.5.8 (target size): for touch every row of the view is at least the touch target high in both densities (SRC-16). The compact density is lower than the pointer target for a fine pointer, by design: it is the density of a tool used with a mouse and the keyboard, it stays above the 24 by 24 the criterion asks, and its rows reach across the view's whole width. A product that cannot accept that uses regular.

इससे जनरेट किया गया: specs/search.spec.json, tokens/sys/measure.tokens.json

कंपोनेंट क्या सँभालता है

  • इनपुट एक खोज फ़ील्ड है, जिसका नाम label से आता है, प्लेसहोल्डर से कभी नहीं, और जहाँ प्लैटफ़ॉर्म के पास खोज का रोल है, वहाँ उसी रोल के साथ।
  • वेब पर डॉक्ड व्यू WAI-ARIA के कॉम्बोबॉक्स पैटर्न पर चलता है। जब तक सुझाव दिखते हैं, इनपुट एक कॉम्बोबॉक्स है, जिसमें aria-autocomplete="list" (inlineCompletion के साथ both), aria-expanded, लिस्ट का नाम देने वाला aria-controls, और सक्रिय विकल्प का नाम देने वाला aria-activedescendant होता है। सुझाव एक लिस्टबॉक्स हैं, जिसका नाम label से आता है: सबसे पहले क्वेरी वाली पंक्ति, जिसका नाम क्वेरी से और विवरण queryRowText से आता है, और फिर हर सुझाव, जिसका नाम उसकी हेडलाइन से और विवरण उसके सहायक टेक्स्ट से आता है। सक्रिय विकल्प ही चुना हुआ विकल्प होता है।
  • जिस पंक्ति को खोज ख़ुद सक्रिय करती है, यानी क्वेरी वाली पंक्ति, उसका नाम सक्रिय डिसेंडेंट के रूप में तब दिया जाता है जब टाइप करना आधा सेकंड रुक जाए, जैसे React Aria का autocomplete करता है: स्क्रीन रीडर पहले टाइप किया गया अक्षर पढ़ता है, फिर वह जो Enter लेगा, और हर कुंजी के बाद कोई पंक्ति नहीं पढ़ता। ऐरो कुंजी जिस पंक्ति पर ले जाती है, उसका नाम तुरंत दिया जाता है। सुझाव का गाढ़ा दिखने वाला जोड़ा हुआ हिस्सा उसकी हेडलाइन के हिस्से के रूप में ही पढ़ा जाता है।
  • डॉक्ड व्यू में फ़ोकस इनपुट में रहता है। व्यू जैसे ही सुझाव दिखाता है, क्वेरी वाली पंक्ति सक्रिय हो जाती है, और क्वेरी या सुझाव हर बार बदलने पर फिर वही सक्रिय होती है; queryRow="none" के साथ कुछ भी सक्रिय नहीं होता, और इनपुट ख़ुद पहले सुझाव से पहले वाली जगह होता है। पहली Down Arrow सक्रिय पंक्ति के बाद वाली पंक्ति पर ले जाती है। जब तक wrap false न हो, सिरों पर कुंजियाँ घूमकर आती हैं। जब कोई सक्रिय पंक्ति आंशिक रूप से व्यू से बाहर हो, तो व्यू उसे स्क्रॉल करके भीतर ले आता है।
  • ऑन-स्क्रीन कीबोर्ड पर कुछ भी अपने-आप सक्रिय नहीं होता, न क्वेरी वाली पंक्ति न नतीजा, और कुछ भी पूरा नहीं किया जाता, इसलिए कीबोर्ड की Search या Go की क्वेरी को वैसे ही सबमिट करती है जैसी टाइप की गई है, जैसे फ़ोन पर सर्च फ़ील्ड करता है; व्यक्ति सुझाव को छूकर चुनता है। जब टच या पेन से इनपुट पर फ़ोकस आता है, तो सर्च कीबोर्ड को ऑन-स्क्रीन मानता है, और ऐरो की, कैरेट हिलाने वाली की या इनपुट पर माउस से दबाने के बाद फिर हार्डवेयर कीबोर्ड मानता है। डिवाइस में टच स्क्रीन होने से यह पता नहीं चलता कि टच स्क्रीन वाले लैपटॉप या कीबोर्ड लगे टैबलेट पर कौन-सा कीबोर्ड इस्तेमाल हो रहा है।
  • जब इनपुट मेथड कंपोज़ कर रहा हो, तब Enter, Escape और ऐरो कुंजियाँ उसी की होती हैं, कुछ भी सक्रिय नहीं होता और कुछ भी पूरा नहीं किया जाता। कन्वर्ज़न पक्का करने वाला Enter कुछ नहीं चुनता, और टेक्स्ट पक्का होने के बाद क्वेरी वाली पंक्ति सक्रिय होती है।
  • फ़ुल-स्क्रीन व्यू और डायलॉग व्यू मोडल डायलॉग हैं, जिनका नाम label से आता है। फ़ोकस हेडर के इनपुट पर जाता है, कैरेट क्वेरी के अंत में रहता है, फ़ोकस व्यू के भीतर रहता है, और बाहर की हर चीज़ निष्क्रिय और छिपी हो जाती है। व्यू बंद होने पर फ़ोकस बार के इनपुट या ट्रिगर पर लौटता है, और व्यू दोबारा नहीं खुलता।
  • ट्रिगर एक बटन है, जिसका नाम label से आता है, और जो बताता है कि वह एक डायलॉग खोलता है और उसका व्यू खुला है या नहीं। वह कीबोर्ड फ़ोकस वैसे ही दिखाता है जैसे बार।
  • डायलॉग के स्क्रिम को दबाने पर वह बंद हो जाता है, और दबाने का असर उसके नीचे की किसी चीज़ तक नहीं पहुँचता। उसका हेडर पीछे जाने के बटन से शुरू होता है, जिस तक Tab पहुँचती है।
  • नतीजे एक लिस्ट हैं, जिसका नाम label से आता है, और ग्रुप का नाम उसकी हेडलाइन से आता है। href वाला नतीजा एक लिंक है, विकल्प कभी नहीं; इनपुट सिर्फ़ तब तक कॉम्बोबॉक्स है जब तक व्यू सुझाव दिखाता है। नतीजे का नाम उसकी हेडलाइन से और विवरण उसके अंश से आता है, और जब वह नए संदर्भ में खुलता है तो उसके बाद targetLabel से।
  • नतीजे हों और सुझाव न हों, तो जब तक फ़ोकस इनपुट में है, पहला नतीजा मौजूदा नतीजा होता है। वह फ़ोकस वाले नतीजे की तरह दिखता है, और इनपुट में Enter उसे वैसे ही खोलता है जैसे उस लिंक पर Enter खोलता। टाइप करना आधा सेकंड रुकने पर उसका लिंक इनपुट का सक्रिय डिसेंडेंट बन जाता है, ताकि स्क्रीन रीडर वह पढ़े जो Enter खोलेगा; इनपुट सर्च बॉक्स ही रहता है। Down Arrow फ़ोकस को दूसरे नतीजे पर, और फिर ग्रुप के पार आगे के नतीजों पर ले जाती है। Command (दूसरे कीबोर्ड पर Control) या Shift के साथ, इनपुट में Enter मौजूदा नतीजे को नए टैब या नई विंडो में खोलता है, जैसे लिंक पर वही दबाना खोलता; कुछ भी नहीं भेजा जाता और व्यू खुला रहता है, ताकि व्यक्ति दूसरा नतीजा भी खोल सके।
  • व्यू में सुझाव हों, तो आख़िरी सुझाव पर Down Arrow फ़ोकस को पहले नतीजे पर ले जाती है, और पहले नतीजे पर Up Arrow आख़िरी सुझाव को सक्रिय करके इनपुट पर लौटाती है। किसी नतीजे पर टाइप करने, मिटाने या पेस्ट करने से फ़ोकस इनपुट पर चला जाता है, जहाँ फिर वह कुंजी अपना काम करती है। मोडल व्यू में Tab नतीजों से वैसे ही गुज़रती है जैसे किसी भी लिंक से।
  • स्थिति पंक्ति एक लाइव रीजन है। statusText बदलने पर पढ़कर सुनाया जाता है, और जब status का मान error हो, तो अलर्ट के रूप में तुरंत। लोड होते समय नतीजे व्यस्त के रूप में चिह्नित होते हैं और लोडिंग इंडिकेटर का नाम statusText से आता है।
  • शॉर्टकट ट्रिगर या इनपुट के कीबोर्ड शॉर्टकट के रूप में दिया जाता है। उसके संकेत को न दबाया जा सकता है, न उस पर फ़ोकस जाता है।
  • इनपुट पर फ़ोकस पहुँचने से व्यू कभी नहीं खुलता, चाहे वह Tab से पहुँचे या फ़ुल-स्क्रीन व्यू से लौटकर।
  • Escape, प्लैटफ़ॉर्म की बैक क्रिया और पीछे जाने का बटन व्यू को बंद करते हैं। डॉक्ड व्यू Tab, Shift+Tab, बाहर दबाने, या फ़ोकस के खोज से बाहर जाने पर भी बंद होता है।
  • मिटाने और पीछे जाने के बटन Tanrei के आइकन बटन हैं, जिनके नाम clearLabel और backLabel से आते हैं। मिटाने के बाद फ़ोकस इनपुट पर लौटता है।
  • leading और trailing स्लॉट के आपके आइकन बटन अपने नाम, रोल और फ़ोकस के पड़ाव बनाए रखते हैं, पढ़ने के क्रम में। वे फ़ुल-स्क्रीन हेडर में नहीं दिखाए जाते।
  • टाइप करना, इनपुट मेथड की कंपोज़िशन, डिक्टेशन और दाएँ से बाएँ वाला टेक्स्ट वैसे ही काम करते हैं जैसे टेक्स्ट फ़ील्ड में। खोज कीबोर्ड की ऐक्शन कुंजी सक्रिय सुझाव या मौजूदा नतीजा लेती है, और क्वेरी वाली पंक्ति पर या दोनों में से कुछ न हो तो क्वेरी सबमिट करती है।
  • बार फ़ोकस को अपने किनारे से दिखाता है, चाहे फ़ोकस कीबोर्ड से आया हो या पॉइंटर से, जैसे फ़ील्ड दिखाता है। सुझाव की पंक्तियाँ सक्रिय रहते हुए पंक्ति के भीतर फ़ोकस रिंग दिखाती हैं। हर पंक्ति और बार न्यूनतम टार्गेट पूरा करते हैं।
  • खोज का ग्लिफ़, शुरुआती आइकन और डिवाइडर सहायक तकनीक से छिपे रहते हैं।
  • बड़े टेक्स्ट साइज़ पर बार और हेडर बढ़ते हैं, क्वेरी एक पंक्ति में रहती है, और सुझाव की पंक्तियाँ अगली पंक्ति में चली जाती हैं।
  • डीबग बिल्ड इन बातों की रिपोर्ट करते हैं: label, clearLabel या backLabel का न होना, सुझाव का ख़ाली या दोहराया हुआ मान, ख़ाली हेडलाइन, अनजान presentation, bar या status, डॉक्ड प्रस्तुति वाला ट्रिगर, वही कुंजियाँ बाइंड करने वाली दूसरी खोज, और दो से ज़्यादा अंतिम बटन।

प्लैटफ़ॉर्म की ज्ञात कमियाँ:

  • SwiftUI, Compose, Flutter और React Native में अभी ट्रिगर, डायलॉग व्यू, नतीजे, स्थिति पंक्ति या शॉर्टकट नहीं हैं। उन प्लैटफ़ॉर्म पर नतीजे व्यू के अपने कॉन्टेंट में दिखाएँ और उनकी संख्या ख़ुद पढ़कर सुनाएँ।
  • SwiftUI, Compose, Flutter और React Native में अभी क्वेरी वाली पंक्ति, इनलाइन कम्प्लीशन और सिरों पर घूमकर आने वाली कुंजियाँ नहीं हैं। वहाँ, जब तक व्यक्ति ऐरो कुंजियों से किसी सुझाव पर नहीं जाता, कुछ भी सक्रिय नहीं होता, तब तक Enter क्वेरी सबमिट करता है, और ऐरो कुंजियाँ सिरों पर रुक जाती हैं।
  • Web: बाइंड किया हुआ शॉर्टकट mod को उस परिपाटी में पढ़ता है जिसमें उसका संकेत लिखा है, यानी जो कोई पूर्वज सेट करता है या नहीं तो प्लैटफ़ॉर्म की, जबकि स्पेक सिर्फ़ प्लैटफ़ॉर्म की परिपाटी का नाम लेता है।
  • SwiftUI, Compose, Flutter और React Native में कॉम्बोबॉक्स या लिस्टबॉक्स का रोल नहीं है। उनका इनपुट एक खोज फ़ील्ड है, और हर सुझाव लिस्ट में अपनी जगह के साथ एक बटन है, जिस तक स्क्रीन रीडर स्वाइप करके पहुँचता है। वहाँ सक्रिय सुझाव इनपुट के सक्रिय डिसेंडेंट के रूप में पढ़कर नहीं सुनाया जाता। Flutter के सुझावों की लिस्ट में कोई जगह भी नहीं है, और SwiftUI और React Native जगह अंग्रेज़ी में बताते हैं (“2 of 3”; React Native का positionText इसे बदलता है)।
  • Flutter इनपुट को खोज इनपुट टाइप के रूप में देता है, खोज बॉक्स के रोल के रूप में नहीं, क्योंकि Flutter 3.32, जो सबसे पुराना वर्शन है जिसे यह सपोर्ट करता है, उस रोल को अस्वीकार करता है।
  • डॉक्ड व्यू के बाहर दबाने पर वह बंद हो जाता है। वेब, SwiftUI, Compose और Flutter पर दबाने का असर उसके नीचे की चीज़ तक भी पहुँचता है; React Native पर नहीं पहुँचता, जैसे मेन्यू के साथ।
  • Web: फ़ुल-स्क्रीन हेडर का इनपुट भी एक कॉम्बोबॉक्स है, इसलिए सक्रिय सुझाव वहाँ भी पढ़कर सुनाया जाता है। स्पेक कॉम्बोबॉक्स का नाम सिर्फ़ डॉक्ड व्यू के लिए लेता है।
  • Web: डॉक्ड व्यू प्लैटफ़ॉर्म के बंद करने के अनुरोध पर, जैसे Android का बैक जेस्चर, बंद नहीं होता। उसे स्क्रिप्ट से रखा जाता है, CSS ऐंकर पोज़िशनिंग से नहीं, जैसा स्पेक का वेब नोट कहता है।
  • अक्षम स्टेट स्लॉट के आइकन बटन तक पहुँचता है, जिन्हें स्पेक उनके अपने स्टेट में छोड़ता है: SwiftUI का .disabled(true) उन्हें भी अक्षम कर देता है, और वेब पर 1 से कम की अक्षम ओपैसिटी उन्हें फीका कर देगी। साथ आने वाले हर सिस्टम की अक्षम ओपैसिटी 1 है।
  • SwiftUI डॉक्ड व्यू को उस चीज़ के ऊपर बनाता है जो खोज का अपना कंटेनर उसके बाद रखता है, विंडो के हर व्यू के ऊपर नहीं। खोज को उसके कंटेनर में बाद में रखें, या उसे zIndex से ऊपर उठाएँ। macOS पर विंडो की ऊँचाई नहीं पढ़ी जाती, इसलिए व्यू हमेशा नीचे की ओर अपनी स्वाभाविक ऊँचाई पर खुलता है, और फ़ुल-स्क्रीन व्यू विंडो जितनी बड़ी एक शीट है।
  • SwiftUI: चयन का हाइलाइट कैरेट के टिंट के साथ चलता है, टेक्स्ट फ़ील्ड के चयन के रंग के साथ नहीं। बिना फ़ोकस वाले इनपुट पर पहला टैप कैरेट को क्वेरी के अंत में रखता है, वहाँ नहीं जहाँ टैप हुआ। कुंजियाँ सिर्फ़ macOS पर जाँची गई हैं, iOS पर हार्डवेयर कीबोर्ड के साथ नहीं।
  • Compose बारीक पॉइंटर और टच में फ़र्क़ नहीं कर सकता, इसलिए उसकी सुझाव की पंक्तियाँ हमेशा 48 ऊँची होती हैं, जबकि वेब की पंक्तियाँ माउस के साथ 44 की होती हैं। डॉक्ड व्यू के बाहर दबाना उसके टेस्ट की पहुँच में नहीं है।
  • Flutter: जिस डॉक्ड व्यू को प्रॉडक्ट expand() से तब खोलता है जब इनपुट पर फ़ोकस नहीं है, वह बाहर दबाने से बंद नहीं होता। फ़ुल-स्क्रीन व्यू को एक Navigator चाहिए; उसके बिना व्यू डॉक्ड रहता है।
  • React Native: डॉक्ड व्यू तब रखा जाता है जब वह खुलता है और जब विंडो या कीबोर्ड बदलता है, पर स्क्रॉल होते बार के साथ नहीं चलता। Escape, ऐरो कुंजियाँ और Tab सिर्फ़ वहीं पहुँचती हैं जहाँ TextInput उन्हें पहुँचाता है, और ओवरले और फ़ुल-स्क्रीन व्यू में फ़ोकस का आना-जाना अभी किसी डिवाइस पर नहीं जाँचा गया है।
  • cupertino में बार फ़ोकस का कोई किनारा नहीं बनाता, क्योंकि iOS का खोज फ़ील्ड फ़ोकस को सिर्फ़ अपने कैरेट और कीबोर्ड से दिखाता है।
  • m3-like में खोज डिफ़ॉल्ट सिस्टम के मान बनाती है: Material के खोज वाले मान तब तक रुके हैं जब तक फ़िडेलिटी रेफ़रेंस उसे शामिल नहीं करता। Material का वह डॉक्ड व्यू, जो बार से एक ही सरफ़ेस के रूप में बढ़कर निकलता है, बार के नीचे एक अलग सरफ़ेस के रूप में बनाया जाता है (मिमिक्री गैप search-docked-view-joins-bar)।

आपको क्या करना है

  • खोज को एक label दें, और clearLabel और, डायलॉग और फ़ुल-स्क्रीन के लिए, backLabel दें, अपने प्रॉडक्ट की भाषा में।
  • मौजूदा क्वेरी के लिए सुझाव दें, ऐसी हेडलाइन के साथ जो अकेले पढ़े जाने पर भी समझ आएँ।
  • आपकी खोज को क्या मिला, यह statusText में कहें, अपने प्रॉडक्ट की भाषा में, हर जवाब के लिए एक बार। खोज उसे पढ़कर सुनाती है; वह नतीजे ख़ुद नहीं गिनती।
  • क्वेरी ख़ुद चलाएँ, और जो जवाब क्रम से बाहर पहुँचते हैं उन्हें छोड़ दें।
  • जिस भी नतीजे का कोई पता है, उसे href दें, और जब वह नए संदर्भ में खुलता हो तो targetLabel भी।
  • शॉर्टकट की कुंजियाँ बाइंड करें, या bindShortcut सेट करें। जो कुंजियाँ कुछ नहीं करतीं, उनका संकेत गुमराह करता है।
  • तय करें कि select क्या करता है, और अगर किसी चुनाव को क्वेरी भरनी चाहिए तो क्वेरी ख़ुद सेट करें।
  • Compose और React Native पर expanded को कॉलबैक से सेट करें, वरना व्यू न खुलेगा, न बंद होगा।
  • वेब पर खोज की क्वेरी को फ़ॉर्म के साथ सबमिट करने के लिए उसे एक name दें।