स्प्लिट बटन वाला कॉम्पोनेंट बनाना

सुलभता के हिसाब से बने स्प्लिट-बटन कॉम्पोनेंट को बनाने का तरीका.

इस पोस्ट में, मैं स्प्लिट बटन बनाने के तरीके के बारे में बताना चाहता हूं . डेमो आज़माएं.

डेमो

अगर आपको वीडियो देखना पसंद है, तो यहां इस पोस्ट का YouTube वर्शन दिया गया है:

खास जानकारी

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

आपके ईमेल ऐप्लिकेशन में, स्प्लिट बटन आसानी से मिल सकता है. मुख्य कार्रवाई भेजें है. हालांकि, कभी-कभी इसे भेजा जा सकता है या ड्राफ़्ट के तौर पर सेव किया जा सकता है:

ईमेल ऐप्लिकेशन में दिखने वाले स्प्लिट बटन का उदाहरण.

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

पार्ट

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

'स्प्लिट करें' बटन बनाने वाले एचटीएमएल एलिमेंट.

टॉप लेवल का स्प्लिट बटन कंटेनर

सबसे ऊपर का कॉम्पोनेंट, इनलाइन फ़्लेक्सबॉक्स होता है. इसमें gui-split-button क्लास होती है, जिसमें प्राइमरी ऐक्शन और .gui-popup-button शामिल होता है.

gui-split-button क्लास की जांच की गई और इस क्लास में इस्तेमाल की गई सीएसएस प्रॉपर्टी दिखाई गईं.

मुख्य ऐक्शन बटन

शुरुआत में दिखने वाला और फ़ोकस किया जा सकने वाला <button>, कंटेनर में फ़िट होता है. इसमें फ़ोकस, हॉवर, और ऐक्टिव इंटरैक्शन के लिए, कोने में दो मैच करने वाले आकार होते हैं, ताकि वे .gui-split-button में दिखें.

बटन एलिमेंट के लिए सीएसएस नियम दिखाने वाला इंस्पेक्टर.

पॉप-अप टॉगल बटन

"पॉप-अप बटन" सहायता एलिमेंट का इस्तेमाल, सेकंडरी बटन की सूची को चालू करने और जानकारी देने के लिए किया जाता है. ध्यान दें कि यह <button> नहीं है और इस पर फ़ोकस नहीं किया जा सकता. हालांकि, यह .gui-popup के लिए पोज़िशनिंग ऐंकर और :focus-within के लिए होस्ट है, जिसका इस्तेमाल पॉप-अप दिखाने के लिए किया जाता है.

gui-popup-button क्लास के लिए सीएसएस नियम दिखाने वाला इंस्पेक्टर.

पॉप-अप कार्ड

यह अपने ऐंकर .gui-popup-button के लिए फ़्लोटिंग कार्ड चाइल्ड है. इसे पूरी तरह से पोज़िशन किया गया है और बटन की सूची को सेमैटिक तरीके से रैप किया गया है.

क्लास gui-popup के लिए सीएसएस नियम दिखाने वाला इंस्पेक्टर

सेकंडरी ऐक्शन

प्राइमरी ऐक्शन बटन के मुकाबले थोड़े छोटे फ़ॉन्ट साइज़ वाला <button>, जिस पर फ़ोकस किया जा सकता है. इसमें प्राइमरी बटन के साथ मिलती-जुलती स्टाइल और आइकॉन होता है.

जांच करने वाला टूल, जो बटन एलिमेंट के लिए सीएसएस नियम दिखा रहा है.

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

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

@custom-media --motionOK (prefers-reduced-motion: no-preference);
@custom-media --dark (prefers-color-scheme: dark);
@custom-media --light (prefers-color-scheme: light);

.gui-split-button {
  --theme:             hsl(220 75% 50%);
  --theme-hover:  hsl(220 75% 45%);
  --theme-active:  hsl(220 75% 40%);
  --theme-text:      hsl(220 75% 25%);
  --theme-border: hsl(220 50% 75%);
  --ontheme:         hsl(220 90% 98%);
  --popupbg:         hsl(220 0% 100%);

  --border: 1px solid var(--theme-border);
  --radius: 6px;
  --in-speed: 50ms;
  --out-speed: 300ms;

  @media (--dark) {
    --theme:             hsl(220 50% 60%);
    --theme-hover:  hsl(220 50% 65%);
    --theme-active:  hsl(220 75% 70%);
    --theme-text:      hsl(220 10% 85%);
    --theme-border: hsl(220 20% 70%);
    --ontheme:         hsl(220 90% 5%);
    --popupbg:         hsl(220 10% 30%);
  }
}

