import React, { useEffect, useRef } from 'react' import ReactDOM from 'react-dom' import { Dropdown } from 'react-bootstrap' import { useEditorContext } from '../../../shared/context/editor-context' import { useFileTreeMainContext } from '../contexts/file-tree-main' import FileTreeItemMenuItems from './file-tree-item/file-tree-item-menu-items' function FileTreeContextMenu() { const { permissionsLevel } = useEditorContext() const { contextMenuCoords, setContextMenuCoords } = useFileTreeMainContext() const toggleButtonRef = useRef(null) useEffect(() => { if (contextMenuCoords) { toggleButtonRef.current = document.querySelector( '.entity-menu-toggle' ) as HTMLButtonElement | null focusContextMenu() } }, [contextMenuCoords]) if (!contextMenuCoords || permissionsLevel === 'readOnly') return null // A11y - Move the focus to the context menu when it opens function focusContextMenu() { const contextMenu = document.querySelector( '[aria-labelledby="dropdown-file-tree-context-menu"]' ) as HTMLElement | null contextMenu?.focus() } function close() { setContextMenuCoords(null) if (toggleButtonRef.current) { // A11y - Move the focus back to the toggle button when the context menu closes by pressing the Esc key toggleButtonRef.current.focus() } } function handleToggle(wantOpen: boolean) { if (!wantOpen) close() } function handleClick() { handleToggle(false) } // A11y - Close the context menu when the user presses the Tab key // Focus should move to the next element in the filetree function handleKeyDown(event: React.KeyboardEvent) { if (event.key === 'Tab') { close() } } return ReactDOM.createPortal( , document.body ) } // fake component required as Dropdowns require a Toggle, even tho we don't want // one for the context menu const FakeDropDownToggle = React.forwardRef( ({ bsRole }, ref) => { return null } ) FakeDropDownToggle.displayName = 'FakeDropDownToggle' export default FileTreeContextMenu