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

ऐक्सेस किया जा सकने वाला स्प्लिट बटन कॉम्पोनेंट बनाने के तरीके के बारे में खास जानकारी.

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

डेमो

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

खास जानकारी

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

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

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

शेयर की गई कार्रवाई की जगह बढ़िया है, क्योंकि उपयोगकर्ता को इधर-उधर देखने की ज़रूरत नहीं होती. उन्हें पता है कि स्प्लिट बटन में ज़रूरी ईमेल कार्रवाइयां शामिल होती हैं.

पार्ट

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

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

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

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

इस क्लास में इस्तेमाल की गई सीएसएस प्रॉपर्टी की जांच की गई और उसे दिखाया गया है.

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

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

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

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

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

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

पॉप-अप कार्ड

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

क्लास जीयू-पॉप-अप के लिए सीएसएस के नियम दिखाने वाला इंस्पेक्टर

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

प्राइमरी ऐक्शन बटन के मुकाबले छोटे फ़ॉन्ट साइज़ वाले <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-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 का इस्तेमाल नहीं कर सकता, क्योंकि यह पॉप-अप को विज़ुअल रूप से मौजूद होने से रोक देगा.

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

<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;
}

स्प्लिट बटन.

<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;
}

कुछ सीएसएस pseudo-classes के साथ इंटरैक्शन स्थितियां जोड़ें और राज्य के लिए मिलती-जुलती कस्टम प्रॉपर्टी का इस्तेमाल करें:

.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%))
  ;
}

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

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

.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-block और padding-inline को जोड़ने के लिए, padding शॉर्टहैंड के बजाय, लॉजिकल साइड की पैडिंग के फ़ायदे पाएं. - border-end-start-radius और दोस्त, दस्तावेज़ के निर्देश के आधार पर किनारों को राउंड-ऑफ़ करेंगे. - width के बजाय inline-size यह पक्का करता है कि साइज़, फ़िज़िकल डाइमेंशन से न जुड़ा हो. - border-inline-start शुरू में एक बॉर्डर जोड़ता है, जो स्क्रिप्ट के निर्देश के आधार पर दाएं या बाएं हिस्से में हो सकता है.

JavaScript

नीचे दिए गए करीब-करीब सभी JavaScript का मकसद सुलभता को बेहतर बनाना है. मेरी दो हेल्पर लाइब्रेरी का इस्तेमाल, टास्क को थोड़ा आसान बनाने के लिए किया जाता है. BlingBlingJS का इस्तेमाल कम शब्दों वाली DOM क्वेरी और इवेंट लिसनर को आसान सेटअप करने के लिए किया गया है. वहीं, 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)
})

नतीजा

अब आपको पता चल गया है कि मैंने इसे कैसे किया, तो आप कैसी होंगी‽ 🙂

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

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