Nordhealth, वेब कॉम्पोनेंट में कस्टम प्रॉपर्टी का इस्तेमाल कैसे करती है

डिज़ाइन सिस्टम और कॉम्पोनेंट लाइब्रेरी में कस्टम प्रॉपर्टी का इस्तेमाल करने के फ़ायदे.

David Darnes
David Darnes

मेरा नाम डेव है और मैं Nordhealth में सीनियर फ़्रंट-एंड डेवलपर हूं. मैं डिज़ाइन सिस्टम Nord के डिज़ाइन और डेवलपमेंट पर काम करती हूं. इसमें हमारी कॉम्पोनेंट लाइब्रेरी के लिए वेब कॉम्पोनेंट बनाना शामिल है. हमने सीएसएस कस्टम प्रॉपर्टी का इस्तेमाल करके, वेब कॉम्पोनेंट की स्टाइल से जुड़ी समस्याओं को कैसे हल किया, इस बारे में हम आपको बताना चाहते हैं. साथ ही, डिज़ाइन सिस्टम और कॉम्पोनेंट लाइब्रेरी में कस्टम प्रॉपर्टी का इस्तेमाल करने के कुछ अन्य फ़ायदों के बारे में भी बताना चाहते हैं.

हम वेब कॉम्पोनेंट कैसे बनाते हैं

अपने वेब कॉम्पोनेंट बनाने के लिए, हम Lit का इस्तेमाल करते हैं. यह एक लाइब्रेरी है, जो स्टेटस, स्कोप वाली स्टाइल, टेंप्लेट बनाने की सुविधा वगैरह जैसे कई बोइलरप्लेट कोड उपलब्ध कराती है. Lit न सिर्फ़ हल्का है, बल्कि इसे नेटिव JavaScript एपीआई पर भी बनाया गया है. इसका मतलब है कि हम कोड का एक छोटा बंडल डिलीवर कर सकते हैं, जो ब्राउज़र में पहले से मौजूद सुविधाओं का फ़ायदा लेता है.


import {html, css, LitElement} from 'lit';

export class SimpleGreeting extends LitElement {
  static styles = css`:host { color: blue; font-family: sans-serif; }`;

  static properties = {
    name: {type: String},
  };

  constructor() {
    super();
    this.name = 'there';
  }

  render() {
    return html`

Hey ${this.name}, welcome to Web Components!

`
; } } customElements.define('simple-greeting', SimpleGreeting);
Lit की मदद से लिखा गया वेब कॉम्पोनेंट.

हालांकि, वेब कॉम्पोनेंट की सबसे खास बात यह है कि वे किसी भी मौजूदा JavaScript फ़्रेमवर्क के साथ काम करते हैं. इसके अलावा, वे बिना किसी फ़्रेमवर्क के भी काम करते हैं. पेज में मुख्य JavaScript पैकेज का रेफ़रंस देने के बाद, वेब कॉम्पोनेंट का इस्तेमाल करना, नेटिव एचटीएमएल एलिमेंट का इस्तेमाल करने जैसा ही होता है. टैग में लगातार हाइफ़न का इस्तेमाल होने से पता चलता है कि यह नेटिव एचटीएमएल एलिमेंट नहीं है. यह ब्राउज़र को यह बताने के लिए स्टैंडर्ड है कि यह एक वेब कॉम्पोनेंट है.

शैडो डीओएम स्टाइल एनकैप्सुलेशन

जिस तरह नेटिव एचटीएमएल एलिमेंट में शैडो डीओएम होता है उसी तरह वेब कॉम्पोनेंट में भी होता है. शैडो डीओएम, किसी एलिमेंट में मौजूद नोड का छिपा हुआ ट्री होता है. इसे विज़ुअलाइज़ करने का सबसे अच्छा तरीका यह है कि आप अपना वेब इंस्पेक्टर खोलें और "शैडो DOM ट्री दिखाएं" विकल्प को चालू करें. ऐसा करने के बाद, इंस्पेक्टर में नेटिव इनपुट एलिमेंट देखें. अब आपके पास उस इनपुट को खोलने और उसमें मौजूद सभी एलिमेंट देखने का विकल्प होगा. इसे हमारे किसी वेब कॉम्पोनेंट के साथ भी आज़माया जा सकता है. इसके लिए, हमारे कस्टम इनपुट कॉम्पोनेंट का शैडो डीओएम देखें.

