/** * Shared TypeScript types for editor components */ import type { Editor } from "@tiptap/react"; import type { BundledLanguage, BundledTheme } from "shiki"; // ============================================================================ // Common Editor Types // ============================================================================ export type EditorMode = "edit" | "preview" | "split"; export interface BaseEditorProps { /** Initial content */ initialValue?: string; /** Callback when content changes */ onChange?: (value: string) => void; /** Placeholder text */ placeholder?: string; /** Height of the editor */ height?: string | number; /** Additional CSS class */ className?: string; /** Whether the editor is read-only */ readOnly?: boolean; } // ============================================================================ // Markdown Editor // ============================================================================ export interface MarkdownEditorProps extends BaseEditorProps { /** Default view mode */ defaultMode?: EditorMode; /** Enable GitHub Flavored Markdown */ enableGfm?: boolean; /** Custom toolbar actions */ toolbar?: React.ReactNode; } // ============================================================================ // Code Editor // ============================================================================ export interface CodeEditorProps extends BaseEditorProps { /** Programming language */ language?: BundledLanguage; /** Show line numbers */ showLineNumbers?: boolean; /** Theme for syntax highlighting */ theme?: BundledTheme; /** Enable language selector */ showLanguageSelector?: boolean; /** Available languages for selector */ availableLanguages?: BundledLanguage[]; } // ============================================================================ // WYSIWYG Editor // ============================================================================ export interface WYSIWYGEditorProps { /** Initial HTML content */ initialValue?: string; /** Callback when content changes */ onChange?: (html: string, json: any) => void; /** Placeholder text */ placeholder?: string; /** Height of the editor */ height?: string | number; /** Additional CSS class */ className?: string; /** Whether the editor is read-only */ readOnly?: boolean; /** Enable tables */ enableTables?: boolean; /** Enable task lists */ enableTaskLists?: boolean; /** Custom toolbar */ toolbar?: (editor: Editor) => React.ReactNode; } // ============================================================================ // Block Editor // ============================================================================ export type BlockType = | "paragraph" | "heading1" | "heading2" | "heading3" | "bulletList" | "orderedList" | "quote" | "code" | "image"; export interface BlockEditorProps { /** Initial JSON content */ initialValue?: any; /** Callback when content changes */ onChange?: (json: any) => void; /** Placeholder text */ placeholder?: string; /** Height of the editor */ height?: string | number; /** Additional CSS class */ className?: string; /** Whether the editor is read-only */ readOnly?: boolean; /** Available block types */ availableBlocks?: BlockType[]; } // ============================================================================ // MDX Editor // ============================================================================ export interface MDXEditorProps extends BaseEditorProps { /** Default view mode */ defaultMode?: EditorMode; /** Custom preview renderer */ renderPreview?: (mdx: string) => Promise | React.ReactNode; /** Available components for MDX */ components?: Record>; /** Show syntax errors */ showErrors?: boolean; } // ============================================================================ // Email Builder // ============================================================================ export interface EmailTemplate { id: string; name: string; subject: string; html: string; } export interface EmailBuilderProps { /** Initial email HTML */ initialValue?: string; /** Callback when content changes */ onChange?: (html: string, subject: string) => void; /** Initial subject line */ initialSubject?: string; /** Template presets */ templates?: EmailTemplate[]; /** Additional CSS class */ className?: string; /** Preview width */ previewWidth?: "mobile" | "desktop"; } // ============================================================================ // Editor State Hook // ============================================================================ export interface EditorState { content: string; isDirty: boolean; isSaving: boolean; lastSaved: Date | null; error: string | null; } export interface UseEditorStateOptions { initialContent?: string; autosaveDelay?: number; onSave?: (content: string) => Promise; onError?: (error: Error) => void; } export interface UseEditorStateReturn extends EditorState { updateContent: (content: string) => void; save: () => Promise; reset: () => void; } // ============================================================================ // Editor Sync Hook // ============================================================================ export interface Collaborator { id: string; name: string; color: string; cursor?: { line: number; column: number }; } export interface EditorSyncOptions { /** WebSocket URL for real-time sync */ wsUrl?: string; /** Document ID for collaborative editing */ documentId?: string; /** User ID */ userId?: string; /** Enable offline support */ enableOffline?: boolean; /** Sync interval in ms */ syncInterval?: number; } export interface EditorSyncState { isConnected: boolean; isOnline: boolean; lastSync: Date | null; pendingChanges: number; collaborators: Collaborator[]; } export interface UseEditorSyncReturn extends EditorSyncState { sendChange: (change: any) => void; syncPendingChanges: () => Promise; } // ============================================================================ // Utility Types // ============================================================================ export interface SerializationOptions { format: "html" | "markdown" | "json" | "text"; pretty?: boolean; } export interface ContentMetrics { characters: number; words: number; readingTime: number; lines: number; }