/** * lumir-editor — react-free 코어("./core") 타입 선언. * 구 @lumir-company/editor 의 공개 타입명을 유지하되, BlockNote 런타임 의존 없이 * 구조적(loose) 타입으로 정의한다(저장 JSON 형태는 동일). */ // ── 블록/인라인 콘텐츠 (BlockNote JSON 호환) ───────────────────────────── export interface StyledText { type: "text"; text: string; styles: Record; } export interface InlineLink { type: "link"; href: string; content: StyledText[]; } /** 표 셀 내 인라인 체크박스(원자). 직렬=인라인 연속, 병렬=줄바꿈("\n")으로 배치. */ export interface InlineCheckbox { type: "checkbox"; checked: boolean; } /** 표 셀 내 순서목록/불렛목록 마커(인라인 원자). 줄 시작에 위치, 번호는 위치 기반(CSS 카운터, 미저장). */ export interface InlineOrderedItem { type: "olItem"; } export interface InlineBulletItem { type: "ulItem"; } export type InlineContent = | StyledText | InlineLink | InlineCheckbox | InlineOrderedItem | InlineBulletItem | Record; /** 구 SerializedStyledText — fontSize 형제키 형태의 styled-text */ export interface SerializedStyledText { type: "text"; text: string; styles: Record; fontSize?: string; } /** 구 DefaultPartialBlock — 저장/로드에 쓰는 블록 JSON(구조 동일, 느슨한 타입) */ export interface DefaultPartialBlock { id?: string; type?: string; props?: Record; content?: InlineContent[] | Record | string; children?: DefaultPartialBlock[]; } // 구 @blocknote 제네릭 별칭 — 런타임이 없으므로 구조적 별칭으로 유지 export type PartialBlock = DefaultPartialBlock; export type DefaultBlockSchema = Record; export type DefaultInlineContentSchema = Record; export type DefaultStyleSchema = Record; // ── 에러 ──────────────────────────────────────────────────────────────── export type LumirErrorCode = | "UPLOAD_FAILED" | "INVALID_FILE_TYPE" | "S3_CONFIG_ERROR" | "NETWORK_ERROR" | "CONTENT_PARSE_ERROR" | "UNKNOWN_ERROR"; export interface LumirErrorDetails { code: LumirErrorCode; message: string; originalError?: Error; context?: Record; } export declare const LUMIR_ERROR_CODES: readonly LumirErrorCode[]; export declare class LumirEditorError extends Error { readonly code: LumirErrorCode; readonly originalError?: Error; readonly context?: Record; constructor(details: LumirErrorDetails); getUserMessage(): string; toJSON(): Record; static fromError(error: unknown, code?: LumirErrorCode, context?: Record): LumirEditorError; static uploadFailed(message: string, originalError?: Error): LumirEditorError; static invalidFileType(fileName: string, allowVideoUpload?: boolean): LumirEditorError; static s3ConfigError(message: string): LumirEditorError; static networkError(originalError?: Error): LumirEditorError; } // ── S3 업로더 ─────────────────────────────────────────────────────────── export interface S3UploaderConfig { apiEndpoint: string; env: "development" | "production"; path: string; fileNameTransform?: (nameWithoutExt: string, file: File) => string; appendUUID?: boolean; preserveExtension?: boolean; onProgress?: (percent: number) => void; uploadTimeoutMs?: number; maxRetries?: number; } export declare function createS3Uploader(config: S3UploaderConfig): (file: File) => Promise; export declare function generateUUID(): string; // ── 색상/글자크기 상수 ───────────────────────────────────────────────── export interface ColorItem { name: string; value: string; color: string; } export declare const TEXT_COLORS: ColorItem[]; export declare const BACKGROUND_COLORS: ColorItem[]; export declare function getHexFromColorValue(value: string, kind?: "text" | "background"): string; export interface FontSizePreset { label: string; value: string; } export declare const FONT_SIZE_PRESETS: FontSizePreset[]; export declare const FONT_SIZE_MIN: number; export declare const FONT_SIZE_MAX: number; export declare const FONT_SIZE_DEFAULT_PX: number; export declare const FONT_SIZE_STEP: number; export declare function parseFontSizePx(value: string | number | null | undefined): number | null; export declare function clampFontSizePx(px: number): number; export declare function toFontSizeValue(px: number): string; export declare function liftFontSize(blocks: DefaultPartialBlock[]): DefaultPartialBlock[]; export declare function lowerFontSize(blocks: DefaultPartialBlock[]): DefaultPartialBlock[]; // ── 호환 유틸 클래스 ─────────────────────────────────────────────────── export declare class ContentUtils { static isValidJSONString(jsonString: string): boolean; static parseJSONContent(jsonString: string): DefaultPartialBlock[] | null; static createDefaultBlock(): DefaultPartialBlock; static validateContent(content: DefaultPartialBlock[] | string | undefined | null, emptyBlockCount?: number): DefaultPartialBlock[]; static createEmptyBlocks(emptyBlockCount: number): DefaultPartialBlock[]; } export declare class EditorConfig { static getDefaultTableConfig(userTables?: LumirEditorProps["tables"]): Required>; static getDefaultHeadingConfig(userHeading?: LumirEditorProps["heading"]): { levels: (1 | 2 | 3 | 4 | 5 | 6)[] }; static getDisabledExtensions(userExtensions?: string[], allowVideo?: boolean, allowAudio?: boolean, allowFile?: boolean): string[]; } export declare function cn(...classes: Array): string; // ── 로케일 ───────────────────────────────────────────────────────────── export type LumirLocale = Record; export declare const KO: LumirLocale; export declare const EN: LumirLocale; export declare const LOCALES: Record; export declare function resolveLocale(locale?: string | LumirLocale): LumirLocale; // ── 에디터 옵션/인스턴스 ─────────────────────────────────────────────── /** 링크 카드(bookmark) 메타 — fetchLinkPreview 반환값. 전부 optional. */ export interface LinkPreview { title?: string; description?: string; image?: string; site?: string; favicon?: string; } /** 구 LumirEditorProps + vanilla 확장(전부 optional — 구 코드 그대로 컴파일됨) */ export interface LumirEditorProps { initialContent?: DefaultPartialBlock[] | string; initialEmptyBlocks?: number; placeholder?: string; uploadFile?: (file: File) => Promise; s3Upload?: S3UploaderConfig; allowVideoUpload?: boolean; allowAudioUpload?: boolean; allowFileUpload?: boolean; maxImageFileSize?: number; maxVideoFileSize?: number; maxAudioFileSize?: number; tables?: { splitCells?: boolean; cellBackgroundColor?: boolean; cellTextColor?: boolean; headers?: boolean; }; heading?: { levels?: (1 | 2 | 3 | 4 | 5 | 6)[] }; defaultStyles?: boolean; disableExtensions?: string[]; tabBehavior?: "prefer-navigate-ui" | "prefer-indent"; trailingBlock?: boolean; editable?: boolean; theme?: "light" | "dark" | Record; formattingToolbar?: boolean; linkToolbar?: boolean; sideMenu?: boolean; sideMenuAddButton?: boolean; slashMenu?: boolean; emojiPicker?: boolean; filePanel?: boolean; tableHandles?: boolean; columnDivider?: boolean; floatingMenu?: boolean; floatingMenuPosition?: "sticky" | "fixed"; className?: string; locale?: string | LumirLocale; resolveFileUrl?: (url: string) => string | Promise; /** 링크 카드(bookmark, mode="card") 전환 시 URL 메타를 조회하는 콜백. CORS 때문에 서버 프록시 권장. * 미주입 시 카드는 URL·도메인만 표시. 임베드(YouTube/Vimeo)는 이 콜백 없이도 동작. */ fetchLinkPreview?: (url: string) => Promise | LinkPreview; showErrorToast?: boolean; trailingBlockType?: string; onContentChange?: (content: DefaultPartialBlock[]) => void; onError?: (error: LumirEditorError) => void; onSelectionChange?: () => void; onImageDelete?: (imageUrl: string) => void; onUploadStart?: (file: File) => void; onUploadEnd?: (file: File) => void; } /** mountLumirEditor 반환 인스턴스 */ export interface VanillaEditor { element: HTMLElement; getDocument(): DefaultPartialBlock[]; getMarkdown(): string; getHTML(): string; getFullHTML(opts?: { title?: string; style?: string }): string; setBlocks(blocks: DefaultPartialBlock[]): void; setMarkdown(md: string): void; commit(): boolean; undo(): boolean; redo(): boolean; canUndo(): boolean; canRedo(): boolean; isComposing(): boolean; setOnContentChange(fn: ((content: DefaultPartialBlock[]) => void) | null): void; isSlashOpen(): boolean; insertFile(file: File): void; isEditable(): boolean; setEditable(on: boolean): void; setTheme(theme: LumirEditorProps["theme"]): void; destroy(): void; formatToolbar?: unknown; tableControls?: unknown; floatingMenu?: unknown; sideMenu?: unknown; columnControls?: unknown; linkToolbar?: unknown; filePanel?: unknown; emojiPicker?: unknown; } /** 구 BlockNoteEditor/EditorType 별칭 — vanilla 인스턴스를 가리킨다 */ export type BlockNoteEditor = VanillaEditor; export type EditorType = VanillaEditor; export type LumirEditorOptions = LumirEditorProps; export declare function mountLumirEditor(host: HTMLElement, opts?: LumirEditorOptions): VanillaEditor; // ── 직렬화/변환 유틸 ─────────────────────────────────────────────────── export declare function inlineContentToHtml(content: InlineContent[]): string; export declare function htmlToInlineContent(html: string | HTMLElement): InlineContent[]; export declare function blockToElement(block: DefaultPartialBlock): HTMLElement; export declare function elementToBlock(el: HTMLElement): DefaultPartialBlock; export declare function blocksToDom(blocks: DefaultPartialBlock[], container: HTMLElement): void; export declare function domToBlocks(container: HTMLElement): DefaultPartialBlock[]; export declare function blocksToMarkdown(blocks: DefaultPartialBlock[]): string; export declare function inlineToMarkdown(content: InlineContent[]): string; export declare function markdownToBlocks(md: string): DefaultPartialBlock[]; export declare function parseInlineMarkdown(text: string): InlineContent[]; export declare function blocksToHtml(blocks: DefaultPartialBlock[]): string; export declare function blocksToFullHtml(blocks: DefaultPartialBlock[], opts?: { title?: string; style?: string }): string; export declare function inlineToHtml(content: InlineContent[]): string; export declare function parseHtmlToBlocks(html: string): DefaultPartialBlock[]; export declare function blocksFromText(text: string): DefaultPartialBlock[]; export declare function isBareUrl(text: string): boolean; export declare function fitColumnWidths(widths: Array, maxWidth: number, min?: number): Array; export declare function parseCssColorToRgb(css: string): { r: number; g: number; b: number } | null; export declare function nearestTextColorValue(css: string): string | null; export declare function nearestBackgroundColorValue(css: string): string | null; export declare function applyInlineMark(container: HTMLElement, mark: string): boolean; export declare function readActiveMarks(container: HTMLElement): Record; // ── 표 모델 ──────────────────────────────────────────────────────────── export interface TableMasterCell { id: number; content: InlineContent[]; r: number; c: number; rowspan: number; colspan: number; [attr: string]: unknown; } export interface TableModel { G: TableMasterCell[][]; columnWidths: Array; headerRows?: number; headerCols?: number; } export declare function newMaster(over?: Partial): TableMasterCell; export declare function newTableModel(rows: number, cols: number): TableModel; export declare function newModelFromG(G: TableMasterCell[][], extra?: Record): TableModel; export declare function normalize(model: TableModel): TableModel; export declare function modelToTableContent(model: TableModel): Record; export declare function tableContentToModel(content: Record): TableModel; export declare function renderTableElement(model: TableModel): HTMLTableElement; export declare function syncModelFromTableDom(tableEl: HTMLTableElement): void;