DevTools में जांचा गया शैडो डीओएम.
सामान्य टेक्स्ट इनपुट एलिमेंट और हमारे Nord इनपुट वेब कॉम्पोनेंट में शैडो डीओएम का उदाहरण.

शैडो डीओएम का एक फ़ायदा (या नुकसान, आपके नज़रिए के हिसाब से) स्टाइल को छोटा करके दिखाना है. अगर वेब कॉम्पोनेंट में सीएसएस लिखी जाती है, तो वे स्टाइल बाहर नहीं निकल सकतीं और न ही मुख्य पेज या अन्य एलिमेंट पर असर डाल सकती हैं. वे पूरी तरह से कॉम्पोनेंट में मौजूद होती हैं. इसके अलावा, मुख्य पेज या पैरंट वेब कॉम्पोनेंट के लिए लिखी गई सीएसएस, आपके वेब कॉम्पोनेंट में लीक नहीं हो सकती.

स्टाइल को इस तरह से कवर करना, हमारी कॉम्पोनेंट लाइब्रेरी के लिए फ़ायदेमंद है. इससे हमें इस बात की ज़्यादा गारंटी मिलती है कि जब कोई व्यक्ति हमारे किसी कंपोनेंट का इस्तेमाल करेगा, तो वह वैसा ही दिखेगा जैसा हमने सोचा है. भले ही, पैरंट पेज पर कोई भी स्टाइल लागू की गई हो. साथ ही, हम अपने सभी वेब कॉम्पोनेंट के रूट या "होस्ट" में all: unset; जोड़ते हैं, ताकि यह पक्का किया जा सके कि वे सभी वेब कॉम्पोनेंट, एक ही वेब पेज पर मौजूद हों.


:host {
  all: unset;
  display: block;
  box-sizing: border-box;
  text-align: start;
  /* ... */
}
शैडो रूट या होस्ट सिलेक्टर पर कॉम्पोनेंट का कुछ बोइलरप्लेट कोड लागू किया जा रहा है.

हालांकि, अगर आपके वेब कॉम्पोनेंट का इस्तेमाल करने वाले किसी व्यक्ति के पास कुछ स्टाइल बदलने की सही वजह है, तो क्या होगा? शायद टेक्स्ट की किसी लाइन को उसके कॉन्टेक्स्ट की वजह से ज़्यादा कंट्रास्ट की ज़रूरत हो या बॉर्डर को ज़्यादा मोटा करना पड़े? अगर आपके कॉम्पोनेंट में कोई स्टाइल नहीं जोड़ी जा सकती, तो स्टाइल के उन विकल्पों को कैसे अनलॉक किया जा सकता है?

ऐसे में, सीएसएस कस्टम प्रॉपर्टी का इस्तेमाल किया जा सकता है.

सीएसएस कस्टम प्रॉपर्टी

कस्टम प्रॉपर्टी का नाम बहुत सही तरीके से रखा गया है—ये सीएसएस प्रॉपर्टी हैं, जिन्हें पूरी तरह से खुद नाम दिया जा सकता है और ज़रूरत के मुताबिक वैल्यू लागू की जा सकती है. इसके लिए ज़रूरी है कि आप उन्हें दो हाइफ़न से पहले लगाएं. कस्टम प्रॉपर्टी का एलान करने के बाद, var() फ़ंक्शन का इस्तेमाल करके, सीएसएस में वैल्यू का इस्तेमाल किया जा सकता है.


:root {
  --n-color-accent: rgb(53, 89, 199);
  /* ... */
}

.n-color-accent-text {
  color: var(--n-color-accent);
}
हमारे सीएसएस फ़्रेमवर्क में, कस्टम प्रॉपर्टी के तौर पर डिज़ाइन टोकन का उदाहरण और हेल्पर क्लास पर इसका इस्तेमाल किया जा रहा है.