लेआउट और रंग

मार्कअप

एलिमेंट, कस्टम क्लास के नाम से <div> के तौर पर शुरू होता है.

<div class="gui-split-button"></div>

प्राइमरी बटन और .gui-popup-button एलिमेंट जोड़ें.

<div class="gui-split-button">
  <button>Send</button>
  <span class="gui-popup-button" aria-haspopup="true" aria-expanded="false" title="Open for more actions"></span>
</div>

ARIA एट्रिब्यूट aria-haspopup और aria-expanded पर ध्यान दें. ये निर्देश, स्क्रीन रीडर के लिए बहुत ज़रूरी हैं. इससे उन्हें स्प्लिट बटन की सुविधा और उसके इस्तेमाल की स्थिति के बारे में जानकारी मिलती है. title एट्रिब्यूट सभी के लिए मददगार है.

<svg> आइकॉन और .gui-popup कंटेनर एलिमेंट जोड़ें.

<div class="gui-split-button">
  <button>Send</button>
  <span class="gui-popup-button" aria-haspopup="true" aria-expanded="false" title="Open for more actions">
    <svg aria-hidden="true" viewBox="0 0 20 20">
      <path d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" />
    </svg>
    <ul class="gui-popup"></ul>
  </span>
</div>

पॉप-अप को आसानी से प्लेस करने के लिए, .gui-popup उस बटन का चाइल्ड एलिमेंट होता है जिससे उसे बड़ा किया जाता है. इस रणनीति का एक ही फ़ायदा है कि .gui-split-button कंटेनर, overflow: hidden का इस्तेमाल नहीं कर सकता. ऐसा इसलिए, क्योंकि इससे पॉप-अप दिखने से बच जाएगा.

<ul> में <li><button> का कॉन्टेंट होता है. यह स्क्रीन रीडर के लिए, एक "बटन सूची" के तौर पर जानकारी देता है. यहां दिखाया गया इंटरफ़ेस ही स्क्रीन रीडर है.

<div class="gui-split-button">
  <button>Send</button>
  <span class="gui-popup-button" aria-haspopup="true" aria-expanded="false" title="Open for more actions">
    <svg aria-hidden="true" viewBox="0 0 20 20">
      <path d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" />
    </svg>
    <ul class="gui-popup">
      <li>
        <button>Schedule for later</button>
      </li>
      <li>
        <button>Delete</button>
      </li>
      <li>
        <button>Save draft</button>
      </li>
    </ul>
  </span>
</div>

मैंने https://heroicons.com से सेकंडरी बटन में आइकॉन जोड़े हैं, ताकि उन्हें शानदार और रंगीन बनाया जा सके. हालांकि, प्राइमरी और सेकंडरी, दोनों बटन के लिए आइकॉन जोड़ना ज़रूरी नहीं है.

<div class="gui-split-button">
  <button>Send</button>
  <span class="gui-popup-button" aria-haspopup="true" aria-expanded="false" title="Open for more actions">
    <svg aria-hidden="true" viewBox="0 0 20 20">
      <path d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" />
    </svg>
    <ul class="gui-popup">
      <li><button>
        <svg aria-hidden="true" viewBox="0 0 24 24">
          <path d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
        </svg>
        Schedule for later
      </button></li>
      <li><button>
        <svg aria-hidden="true" viewBox="0 0 24 24">
          <path d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
        </svg>
        Delete
      </button></li>
      <li><button>
        <svg aria-hidden="true" viewBox="0 0 24 24">
          <path d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z" />
        </svg>
        Save draft
      </button></li>
    </ul>
  </span>
</div>

स्टाइल

एचटीएमएल और कॉन्टेंट की जगह तय होने के बाद, स्टाइल में रंग और लेआउट जोड़े जा सकते हैं.

स्प्लिट बटन कंटेनर को स्टाइल करना

