Skip to content

fatalerrorcoded/preact-context-menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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>
    );
}

About

A context menu for Preact

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published