excalidraw/src/components/ContextMenu.tsx
dependabot-preview[bot] 722c498abe
Bump prettier from 1.19.1 to 2.0.1 (#1060)
* Bump prettier from 1.19.1 to 2.0.1

Bumps [prettier](https://github.com/prettier/prettier) from 1.19.1 to 2.0.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/1.19.1...2.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Update formatting

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Panayiotis Lipiridis <lipiridis@gmail.com>
2020-03-23 13:05:07 +02:00

90 lines
1.9 KiB
TypeScript

import React from "react";
import { Popover } from "./Popover";
import { render, unmountComponentAtNode } from "react-dom";
import "./ContextMenu.css";
type ContextMenuOption = {
label: string;
action(): void;
};
type Props = {
options: ContextMenuOption[];
onCloseRequest?(): void;
top: number;
left: number;
};
function ContextMenu({ options, onCloseRequest, top, left }: Props) {
return (
<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>
);
}
function ContextMenuOption({ label, action }: ContextMenuOption) {
return (
<button className="context-menu-option" onClick={action}>
{label}
</button>
);
}
let contextMenuNode: HTMLDivElement;
function 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;
};
function 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(),
);
}
},
};