menu2html is a quick-and-dirty 3KB JS library for generating desktop-like menubar.

^ try playing with the menu above to see it work.

it contains a single function that takes in a JS object and outputs a string containing the HTML.

it can be used to generate on-the-fly on the browser side, or as a part of program that writes html to file.

you can find the full source code here.

example:

      let menu = {'Group':{'Item 1':function(){}, 'Item 2':function(){}}};
      let html = menu2html(menu);
      document.getElementById('parent-div').innerHTML = html;
    

the menu above is generated from the following object. try edit and click here to compile

please refrain from pasting arbitrary code above. whatever you enter will be eval()'ed.

try `filter:invert(100%)` for "light mode" and other filters for brightness/tint etc. click here to try

To make radios and checkboxes, prefix the label with `( )` (radio off) or `(*)` (radio on) or `[ ]` (checkbox off) or `[x]` (checkbox on). Groups of radio items are delimited by separators. Only one in a group of radios can be selected. Checkboxes work independantly of each other. Try them out in the `Options` menu above.

Note that when generating a menu on the client side, the callbacks passed to menu2html() cannot refer to local contexts (meaning global functions and variables only). This is because the output is a string, and cannot include closure. However, you can find the element by ID and manually attach callbacks if closure is necessary. For example:

  let myGlobalVar = 1;
  function foo(){
    let myLocalVar = 2;
    document.body.innerHTML = menu2html({'Group':{
      'Item 1': function(){alert(myGlobalVar)},     // this is OK
      'Item 2': function(){alert(myLocalVar)},      // won't work
      'Item 3': function(){}                        // add the callback manually below
    }});
    
    document.getElementById('Group/Item 3').addEventListener('click',function(){
      alert(myLocalVar);  // this will work
    });
  }

Notice that the element ID of each menu item is its path joined with '/'. e.g. "My Menu/My Submenu/Subsubmenu/Item Name"

menu2html otherwise allows very little customization, as it is intended for dropping into web experiments as quick-and-dirty bare-minimum ui. please use a proper gui framework if fancier result is desired.

Lingdong Huang 2021. MIT License