# Context Menu

# ContextMenu

# Description

The ContextMenu component displays a contextual pop-up menu that appears relative to a target element or specific screen coordinates. It is designed for surfacing a list of commands or options in response to user interactions such as clicks or right-clicks. This component is part of the Surfaces group and supports features like submenus, dividers, headers, and disabled items. It is ideal when you need to present contextual actions without cluttering the main UI.

# Usage

The ContextMenu is instantiated using the static helper method from the Tesserae.UI class. Items can be added via the fluent API using the Items method, and the menu is shown by calling ShowFor (with either an IComponent or an HTMLElement) or ShowAt (with explicit x, y coordinates). When the menu is active, it manages focus and supports keyboard navigation (up/down arrows to navigate, Esc to dismiss).

Below is a minimalistic sample demonstrating how to create and show a basic ContextMenu:

using System;
using Tesserae;
using static Tesserae.UI;
using static H5.Core.dom;

public class MyContextMenuSample
{
    public void ShowMenuForButton()
    {
        // Create a context menu and add items
        var contextMenu = ContextMenu().Items(
            ContextMenuItem("New").OnClick((s, e) => Toast().Information("New clicked")),
            ContextMenuItem().Divider(),
            ContextMenuItem("Edit").OnClick((s, e) => Toast().Information("Edit clicked")),
            ContextMenuItem("Delete").Disabled() // a disabled item
        );

        // Create a button that triggers the context menu
        var button = Button("Open Context Menu").OnClick((s, e) => {
            // Show the context menu relative to the button
            contextMenu.ShowFor(button);
        });

        // Render the button to the document body (or attach it to any container)
        document.body.appendChild(button.Render());
    }
}

# Methods

  • Clear()
    • Description: Clears all current menu items from the ContextMenu.
    • Parameters: None.
  • Replace(Item newComponent, Item oldComponent)
    • Description: Replaces an existing menu item (oldComponent) with a new one (newComponent) in the ContextMenu.
    • Parameters:
      • newComponent: The new menu item component.
      • oldComponent: The menu item component to be replaced.
  • Add(Item component)
    • Description: Adds a new menu item to the ContextMenu and sets its click behavior to invoke any registered handlers and hide the menu.
    • Parameters:
      • component: The menu item to be added.
  • OnHide(Action onHidden)
    • Description: Registers an action to be executed when the ContextMenu is hidden.
    • Parameters:
      • onHidden: The callback action to run upon hiding.
  • ShowFor(IComponent component, int distanceX = 1, int distanceY = 1)
    • Description: Displays the ContextMenu relative to another Tesserae component.
    • Parameters:
      • component: The component that serves as the anchor.
      • distanceX: Optional horizontal offset.
      • distanceY: Optional vertical offset.
  • ShowFor(HTMLElement element, int distanceX = 1, int distanceY = 1)
    • Description: Displays the ContextMenu relative to an HTML element.
    • Parameters:
      • element: The HTMLElement to anchor to.
      • distanceX: Optional horizontal offset.
      • distanceY: Optional vertical offset.
  • ShowAt(int x, int y, int minWidth)
    • Description: Displays the ContextMenu at specified screen coordinates with a defined minimum width.
    • Parameters:
      • x: The x-coordinate where the menu will appear.
      • y: The y-coordinate where the menu will appear.
      • minWidth: The minimum width of the menu.
  • Items(params Item[] children)
    • Description: A helper method to add multiple menu items at once.
    • Parameters:
      • children: An array of menu items to add.

# Public Properties

No public properties are explicitly exposed for the ContextMenu component.

# Samples

# Basic ContextMenu with Standard Items

This sample demonstrates how to instantiate a ContextMenu, add standard menu items including a divider and a disabled item, and then show the menu relative to a button click.

using System;
using Tesserae;
using static Tesserae.UI;
using static H5.Core.dom;

public class ContextMenuBasicSample
{
    public void RenderSample()
    {
        // Create the ContextMenu with a set of items.
        var contextMenu = ContextMenu().Items(
            ContextMenuItem("New").OnClick((s, e) => Toast().Information("New clicked")),
            ContextMenuItem().Divider(),
            ContextMenuItem("Edit").OnClick((s, e) => Toast().Information("Edit clicked")),
            ContextMenuItem("Properties").OnClick((s, e) => Toast().Information("Properties clicked")),
            ContextMenuItem("Header").Header(),
            ContextMenuItem("Disabled").Disabled(),
            ContextMenuItem("Link").OnClick((s, e) => Toast().Information("Link clicked"))
        );

        // Create a button that will trigger the ContextMenu.
        var openButton = Button("Open Context Menu").OnClick((s, e) =>
        {
            // Display the context menu relative to the button.
            contextMenu.ShowFor(openButton);
        });

        // Attach the button to the document.
        document.body.appendChild(openButton.Render());
    }
}

# ContextMenu with Submenus

This sample demonstrates a ContextMenu that includes items with submenus. Submenus are defined by creating additional ContextMenu instances and attaching them to a parent menu item.

using System;
using Tesserae;
using static Tesserae.UI;
using static H5.Core.dom;

public class ContextMenuWithSubmenusSample
{
    public void RenderSample()
    {
        // Define the submenu for additional editing options.
        var subMenu = ContextMenu().Items(
            ContextMenuItem("Sub Edit 1").OnClick((s, e) => Toast().Information("Sub Edit 1 clicked")),
            ContextMenuItem("Sub Edit 2").OnClick((s, e) => Toast().Information("Sub Edit 2 clicked"))
        );
        
        // Create the main ContextMenu and attach a submenu to one of the items.
        var mainMenu = ContextMenu().Items(
            ContextMenuItem("New").OnClick((s, e) => Toast().Information("New clicked")),
            ContextMenuItem("Edit").OnClick((s, e) => Toast().Information("Edit clicked")),
            ContextMenuItem("More Options").SubMenu(subMenu),
            ContextMenuItem("Disabled").Disabled()
        );

        // Create a button that triggers the main context menu.
        var button = Button("Open Menu with Submenus").OnClick((s, e) =>
        {
            mainMenu.ShowFor(button);
        });

        // Append the button to the document.
        document.body.appendChild(button.Render());
    }
}

# See also

  • ContextMenuItem: Use ContextMenuItem to define individual menu entries.
  • Toast: Use Toast to provide user feedback when commands are executed.
  • Dialog, Panel: Other surface components that manage overlays and user interactions.