JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 51
  • Score
    100M100P100Q83450F
  • License MIT

A context menu in Preact

Package Exports

  • preact-context-menu
  • preact-context-menu/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (preact-context-menu) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Preact Context Menu

Installation

Using yarn

yarn add preact-context-menu

Using npm

npm install --save preact-context-menu

Usage

The simplest way to use preact-context-menu is to setup a pair of ContextMenu and ContextMenuTrigger with the same ID

import { h } from "preact";
import { ContextMenu, ContextMenuTrigger } from "preact-context-menu";

function Component() {
    return (
        <div>
            <ContextMenu id="unique_id">
                My Context Menu
            </ContextMenu>
            <ContextMenuTrigger id="unique_id">
                Right-click me to open context menu!
            </ContextMenuTrigger>
        </div>
    );
}

Opening and closing menus

Besides closing when clicked outside of, a menu can also be closed when a MenuItem is clicked or when you call the function provided from the MenuContext that can be imported from preact-context-menu/menu

An onClose function prop is triggered on ContextMenu if present, with a data parameter if provided to a MenuItem or passed to the MenuContext close function, or undefined when closed by clicking outside of the menu

import { h } from "preact";
import { ContextMenu, MenuItem } from "preact-context-menu";
import { MenuContext } from "preact-context-menu/menu";

function Menu() {
    return (
        <ContextMenu id="unique_id">
            <MenuItem>
                Click me to close the menu!
            </MenuItem>
            <br /><br />
            {/* or to pass info to the onClose prop on ContextMenu */}
            <MenuItem data={{ hello: "Hello, world!" }}>
                Click me to close the menu with data!
            </MenuItem>
            <br /><br />
            <MenuContext.Consumer>
                {(close) => (
                    <div>
                        <span onClick={() => close()}>Click me to close the menu!</span>
                        <br /><br />
                        <span onClick={() => close({ hello: "Hello, world!" })}>Click me to close the menu with data!</span>
                    </div>
                )}
            </MenuContext.Consumer>
        </ContextMenu>
    )
}

If you want to avoid wrapping your component in a span that listens for the browser's context menu event, you can use attachContextMenu to create a trigger out of any component, optionally passing any extra data.

import { h } from "preact";
import { ContextMenu, useTriggerEvents } from "preact-context-menu";

function Component() {
    return (
        <div>
            <ContextMenu id="unique_id">
                My Context Menu
            </ContextMenu>
            <div {...useTriggerEvents("unique_id")}>
                Right-click me to open context menu!
            </div>
            <div {...useTriggerEvents("unique_id", { hello: "Hello, world!" })}>
                Right-click me to open context menu with data!
            </div>
        </div>
    );
}

Opening a menu programmatically

A context menu can also be opened by calling the openContextMenu function with the context menu ID and optionally any data and/or the coordinates where the context menu should appear

A context menu will open at the last known mouse location if no coordinates are provided.

import { openContextMenu } from "preact-context-menu";

openContextMenu("unique_id");

// Or with the coordinates
openContextMenu("unique_id", {}, {
    x: 30,
    y: 10,
});

// Providing extra data
openContextMenu("unique_id", { hello: "Hello, world!" });

Getting data into and out of a menu

For getting data into a context menu, you can use a ContextMenuWithData, which instead of an element, takes a function that passes the data down

import { h } from "preact";
import { ContextMenuWithData } from "preact-context-menu";

function Menu() {
    return (
        <ContextMenuWithData id="unique_id">
            {(data) => (
                <span>{JSON.stringify(data)}</span>
            )}
        </ContextMenuWithData>
    );
}

To get data out of a context menu containing menu items, you can use the onClose prop on the context menu to detect when the menu is closed either by clicking on a menu item, or outside the menu

When the menu is closed by clicking outside of it, onClose will be passed undefined as the data argument.

import { h } from "preact";
import { useState } from "preact/hooks";
import { ContextMenu } from "preact-context-menu";

function Component() {
    const [data, setData] = useState<any>(undefined);
    const onClose = useCallback((data: any) => {
        console.log(data);
        setData(data);
    }, []);

    return (
        <div>
            <div>Returned data: {data ? data.toString() : "undefined"}</div>
            <br />
            <ContextMenu id="unique_id" onClose={onClose}>
                <ul>
                    <li>
                        <MenuItem data={1}>
                            Click me to return 1!
                        </MenuItem>
                    </li>
                    <li>
                        <MenuItem data="Hello, world!">
                            Or me to return "Hello, world!"!
                        </MenuItem>
                    </li>
                </ul>
            </ContextMenu>
        </div>
    );
}