{"id":18045632,"url":"https://github.com/piroor/webextensions-lib-menu-ui","last_synced_at":"2025-04-10T01:33:13.241Z","repository":{"id":138842802,"uuid":"120408264","full_name":"piroor/webextensions-lib-menu-ui","owner":"piroor","description":"Menu-like UI library for Firefox addons based on WebExtensions","archived":false,"fork":false,"pushed_at":"2025-01-07T02:21:40.000Z","size":275,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"trunk","last_synced_at":"2025-03-24T03:11:28.118Z","etag":null,"topics":["firefox-addon","hacktoberfest","menu","panel","popup","submenu","webextensions"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piroor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-06T05:53:07.000Z","updated_at":"2025-01-07T02:21:44.000Z","dependencies_parsed_at":"2023-03-17T23:15:56.051Z","dependency_job_id":null,"html_url":"https://github.com/piroor/webextensions-lib-menu-ui","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-menu-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-menu-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-menu-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piroor%2Fwebextensions-lib-menu-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piroor","download_url":"https://codeload.github.com/piroor/webextensions-lib-menu-ui/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248140561,"owners_count":21054303,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firefox-addon","hacktoberfest","menu","panel","popup","submenu","webextensions"],"created_at":"2024-10-30T18:13:48.563Z","updated_at":"2025-04-10T01:33:13.184Z","avatar_url":"https://github.com/piroor.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# webextensions-lib-menu-ui\n\n![Build Status](https://github.com/piroor/webextensions-lib-menu-ui/actions/workflows/main.yml/badge.svg?branch=trunk)\n\nHelps to provide menu like UI.\n\nThe menu will behave similar to a native menu UI for major operations via the pointing device and the keyboard).\n\n## Screenshots\n\n![(Screenshot of menu-like UI)](screenshots/menu.png)\n\n![(Screenshot of panel-like UI)](screenshots/panel.png)\n\n## Usage\n\nLoad the file `MenuUI.js` from any visible document (sidebar panel or browser action panel), like:\n\n```html\n\u003cscript type=\"application/javascript\" src=\"./MenuUI.js\"\u003e\u003c/script\u003e\n```\n\nAnd define hierarchical menu based on `ul`-`li` list, like:\n\n```html\n\u003cul id=\"menu\"\u003e\n  \u003cli\u003e\u0026amp;Save\u003c/li\u003e\n  \u003cli\u003eCo\u0026amp;py\n    \u003cul\u003e\n      \u003cli\u003e\u0026amp;Title\u003c/li\u003e\n      \u003cli\u003e\u0026amp;URL\u003c/li\u003e\n      \u003cli\u003e\u0026amp;Metadata\n        \u003cul\u003e\n          \u003cli\u003e\u0026amp;Author\u003c/li\u003e\n          \u003cli\u003e\u0026amp;Email\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/li\u003e\n  \u003cli class=\"separator\"\u003e\u003c/li\u003e\n  \u003cli\u003e\u0026amp;Close\u003c/li\u003e\n\u003c/ul\u003e\n```\n\nThen, create an instance of `MenuUI` with required parameters like:\n\n```javascript\nvar menuUI = new MenuUI({\n  root:      document.getElementById('menu'),\n  onCommand: (aItem, aEvent) =\u003e {\n    // handle click event on an item\n  }\n});\n```\n\nNow you can open/close menu-like UI by its instance method:\n\n```javascript\nwindow.addEventListener('contextmenu', aEvent =\u003e {\n  aEvent.stopPropagation();\n  aEvent.preventDefault();\n  // open custom menu instead of native context menu\n  menuUI.open({\n    left: aEvent.clientX,\n    top:  aEvent.clientY\n  });\n});\n```\n\n\n### Parameters for the constructor\n\nHere is the list of parameters for the `MenuUI` constructor:\n\n * `root` (required): The top-level list to become a menu. (`Element`)\n * `onCommand` (required): The handler for click event on a menu item. (`Function`)\n * `onShown` (optional): The handler called when the menu is shown (opened). (`Function`)\n * `onHidden` (optional): The handler called when the menu is hidden (closed). (`Function`)\n * `appearance` (optional): The visual style of the menu. (`String`, default is `menu`.) Possible values:\n   - `menu`: similar to native menu UI.\n   - `panel`: similar to popup panel UI.\n * `animationDuration` (optional): The duration of the animation of fade-in-out effect, in milliseconds. (`Integer`, default value is `150`.)\n * `subMenuOpenDelay` (optional): The delay when a submenu is opened after its parent item is pointed, in milliseconds. (`Integer`, default value is `300`.)\n * `subMenuCloseDelay` (optional): The delay when a submenu is closed after foreign item is pointed, in milliseconds. (`Integer`, default value is `300`.)\n * `incrementalSearch` (optional): Activate incremental search mode or not. (`Boolean`, default value is `false`.)\n * `incrementalSearchTimeout` (optional): Timeout seconds to clear last incremental search buffer. (`Integer`, default value is `1000`.)\n\n\n## Features of instances\n\n### How to open the menu\n\nThe instance method `open()` opens the menu. You can specify the position of the opened menu in two ways:\n\n#### Open the menu at specified position\n\nSpecifying 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:\n\n```javascript\nwindow.addEventListener('click', aEvent =\u003e {\n  menuUI.open({\n    left: aEvent.clientX,\n    top:  aEvent.clientY\n  });\n});\n```\n\n#### Open the menu near specified anchor element\n\nSpecifying 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:\n\n```javascript\nconst button = document.getElementById('button');\nbutton.addEventListener('click', () =\u003e {\n  menuUI.open({\n    anchor: button\n  });\n});\n```\n\n#### Canceller for `open()` method\n\nThe `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:\n\n```javascript\nlet canceled = false;\n\nbutton.addEventListener('click', () =\u003e {\n  menuUI.open({\n    left: aEvent.clientX,\n    top:  aEvent.clientY,\n    canceller: () =\u003e {\n      return canceled;\n    }\n  });\n});\n\nbutton.addEventListener('dblclick', () =\u003e {\n  canceled = true;\n  menuUI.close();\n});\n```\n\nOn this case, if you double-click the button, the menu won't be shown.\n\n### How to close the menu\n\nCalling an instance method `close()` will close the opened menu. This method will close all submenus also.\n\n### How to know the menu is opened or not\n\nThere is an instance property `opened`. It returns a boolean value and `true` means \"opened\", `false` means \"closed\".\n\n### How to run command by menu selection\n\nA 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.\n\n```javascript\nvar menuUI = new MenuUI({\n  root:      document.getElementById('menu'),\n  onCommand: (aItem, aEvent) =\u003e {\n    switch (aItem.id) {\n      case 'command1':\n        doCommand1();\n        break;\n\n      case 'command2':\n        doCommand2();\n        break;\n\n      default:\n        doGenericCommand(aItem.dataset.value);\n        break;\n    }\n    menuUI.close();\n  }\n});\n```\n\nNote that the menu is not closed automatically by clicking on a menu item. You need to close the menu itself manually after doing something.\n\n### Menu separator\n\nBlank `\u003cli\u003e` elements with a class `separator` are treated as menu separator.\n\n### Accesskeys for keyboard operations\n\nIf the label of a menu item contains a part `\u0026` (`\u0026amp;` in HTML) followed by an non-whitespace character (like `\u0026A`), the character following to the `\u0026` will be treated as the accesskey of the item.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiroor%2Fwebextensions-lib-menu-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiroor%2Fwebextensions-lib-menu-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiroor%2Fwebextensions-lib-menu-ui/lists"}