export interface ActiveFormats { bold: boolean; italic: boolean; underline: boolean; justifyLeft: boolean; justifyCenter: boolean; justifyRight: boolean; insertUnorderedList: boolean; insertOrderedList: boolean; link: boolean; h1: boolean; h2: boolean; h3: boolean; p: boolean; } export interface UseRichTextEditorProps { /** Current HTML value of the editor */ value: string; /** Called whenever the editor content changes */ onChange?: (value: string) => void; } export interface UseRichTextEditorReturn { /** Attach to the `contenteditable` div */ editorRef: React.RefObject; /** Attach to the search `` */ searchInputRef: React.RefObject; /** Attach to the link URL `` */ linkInputRef: React.RefObject; /** Map of currently active formatting commands */ activeFormats: ActiveFormats; /** Whether the inline search bar is open */ isSearchOpen: boolean; setIsSearchOpen: (open: boolean) => void; /** Current search query string */ searchQuery: string; setSearchQuery: (query: string) => void; /** Current link URL being edited */ linkUrl: string; setLinkUrl: (url: string) => void; /** Whether the link popover is open */ isLinkOpen: boolean; /** * True when the popover was opened with a non-collapsed text selection * (or with the cursor inside an existing link). Use this to decide whether * to show the link-insert form vs. the "select text first" hint. */ hasSavedSelection: boolean; /** Word count of the editor content */ wordCount: number; /** Character count of the editor content */ characterCount: number; /** Re-read the current selection and update `activeFormats` */ updateActiveFormats: () => void; /** Execute a `document.execCommand` and sync state */ execCommand: (command: string, value?: string) => void; /** Called on every `input` event of the editor */ handleInput: () => void; /** Search forward or backward for `searchQuery` */ performSearch: (text: string, backward?: boolean) => void; /** Create or update a hyperlink at the current selection */ handleCreateLink: () => void; /** Remove the hyperlink at the current cursor position */ handleUnlink: () => void; /** Handle link popover open/close (saves selection, pre-fills URL) */ onLinkPopoverOpenChange: (open: boolean) => void; } /** * `useRichTextEditor` — Headless hook for the RichTextEditor component. * * Encapsulates all state, refs, and DOM-manipulation logic for a * `contenteditable`-based rich text editor. Use this hook when you need to * build a fully custom editor UI while reusing the same formatting logic as * the default `RichTextEditor` component. * * @example * ```tsx * import { useRichTextEditor } from 'xertica-ui/ui'; * * function MyEditor({ value, onChange }) { * const { * editorRef, * activeFormats, * execCommand, * handleInput, * wordCount, * } = useRichTextEditor({ value, onChange }); * * return ( *
* *
* {wordCount} words *
* ); * } * ``` */ export declare function useRichTextEditor({ value, onChange, }: UseRichTextEditorProps): UseRichTextEditorReturn;