diff --git a/v3/V3 Changes.md b/v3/V3 Changes.md
index f2fe55308..f805429c1 100644
--- a/v3/V3 Changes.md
+++ b/v3/V3 Changes.md
@@ -59,3 +59,14 @@ TBD
Dialogs are now available in JavaScript!
+## Drag and Drop
+
+TBD
+
+## Context Menus
+
+Context menus are contextual menus that are shown when the user right clicks on an element. Creating a context menu is the same as creating a standard menu , by using `app.NewMenu()`. To make the context menu available to a window, call `window.RegisterContextMenu(name, menu)`. The name will be the id of the context menu and used by the frontend.
+
+To indicate that an element has a context menu, add the `data-contextmenu-id` attribute to the element. The value of this attribute should be the name of a context menu previously registered with the window.
+
+It is possible to register a context menu at the application level, making it available to all windows. This can be done using `app.RegisterContextMenu(name, menu)`. If a context menu cannot be found at the window level, the application context menus will be checked. A demo of this can be found in `v3/examples/contextmenus`.
\ No newline at end of file
diff --git a/v3/examples/contextmenus/assets/index.html b/v3/examples/contextmenus/assets/index.html
new file mode 100644
index 000000000..9f499d500
--- /dev/null
+++ b/v3/examples/contextmenus/assets/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+ Title
+
+
+
+
+Events Demo
+
+
+
1
+
+
+
2
+
+
+
3
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/v3/examples/contextmenus/main.go b/v3/examples/contextmenus/main.go
new file mode 100644
index 000000000..0ed4fcc69
--- /dev/null
+++ b/v3/examples/contextmenus/main.go
@@ -0,0 +1,70 @@
+package main
+
+import (
+ "embed"
+ _ "embed"
+ "fmt"
+ "log"
+
+ "github.com/wailsapp/wails/v3/pkg/application"
+)
+
+//go:embed assets
+var assets embed.FS
+
+func main() {
+
+ app := application.New(application.Options{
+ Name: "Context Menu Demo",
+ Description: "A demo of the Context Menu API",
+ Mac: application.MacOptions{
+ ApplicationShouldTerminateAfterLastWindowClosed: true,
+ },
+ })
+
+ mainWindow := app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{
+ Title: "Context Menu Demo",
+ Assets: application.AssetOptions{
+ FS: assets,
+ },
+ Mac: application.MacWindow{
+ Backdrop: application.MacBackdropTranslucent,
+ TitleBar: application.MacTitleBarHiddenInsetUnified,
+ InvisibleTitleBarHeight: 50,
+ },
+ })
+
+ app.NewWebviewWindowWithOptions(&application.WebviewWindowOptions{
+ Title: "Context Menu Demo",
+ Assets: application.AssetOptions{
+ FS: assets,
+ },
+ Mac: application.MacWindow{
+ Backdrop: application.MacBackdropTranslucent,
+ TitleBar: application.MacTitleBarHiddenInsetUnified,
+ InvisibleTitleBarHeight: 50,
+ },
+ })
+
+ contextMenu := app.NewMenu()
+ contextMenu.Add("Click Me").OnClick(func(data *application.Context) {
+ fmt.Printf("Context menu data: %+v\n", data.ContextMenuData())
+ })
+
+ globalContextMenu := app.NewMenu()
+ globalContextMenu.Add("Default context menu item").OnClick(func(data *application.Context) {
+ fmt.Printf("Context menu data: %+v\n", data.ContextMenuData())
+ })
+
+ // Registering the menu with a window will make it available to that window only
+ mainWindow.RegisterContextMenu("test", contextMenu)
+
+ // Registering the menu with the app will make it available to all windows
+ app.RegisterContextMenu("test", globalContextMenu)
+
+ err := app.Run()
+
+ if err != nil {
+ log.Fatal(err.Error())
+ }
+}
diff --git a/v3/examples/events/assets/index.html b/v3/examples/events/assets/index.html
index ea898b037..1e59ac92f 100644
--- a/v3/examples/events/assets/index.html
+++ b/v3/examples/events/assets/index.html
@@ -23,17 +23,6 @@
window.addEventListener("dragstart", (event) =>
event.dataTransfer.setData("text/plain", "This text may be dragged")
);
- window.addEventListener("contextmenu", (event) => {
- console.log({event})
- let element = event.target;
- let contextMenuId = element.getAttribute("data-contextmenu-id");
- if (contextMenuId) {
- let contextMenuData = element.getAttribute("data-contextmenu-data");
- console.log({contextMenuId, contextMenuData, x: event.clientX, y: event.clientY});
- _wails.openContextMenu(contextMenuId, event.clientX, event.clientY, contextMenuData);
- event.preventDefault();
- }
- });