Native डुअल रेंज इनपुट
(muffinman.io)@stanko/dual-range-inputदो native HTML range input को जोड़कर एक डुअल-रेंज स्लाइडर बनाता है, और ब्राउज़र के डिफ़ॉल्ट interaction व accessibility का ज्यों-का-त्यों उपयोग करता है- इसका implementation मुख्य रूप से input values को sync करने वाले लगभग 50 lines of JavaScript और CSS पर आधारित है, इसलिए drag और accessibility को सीधे दोबारा बनाने वाले पुराने तरीकों की तुलना में यह अधिक सरल है
- दोनों inputs का
min,maxऔर width चुने गए values के midpoint के अनुसार अपडेट होते हैं, और track पर click करने पर जो thumb ज्यादा पास होता है वह उस value पर चला जाता है - चूंकि range input का track वास्तविक input width से छोटा होता है, implementation में calculation में thumb width जोड़ी जाती है और wrapper padding से अतिरिक्त width को absorb किया जाता है
- theme को CSS variables और gradient से समायोजित किया जा सकता है, इसलिए selected range color, thumb size और track color आदि को override किया जा सकता है
Native range input से बना डुअल स्लाइडर
@stanko/dual-range-inputदो HTML range input को साथ-साथ रखकर डुअल रेंज इनपुट लागू करता है- यहां “native” का मतलब एक single browser control नहीं है, बल्कि दो range input का उपयोग करके ब्राउज़र के default interaction और accessibility features को बनाए रखना है
- implementation input को sync करने वाले लगभग 50 lines of JavaScript और visual polish के लिए CSS से बना है
- इसकी शुरुआत इस ज़रूरत से हुई कि एक generative drawing tool में parameters के minimum और maximum values को adjust करने वाला UI चाहिए था
- requirements दो थीं
- native HTML range input का उपयोग करना
- track पर click करने पर, दो thumbs में से click point के ज्यादा करीब वाला thumb उस value पर चला जाए
Value sync और click handling
- जब दो inputs में से कोई एक बदलता है, लाइब्रेरी चुनी गई दो values के बीच का midpoint calculate करती है
- हर input के
minऔरmaxattributes को midpoint के अनुसार सेट किया जाता है - दोनों inputs की width भी midpoint के आधार पर अपडेट की जाती है
- हर input के
- inputs का size इस तरह adjust किया जाता है कि वे midpoint पर मिलें, इसलिए दो thumbs के बीच click करने पर click position के करीब वाला thumb move होता है
- अगर दो thumbs के बीच step की संख्या odd हो, तो आख़िरी बार उपयोग किया गया input प्राथमिकता पाता है
CSS calculations और styling
- range input का track पूरे input width से छोटा होता है, और ब्राउज़र दोनों तरफ़ कुछ जगह छोड़ता है ताकि thumb बाहर न निकले
- अगर input width को बस 25% और 75% की तरह बांट दिया जाए, तो वास्तविक track ratio सही नहीं बैठता
- implementation हर input width में
--dri-thumb-widthजोड़ता है, और extra width को संभालने के लिए wrapper में padding जोड़ता है
- styling ब्राउज़र की range input CSS styling capabilities का उपयोग करती है
- track और thumb को style किया जाता है, और बीच के उस हिस्से में जहां दोनों tracks मिलते हैं, border radius न बने यह सुनिश्चित किया जाता है
- theme को CSS variable override से बनाया जा सकता है
- मुख्य variables में
--dri-height,--dri-thumb-width,--dri-thumb-color,--dri-track-color,--dri-track-filled-color,--dri-track-border-radiusआदि शामिल हैं
- मुख्य variables में
- चुनी हुई range को CSS gradient से भरा जाता है
- gradient position को
--dri-gradient-positionvariable से सेट किया जाता है - code में input width अपडेट करते समय यह variable भी साथ में अपडेट किया जाता है
- gradient position को
- यह implementation drag और accessibility को custom library से दोबारा बनाने के बजाय, जहां तक संभव हो पहले native elements का उपयोग करने वाला approach है
1 टिप्पणियां
Hacker News की टिप्पणियाँ
मेरे हिसाब से इस तरह के slider में बीच वाला क्षेत्र भी हमेशा drag किया जा सकना चाहिए। यानी बीच से पकड़ने पर दोनों handles साथ-साथ move होने चाहिए
संदर्भ के लिए, Unity इसे ऐसे handle करता है: https://docs.unity3d.com/StaticFiles/ScriptRefImages/EditorG...
“हमेशा” शायद थोड़ा ज़्यादा strong शब्द हो सकता है
मैं लेखक हूँ। इसे HN पर देखकर अच्छा लगा
देखा कि लोग यहाँ issues और bug reports छोड़ने लगे हैं, और यहाँ काफी देर हो चुकी है, इसलिए कल देखूँगा
मैंने इसे generative image work के लिए बनाया था, क्योंकि मुझे numbers enter करने के बजाय slider drag करते हुए यह देखना ज़्यादा पसंद है कि image कैसे बदलती है
मैंने इसे जितना हो सके minimal रखने की कोशिश की
अभी मैं SwiftUI इस्तेमाल कर रहा हूँ, जहाँ अपना component बनाना लगभग बहुत ही आसान है। लेकिन जैसा लेखक ने समझाया, वह हमेशा best option नहीं होता, और native components अक्सर काफी feature-rich होते हैं
मैंने article को iOS के Firefox जैसे थोड़े unusual browser में भी check किया, और यह ठीक चला। बहुत बढ़िया काम
इसे इस्तेमाल करके देखते ही एक bug मिल गया। slider को 100 - 100 तक drag करने के बाद अगर 99 - 99 बनाना चाहें, तो नहीं होता
99 - 100 से भी वहाँ नहीं जा सकते, और 98 - 99 से भी नहीं जा सकते। 99 - 99 तक पहुँचने का इकलौता तरीका है lower bound को 98 से भी नीचे खींचना
98 - 99 की स्थिति में अगर 97 - 99 तक नीचे ले जाएँ, तब 99 - 99 पर जा सकते हैं
यह bug कहीं भी हो सकता है; 99 - 99 slider के end के पास है इसलिए बस सबसे आसानी से reproduce हुआ। आम तौर पर किसी भी X - X state में अगर एक end को 1 step move करते हैं, तो दूसरे end को उस gap में नहीं खींच सकते। gap बंद करने के लिए पहले दूसरे end को और दूर खींचना पड़ता है
report के लिए धन्यवाद, इसे ज़रूर fix करूँगा
लेकिन एक दूसरा visual bug है। 23-25 से शुरू करके 24-25 पर drag करें, तो 25 पर मौजूद right handle कुछ pixels move करता है। left handle को वापस 23 पर लाएँ तो right handle भी वापस आ जाता है
शानदार! मुझे हमेशा लगता था कि HTML input में दो-value range input implementation की ज़रूरत है, क्योंकि यह काफी sense बनाता है
उदाहरण के लिए, “मैं ऐसे products filter करना चाहता हूँ जिनमें widgets कम से कम X और अधिकतम Y हों” जैसा use case है
हालांकि Firefox में एक bug मिला जिसे highlight करना चाहूँगा। minimum या maximum handle पर click करने पर हर बार value एक step ऊपर या नीचे बदल जाती है
अगर handle के बिल्कुल center पर click करने की कोशिश करें तो value नहीं बदलती, लेकिन थोड़ा left click करें तो selected value एक step घटती है और थोड़ा right click करें तो बढ़ती है
expected behavior यह है कि value तभी बदले जब button दबाए रखते हुए mouse pointer को सचमुच move करने जैसा explicit change action किया जाए
Firefox ऐसे click को track पर direct click की तरह interpret करता है। यह library उसमें बिल्कुल दखल नहीं देती; यह बस Firefox का behavior है
यह बढ़िया है कि यह keyboard से काम करता है। सही तरह से काम करता है, इसलिए Shift-Tab दबाए रखें तो पीछे भी जा सकते हैं
सच में अच्छी तरह बनाया गया है, और यह बहुत छोटी बात है, लेकिन उस interaction को सही implement करने के लिए धन्यवाद
हमारी company के design system में भी एक intern ने इसी तरह side-by-side रखा हुआ proof of concept बनाया था, लेकिन एक input के pixels थोड़ा-थोड़ा jump करते रहते थे और आखिरकार हम इसे ठीक से नहीं बना पाए
इसलिए दूसरे intern ने overlapping input range के 2 elements इस्तेमाल करने वाला solution निकाला
जब भी range input की ज़रूरत होती थी, मैं jQuery UI slider इस्तेमाल करता था, और सिर्फ एक slider के लिए page में jQuery और jQuery UI जोड़ने पड़ते थे। यह सच में अच्छा है
edit: क्या ESM module के बजाय सीधे इस्तेमाल की जा सकने वाली plain JS file prebuild करके देने की संभावना है?
"export default"line हटा देंhttps://cdn.jsdelivr.net/npm/@stanko/dual-range-input@0.9.8/...
CSS भी न भूलें
https://cdn.jsdelivr.net/npm/@stanko/dual-range-input@0.9.8/...
पता नहीं bugs यहाँ report करना ठीक है या नहीं। पहले दो examples के handles touch interaction को intercept करके scrolling रोक देते हैं। बाद के तीन examples में ऐसा नहीं होता
इसके side effect के तौर पर, उंगली के नीचे वाला label दिखाने के लिए ऊपर drag नहीं कर सकते, और page scroll हो जाता है जिससे label उंगली के नीचे ही बना रहता है
जानना चाहूँगा कि आप कौन-सा browser और operating system इस्तेमाल कर रहे हैं। यह library native input इस्तेमाल करती है, इसलिए scrolling block करने को लेकर कुछ नहीं करती
मेरे iOS phone पर, styling लागू हो या न हो, सभी
input[type=range]elements पर scrolling block होती है[1] https://github.com/Stanko/dual-range-input/issues
“native” वाला हिस्सा debateable है। कहा गया है कि library दो native HTML range inputs इस्तेमाल करती है, इसलिए native interaction और accessibility features preserved रहते हैं, लेकिन मेरा standard साफ है
अगर intended तरीके से काम करने के लिए JavaScript की ज़रूरत है, तो वह अब native नहीं है
फिर भी लेखक का intent समझ आता है। JS से चलने वाले divs का ढेर खुद implement करने के बजाय उन्होंने regular sliders को combine किया, इसलिए यह native solution के काफी करीब है। अगर smart CSS से JavaScript को replace नहीं किया जा सकता, तो शायद यह जितना संभव हो उतना करीब तरीका है
native है या नहीं, इससे अलग, ऐसे widgets उपलब्ध हों तो बहुत useful हैं और इस area में implementations की कमी थी
popoverattribute आने से पहले JavaScript के बिना इसे खोलना संभव ही नहीं थाऔर form validation जैसे मामलों में browser के internal validation tools बिल्कुल इस्तेमाल न करने वाली libraries से अलग समझे जाने लायक native vanilla JavaScript methods भी हैं
https://spodj.intermer.net/ बनाते समय मैं कुछ ऐसा ही ढूँढ रहा था
ज़रूरी functionality पाने के लिए मुझे React का थोड़ा बेढंगा इस्तेमाल करना पड़ा, क्योंकि मैं frontend development में अच्छा नहीं हूँ