इनहेरिटेंस की बात करें, तो सभी कस्टम प्रॉपर्टी इनहेरिट की जाती हैं. ये सामान्य सीएसएस प्रॉपर्टी और वैल्यू के सामान्य व्यवहार का पालन करती हैं. पैरंट एलिमेंट या एलिमेंट पर लागू की गई किसी भी कस्टम प्रॉपर्टी का इस्तेमाल, अन्य प्रॉपर्टी की वैल्यू के तौर पर किया जा सकता है. हम अपने डिज़ाइन टोकन के लिए कस्टम प्रॉपर्टी का ज़्यादा से ज़्यादा इस्तेमाल करते हैं. इसके लिए, हम उन्हें अपने सीएसएस फ़्रेमवर्क के ज़रिए रूट एलिमेंट पर लागू करते हैं. इसका मतलब है कि पेज पर मौजूद सभी एलिमेंट इन टोकन वैल्यू का इस्तेमाल कर सकते हैं. भले ही, वे वेब कॉम्पोनेंट, सीएसएस हेल्पर क्लास हों या कोई डेवलपर, जो टोकन की हमारी सूची से कोई वैल्यू चुनना चाहता हो.

var() फ़ंक्शन का इस्तेमाल करके, कस्टम प्रॉपर्टी को इनहेरिट करने की सुविधा की मदद से, हम अपने वेब कॉम्पोनेंट के शैडो डीओएम को ऐक्सेस करते हैं. साथ ही, डेवलपर को हमारे कॉम्पोनेंट को स्टाइल करते समय ज़्यादा बेहतर तरीके से कंट्रोल करने की सुविधा देते हैं.

Nord वेब कॉम्पोनेंट में कस्टम प्रॉपर्टी

जब भी हम अपने डिज़ाइन सिस्टम के लिए कोई कॉम्पोनेंट डेवलप करते हैं, तो हम उसकी सीएसएस के लिए सोच-समझकर काम करते हैं. हमारा मकसद, कम से कम कोड का इस्तेमाल करना है, लेकिन उसे आसानी से मैनेज किया जा सके. हमारे पास मौजूद डिज़ाइन टोकन, रूट एलिमेंट पर हमारे मुख्य सीएसएस फ़्रेमवर्क में कस्टम प्रॉपर्टी के तौर पर तय किए गए हैं.


:root {
  --n-space-m: 16px;
  --n-space-l: 24px;
  /* ... */
  --n-color-background: rgb(255, 255, 255);
  --n-color-border: rgb(216, 222, 228);
  /* ... */
}
रूट सिलेक्टर पर सीएसएस कस्टम प्रॉपर्टी तय की जा रही हैं.

इसके बाद, इन टोकन वैल्यू का रेफ़रंस हमारे कॉम्पोनेंट में दिया जाता है. कुछ मामलों में, हम सीधे सीएसएस प्रॉपर्टी पर वैल्यू लागू करेंगे. हालांकि, अन्य मामलों में, हम एक नई कॉन्टेक्स्टल कस्टम प्रॉपर्टी तय करेंगे और उस पर वैल्यू लागू करेंगे.


:host {
  --n-tab-group-padding: 0;
  --n-tab-list-background: var(--n-color-background);
  --n-tab-list-border: inset 0 -1px 0 0 var(--n-color-border);
  /* ... */
}

.n-tab-group-list {
  box-shadow: var(--n-tab-list-border);
  background-color: var(--n-tab-list-background);
  gap: var(--n-space-s);
  /* ... */
}
कस्टम प्रॉपर्टी, कॉम्पोनेंट के शैडो रूट पर तय की जा रही हैं. इसके बाद, कॉम्पोनेंट स्टाइल में उनका इस्तेमाल किया जा रहा है. डिज़ाइन टोकन की सूची में मौजूद कस्टम प्रॉपर्टी का भी इस्तेमाल किया जा रहा है.

