2019-08-27 23:50:43 -07:00
|
|
|
import React, { useState } from 'react';
|
2022-04-22 14:33:13 +01:00
|
|
|
|
2020-12-15 10:53:04 +01:00
|
|
|
import { ContextMenu } from '../ContextMenu/ContextMenu';
|
2019-08-27 23:50:43 -07:00
|
|
|
|
2022-09-05 11:43:02 -04:00
|
|
|
export interface WithContextMenuProps {
|
2020-10-27 17:18:45 +02:00
|
|
|
/** Menu item trigger that accepts openMenu prop */
|
2019-08-27 23:50:43 -07:00
|
|
|
children: (props: { openMenu: React.MouseEventHandler<HTMLElement> }) => JSX.Element;
|
2020-10-27 17:18:45 +02:00
|
|
|
/** A function that returns an array of menu items */
|
2021-03-18 12:58:07 +01:00
|
|
|
renderMenuItems: () => React.ReactNode;
|
2022-02-09 11:43:08 -08:00
|
|
|
/** On menu open focus the first element */
|
|
|
|
|
focusOnOpen?: boolean;
|
2019-08-27 23:50:43 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-09 11:43:08 -08:00
|
|
|
export const WithContextMenu: React.FC<WithContextMenuProps> = ({ children, renderMenuItems, focusOnOpen = true }) => {
|
2019-08-27 23:50:43 -07:00
|
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
2020-06-22 09:02:58 -04:00
|
|
|
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
|
2019-08-27 23:50:43 -07:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{children({
|
2021-01-20 07:59:48 +01:00
|
|
|
openMenu: (e) => {
|
2019-08-27 23:50:43 -07:00
|
|
|
setIsMenuOpen(true);
|
2020-06-22 09:02:58 -04:00
|
|
|
setMenuPosition({
|
2019-08-27 23:50:43 -07:00
|
|
|
x: e.pageX,
|
|
|
|
|
y: e.pageY,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
|
|
{isMenuOpen && (
|
|
|
|
|
<ContextMenu
|
|
|
|
|
onClose={() => setIsMenuOpen(false)}
|
|
|
|
|
x={menuPosition.x}
|
|
|
|
|
y={menuPosition.y}
|
2021-03-18 12:58:07 +01:00
|
|
|
renderMenuItems={renderMenuItems}
|
2022-02-09 11:43:08 -08:00
|
|
|
focusOnOpen={focusOnOpen}
|
2019-08-27 23:50:43 -07:00
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|