Files
simple-react-app-kit/packages/lexical/src/toolbar.tsx
T

95 lines
2.5 KiB
TypeScript
Raw Normal View History

import { useEffect, useMemo, useState } from "react"
import type { ComponentProps, ReactNode } from "react"
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"
import { mergeRegister } from "@lexical/utils"
import {
CAN_REDO_COMMAND,
CAN_UNDO_COMMAND,
COMMAND_PRIORITY_LOW,
SELECTION_CHANGE_COMMAND,
} from "lexical"
import { TooltipProvider } from "@workspace/ui/components/tooltip"
import { cn } from "@workspace/ui/lib/utils"
import { defaultActionState, LexicalActionContext } from "./context"
import { LexicalActionTree } from "./actions-view"
import { useLexicalActions } from "./actions-context"
export type LexicalFixedToolbarProps = ComponentProps<"div">
function LexicalActionRuntimeProvider({ children }: { children: ReactNode }) {
const [editor] = useLexicalComposerContext()
const [state, setState] = useState(defaultActionState)
const context = useMemo(() => ({ editor, state }), [editor, state])
useEffect(() => {
const update = () => {
setState((current) => ({
...current,
revision: current.revision + 1,
}))
}
return mergeRegister(
editor.registerUpdateListener(update),
editor.registerCommand(
SELECTION_CHANGE_COMMAND,
() => {
update()
return false
},
COMMAND_PRIORITY_LOW
),
editor.registerCommand(
CAN_UNDO_COMMAND,
(canUndo) => {
setState((current) => ({ ...current, canUndo }))
return false
},
COMMAND_PRIORITY_LOW
),
editor.registerCommand(
CAN_REDO_COMMAND,
(canRedo) => {
setState((current) => ({ ...current, canRedo }))
return false
},
COMMAND_PRIORITY_LOW
)
)
}, [editor])
return (
<LexicalActionContext.Provider value={context}>
<TooltipProvider>{children}</TooltipProvider>
</LexicalActionContext.Provider>
)
}
export function LexicalFixedToolbar({
className,
children,
...props
}: LexicalFixedToolbarProps) {
const actions = useLexicalActions("toolbar")
if (actions.length === 0 && children == null) return null
return (
<LexicalActionRuntimeProvider>
<div
role="toolbar"
className={cn(
"flex min-h-11 flex-wrap items-center gap-1 border-b p-1",
className
)}
{...props}
>
<LexicalActionTree items={actions} />
{children}
</div>
</LexicalActionRuntimeProvider>
)
}
export { LexicalActionRuntimeProvider }