site-header.js

import { queryOne, queryAll } from '@ecl/dom-utils';
import { createFocusTrap } from 'focus-trap';

/**
 * @param {HTMLElement} element DOM element for component instantiation and scope
 * @param {Object} options
 * @param {String} options.languageLinkSelector
 * @param {String} options.languageListOverlaySelector
 * @param {String} options.languageListEuSelector
 * @param {String} options.languageListNonEuSelector
 * @param {String} options.closeOverlaySelector
 * @param {String} options.searchToggleSelector
 * @param {String} options.searchFormSelector
 * @param {String} options.loginToggleSelector
 * @param {String} options.loginBoxSelector
 * @param {integer} options.tabletBreakpoint
 * @param {Boolean} options.attachClickListener Whether or not to bind click events
 * @param {Boolean} options.attachKeyListener Whether or not to bind keyboard events
 * @param {Boolean} options.attachResizeListener Whether or not to bind resize events
 */
export class SiteHeader {
  /**
   * @static
   * Shorthand for instance creation and initialisation.
   *
   * @param {HTMLElement} root DOM element for component instantiation and scope
   *
   * @return {SiteHeader} An instance of SiteHeader.
   */
  static autoInit(root, { SITE_HEADER_CORE: defaultOptions = {} } = {}) {
    const siteHeader = new SiteHeader(root, defaultOptions);
    siteHeader.init();
    root.ECLSiteHeader = siteHeader;
    return siteHeader;
  }

  constructor(
    element,
    {
      containerSelector = '[data-ecl-site-header-top]',
      languageLinkSelector = '[data-ecl-language-selector]',
      languageListOverlaySelector = '[data-ecl-language-list-overlay]',
      languageListEuSelector = '[data-ecl-language-list-eu]',
      languageListNonEuSelector = '[data-ecl-language-list-non-eu]',
      languageListContentSelector = '[data-ecl-language-list-content]',
      closeOverlaySelector = '[data-ecl-language-list-close]',
      searchToggleSelector = '[data-ecl-search-toggle]',
      searchFormSelector = '[data-ecl-search-form]',
      loginToggleSelector = '[data-ecl-login-toggle]',
      loginBoxSelector = '[data-ecl-login-box]',
      notificationSelector = '[data-ecl-site-header-notification]',
      attachClickListener = true,
      attachKeyListener = true,
      attachResizeListener = true,
      tabletBreakpoint = 768,
      customActionToggleSelector = '[data-ecl-custom-action]',
      customActionOverlaySelector = '[data-ecl-custom-action-overlay]',
      customActionCloseSelector = '[data-ecl-custom-action-close]',
    } = {},
  ) {
    // Check element
    if (!element || element.nodeType !== Node.ELEMENT_NODE) {
      throw new TypeError(
        'DOM element should be given to initialize this widget.',
      );
    }

    this.element = element;

    // Options
    this.containerSelector = containerSelector;
    this.languageLinkSelector = languageLinkSelector;
    this.languageListOverlaySelector = languageListOverlaySelector;
    this.languageListEuSelector = languageListEuSelector;
    this.languageListNonEuSelector = languageListNonEuSelector;
    this.languageListContentSelector = languageListContentSelector;
    this.closeOverlaySelector = closeOverlaySelector;
    this.searchToggleSelector = searchToggleSelector;
    this.searchFormSelector = searchFormSelector;
    this.loginToggleSelector = loginToggleSelector;
    this.notificationSelector = notificationSelector;
    this.loginBoxSelector = loginBoxSelector;
    this.attachClickListener = attachClickListener;
    this.attachKeyListener = attachKeyListener;
    this.attachResizeListener = attachResizeListener;
    this.tabletBreakpoint = tabletBreakpoint;
    this.customActionToggleSelector = customActionToggleSelector;
    this.customActionOverlaySelector = customActionOverlaySelector;
    this.customActionCloseSelector = customActionCloseSelector;

    // Private variables
    this.languageMaxColumnItems = 8;
    this.languageLink = null;
    this.languageListOverlay = null;
    this.languageListEu = null;
    this.languageListNonEu = null;
    this.languageListContent = null;
    this.close = null;
    this.focusTrap = null;
    this.searchToggle = null;
    this.searchForm = null;
    this.loginToggle = null;
    this.loginBox = null;
    this.resizeTimer = null;
    this.direction = null;
    this.notificationContainer = null;
    this.customActionToggle = null;
    this.customActionOverlay = null;
    this.customActionClose = null;
    this.customActionFocusTrap = null;

    // Bind `this` for use in callbacks
    this.openOverlay = this.openOverlay.bind(this);
    this.closeOverlay = this.closeOverlay.bind(this);
    this.toggleOverlay = this.toggleOverlay.bind(this);
    this.toggleSearch = this.toggleSearch.bind(this);
    this.toggleLogin = this.toggleLogin.bind(this);
    this.setLoginArrow = this.setLoginArrow.bind(this);
    this.setSearchArrow = this.setSearchArrow.bind(this);
    this.handleKeyboardLanguage = this.handleKeyboardLanguage.bind(this);
    this.handleKeyboardGlobal = this.handleKeyboardGlobal.bind(this);
    this.handleClickGlobal = this.handleClickGlobal.bind(this);
    this.handleResize = this.handleResize.bind(this);
    this.setLanguageListHeight = this.setLanguageListHeight.bind(this);
    this.handleNotificationClose = this.handleNotificationClose.bind(this);

    this.openCustomAction = this.openCustomAction.bind(this);
    this.closeCustomAction = this.closeCustomAction.bind(this);
    this.toggleCustomAction = this.toggleCustomAction.bind(this);
    this.handleKeyboardCustomAction =
      this.handleKeyboardCustomAction.bind(this);
  }

