All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.resources.frontend.menubarConnector.js Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2000-2024 Vaadin Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
import './contextMenuConnector.js';

  /**
   * Initializes the connector for a menu bar element.
   *
   * @param {HTMLElement} menubar
   * @param {string} appId
   */
  function initLazy(menubar, appId) {
    if (menubar.$connector) {
      return;
    }

    const observer = new MutationObserver((records) => {
      const hasChangedAttributes = records.some((entry) => {
        const oldValue = entry.oldValue;
        const newValue = entry.target.getAttribute(entry.attributeName);
        return oldValue !== newValue;
      });

      if (hasChangedAttributes) {
        menubar.$connector.generateItems();
      }
    });

  menubar.$connector = {
    /**
     * Generates and assigns the items to the menu bar.
     *
     * When the method is called without providing a node id,
     * the previously generated items tree will be used.
     * That can be useful if you only want to sync the disabled and hidden properties of root items.
     *
     * @param {number | undefined} nodeId
     */
    generateItems(nodeId) {
      if (!menubar.shadowRoot) {
        // workaround for https://github.com/vaadin/flow/issues/5722
        setTimeout(() => menubar.$connector.generateItems(nodeId));
        return;
      }

        if (!menubar._container) {
          // Menu-bar defers first buttons render to avoid re-layout
          // See https://github.com/vaadin/web-components/issues/7271
          queueMicrotask(() => menubar.$connector.generateItems(nodeId));
          return;
        }

        if (nodeId) {
          menubar.__generatedItems = window.Vaadin.Flow.contextMenuConnector.generateItemsTree(appId, nodeId);
        }

        let items = menubar.__generatedItems || [];

        items.forEach((item) => {
          // Propagate disabled state from items to parent buttons
          item.disabled = item.component.disabled;

          // Saving item to component because `_item` can be reassigned to a new value
          // when the component goes to the overflow menu
          item.component._rootItem = item;
        });

        // Observe for hidden and disabled attributes in case they are changed by Flow.
        // When a change occurs, the observer will re-generate items on top of the existing tree
        // to sync the new attribute values with the corresponding properties in the items array.
        items.forEach((item) => {
          observer.observe(item.component, {
            attributeFilter: ['hidden', 'disabled'],
            attributeOldValue: true
          });
        });

        // Remove hidden items entirely from the array. Just hiding them
        // could cause the overflow button to be rendered without items.
        //
        // The items-prop needs to be set even when all items are visible
        // to update the disabled state and re-render buttons.
        items = items.filter((item) => !item.component.hidden);

        menubar.items = items;

      // Propagate click events from the menu buttons to the item components
      menubar._buttons.forEach((button) => {
        if (button.item && button.item.component) {
          button.addEventListener('click', (e) => {
            if (e.composedPath().indexOf(button.item.component) === -1) {
              button.item.component.click();
              e.stopPropagation();
            }
          });
        }
      });
    }
  };
}

  function setClassName(component) {
    const item = component._rootItem || component._item;

    if (item) {
      item.className = component.className;
    }
  }

window.Vaadin.Flow.menubarConnector = { initLazy, setClassName };




© 2015 - 2025 Weber Informatics LLC | Privacy Policy