import { createStyles, Menu } from "@mantine/core"; import { BlockSchema } from "bocknoat-core"; import * as _ from "lodash"; import { useEffect, useRef } from "react"; import { ReactSlashMenuItem } from "../ReactSlashMenuItem"; import { SlashMenuItem } from "./SlashMenuItem"; export type SlashMenuProps = { items: ReactSlashMenuItem[]; keyboardHoveredItemIndex: number; itemCallback: (item: ReactSlashMenuItem) => void; }; export function SlashMenu( props: SlashMenuProps ) { const { classes } = createStyles({ root: {} })(undefined, { name: "SlashMenu", }); const menuRef = useRef(null); const renderedItems: any[] = []; let index = 0; const groups = _.groupBy(props.items, (i) => i.group); _.forEach(groups, (el) => { renderedItems.push( {el[0].group} ); for (const item of el) { renderedItems.push( props.itemCallback(item)} /> ); index++; } }); useEffect(() => { setTimeout(() => { if (!menuRef.current) { return; } if (menuRef.current.childElementCount > 0) { // Reset any previously set max-height (menuRef.current.firstElementChild as HTMLDivElement).style.maxHeight = "none"; // Get the menu DOM rect const domRect = menuRef.current.firstElementChild!.getBoundingClientRect(); // Set the menu max height, based on the Tippy position. Checking if // the top of the menu is above the viewport (position < 0) is a quick // way to check if the placement is "top" or "bottom". ( menuRef.current.firstElementChild as HTMLDivElement ).style.maxHeight = `${Math.min( domRect.top >= 0 ? window.innerHeight - domRect.top - 20 : domRect.bottom - 20 )}px`; } }, 10); }, []); return (
{renderedItems.length > 0 ? ( renderedItems ) : ( No match found )}
); }