import { AppState } from '@/UIModels/AppState' import { Icon } from '@/Components/Icon' import VisuallyHidden from '@reach/visually-hidden' import { useCloseOnBlur } from '@/Hooks/useCloseOnBlur' import { Disclosure, DisclosureButton, DisclosurePanel } from '@reach/disclosure' import { useRef, useState } from 'preact/hooks' import { observer } from 'mobx-react-lite' import { NotesOptions } from './NotesOptions' import { WebApplication } from '@/UIModels/Application' import { FOCUSABLE_BUT_NOT_TABBABLE } from '@/Constants' type Props = { application: WebApplication appState: AppState onClickPreprocessing?: () => Promise } export const NotesOptionsPanel = observer(({ application, appState, onClickPreprocessing }: Props) => { const [open, setOpen] = useState(false) const [position, setPosition] = useState({ top: 0, right: 0, }) const [maxHeight, setMaxHeight] = useState('auto') const buttonRef = useRef(null) const panelRef = useRef(null) const [closeOnBlur] = useCloseOnBlur(panelRef, setOpen) return ( { const rect = buttonRef.current?.getBoundingClientRect() if (rect) { const { clientHeight } = document.documentElement const footerElementRect = document.getElementById('footer-bar')?.getBoundingClientRect() const footerHeightInPx = footerElementRect?.height if (footerHeightInPx) { setMaxHeight(clientHeight - rect.bottom - footerHeightInPx - 2) } setPosition({ top: rect.bottom, right: document.body.clientWidth - rect.right, }) const newOpenState = !open if (newOpenState && onClickPreprocessing) { await onClickPreprocessing() } setOpen(newOpenState) } }} > { if (event.key === 'Escape') { setOpen(false) } }} onBlur={closeOnBlur} ref={buttonRef} className="sn-icon-button border-contrast" > Actions { if (event.key === 'Escape') { setOpen(false) buttonRef.current?.focus() } }} ref={panelRef} style={{ ...position, maxHeight, }} className="sn-dropdown sn-dropdown--animated min-w-80 max-h-120 max-w-xs flex flex-col pt-2 overflow-y-auto fixed" onBlur={closeOnBlur} tabIndex={FOCUSABLE_BUT_NOT_TABBABLE} > {open && } ) })