first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
import React, {ReactElement, useEffect} from 'react';
import {useListbox} from '../../forms/listbox/use-listbox';
import {Listbox} from '../../forms/listbox/listbox';
import {Menu} from './menu-trigger';
import {useListboxKeyboardNavigation} from '../../forms/listbox/use-listbox-keyboard-navigation';
import {useTypeSelect} from '../../forms/listbox/use-type-select';
import {ListBoxChildren, ListboxProps} from '../../forms/listbox/types';
import {VirtualElement} from '@floating-ui/react-dom';
const preventContextOnMenu = (e: MouseEvent) => {
e.preventDefault();
};
type Props = ListboxProps &
ListBoxChildren<any> & {
position?: {x: number; y: number} | null;
};
export function ContextMenu({position, children, ...props}: Props) {
const listbox = useListbox({
...props,
isOpen: props.isOpen && !!position,
placement: 'right-start',
floatingWidth: 'auto',
role: 'menu',
loopFocus: true,
children:
(children as ReactElement)?.type === Menu
? (children as ReactElement).props.children
: children,
});
const {
reference,
refs,
state: {isOpen, setIsOpen, activeIndex},
focusItem,
listContent,
} = listbox;
useEffect(() => {
if (refs.floating.current) {
refs.floating.current.addEventListener(
'contextmenu',
preventContextOnMenu,
);
return () => {
refs.floating.current?.removeEventListener(
'contextmenu',
preventContextOnMenu,
);
};
}
}, [refs.floating]);
useEffect(() => {
if (position) {
reference(pointToVirtualElement(position));
setIsOpen(true);
} else {
setIsOpen(false);
}
}, [position, reference, setIsOpen]);
const {handleListboxKeyboardNavigation} =
useListboxKeyboardNavigation(listbox);
const {findMatchingItem} = useTypeSelect();
return (
<Listbox
listbox={listbox}
onKeyDownCapture={e => {
if (!isOpen) return;
const i = findMatchingItem(e, listContent, activeIndex);
if (i) {
focusItem('increment', i);
}
}}
onKeyDown={handleListboxKeyboardNavigation}
/>
);
}
export function pointToVirtualElement(
{x, y}: {x: number; y: number},
contextElement?: Element,
): VirtualElement {
return {
getBoundingClientRect() {
return {
x,
y,
width: 0,
height: 0,
top: y,
right: x,
bottom: y,
left: x,
};
},
contextElement,
};
}