  /**
   * Initialise component.
   */
  init() {
    if (!ECL) {
      throw new TypeError('Called init but ECL is not present');
    }
    ECL.components = ECL.components || new Map();
    this.arrowSize = '0.5rem';
    // Bind global events
    if (this.attachKeyListener) {
      document.addEventListener('keyup', this.handleKeyboardGlobal);
    }
    if (this.attachClickListener) {
      document.addEventListener('click', this.handleClickGlobal);
    }
    if (this.attachResizeListener) {
      window.addEventListener('resize', this.handleResize);
    }

    // Site header elements
    this.container = queryOne(this.containerSelector);

    // Language list management
    this.languageLink = queryOne(this.languageLinkSelector);
    this.languageListOverlay = queryOne(this.languageListOverlaySelector);
    this.languageListEu = queryOne(this.languageListEuSelector);
    this.languageListNonEu = queryOne(this.languageListNonEuSelector);
    this.languageListContent = queryOne(this.languageListContentSelector);
    this.close = queryOne(this.closeOverlaySelector);
    this.notification = queryOne(this.notificationSelector);

    // direction
    this.direction = getComputedStyle(this.element).direction;
    if (this.direction === 'rtl') {
      this.element.classList.add('ecl-site-header--rtl');
    }

    // Create focus trap
    if (this.languageListOverlay) {
      this.focusTrap = createFocusTrap(this.languageListOverlay, {
        onDeactivate: this.closeOverlay,
        allowOutsideClick: true,
      });
    }

    if (this.attachClickListener && this.languageLink) {
      this.languageLink.addEventListener('click', this.toggleOverlay);
    }
    if (this.attachClickListener && this.close) {
      this.close.addEventListener('click', this.toggleOverlay);
    }
    if (this.attachKeyListener && this.languageLink) {
      this.languageLink.addEventListener(
        'keydown',
        this.handleKeyboardLanguage,
      );
    }

    // Search form management
    this.searchToggle = queryOne(this.searchToggleSelector);
    this.searchForm = queryOne(this.searchFormSelector);

    if (this.attachClickListener && this.searchToggle) {
      this.searchToggle.addEventListener('click', this.toggleSearch);
    }

    // Login management
    this.loginToggle = queryOne(this.loginToggleSelector);
    this.loginBox = queryOne(this.loginBoxSelector);

    if (this.attachClickListener && this.loginToggle) {
      this.loginToggle.addEventListener('click', this.toggleLogin);
    }

    // Custom action management
    this.customActionToggle = queryOne(this.customActionToggleSelector);
    this.customActionOverlay = queryOne(this.customActionOverlaySelector);
    this.customActionClose = queryOne(this.customActionCloseSelector);

    if (this.customActionOverlay) {
      // Create a separate focus trap for the custom action overlay
      this.customActionFocusTrap = createFocusTrap(this.customActionOverlay, {
        onDeactivate: this.closeCustomAction,
        allowOutsideClick: true,
      });
    }

    if (this.attachClickListener && this.customActionToggle) {
      this.customActionToggle.addEventListener(
        'click',
        this.toggleCustomAction,
      );
    }
    if (this.attachClickListener && this.customActionClose) {
      this.customActionClose.addEventListener('click', this.toggleCustomAction);
    }
    if (this.attachKeyListener && this.customActionToggle) {
      this.customActionToggle.addEventListener(
        'keydown',
        this.handleKeyboardCustomAction,
      );
    }

    // Set ecl initialized attribute
    this.element.setAttribute('data-ecl-auto-initialized', 'true');
    ECL.components.set(this.element, this);

    if (this.notification) {
      this.notificationContainer = this.notification.closest(
        '.ecl-site-header__notification',
      );

      setTimeout(() => {
        const eclNotification = ECL.components.get(this.notification);

        if (eclNotification) {
          eclNotification.on('onClose', this.handleNotificationClose);
        }
      }, 0);
    }
  }

