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

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

David Darnes
David Darnes

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

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

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


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);
लिट के साथ लिखा गया वेब कॉम्पोनेंट.

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


// TODO: DevSite - Code sample removed as it used inline event handlers
किसी पेज पर ऊपर बनाए गए वेब कॉम्पोनेंट का इस्तेमाल करना.

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

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

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

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

स्टाइल को एग्रीगेट करने की सुविधा से, हमारी कॉम्पोनेंट लाइब्रेरी में काफ़ी फ़ायदा होता है. इससे हमें इस बात की ज़्यादा गारंटी मिलती है कि जब कोई व्यक्ति हमारे किसी कॉम्पोनेंट का इस्तेमाल करता है, तो वह हमारी उम्मीद के मुताबिक दिखेगा. भले ही, पैरंट पेज पर कोई भी स्टाइल लागू हो. साथ ही, यह पक्का करने के लिए कि हम 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);
}
यह टैब कॉम्पोनेंट का ऐसा वैरिएशन है जिसमें पैडिंग (जगह) को कई अपडेट के बजाय, सिर्फ़ एक कस्टम प्रॉपर्टी को अपडेट करके बदला जा रहा है.

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


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

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

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

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

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

इस लेख को लिखने के समय, हम अपने दस्तावेज़ में, संदर्भ के हिसाब से काम करने वाली इन कस्टम प्रॉपर्टी के बारे में नहीं बताते. हालांकि, हमारा प्लान है कि हम इन प्रॉपर्टी के बारे में बताएं, ताकि हमारी डेवलपमेंट टीम इन प्रॉपर्टी को समझ सके और उनका फ़ायदा ले सके. हमारे कॉम्पोनेंट, एनपीएम पर मेनिफ़ेस्ट फ़ाइल के साथ पैकेज किए जाते हैं. इसमें इनके बारे में पूरी जानकारी होती है. इसके बाद, जब हमारी दस्तावेज़ साइट डिप्लॉय होती है, तो हम मेनिफ़ेस्ट फ़ाइल को डेटा के तौर पर इस्तेमाल करते हैं. इसके लिए, 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>
हमारे डिवाइडर कॉम्पोनेंट के दो इंस्टेंस, जिनमें दो अलग-अलग कलर ट्रीटमेंट की ज़रूरत है. एक ऐसा सेक्शन होता है जिसका इस्तेमाल किसी खास सिलेक्टर के लिए किया जा सकता है, लेकिन हमें डिवाइडर को खास तौर पर टारगेट करना होता है.

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

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

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



: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 पर टैग करें. आप Twitter पर Nordhealth के @NordhealthHQ के साथ-साथ, मेरी टीम के उन सदस्यों को भी देख सकते हैं जिन्होंने इस डिज़ाइन सिस्टम को एक साथ लाने और इस लेख में बताई गई सुविधाओं को लागू करने के लिए कड़ी मेहनत की है: @Viljamis, @WickyNilliams, और @eric_habich.

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