हम कुछ ऐसी वैल्यू भी एबस्ट्रैक्ट करेंगे जो कॉम्पोनेंट के हिसाब से होती हैं, लेकिन हमारे टोकन में नहीं होती हैं. साथ ही, हम उन्हें संदर्भ के हिसाब से बनाई गई कस्टम प्रॉपर्टी में बदल देंगे. कॉम्पोनेंट के हिसाब से कस्टम प्रॉपर्टी से हमें दो मुख्य फ़ायदे मिलते हैं. पहला, इसका मतलब है कि हम अपनी सीएसएस के साथ ज़्यादा "ड्राई" हो सकते हैं, क्योंकि उस वैल्यू को कॉम्पोनेंट के अंदर कई प्रॉपर्टी पर लागू किया जा सकता है.


.n-tab-group-list::before {
  /* ... */
  padding-inline-start: var(--n-tab-group-padding);
}

.n-tab-group-list::after {
  /* ... */
  padding-inline-end: var(--n-tab-group-padding);
}
कॉम्पोनेंट कोड में कई जगहों पर इस्तेमाल की जा रही, टैब ग्रुप पैडिंग की कॉन्टेक्स्टल कस्टम प्रॉपर्टी.

दूसरा, इससे कॉम्पोनेंट की स्थिति और वैरिएशन में होने वाले बदलावों को आसानी से मैनेज किया जा सकता है. उदाहरण के लिए, जब किसी होवर या चालू स्थिति या इस मामले में, किसी वैरिएशन को स्टाइल किया जा रहा हो, तो उन सभी प्रॉपर्टी को अपडेट करने के लिए सिर्फ़ कस्टम प्रॉपर्टी में बदलाव करना होगा.


:host([padding="l"]) {
  --n-tab-group-padding: var(--n-space-l);
}
टैब कॉम्पोनेंट का एक वैरिएशन, जिसमें कई अपडेट के बजाय एक ही कस्टम प्रॉपर्टी अपडेट का इस्तेमाल करके पैडिंग बदली जा रही है.

हालांकि, सबसे ज़्यादा फ़ायदा यह है कि जब हम किसी कॉम्पोनेंट पर इन कॉन्टेक्स्टल कस्टम प्रॉपर्टी तय करते हैं, तो हम अपने हर कॉम्पोनेंट के लिए एक तरह का कस्टम सीएसएस एपीआई बनाते हैं. इस एपीआई का इस्तेमाल, उस कॉम्पोनेंट के उपयोगकर्ता कर सकते हैं.


<nord-tab-group label="Title">
  <!-- ... -->
</nord-tab-group>

<style>
  nord-tab-group {
    --n-tab-group-padding: var(--n-space-xl);
  }
</style>
पेज पर टैब ग्रुप कॉम्पोनेंट का इस्तेमाल करना और पैडिंग कस्टम प्रॉपर्टी को बड़े साइज़ पर अपडेट करना.

पिछले उदाहरण में, हमारे वेब कॉम्पोनेंट में से एक को दिखाया गया है. इसमें, कॉन्टेक्स्ट के हिसाब से बदली गई कस्टम प्रॉपर्टी को सिलेक्टर की मदद से दिखाया गया है. इस पूरे तरीके का नतीजा एक ऐसा कॉम्पोनेंट है जो उपयोगकर्ता को स्टाइल करने की ज़रूरत के हिसाब से ज़रूरत के मुताबिक विकल्प देता है. साथ ही, ज़्यादातर असल स्टाइल को भी ध्यान में रखता है. साथ ही, बोनस के तौर पर, कॉम्पोनेंट डेवलपर के तौर पर हमारे पास उन स्टाइल को इंटरसेप्ट करने की सुविधा होती है जिन्हें उपयोगकर्ता ने लागू किया है. अगर हमें उनमें से किसी प्रॉपर्टी में बदलाव करना है या उसे बड़ा करना है, तो उपयोगकर्ता को अपने कोड में बदलाव करने की ज़रूरत नहीं पड़ेगी.

