1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import React from "react";
- import { Popover } from "./Popover";
- import { render, unmountComponentAtNode } from "react-dom";
- import "./ContextMenu.scss";
- type ContextMenuOption = {
- label: string;
- action(): void;
- };
- type Props = {
- options: ContextMenuOption[];
- onCloseRequest?(): void;
- top: number;
- left: number;
- };
- const ContextMenu = ({ options, onCloseRequest, top, left }: Props) => {
- const isDarkTheme = !!document
- .querySelector(".excalidraw")
- ?.classList.contains("Appearance_dark");
- const wrapperClasses = `excalidraw ${
- isDarkTheme ? "Appearance_dark Appearance_dark-background-none" : ""
- }`;
- return (
- <div className={wrapperClasses}>
- <Popover
- onCloseRequest={onCloseRequest}
- top={top}
- left={left}
- fitInViewport={true}
- >
- <ul
- className="context-menu"
- onContextMenu={(event) => event.preventDefault()}
- >
- {options.map((option, idx) => (
- <li key={idx} onClick={onCloseRequest}>
- <ContextMenuOption {...option} />
- </li>
- ))}
- </ul>
- </Popover>
- </div>
- );
- };
- const ContextMenuOption = ({ label, action }: ContextMenuOption) => (
- <button className="context-menu-option" onClick={action}>
- {label}
- </button>
- );
- let contextMenuNode: HTMLDivElement;
- const getContextMenuNode = (): HTMLDivElement => {
- if (contextMenuNode) {
- return contextMenuNode;
- }
- const div = document.createElement("div");
- document.body.appendChild(div);
- return (contextMenuNode = div);
- };
- type ContextMenuParams = {
- options: (ContextMenuOption | false | null | undefined)[];
- top: number;
- left: number;
- };
- const handleClose = () => {
- unmountComponentAtNode(getContextMenuNode());
- };
- export default {
- push(params: ContextMenuParams) {
- const options = Array.of<ContextMenuOption>();
- params.options.forEach((option) => {
- if (option) {
- options.push(option);
- }
- });
- if (options.length) {
- render(
- <ContextMenu
- top={params.top}
- left={params.left}
- options={options}
- onCloseRequest={handleClose}
- />,
- getContextMenuNode(),
- );
- }
- },
- };
|