व्यवहार
प्रकार के दो चुनाव — दबाने का जवाब कैसे दिया जाता है और कीबोर्ड फ़ोकस कैसा दिखता है — जिन्हें डिज़ाइन सिस्टम किसी भी दूसरे टोकन की तरह तय करता है।
एक डिज़ाइन सिस्टम को दूसरे से अलग करने वाली लगभग हर चीज़ एक मात्रा है: कोई रेडियस, कोई टोन, कोई अवधि। मात्राएँ मान हैं, और लेयर उन्हें बदलती है।
कुछ अंतर मात्रा के नहीं होते। एक सिस्टम दबाने का जवाब रिपल से देता है और दूसरा कंट्रोल को धुँधला कर देता है; एक फ़ोकस वाले कंट्रोल के चारों ओर सख़्त रिंग बनाता है और दूसरा नरम चमक। किसी मौजूदा टोकन पर कोई भी संख्या एक को दूसरे में नहीं बदल सकती। Tanrei इन्हें प्रकार के चुनाव कहता है और sys.behavior के अंतर्गत दो टोकन के रूप में रखता है। हर टोकन व्यवहार के तरीक़ों की एक छोटी, बंद सूची देता है, और डिज़ाइन सिस्टम उनमें से एक चुनता है।
| डिज़ाइन सिस्टम | pressed-feedback | focus-style |
|---|---|---|
tanrei | overlay | ring |
cupertino | dim | ring |
m3-expressive-like | ripple | ring |
m3-like | ripple | ring |
इससे जनरेट किया गया: tokens/systems/*.system.json, design/tokens/<system>/tanrei.light.tokens.json
कंपोनेंट ये टोकन पढ़ते हैं। वे कभी यह नहीं देखते कि कौन-सा डिज़ाइन सिस्टम सक्रिय है।
tanrei.sys.behavior.pressed-feedback
How a press is answered. overlay: the pressed tokens apply to the whole container at once. ripple: the pressed state layer grows from the point of contact. dim: the pressed opacity applies to the whole control and no state layer is drawn. none: no visual answer to a press (focus and hover still apply).
इससे जनरेट किया गया: tokens/sys/behavior.tokens.json
| मान | दबाए जाने के दौरान कंपोनेंट क्या बनाता है |
|---|---|
overlay |
दबाए हुए स्टेट के टोकन पूरे कंटेनर पर एक साथ लागू होते हैं। |
ripple |
दबाए हुए स्टेट की स्टेट लेयर संपर्क के बिंदु से फैलती है — दबाना कीबोर्ड से हो तो केंद्र से — और कंटेनर के शेप में क्लिप होती है। |
dim |
कंपोनेंट की दबाए हुए स्टेट की ओपैसिटी पूरे कंट्रोल पर लागू होती है। कोई स्टेट लेयर नहीं बनती। |
none |
कुछ नहीं। होवर और फ़ोकस फिर भी दिखते हैं। |
यह चुनाव सिर्फ़ यह तय करता है कि दबाए हुए स्टेट की लेयर कैसे प्रकट होती है। उसका रंग और ओपैसिटी अब भी कंपोनेंट के हर स्टेट के टोकन से आते हैं, जिनके मान लेयर पहले की तरह तय करती है।
चुनाव जो भी हो, दबाया हुआ स्टेट बिना देरी के प्रकट होता है और कम से कम sys.motion.duration.press-hold तक दिखता रहता है (डिफ़ॉल्ट रूप से 100ms, जो मोशन डायल के अनुसार चलता है)। एक टैप या कुंजी का दबना एक फ़्रेम के भीतर ख़त्म हो जाता है; इस न्यूनतम अवधि के बिना जवाब दिख ही नहीं पाता। Button इसे आवश्यकता BTN-8 और BTN-9 के रूप में कहता है।
कोना सीधे किनारे में कैसे ढलता है, यह प्रकार का चुनाव लगता है — गोलाकार या सतत — पर यह एक मात्रा है: Figma की कॉर्नर स्मूदिंग, 0 से 1 तक, जिसमें 0.6 iOS का कोना है। यह उन्हीं रेडियस के साथ रहती है जिन्हें यह आकार देती है, sys.shape.corner-smoothing के रूप में, और इसका वर्णन शेप पेज पर है।
tanrei.sys.behavior.focus-style
How keyboard focus is shown. ring: the two-tone focus ring at sys.focus offset and width. glow: the same colors as a soft halo (blurred by the ring width) instead of a hard line. Both must meet the focus contrast invariants.
इससे जनरेट किया गया: tokens/sys/behavior.tokens.json
glow उन्हीं दो फ़ोकस रंगों, ऑफ़सेट और चौड़ाई से बनता है जिनसे रिंग बनती है, इसलिए फ़ोकस के कंट्रास्ट इनवेरिएंट उस पर बिना बदलाव के लागू होते हैं। यह इंडिकेटर के किनारे को बदलता है, इस बात को नहीं कि इंडिकेटर है या नहीं।
हर सिस्टम के अंतर्गत वही Button, जिसे इंस्टॉल किया गया वेब बिल्ड बनाता है। हर एक को दबाएँ, फिर Tab से उस तक पहुँचें।
दबाएँ, फिर Tab दबाएँ
tanrei overlay · ring
cupertino dim · ring
m3-expressive-like ripple · ring
m3-like ripple · ring
चुनाव किसी भी मान की तरह बदला जाता है: tokens के अंतर्गत, एक reason के साथ।
{
"id": "acme",
"extends": "tanrei",
"tokens": {
"tanrei.sys.behavior.pressed-feedback": { "$value": 1, "reason": "Acme दबाने का जवाब रिपल से देता है।" },
"tanrei.sys.behavior.focus-style": { "$value": 1, "reason": "Acme कीबोर्ड फ़ोकस को चमक के रूप में दिखाता है।" }
}
}$value एक संख्या है: टोकन की सूची में उस नाम की जगह, 0 से गिनकर। pressed-feedback के लिए सूची overlay, ripple, dim, none है, इसलिए 1 का मतलब ripple है। Tanrei की टोकन फ़ाइलें जिस फ़ॉर्मैट में हैं (DTCG 2025.10), उसमें स्ट्रिंग टाइप नहीं है, इसीलिए फ़ाइल में इंडेक्स रखा जाता है। सूची से बाहर का इंडेक्स बिल्ड अस्वीकार कर देता है।
संख्या लेयर फ़ाइल में ही रहती है। जनरेट की गई CSS में नाम होता है (--tanrei-sys-behavior-pressed-feedback: ripple), और SwiftUI, Compose, Flutter और React Native को सिस्टम इंस्टेंस पर एक टाइप किया हुआ एन्यूमरेशन मिलता है।
सूचियाँ ख़ुद कोर शब्दावली का हिस्सा हैं। लेयर नामों में से चुनती है; वह कोई नाम जोड़ नहीं सकती। व्यवहार का नया तरीक़ा हर प्लैटफ़ॉर्म को बनाना पड़ता है, इसलिए शब्दावली के किसी भी दूसरे बदलाव की तरह उसका प्रस्ताव कोर के लिए रखा जाता है।
हर सूची का पहला नाम डिफ़ॉल्ट है, और वही फ़ॉलबैक भी है। जो प्लैटफ़ॉर्म कोई चुनाव नहीं बना सकता, वह उसकी जगह पहला मान बनाता है और अपने पैकेज के README में यह बात लिखता है।
टिप्पणी
इंडेक्स हाथ से लिखना अटपटा है, इसलिए Theme Studio (Behaviour ग्रुप), tanrei explain और MCP सर्वर नाम दिखाते और स्वीकार करते हैं।