हमें यह तरीका बहुत असरदार लगता है. यह न सिर्फ़ डिज़ाइन सिस्टम के कॉम्पोनेंट बनाने वाले लोगों के लिए, बल्कि हमारी डेवलपमेंट टीम के लिए भी बहुत असरदार है. ऐसा इसलिए, क्योंकि वे हमारे प्रॉडक्ट में इन कॉम्पोनेंट का इस्तेमाल करते हैं.

कस्टम प्रॉपर्टी का ज़्यादा से ज़्यादा फ़ायदा पाना

इस लेख को लिखने के समय, हम अपने दस्तावेज़ में, संदर्भ के हिसाब से काम करने वाली इन कस्टम प्रॉपर्टी के बारे में नहीं बताते. हालांकि, हमारा प्लान है कि हम इन प्रॉपर्टी के बारे में बताएं, ताकि हमारी डेवलपमेंट टीम इन प्रॉपर्टी को समझ सके और उनका फ़ायदा ले सके. हमारे कॉम्पोनेंट, npm पर मेनिफ़ेस्ट फ़ाइल के साथ पैकेज किए जाते हैं. इसमें उनके बारे में सारी जानकारी होती है. इसके बाद, दस्तावेज़ों की साइट को डिप्लॉय करने पर, हम मेनिफ़ेस्ट फ़ाइल को डेटा के तौर पर इस्तेमाल करते हैं. ऐसा Eleventy और उसकी ग्लोबल डेटा सुविधा का इस्तेमाल करके किया जाता है. हमारा प्लान है कि हम इस मेनिफ़ेस्ट डेटा फ़ाइल में, संदर्भ के हिसाब से काम करने वाली कस्टम प्रॉपर्टी शामिल करें.

हम इस बात को भी बेहतर बनाना चाहते हैं कि ये संदर्भ के हिसाब से बनाई गई कस्टम प्रॉपर्टी, वैल्यू को कैसे इनहेरिट करती हैं. उदाहरण के लिए, अगर आपको दो डिवाइडर कॉम्पोनेंट का रंग बदलना है, तो आपको खास तौर पर सिलेक्टर की मदद से उन दोनों कॉम्पोनेंट को टारगेट करना होगा या स्टाइल एट्रिब्यूट की मदद से, सीधे तौर पर एलिमेंट पर कस्टम प्रॉपर्टी लागू करनी होगी. यह तरीका ठीक लग सकता है, लेकिन अगर डेवलपर उन स्टाइल को किसी एलिमेंट या रूट लेवल पर तय कर सकता है, तो यह ज़्यादा मददगार होगा.


<nord-divider></nord-divider>

<section>
  <nord-divider></nord-divider>
   <!-- ... -->
</section>

<style>
  nord-divider {
    --n-divider-color: var(--n-color-status-danger);
  }

  section {
    padding: var(--n-space-s);
    background: var(--n-color-surface-raised);
  }
  
  section nord-divider {
    --n-divider-color: var(--n-color-status-success);
  }
</style>
हमारे डिवाइडर कॉम्पोनेंट के दो उदाहरण, जिनमें दो अलग-अलग रंगों का इस्तेमाल किया गया है. एक सेक्शन में नेस्ट किया गया है, जिसका इस्तेमाल हम ज़्यादा सटीक सिलेक्टर के लिए कर सकते हैं. हालांकि, हमें खास तौर पर डिवाइडर को टारगेट करना होगा.

आपको कस्टम प्रॉपर्टी की वैल्यू सीधे कॉम्पोनेंट पर सेट करनी होगी, क्योंकि हम उन्हें कॉम्पोनेंट होस्ट सिलेक्टर की मदद से उसी एलिमेंट पर तय कर रहे हैं. कॉम्पोनेंट में सीधे तौर पर इस्तेमाल किए जाने वाले ग्लोबल डिज़ाइन टोकन, इस समस्या से पूरी तरह से अछूते रहते हैं. साथ ही, इन्हें पैरंट एलिमेंट पर भी इंटरसेप्ट किया जा सकता है. हम दोनों तरीकों का फ़ायदा कैसे ले सकते हैं?

निजी और सार्वजनिक कस्टम प्रॉपर्टी

