import { EditorView } from 'prosemirror-view'; import { ReactNode } from 'react'; import { SidebarItem, EditorPluginCore, PluginPanelProps, RenderedDomContext, SidebarItemContext } from '@heyirisai/docx-editor-core/plugin-api'; /** * React Plugin Interface for the DOCX Editor * * Extends the framework-agnostic EditorPluginCore with React-specific * UI rendering capabilities (Panel component, renderOverlay). */ /** * React-specific editor plugin interface. * * Extends EditorPluginCore with: * - Panel: React component for rendering in the annotation panel * - renderOverlay: Function returning ReactNode for overlay rendering */ /** * Render props passed to each sidebar item. */ interface SidebarItemRenderProps { /** Whether this item is currently expanded/active. */ isExpanded: boolean; /** Toggle expand/collapse for this item. */ onToggleExpand: () => void; /** Ref callback to measure the rendered card height. */ measureRef: (el: HTMLDivElement | null) => void; } /** * A sidebar item with React rendering, anchored to a document position. */ interface ReactSidebarItem extends SidebarItem { /** Render the card content. */ render: (props: SidebarItemRenderProps) => ReactNode; /** Estimated height in pixels (for pre-layout before measurement). Default: 40. */ estimatedHeight?: number; } interface ReactEditorPlugin extends EditorPluginCore { /** * React component to render in the annotation panel area. * Receives editor state and callbacks for interaction. */ Panel?: React.ComponentType>; /** * Render an overlay on top of the rendered pages. * Use this for highlights, annotations, or other visual elements * that need to be positioned relative to the document content. */ renderOverlay?: (context: RenderedDomContext, state: TState, editorView: EditorView | null) => ReactNode; /** * Provide sidebar items anchored to document positions. * Called whenever plugin state changes. * Items from all plugins are merged and laid out together in a unified sidebar. */ getSidebarItems?: (state: TState, context: SidebarItemContext) => ReactSidebarItem[]; } /** * Backwards-compatible alias — EditorPlugin is now ReactEditorPlugin. */ type EditorPlugin = ReactEditorPlugin; /** * Context value provided to plugins and panels. */ interface PluginContext { /** All registered plugins */ plugins: EditorPlugin[]; /** Current editor view */ editorView: EditorView | null; /** Set the editor view (called by editor on mount) */ setEditorView: (view: EditorView | null) => void; /** Get plugin state by plugin ID */ getPluginState: (pluginId: string) => T | undefined; /** Update plugin state */ setPluginState: (pluginId: string, state: T) => void; /** Scroll to a position in the editor */ scrollToPosition: (pos: number) => void; /** Select a range in the editor */ selectRange: (from: number, to: number) => void; } /** * Props for the PluginHost component. */ interface PluginHostProps { /** Plugins to enable */ plugins: EditorPlugin[]; /** The editor component (passed as child) */ children: React.ReactElement; /** Class name for the host container */ className?: string; } /** * Ref interface for the PluginHost component. */ interface PluginHostRef { /** Get plugin state by plugin ID */ getPluginState: (pluginId: string) => T | undefined; /** Update plugin state for a plugin */ setPluginState: (pluginId: string, state: T) => void; /** Get the current editor view */ getEditorView: () => EditorView | null; /** Force a refresh of all plugin states */ refreshPluginStates: () => void; } export type { EditorPlugin as E, PluginHostProps as P, ReactSidebarItem as R, SidebarItemRenderProps as S, PluginHostRef as a, ReactEditorPlugin as b, PluginContext as c };