inline-flex डिसप्ले टाइप, इस रैपिंग कॉम्पोनेंट के लिए अच्छा काम करता है, क्योंकि यह अन्य स्प्लिट बटन, ऐक्शन या एलिमेंट के साथ इनलाइन में फ़िट होना चाहिए.

.gui-split-button {
  display: inline-flex;
  border-radius: var(--radius);
  background: var(--theme);
  color: var(--ontheme);
  fill: var(--ontheme);

  touch-action: manipulation;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

&#39;स्प्लिट करें&#39; बटन.

<button> स्टाइल

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

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

.gui-split-button button {
  cursor: pointer;
  appearance: none;
  background: none;
  border: none;

  display: inline-flex;
  align-items: center;
  gap: 1ch;
  white-space: nowrap;

  font-family: inherit;
  font-size: inherit;
  font-weight: 500;

  padding-block: 1.25ch;
  padding-inline: 2.5ch;

  color: var(--ontheme);
  outline-color: var(--theme);
  outline-offset: -5px;
}

कुछ सीएसएस स्यूडो-क्लास की मदद से इंटरैक्शन की स्थितियां जोड़ें. साथ ही, स्थिति के लिए मैच करने वाली कस्टम प्रॉपर्टी का इस्तेमाल करें:

.gui-split-button button {
  

  &:is(:hover, :focus-visible) {
    background: var(--theme-hover);
    color: var(--ontheme);

    & > svg {
      stroke: currentColor;
      fill: none;
    }
  }

  &:active {
    background: var(--theme-active);
  }
}

डिज़ाइन इफ़ेक्ट को पूरा करने के लिए, मुख्य बटन को कुछ खास स्टाइल की ज़रूरत होती है:

.gui-split-button > button {
  border-end-start-radius: var(--radius);
  border-start-start-radius: var(--radius);

  & > svg {
    fill: none;
    stroke: var(--ontheme);
  }
}

आखिर में, हल्के रंग वाली थीम के बटन और आइकॉन को शेड दिया गया है, ताकि उन्हें थोड़ा शानदार बनाया जा सके:

.gui-split-button {
  @media (--light) {
    & > button,
    & button:is(:focus-visible, :hover) {
      text-shadow: 0 1px 0 var(--theme-active);
    }
    & > .gui-popup-button > svg,
    & button:is(:focus-visible, :hover) > svg {
      filter: drop-shadow(0 1px 0 var(--theme-active));
    }
  }
}

इस बटन में, माइक्रोइंटरैक्शन और छोटी-छोटी बातों पर ध्यान दिया गया है.

:focus-visible के बारे में एक नोट

ध्यान दें कि बटन स्टाइल में :focus के बजाय :focus-visible का इस्तेमाल कैसे किया जाता है. :focus एक ऐसा यूज़र इंटरफ़ेस बनाने के लिए बेहद अहम है जिसे ऐक्सेस किया जा सकता है. हालांकि, इसका एक नुकसान है: उपयोगकर्ता को यह देखने की ज़रूरत है या नहीं, यह फ़ैसला करना आसान नहीं है और इस पर फ़ोकस करना चाहिए.

नीचे दिए गए वीडियो में, इस माइक्रोइंटरैक्शन को अलग-अलग हिस्सों में बांटा गया है. इससे यह पता चलता है कि :focus-visible, बेहतर विकल्प कैसे है.

पॉप-अप बटन को स्टाइल करना

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

स्प्लिट बटन का ऐरो वाला हिस्सा, जिसका इस्तेमाल पॉप-अप को ट्रिगर करने के लिए किया जाता है.

.gui-popup-button {
  inline-size: 4ch;
  cursor: pointer;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-inline-start: var(--border);
  border-start-end-radius: var(--radius);
  border-end-end-radius: var(--radius);
}

सीएसएस नेस्टिंग और :is() फ़ंक्शनल सिलेक्टर की मदद से, कर्सर घुमाने, फ़ोकस करने, और चालू होने की स्थितियों में लेयर:

.gui-popup-button {
  

  &:is(:hover,:focus-within) {
    background: var(--theme-hover);
  }

  /* fixes iOS trying to be helpful */
  &:focus {
    outline: none;
  }

  &:active {
    background: var(--theme-active);
  }
}

ये स्टाइल, पॉप-अप दिखाने और छिपाने के लिए मुख्य हुक हैं. जब .gui-popup-button के किसी भी चाइल्ड पर focus हो, तो आइकॉन और पॉप-अप पर opacity, पोज़िशन, और pointer-events सेट करें.

.gui-popup-button {
  

  &:focus-within {
    & > svg {
      transition-duration: var(--in-speed);
      transform: rotateZ(.5turn);
    }
    & > .gui-popup {
      transition-duration: var(--in-speed);
      opacity: 1;
      transform: translateY(0);
      pointer-events: auto;
    }
  }
}

इन और आउट स्टाइल के पूरा होने के बाद, आखिरी चरण में उपयोगकर्ता की मोशन सेटिंग के आधार पर, शर्त के मुताबिक ट्रांज़िशन ट्रांसफ़ॉर्म करना होता है:

.gui-popup-button {
  

  @media (--motionOK) {
    & > svg {
      transition: transform var(--out-speed) ease;
    }
    & > .gui-popup {
      transform: translateY(5px);

      transition:
        opacity var(--out-speed) ease,
        transform var(--out-speed) ease;
    }
  }
}

कोड को ध्यान से देखने पर पता चलता है कि कम मोशन पसंद करने वाले उपयोगकर्ताओं के लिए, ओपैसिटी में अब भी बदलाव होता है.

पॉप-अप को स्टाइल करना

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

फ़्लोटिंग कार्ड एलिमेंट.

.gui-popup {
  --shadow: 220 70% 15%;
  --shadow-strength: 1%;

  opacity: 0;
  pointer-events: none;

  position: absolute;
  bottom: 80%;
  left: -1.5ch;

  list-style-type: none;
  background: var(--popupbg);
  color: var(--theme-text);
  padding-inline: 0;
  padding-block: .5ch;
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-size: .9em;
  transition: opacity var(--out-speed) ease;

  box-shadow:
    0 -2px 5px 0 hsl(var(--shadow) / calc(var(--shadow-strength) + 5%)),
    0 1px 1px -2px hsl(var(--shadow) / calc(var(--shadow-strength) + 10%)),
    0 2px 2px -2px hsl(var(--shadow) / calc(var(--shadow-strength) + 12%)),
    0 5px 5px -2px hsl(var(--shadow) / calc(var(--shadow-strength) + 13%)),
    0 9px 9px -2px hsl(var(--shadow) / calc(var(--shadow-strength) + 14%)),
    0 16px 16px -2px hsl(var(--shadow) / calc(var(--shadow-strength) + 20%))
  ;
}

आइकॉन और बटन को ब्रैंड के रंग दिए गए हैं, ताकि हर डार्क और लाइट थीम वाले कार्ड में उन्हें बेहतर तरीके से स्टाइल किया जा सके:

चेकआउट, तुरंत पेमेंट, और बाद के लिए सेव करने के लिए लिंक और आइकॉन.

.gui-popup {
  

  & svg {
    fill: var(--popupbg);
    stroke: var(--theme);

    @media (prefers-color-scheme: dark) {
      stroke: var(--theme-border);
    }
  }

  & button {
    color: var(--theme-text);
    width: 100%;
  }
}

गहरे रंग की थीम वाले पॉप-अप में टेक्स्ट और आइकॉन की शैडो जोड़ी गई है. साथ ही, बॉक्स की शैडो थोड़ी ज़्यादा गहरी है:

गहरे रंग वाली थीम में पॉप-अप.

.gui-popup {
  

  @media (--dark) {
    --shadow-strength: 5%;
    --shadow: 220 3% 2%;

    & button:not(:focus-visible, :hover) {
      text-shadow: 0 1px 0 var(--ontheme);
    }

    & button:not(:focus-visible, :hover) > svg {
      filter: drop-shadow(0 1px 0 var(--ontheme));
    }
  }
}

आइकॉन के लिए सामान्य <svg> स्टाइल

सभी आइकॉन, बटन font-size के साइज़ के हिसाब से होते हैं. इनका साइज़ तय करने के लिए, ch यूनिट को inline-size के तौर पर इस्तेमाल किया जाता है. हर आइकॉन को कुछ स्टाइल भी दी जाती हैं, ताकि आइकॉन को सॉफ़्ट और स्मूद बनाया जा सके.

.gui-split-button svg {
  inline-size: 2ch;
  box-sizing: content-box;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 2px;
}

दाएं से बाएं लेआउट

लॉजिकल प्रॉपर्टी से सभी मुश्किल काम किए जा सकते हैं. यहां इस्तेमाल की गई लॉजिकल प्रॉपर्टी की सूची दी गई है: - display: inline-flex, इनलाइन फ़्लेक्स एलिमेंट बनाता है. - padding के बजाय, padding-block और padding-inline को एक साथ इस्तेमाल करने पर, लॉजिकल साइड को पैड करने के फ़ायदे मिलते हैं. - border-end-start-radius और friends, दस्तावेज़ के डायरेक्शन के आधार पर कोने को गोल कर देंगे. - width के बजाय inline-size का इस्तेमाल करने से यह पक्का होता है कि साइज़, फ़िज़िकल डाइमेंशन से जुड़ा न हो. - border-inline-start, शुरुआत में बॉर्डर जोड़ता है. यह बॉर्डर, स्क्रिप्ट के डायरेक्शन के हिसाब से दाईं या बाईं ओर हो सकता है.

JavaScript

यहां दिए गए JavaScript को ऐक्सेस-योग्यता को बेहतर बनाने के लिए बनाया गया है. टास्क को आसान बनाने के लिए, मेरी दो मददगार लाइब्रेरी का इस्तेमाल किया जाता है. BlingBlingJS का इस्तेमाल, कम शब्दों में डीओएम क्वेरी और आसान इवेंट लिसनर सेटअप करने के लिए किया जाता है. वहीं, roving-ux, पॉप-अप के लिए ऐक्सेस किए जा सकने वाले कीबोर्ड और गेमपैड इंटरैक्शन को आसान बनाने में मदद करता है.

import $ from 'blingblingjs'
import {rovingIndex} from 'roving-ux'

const splitButtons = $('.gui-split-button')
const popupButtons = $('.gui-popup-button')

ऊपर दी गई लाइब्रेरी इंपोर्ट करने के बाद, ऐलिमेंट चुने गए और वैरिएबल में सेव किए गए. अब, अनुभव को अपग्रेड करने के लिए कुछ फ़ंक्शन ही बाकी हैं.

रोविंग इंडेक्स

जब कोई कीबोर्ड या स्क्रीन रीडर, .gui-popup-button पर फ़ोकस करता है, तो हम .gui-popup में पहले (या हाल ही में फ़ोकस किए गए) बटन पर फ़ोकस करना चाहते हैं. लाइब्रेरी, element और target पैरामीटर की मदद से, ऐसा करने में हमारी मदद करती है.

popupButtons.forEach(element =>
  rovingIndex({
    element,
    target: 'button',
  }))

एलिमेंट अब फ़ोकस <button> चिल्ड्रन पर फ़ोकस करता है और विकल्पों को ब्राउज़ करने के लिए स्टैंडर्ड ऐरो बटन नेविगेशन को चालू करता है.

aria-expanded को टॉगल करना

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

popupButtons.on('focusin', e => {
  e.currentTarget.setAttribute('aria-expanded', true)
})

popupButtons.on('focusout', e => {
  e.currentTarget.setAttribute('aria-expanded', false)
})

Escape बटन को चालू करना

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

popupButtons.on('keyup', e => {
  if (e.code === 'Escape')
    e.target.blur()
})

अगर पॉप-अप बटन पर Escape बटन दबाया जाता है, तो वह blur() की मदद से फ़ोकस हटा देता है.

स्प्लिट बटन पर क्लिक

आखिर में, अगर उपयोगकर्ता बटन पर क्लिक करता है, टैप करता है या कीबोर्ड से इंटरैक्ट करता है, तो ऐप्लिकेशन को सही कार्रवाई करनी चाहिए. यहां इवेंट बबल करने की सुविधा का फिर से इस्तेमाल किया गया है. हालांकि, इस बार .gui-split-button कंटेनर पर, चाइल्ड पॉप-अप या प्राइमरी ऐक्शन से बटन पर होने वाले क्लिक को कैप्चर करने के लिए.

splitButtons.on('click', event => {
  if (event.target.nodeName !== 'BUTTON') return
  console.info(event.target.innerText)
})

नतीजा

अब जब आपको पता है कि मैंने इसे कैसे किया, तो आप कैसे करेंगे 🙂

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

कम्यूनिटी रीमिक्स