paragraphs_bundles-1.0.x-dev/modules/paragraph_bundle_accordion/js/paragraph-bundle-accordion.js

modules/paragraph_bundle_accordion/js/paragraph-bundle-accordion.js
/**
 * @file
 * Paragraph Bundle Accordion.
 *
 * Filename:     paragraph-bundle-accordion.js
 * Website:      https://www.flashwebcenter.com
 * Developer:    Alaa Haddad https://www.alaahaddad.com.
 */
((Drupal, drupalSettings, once) => {
  'use strict';

  Drupal.behaviors.paragraphsAccordionBundle = {
    attach: function(context, settings) {
      // Utility function to get elements by ID
      const getElementsById = (id) => {
        const wrapper = context.querySelectorAll(`#${id} > .pb__accor-wrap-btn-item`);
        const minusButton = context.querySelector(`#${id} > .pb__ex-button > button.pb__minus`);
        const plusButton = context.querySelector(`#${id} > .pb__ex-button > button.pb__plus`);
        return [wrapper, minusButton, plusButton];
      };

      // Function to update the tabindex based on visibility
      const updateTabindex = (button) => {
        if (window.getComputedStyle(button).display === 'none') {
          button.setAttribute('tabindex', '-1');
        } else {
          button.removeAttribute('tabindex');
        }
      };

      const toggleClassAndDisplay = (buttonSelector, addClass, removeClass, hideIndex, showIndex) => {
        once('toggleClassAndDisplay', buttonSelector, context).forEach((button) => {
          button.addEventListener('click', function(event) {
            const classId = event.target.closest('.pb__accor').id;
            const [wrapper, minusButton, plusButton] = getElementsById(classId);
            wrapper.forEach((element) => {
              element.classList.remove(removeClass);
              element.classList.add(addClass);
              const isExpand = addClass === 'pb__active';
              const toggleButton = element.querySelector('.pb__accor-button');
              const contentPane = element.querySelector('.pb__accor-pane');
              if (toggleButton) {
                toggleButton.setAttribute('aria-expanded', isExpand);
              }
              if (contentPane) {
                contentPane.setAttribute('aria-hidden', !isExpand);
              }
            });

            if (minusButton) {
              minusButton.style.display = hideIndex === 1 ? "none" : "block";
              updateTabindex(minusButton);
            }
            if (plusButton) {
              plusButton.style.display = showIndex === 1 ? "none" : "block";
              updateTabindex(plusButton);
            }
          });
        });
      };

      const toggleActiveState = (buttonSelector, activeClass, inactiveClass) => {
        once('toggleActiveState', buttonSelector, context).forEach((button) => {
          button.addEventListener('click', function (event) {
            const element = event.target.closest('.pb__accor-wrap-btn-item');
            const toggleButton = element.querySelector('.pb__accor-button');
            const contentPane = element.querySelector('.pb__accor-pane');
            const plusMinus = element.querySelector('.pb__plus-minus'); // Target plus-minus container

            const isCurrentlyActive = toggleButton.getAttribute('aria-expanded') === 'true';

            // Update classes and ARIA attributes for the button
            element.classList.toggle(activeClass, !isCurrentlyActive);
            element.classList.toggle(inactiveClass, isCurrentlyActive);
            toggleButton.setAttribute('aria-expanded', String(!isCurrentlyActive));
            if (contentPane) {
              contentPane.setAttribute('aria-hidden', String(isCurrentlyActive));
            }

            // Update plus/minus visibility and aria-hidden attributes
            if (plusMinus) {
              const plus = plusMinus.querySelector('.pb__plus');
              const minus = plusMinus.querySelector('.pb__minus');
              if (plus && minus) {
                plus.style.display = isCurrentlyActive ? 'block' : 'none';
                minus.style.display = isCurrentlyActive ? 'none' : 'block';

                // Explicitly set aria-hidden for plus/minus spans
                plus.setAttribute('aria-hidden', String(!isCurrentlyActive));
                minus.setAttribute('aria-hidden', String(isCurrentlyActive));
              }
            }
          });
        });
      };

      once('expand-collapse-all', '.pb__ex-button > button', context).forEach((button) => {
        button.addEventListener('click', () => {
          const isExpand = button.classList.contains('pb__plus');
          const accId = button.getAttribute('aria-controls');
          const elements = context.querySelectorAll(`#${accId} .pb__accor-wrap-btn-item`);

          // Update all accordion items
          elements.forEach(element => {
            const toggleButton = element.querySelector('.pb__accor-button');
            const contentPane = element.querySelector('.pb__accor-pane');
            const plusMinus = element.querySelector('.pb__plus-minus');

            // Toggle active/inactive classes and ARIA attributes
            element.classList.toggle('pb__active', isExpand);
            element.classList.toggle('pb__active-no', !isExpand);
            if (toggleButton) {
              toggleButton.setAttribute('aria-expanded', isExpand);
            }
            if (contentPane) {
              contentPane.setAttribute('aria-hidden', !isExpand);
            }

            // Update plus/minus visibility for each item
            if (plusMinus) {
              const plus = plusMinus.querySelector('.pb__plus');
              const minus = plusMinus.querySelector('.pb__minus');
              if (plus && minus) {
                plus.style.display = isExpand ? 'none' : 'block';
                minus.style.display = isExpand ? 'block' : 'none';
                plus.setAttribute('aria-hidden', isExpand);
                minus.setAttribute('aria-hidden', !isExpand);
              }
            }
          });
        });
      });

      // Initialize toggle functions
      toggleActiveState('.pb__accor-button', 'pb__active', 'pb__active-no');
      toggleClassAndDisplay('.pb__ex-button>button.pb__plus', 'pb__active', 'pb__active-no', 2, 1);
      toggleClassAndDisplay('.pb__ex-button>button.pb__minus', 'pb__active-no', 'pb__active', 1, 2);
    }
  };
})(Drupal, drupalSettings, once);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc