import { memo, useCallback, useRef, useState } from 'react' import { createPortal } from 'react-dom' import { useCodeMirrorStateContext, useCodeMirrorViewContext, } from './codemirror-editor' import { searchPanelOpen } from '@codemirror/search' import { useResizeObserver } from '../../../shared/hooks/use-resize-observer' import { ToolbarButton } from './toolbar/toolbar-button' import { ToolbarItems } from './toolbar/toolbar-items' import * as commands from '../extensions/toolbar/commands' import { ToolbarOverflow } from './toolbar/overflow' import useDropdown from '../../../shared/hooks/use-dropdown' import { getPanel } from '@codemirror/view' import { createToolbarPanel } from '../extensions/toolbar/toolbar-panel' export const CodeMirrorToolbar = () => { const view = useCodeMirrorViewContext() const panel = getPanel(view, createToolbarPanel) if (!panel) { return null } return createPortal(, panel.dom) } const Toolbar = memo(function Toolbar() { const state = useCodeMirrorStateContext() const [overflowed, setOverflowed] = useState(false) const [collapsed, setCollapsed] = useState(false) const overflowBeforeRef = useRef(null) const overflowedItemsRef = useRef>(new Set()) const { open: overflowOpen, onToggle: setOverflowOpen, ref: overflowRef, } = useDropdown() const buildOverflow = useCallback( (element: Element) => { setOverflowOpen(false) setOverflowed(false) if (overflowBeforeRef.current) { overflowedItemsRef.current = new Set() const buttonGroups = [ ...element.querySelectorAll('[data-overflow]'), ].reverse() // restore all the overflowed items for (const buttonGroup of buttonGroups) { buttonGroup.classList.remove('overflow-hidden') } // find all the available items for (const buttonGroup of buttonGroups) { if (element.scrollWidth <= element.clientWidth) { break } // add this item to the overflow overflowedItemsRef.current.add(buttonGroup.dataset.overflow!) buttonGroup.classList.add('overflow-hidden') } setOverflowed(overflowedItemsRef.current.size > 0) } }, [setOverflowOpen] ) // build when the container resizes const resizeRef = useResizeObserver(buildOverflow) const toggleToolbar = useCallback(() => { setCollapsed(value => !value) }, []) if (collapsed) { return null } return (
) })