  /**
   * Destroy component.
   */
  destroy() {
    if (this.attachClickListener && this.languageLink) {
      this.languageLink.removeEventListener('click', this.toggleOverlay);
    }
    if (this.focusTrap) {
      this.focusTrap.deactivate();
    }

    if (this.attachKeyListener && this.languageLink) {
      this.languageLink.removeEventListener(
        'keydown',
        this.handleKeyboardLanguage,
      );
    }

    if (this.attachClickListener && this.close) {
      this.close.removeEventListener('click', this.toggleOverlay);
    }

    if (this.attachClickListener && this.searchToggle) {
      this.searchToggle.removeEventListener('click', this.toggleSearch);
    }

    if (this.attachClickListener && this.loginToggle) {
      this.loginToggle.removeEventListener('click', this.toggleLogin);
    }

    if (this.attachClickListener && this.customActionToggle) {
      this.customActionToggle.removeEventListener(
        'click',
        this.toggleCustomAction,
      );
    }
    if (this.customActionFocusTrap) {
      this.customActionFocusTrap.deactivate();
    }
    if (this.attachKeyListener && this.customActionToggle) {
      this.customActionToggle.removeEventListener(
        'keydown',
        this.handleKeyboardCustomAction,
      );
    }
    if (this.attachClickListener && this.customActionClose) {
      this.customActionClose.removeEventListener(
        'click',
        this.toggleCustomAction,
      );
    }

    if (this.attachKeyListener) {
      document.removeEventListener('keyup', this.handleKeyboardGlobal);
    }

    if (this.attachClickListener) {
      document.removeEventListener('click', this.handleClickGlobal);
    }

    if (this.attachResizeListener) {
      window.removeEventListener('resize', this.handleResize);
    }

    if (this.element) {
      this.element.removeAttribute('data-ecl-auto-initialized');
      this.element.classList.remove('ecl-site-header--rtl');
      ECL.components.delete(this.element);
    }
  }

