Giter VIP home page Giter VIP logo

webextensions-lib-menu-ui's Introduction

webextensions-lib-menu-ui

Build Status

Helps to provide menu like UI.

The menu will behave similar to a native menu UI for major operations via the pointing device and the keyboard).

Screenshots

(Screenshot of menu-like UI)

(Screenshot of panel-like UI)

Usage

Load the file MenuUI.js from any visible document (sidebar panel or browser action panel), like:

<script type="application/javascript" src="./MenuUI.js"></script>

And define hierarchical menu based on ul-li list, like:

<ul id="menu">
  <li>&amp;Save</li>
  <li>Co&amp;py
    <ul>
      <li>&amp;Title</li>
      <li>&amp;URL</li>
      <li>&amp;Metadata
        <ul>
          <li>&amp;Author</li>
          <li>&amp;Email</li>
        </ul>
      </li>
    </ul>
  </li>
  <li class="separator"></li>
  <li>&amp;Close</li>
</ul>

Then, create an instance of MenuUI with required parameters like:

var menuUI = new MenuUI({
  root:      document.getElementById('menu'),
  onCommand: (aItem, aEvent) => {
    // handle click event on an item
  }
});

Now you can open/close menu-like UI by its instance method:

window.addEventListener('contextmenu', aEvent => {
  aEvent.stopPropagation();
  aEvent.preventDefault();
  // open custom menu instead of native context menu
  menuUI.open({
    left: aEvent.clientX,
    top:  aEvent.clientY
  });
});

Parameters for the constructor

Here is the list of parameters for the MenuUI constructor:

  • root (required): The top-level list to become a menu. (Element)
  • onCommand (required): The handler for click event on a menu item. (Function)
  • onShown (optional): The handler called when the menu is shown (opened). (Function)
  • onHidden (optional): The handler called when the menu is hidden (closed). (Function)
  • appearance (optional): The visual style of the menu. (String, default is menu.) Possible values:
    • menu: similar to native menu UI.
    • panel: similar to popup panel UI.
  • animationDuration (optional): The duration of the animation of fade-in-out effect, in milliseconds. (Integer, default value is 150.)
  • subMenuOpenDelay (optional): The delay when a submenu is opened after its parent item is pointed, in milliseconds. (Integer, default value is 300.)
  • subMenuCloseDelay (optional): The delay when a submenu is closed after foreign item is pointed, in milliseconds. (Integer, default value is 300.)
  • incrementalSearch (optional): Activate incremental search mode or not. (Boolean, default value is false.)
  • incrementalSearchTimeout (optional): Timeout seconds to clear last incremental search buffer. (Integer, default value is 1000.)

Features of instances

How to open the menu

The instance method open() opens the menu. You can specify the position of the opened menu in two ways:

Open the menu at specified position

Specifying corrdinates via left and top will show the menu near given coordinates. Typically this form is useful to open menu based on mouse events, like:

window.addEventListener('click', aEvent => {
  menuUI.open({
    left: aEvent.clientX,
    top:  aEvent.clientY
  });
});

Open the menu near specified anchor element

Specifying an element via anchor will show the menu near the element. Typically this form is useful to open menu as a dropdown or popup, like:

const button = document.getElementById('button');
button.addEventListener('click', () => {
  menuUI.open({
    anchor: button
  });
});

Canceller for open() method

The open() instance method accepts one more optional parameter, canceller. It is a function returning boolean value, and the opening operation of the menu will be canceled if the function returns false. For example:

let canceled = false;

button.addEventListener('click', () => {
  menuUI.open({
    left: aEvent.clientX,
    top:  aEvent.clientY,
    canceller: () => {
      return canceled;
    }
  });
});

button.addEventListener('dblclick', () => {
  canceled = true;
  menuUI.close();
});

On this case, if you double-click the button, the menu won't be shown.

How to close the menu

Calling an instance method close() will close the opened menu. This method will close all submenus also.

How to know the menu is opened or not

There is an instance property opened. It returns a boolean value and true means "opened", false means "closed".

How to run command by menu selection

A function specified via the onCommand parameter for the constructor will be called when a menu item without submenu is triggered. The function will receive the triggered menu item as its first argument. The second argument is the raw DOM event. Then you can do anything for the item.

var menuUI = new MenuUI({
  root:      document.getElementById('menu'),
  onCommand: (aItem, aEvent) => {
    switch (aItem.id) {
      case 'command1':
        doCommand1();
        break;

      case 'command2':
        doCommand2();
        break;

      default:
        doGenericCommand(aItem.dataset.value);
        break;
    }
    menuUI.close();
  }
});

Note that the menu is not closed automatically by clicking on a menu item. You need to close the menu itself manually after doing something.

Menu separator

Blank <li> elements with a class separator are treated as menu separator.

Accesskeys for keyboard operations

If the label of a menu item contains a part & (&amp; in HTML) followed by an non-whitespace character (like &A), the character following to the & will be treated as the accesskey of the item.

webextensions-lib-menu-ui's People

Contributors

piroor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

webextensions-lib-menu-ui's Issues

Support multi-letters keyboard navigation for item labels

Original: piroor/treestyletab#3077

Steps to reproduce

  1. Prepare multiple items with labels:
    • cabinet
    • column
    • auto
    • bold
  2. Hit "cab" from the keybaord.

Actual result

It moves focus as "cabinet" => "auto" => "bold" based on implicit accesskeys (the first letter).

Expectedresult

It should focus to the item "cabinet" (when they have no accesskey).

This behavior is beyond the simulation of Firefox's native menu, so this should be an optional behavior.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.