vscode-webview-ui-toolkit
vscode-webview-ui-toolkit copied to clipboard
Add `Menu` to toolkit
Feature/component description
Implement the Menu component. Menu items could be configured to feature selection state, icons, and even sub-menus.
Use case
This component would serve as a relatively generic context menu/popover for executing actions or selecting boolean states. These are typically coupled with icon buttons, right click options, and more in VS Code.
Screenshots/references
@daviddossett is this something your team might be picking up soon? Or would you be interested in external contributions?
I ask because we recently needed this control for some work in https://github.com/microsoft/vscode-edge-devtools/, but ended up creating a custom control as there wasn't an official one available yet. Rather than continuing to enhance our own control, I'd rather see us migrate to something more official (and help build it if necessary) to benefit from future community contributions and maintenance.
From what I've seen it looks like FAST already provides the core functionality for Menu so most of the work would be skinning the control to tie it in to the correct VS Code CSS variables. That said, I've not worked on FAST components yet, so I could be missing some key steps.
Thanks for letting us know! We are indeed looking at releasing that component in the near future. @hawkticehurst is on vacation for another week or two but we recently talked about doing this work in the next month or two. I'll update this thread as soon as I can.
Hi folks, any update on this request?
Hey @fernandops26! (cc @antross)
It looks like there is actually movement for a context menu to be exposed by the VS Code core API, so we're currently waiting/watching to see how that will play out (since we'd prefer to see context menu support in webviews come from core).
You can read some of the conversation here and then see an open PR here.
Hi, are there any updates on this request?
I've looked into the new official context menu API, but I'm not sure if that's a good fit for what I need, which is a menu that only appears when a button is clicked, like in the first screenshot in the original post on this thread (as opposed to the context menu API, which appears when right-clicked, and I've so far been unable to find if there's a way to even trigger that programmatically). The content I show in my webview is also highly dynamic, so having to predefine all the possible context menus in the extension's package.json is quite undesirable. I'd love to know if there are plans to include menu functionality in this toolkit, or if I'll have to look into other solutions.
Hey @HJfod!
No significant updates at this time, unfortunately, but thank you for chiming in!
Re: menu button
I did some technical explorations a few months back and was able to prototype a basic version of a menu button that when clicked can render a context menu by doing something along these lines (this assumes a context menu has been configured in package.json):
<button id="btn">Some button</button>
const btn = document.getElementById('btn');
btn?.addEventListener('click', (e) => {
const evt = new MouseEvent('contextmenu', {
bubbles: true,
clientX: e.clientX,
clientY: e.clientY,
});
e.target?.dispatchEvent(evt);
e.stopImmediatePropagation();
});
Note: The above example will render a context menu at the exact X/Y coordinates of your mouse cursor, so there would need to be some adjustments to render the menu in an X/Y position that aligns with the bottom of the button –– but the main point is that the core idea works.
Re: dynamic content
Yeah, circling back to the final API it does indeed seem like there is no way to dynamically add content at this time, so this might be another request we need to bubble up to the VS Code core because I would really prefer to use the context menu API since it can correctly render native operating system menus.
But while we're here can you give me some more context for what types of things you want to accomplish with a dynamically rendered context menu?
Quick note on toolkit state of the world
Beyond that, I've been mentioning in most issues that the toolkit is really tightly resourced at this time (myself and one other person split our time between this and a handful of other projects) so I just want to set expectations that it might take a while to tackle this, but it is very much on the backlog :) Hope you understand
The VSCode context menu API has some shortages:
- Cannot get the information of the selected DOM(
document.getSelection()) in command args, with which I have to post a message to the webview back again. - Cannot hide the native Copy/Paste/Cut menus
@tianjianchn have you tried adding this? data-vscode-context="{"preventDefaultContextMenuItems": true}"
Or in JSX, data-vscode-context={JSON.stringify({preventDefaultContextMenuItems: true})}
Cannot hide the native Copy/Paste/Cut menus
Yep, exactly like @r3m0t said (thank you for chiming in!), adding the following attribute to the button (or any element where a context menu should be rendered when right-clicked) will hide the default menu items (i.e. Copy/Paste/Cut)
<button id='btn' data-vscode-context='{"preventDefaultContextMenuItems": true}'>Some button</button>
Cannot get the information of the selected DOM (
document.getSelection()) in command args, with which I have to post a message to the webview back again.
Could you explain this a bit more? I don't know too much about document.getSelection() beyond a skim of the MDN docs but it's unclear to me how this is related to context menus.
Wow, thanks @r3m0t and @hawkticehurst , it works!
Could you explain this a bit more? I don't know too much about
document.getSelection()beyond a skim of the MDN docs but it's unclear to me how this is related to context menus.
For example, I select multiple lines in a web page like below, right click at that region and click one context menu(assume Delete files). I have to go back to the webview DOM to get the selected files through document.getSelection(), since VSCode command is running in NodeJs(Extension Host).

Found a solution. I could get the selection and extract the files on contextmenu event in DOM, then set the params in data-vscode-context attribute, which will be passed to the command 😂