New

docx-editor 1.x has shipped. Vue support, i18n, agents. Read the migration guide →

API Referencev1.0.2

@eigenpal/docx-editor-react/plugin-api

Generic plugin interface and host component for integrating external plugins with the editor. Pairs with the framework-agnostic plugin types exported from `@eigenpal/docx-editor-core/plugin-api`.

Functions(1)

fn

createTemplatePlugin

Create the template plugin instance.

declare function createPlugin(_options?: {
    defaultCollapsed?: boolean;
    panelPosition?: 'left' | 'right';
    panelWidth?: number;
}): ReactEditorPlugin<TemplatePluginState>;

Interfaces(6)

Context value provided to plugins and panels.

interface PluginContext
MemberTypeSummary
editorViewEditorView | nullCurrent editor view
getPluginState<T>(pluginId: string) => T | undefinedGet plugin state by plugin ID
pluginsEditorPlugin[]All registered plugins
scrollToPosition(pos: number) => voidScroll to a position in the editor
selectRange(from: number, to: number) => voidSelect a range in the editor
setEditorView(view: EditorView | null) => voidSet the editor view (called by editor on mount)
setPluginState<T>(pluginId: string, state: T) => voidUpdate plugin state

Props for the PluginHost component.

interface PluginHostProps
MemberTypeSummary
childrenReact.ReactElementThe editor component (passed as child)
className?stringClass name for the host container
pluginsEditorPlugin[]Plugins to enable

Ref interface for the PluginHost component.

interface PluginHostRef
MemberTypeSummary
getEditorView() => EditorView | nullGet the current editor view
getPluginState<T>(pluginId: string) => T | undefinedGet plugin state by plugin ID
refreshPluginStates() => voidForce a refresh of all plugin states
setPluginState<T>(pluginId: string, state: T) => voidUpdate plugin state for a plugin
interface ReactEditorPlugin<TState = any> extends EditorPluginCore<TState>
MemberTypeSummary
getSidebarItems?(state: TState, context: SidebarItemContext) => ReactSidebarItem[]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.
Panel?React.ComponentType<PluginPanelProps<TState>>React component to render in the annotation panel area. Receives editor state and callbacks for interaction.
renderOverlay?(context: RenderedDomContext, state: TState, editorView: EditorView | null) => ReactNodeRender 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.

A sidebar item with React rendering, anchored to a document position.

interface ReactSidebarItem extends SidebarItem
MemberTypeSummary
estimatedHeight?numberEstimated height in pixels (for pre-layout before measurement). Default: 40.
render(props: SidebarItemRenderProps) => ReactNodeRender the card content.
interface

SidebarItemRenderProps

packages/react/src/plugin-api/types.ts:40

Render props passed to each sidebar item.

interface SidebarItemRenderProps
MemberTypeSummary
isExpandedbooleanWhether this item is currently expanded/active.
measureRef(el: HTMLDivElement | null) => voidRef callback to measure the rendered card height.
onToggleExpand() => voidToggle expand/collapse for this item.

Type aliases(1)

Backwards-compatible alias — EditorPlugin is now ReactEditorPlugin.

type EditorPlugin<TState = any> = ReactEditorPlugin<TState>;

Variables(3)

PLUGIN_HOST_STYLES = "\n.plugin-host {\n  display: flex;\n  width: 100%;\n  height: 100%;\n  overflow: visible;\n  position: relative;\n}\n\n.plugin-host-editor {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  overflow: visible;\n}\n\n\n.plugin-panels-left,\n.plugin-panels-right {\n  display: flex;\n  flex-direction: column;\n  flex-shrink: 0;\n  background: #f8f9fa;\n  border-color: #e9ecef;\n}\n\n.plugin-panels-left {\n  border-right: 1px solid #e9ecef;\n}\n\n.plugin-panels-right {\n  border-left: 1px solid #e9ecef;\n}\n\n.plugin-panels-bottom {\n  border-top: 1px solid #e9ecef;\n  background: #f8f9fa;\n}\n\n.plugin-panel {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n  transition: width 0.2s ease, height 0.2s ease;\n}\n\n.plugin-panel.collapsed {\n  overflow: visible;\n}\n\n.plugin-panel-toggle {\n  display: flex;\n  align-items: center;\n  gap: 4px;\n  padding: 6px 8px;\n  background: transparent;\n  border: none;\n  cursor: pointer;\n  font-size: 12px;\n  color: #6c757d;\n  white-space: nowrap;\n}\n\n.plugin-panel.collapsed .plugin-panel-toggle {\n  writing-mode: vertical-rl;\n  text-orientation: mixed;\n  flex-direction: column;\n  height: 100%;\n  padding: 8px 6px;\n}\n\n.plugin-panel-toggle:hover {\n  background: #e9ecef;\n  color: #495057;\n}\n\n.plugin-panel-toggle-icon {\n  font-weight: bold;\n  font-size: 14px;\n}\n\n.plugin-panel.collapsed .plugin-panel-toggle-icon {\n  transform: rotate(90deg);\n}\n\n.plugin-panel-toggle-label {\n  font-weight: 500;\n}\n\n.plugin-panel-content {\n  flex: 1;\n  overflow: auto;\n}\n\n/* Right panel rendered inside viewport - scrolls with content */\n.plugin-panel-in-viewport {\n  position: absolute;\n  top: 0;\n  /* Position is set dynamically via inline styles based on page edge */\n  width: 220px;\n  pointer-events: auto;\n  z-index: 10;\n  overflow: visible;\n}\n\n.plugin-panel-in-viewport.collapsed {\n  width: 32px;\n}\n\n.plugin-panel-in-viewport .plugin-panel-toggle {\n  position: sticky;\n  top: 0;\n  background: rgba(255, 255, 255, 0.95);\n  border-radius: 4px;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.plugin-panel-in-viewport-content {\n  overflow: visible;\n  position: relative;\n}\n\n/* Plugin overlay container for rendering highlights/decorations */\n.plugin-overlays-container {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  pointer-events: none;\n  overflow: visible;\n  z-index: 5;\n}\n\n.plugin-overlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  pointer-events: none;\n}\n\n/* Individual overlay children manage their own pointer-events.\n   Do NOT set pointer-events: auto here \u2014 it overrides overlay containers\n   that need pointer-events: none to let clicks pass through to the editor. */\n"

PluginHost Component

Wraps the editor and provides: - Plugin state management - Panel rendering for each plugin - CSS injection for plugin styles - Callbacks for editor interaction

PluginHost: React.ForwardRefExoticComponent<PluginHostProps & React.RefAttributes<PluginHostRef>>

Default template plugin instance.

templatePlugin: ReactEditorPlugin<TemplatePluginState>