  /**
   * Method repositions a popover overlay in the viewport.
   * It also (optionally) handles language-list–specific logic such as columns.
   *
   * @param {HTMLElement} overlay The overlay element to be positioned
   * @param {HTMLElement} toggle The toggle button/link that opens the overlay
   * @param {String} arrowCssVar The CSS variable name for arrow positioning
   */
  updateOverlayPosition(
    overlay,
    toggle,
    arrowCssVar = '--ecl-overlay-arrow-position',
  ) {
    if (!overlay || !toggle || !this.container) return;

    // If this overlay is the language overlay, handle columns (EU vs Non-EU items)
    if (overlay === this.languageListOverlay) {
      // Calculate columns for the EU language list
      if (this.languageListEu) {
        const itemsEu = queryAll(
          '.ecl-site-header__language-item',
          this.languageListEu,
        );
        const columnsEu = Math.ceil(
          itemsEu.length / this.languageMaxColumnItems,
        );
        if (columnsEu > 1) {
          this.languageListEu.classList.add(
            `ecl-site-header__language-category--${columnsEu}-col`,
          );
        }
      }

      // Calculate columns for the Non-EU language list
      if (this.languageListNonEu) {
        const itemsNonEu = queryAll(
          '.ecl-site-header__language-item',
          this.languageListNonEu,
        );
        const columnsNonEu = Math.ceil(
          itemsNonEu.length / this.languageMaxColumnItems,
        );
        if (columnsNonEu > 1) {
          this.languageListNonEu.classList.add(
            `ecl-site-header__language-category--${columnsNonEu}-col`,
          );
        }
      }

      // Remove stacked classes first
      if (this.languageListEu) {
        this.languageListEu.parentNode.classList.remove(
          'ecl-site-header__language-content--stack',
        );
      } else if (this.languageListNonEu) {
        this.languageListNonEu.parentNode.classList.remove(
          'ecl-site-header__language-content--stack',
        );
      }
    }

    // Clear leftover classes/inline styles
    overlay.classList.remove(
      'ecl-site-header__language-container--push-right',
      'ecl-site-header__language-container--push-left',
      'ecl-site-header__language-container--full',
    );
    overlay.style.removeProperty(arrowCssVar);
    overlay.style.removeProperty('right');
    overlay.style.removeProperty('left');

    // Calculate bounding rects
    let popoverRect = overlay.getBoundingClientRect();
    const containerRect = this.container.getBoundingClientRect();
    const screenWidth = window.innerWidth;
    const toggleRect = toggle.getBoundingClientRect();

    // If this is the language overlay, handle “too wide” scenario
    if (overlay === this.languageListOverlay) {
      if (popoverRect.width > containerRect.width) {
        // Stack elements
        if (this.languageListEu) {
          this.languageListEu.parentNode.classList.add(
            'ecl-site-header__language-content--stack',
          );
        } else if (this.languageListNonEu) {
          this.languageListNonEu.parentNode.classList.add(
            'ecl-site-header__language-content--stack',
          );
        }
      }
    }

    // Mobile: full width if below tablet breakpoint
    if (window.innerWidth < this.tabletBreakpoint) {
      overlay.classList.add('ecl-site-header__language-container--full');
      // Recompute popoverRect after applying the class
      popoverRect = overlay.getBoundingClientRect();
      // Position arrow
      const arrowPosition =
        popoverRect.right - toggleRect.right + toggleRect.width / 2;
      overlay.style.setProperty(
        arrowCssVar,
        `calc(${arrowPosition}px - ${this.arrowSize})`,
      );
      return;
    }

    // If popover extends beyond right edge in LTR
    if (this.direction === 'ltr' && popoverRect.right > screenWidth) {
      overlay.classList.add('ecl-site-header__language-container--push-right');
      overlay.style.setProperty(
        'right',
        `calc(-${containerRect.right}px + ${toggleRect.right}px)`,
      );
      const arrowPos =
        containerRect.right - toggleRect.right + toggleRect.width / 2;
      overlay.style.setProperty(
        arrowCssVar,
        `calc(${arrowPos}px - ${this.arrowSize})`,
      );
    }
    // If popover extends beyond left edge in RTL
    else if (this.direction === 'rtl' && popoverRect.left < 0) {
      overlay.classList.add('ecl-site-header__language-container--push-left');
      overlay.style.setProperty(
        'left',
        `calc(-${toggleRect.left}px + ${containerRect.left}px)`,
      );
      const arrowPos =
        toggleRect.right - containerRect.left - toggleRect.width / 2;
      overlay.style.setProperty(arrowCssVar, `${arrowPos}px`);
    }
  }

  /**
   * Wrapper: Update display of the modal language list overlay
   * (Calls the new `updateOverlayPosition` for the language popover).
   */
  updateOverlay() {
    if (!this.languageListOverlay || !this.languageLink) return;
    this.updateOverlayPosition(this.languageListOverlay, this.languageLink);
  }

  /**
   * Removes the containers of the notification element
   */
  handleNotificationClose() {
    if (this.notificationContainer) {
      this.notificationContainer.remove();
    }
  }

  /**
   * Set a max height for the language list content
   */
  setLanguageListHeight() {
    const viewportHeight = window.innerHeight;

    if (this.languageListContent) {
      const listTop = this.languageListContent.getBoundingClientRect().top;

      const availableSpace = viewportHeight - listTop;
      if (availableSpace > 0) {
        this.languageListContent.style.maxHeight = `${availableSpace}px`;
      }
    }
  }

  /**
   * Shows the modal language list overlay.
   */
  openOverlay() {
    // Display language list
    this.languageListOverlay.hidden = false;
    this.languageListOverlay.setAttribute('aria-modal', 'true');
    this.languageLink.setAttribute('aria-expanded', 'true');
    this.setLanguageListHeight();
  }