निजी कस्टम प्रॉपर्टी, Lea Verou की एक पहल है. यह कॉम्पोनेंट पर मौजूद, कॉन्टेक्स्ट के हिसाब से काम करने वाली "निजी" कस्टम प्रॉपर्टी है. हालांकि, इसे फ़ॉलबैक के साथ "सार्वजनिक" कस्टम प्रॉपर्टी पर सेट किया जाता है.



:host {
  --_n-divider-color: var(--n-divider-color, var(--n-color-border));
  --_n-divider-size: var(--n-divider-size, 1px);
}

.n-divider {
  border-block-start: solid var(--_n-divider-size) var(--_n-divider-color);
  /* ... */
}
डिवाइडर वेब कॉम्पोनेंट की सीएसएस, जिसमें कॉन्टेक्स्ट के हिसाब से कस्टम प्रॉपर्टी को अडजस्ट किया गया है, ताकि इंटरनल सीएसएस किसी निजी कस्टम प्रॉपर्टी पर निर्भर हो. इसे फ़ॉलबैक के साथ सार्वजनिक कस्टम प्रॉपर्टी पर सेट किया गया है.

संदर्भ के हिसाब से कस्टम प्रॉपर्टी को इस तरह से तय करने का मतलब है कि हम अब भी वे सभी काम कर सकते हैं जो पहले कर रहे थे. जैसे, ग्लोबल टोकन की वैल्यू इनहेरिट करना और अपने पूरे कॉम्पोनेंट कोड में वैल्यू का फिर से इस्तेमाल करना. हालांकि, कॉम्पोनेंट अपने-आप या किसी पैरंट एलिमेंट पर उस प्रॉपर्टी की नई परिभाषाएं भी इनहेरिट करेगा.


<nord-divider></nord-divider>

<section>
  <nord-divider></nord-divider>
   <!-- ... -->
</section>

<style>
  nord-divider {
    --n-divider-color: var(--n-color-status-danger);
  }

  section {
    padding: var(--n-space-s);
    background: var(--n-color-surface-raised);
    --n-divider-color: var(--n-color-status-success);
  }
</style>
दो डिवाइडर फिर से दिख रहे हैं. हालांकि, इस बार सेक्शन सिलेक्टर में डिवाइडर की संदर्भ कस्टम प्रॉपर्टी जोड़कर, डिवाइडर का रंग बदला जा सकता है. डिवाइडर इसे इनहेरिट करेगा, जिससे कोड ज़्यादा आसान और बेहतर बन जाएगा.

ऐसा हो सकता है कि इस तरीके को "निजी" न माना जाए. हालांकि, हमें लगता है कि यह उस समस्या का बेहतर समाधान है जिसकी वजह से हम परेशान थे. जब भी हमें मौका मिलेगा, हम अपने कॉम्पोनेंट में इस समस्या को हल करेंगे. इससे हमारी डेवलपमेंट टीम को कॉम्पोनेंट के इस्तेमाल पर ज़्यादा कंट्रोल मिलेगा. साथ ही, हमारे मौजूदा गार्डरिल से भी फ़ायदा मिलेगा.

हमें उम्मीद है कि सीएसएस कस्टम प्रॉपर्टी के साथ वेब कॉम्पोनेंट का इस्तेमाल करने के तरीके के बारे में यह जानकारी आपके लिए काम की होगी. हमें बताएं कि आपको यह सुविधा कैसी लगी. अगर आपको अपने वीडियो में इनमें से किसी भी तरीके का इस्तेमाल करना है, तो मुझे Twitter पर @DavidDarnes पर टैग करें. Nordhealth @NordhealthHQ को Twitter पर भी ढूंढा जा सकता है. साथ ही, मेरी टीम के अन्य सदस्यों को भी ढूंढा जा सकता है. इन सदस्यों ने इस डिज़ाइन सिस्टम को एक साथ लाने और इस लेख में बताई गई सुविधाओं को लागू करने के लिए कड़ी मेहनत की है: @Viljamis, @WickyNilliams, और @eric_habich.

Dan Cristian Pădureț की हीरो इमेज