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 (
)
})