  /**
   * Hides the modal language list overlay.
   */
  closeOverlay() {
    this.languageListOverlay.hidden = true;
    this.languageListOverlay.removeAttribute('aria-modal');
    this.languageLink.setAttribute('aria-expanded', 'false');
  }

  /**
   * Toggles the modal language list overlay.
   *
   * @param {Event} e
   */
  toggleOverlay(e) {
    if (!this.languageListOverlay || !this.focusTrap) return;

    e.preventDefault();

    if (this.languageListOverlay.hasAttribute('hidden')) {
      this.openOverlay();
      this.updateOverlayPosition(this.languageListOverlay, this.languageLink);
      this.focusTrap.activate();
    } else {
      this.focusTrap.deactivate();
    }
  }

  /**
   * Toggles the search form.
   *
   * @param {Event} e
   */
  toggleSearch(e) {
    if (!this.searchForm) return;

    e.preventDefault();

    // Get current status
    const isExpanded =
      this.searchToggle.getAttribute('aria-expanded') === 'true';

    // Close other boxes
    if (
      this.loginToggle &&
      this.loginToggle.getAttribute('aria-expanded') === 'true'
    ) {
      this.toggleLogin(e);
    }

    // Toggle the search form
    this.searchToggle.setAttribute(
      'aria-expanded',
      isExpanded ? 'false' : 'true',
    );

    if (!isExpanded) {
      this.searchForm.classList.add('ecl-site-header__search--active');
      this.setSearchArrow();
    } else {
      this.searchForm.classList.remove('ecl-site-header__search--active');
    }
  }

  setLoginArrow() {
    const loginRect = this.loginBox.getBoundingClientRect();
    if (loginRect.x === 0) {
      const loginToggleRect = this.loginToggle.getBoundingClientRect();
      const arrowPosition =
        document.documentElement.clientWidth -
        loginToggleRect.right +
        loginToggleRect.width / 2;

      this.loginBox.style.setProperty(
        '--ecl-login-arrow-position',
        `calc(${arrowPosition}px - ${this.arrowSize})`,
      );
    }
  }

  setSearchArrow() {
    const searchRect = this.searchForm.getBoundingClientRect();
    if (searchRect.x === 0) {
      const searchToggleRect = this.searchToggle.getBoundingClientRect();
      const arrowPosition =
        document.documentElement.clientWidth -
        searchToggleRect.right +
        searchToggleRect.width / 2;

      this.searchForm.style.setProperty(
        '--ecl-search-arrow-position',
        `calc(${arrowPosition}px - ${this.arrowSize})`,
      );
    }
  }

  /**
   * Toggles the login form.
   *
   * @param {Event} e
   */
  toggleLogin(e) {
    if (!this.loginBox) return;

    e.preventDefault();

    // Get current status
    const isExpanded =
      this.loginToggle.getAttribute('aria-expanded') === 'true';

    // Close other boxes
    if (
      this.searchToggle &&
      this.searchToggle.getAttribute('aria-expanded') === 'true'
    ) {
      this.toggleSearch(e);
    }

    // Toggle the login box
    this.loginToggle.setAttribute(
      'aria-expanded',
      isExpanded ? 'false' : 'true',
    );
    if (!isExpanded) {
      this.loginBox.classList.add('ecl-site-header__login-box--active');
      this.setLoginArrow();
    } else {
      this.loginBox.classList.remove('ecl-site-header__login-box--active');
    }
  }

  /**
   * Handles keyboard events specific to the language list.
   *
   * @param {Event} e
   */
  handleKeyboardLanguage(e) {
    // Open the menu with space and enter
    if (e.keyCode === 32 || e.key === 'Enter') {
      this.toggleOverlay(e);
    }
  }

  /**
   * Handles global keyboard events, triggered outside of the site header.
   *
   * @param {Event} e
   */
  handleKeyboardGlobal(e) {
    if (!this.languageLink) return;
    const listExpanded = this.languageLink.getAttribute('aria-expanded');

    // Detect press on Escape
    if (e.key === 'Escape' || e.key === 'Esc') {
      if (listExpanded === 'true') {
        this.toggleOverlay(e);
      }
      if (
        this.customActionToggle &&
        this.customActionToggle.getAttribute('aria-expanded') === 'true'
      ) {
        this.toggleCustomAction(e);
      }
    }
  }

  /**
   * Handles global click events, triggered outside of the site header.
   *
   * @param {Event} e
   */
  handleClickGlobal(e) {
    if (!this.languageLink && !this.searchToggle && !this.loginToggle) return;
    const listExpanded =
      this.languageLink && this.languageLink.getAttribute('aria-expanded');
    const loginExpanded =
      this.loginToggle &&
      this.loginToggle.getAttribute('aria-expanded') === 'true';
    const searchExpanded =
      this.searchToggle &&
      this.searchToggle.getAttribute('aria-expanded') === 'true';
    // Check if the language list is open
    if (listExpanded === 'true') {
      // Check if the click occured in the language popover
      if (
        !this.languageListOverlay.contains(e.target) &&
        !this.languageLink.contains(e.target)
      ) {
        this.toggleOverlay(e);
      }
    }
    if (loginExpanded) {
      if (
        !this.loginBox.contains(e.target) &&
        !this.loginToggle.contains(e.target)
      ) {
        this.toggleLogin(e);
      }
    }
    if (searchExpanded) {
      if (
        !this.searchForm.contains(e.target) &&
        !this.searchToggle.contains(e.target)
      ) {
        this.toggleSearch(e);
      }
    }

    // Custom action
    const customActionExpanded =
      this.customActionToggle &&
      this.customActionToggle.getAttribute('aria-expanded') === 'true';
    if (customActionExpanded) {
      if (
        !this.customActionOverlay.contains(e.target) &&
        !this.customActionToggle.contains(e.target)
      ) {
        this.toggleCustomAction(e);
      }
    }
  }

  /**
   * Trigger events on resize
   * Uses a debounce, for performance
   */
  handleResize() {
    if (this.resizeTimer) {
      clearTimeout(this.resizeTimer);
    }
    this.resizeTimer = setTimeout(() => {
      // If language overlay is open, reposition
      if (
        this.languageListOverlay &&
        !this.languageListOverlay.hasAttribute('hidden')
      ) {
        this.updateOverlayPosition(this.languageListOverlay, this.languageLink);
      }

      // If custom action overlay is open, reposition
      if (
        this.customActionOverlay &&
        !this.customActionOverlay.hasAttribute('hidden')
      ) {
        this.updateOverlayPosition(
          this.customActionOverlay,
          this.customActionToggle,
          '--ecl-overlay-arrow-position',
        );
      }

      // If the login box is open, re-position arrow
      if (
        this.loginBox &&
        this.loginBox.classList.contains('ecl-site-header__login-box--active')
      ) {
        this.setLoginArrow();
      }

      // If the search box is open, re-position arrow
      if (
        this.searchForm &&
        this.searchForm.classList.contains('ecl-site-header__search--active')
      ) {
        this.setSearchArrow();
      }
    }, 200);
  }

  /**
   * Shows the custom action overlay.
   */
  openCustomAction() {
    if (!this.customActionOverlay) return;
    this.customActionOverlay.hidden = false;
    this.customActionOverlay.setAttribute('aria-modal', 'true');
    this.customActionToggle.setAttribute('aria-expanded', 'true');
  }

  /**
   * Hides the custom action overlay.
   */
  closeCustomAction() {
    if (!this.customActionOverlay) return;
    this.customActionOverlay.hidden = true;
    this.customActionOverlay.removeAttribute('aria-modal');
    this.customActionToggle.setAttribute('aria-expanded', 'false');
  }

  /**
   * Toggles the custom action overlay.
   *
   * @param {Event} e
   */
  toggleCustomAction(e) {
    if (!this.customActionOverlay || !this.customActionFocusTrap) return;

    e.preventDefault();

    // Check current state
    const isHidden = this.customActionOverlay.hasAttribute('hidden');

    if (isHidden) {
      this.openCustomAction();
      // Reuse the same overlay positioning logic,
      // but use a different CSS arrow var for custom action if you like.
      this.updateOverlayPosition(
        this.customActionOverlay,
        this.customActionToggle,
        '--ecl-overlay-arrow-position',
      );
      this.customActionFocusTrap.activate();
    } else {
      this.customActionFocusTrap.deactivate();
    }
  }

  /**
   * Handles keyboard events specific to the custom action toggle.
   *
   * @param {Event} e
   */
  handleKeyboardCustomAction(e) {
    // Open the custom action with space and enter
    if (e.keyCode === 32 || e.key === 'Enter') {
      this.toggleCustomAction(e);
    }
  }
}

export default SiteHeader;