import * as react from 'react'; import { LuthorEditorThemeOverrides, CommandPaletteItem, SlashCommandItem, FontFamilyOption, FontSizeOption, LineHeightOption, CodeLanguageOptionsConfig, LuthorTheme, SourceMetadataMode, MarkdownBridgeFlavor, Extension as Extension$1, MarkdownBridgeOptions, EditorConfig } from '@lyfie/luthor-headless'; /** * Copyright (c) Luthor Team and contributors. * Open source under the MIT License (LICENSE). * Fork it. Remix it. Ship it. * Build freely. Credit kindly. */ type CoreTheme = "light" | "dark"; type CoreEditorMode = "visual-only" | "visual-editor" | "visual" | "json" | "markdown" | "html"; declare const BLOCK_HEADING_LEVELS: readonly ["h1", "h2", "h3", "h4", "h5", "h6"]; type BlockHeadingLevel = (typeof BLOCK_HEADING_LEVELS)[number]; type BlockFormat = "p" | BlockHeadingLevel; type ImageAlignment = "left" | "center" | "right" | "none"; type TextAlignment = "left" | "center" | "right" | "justify"; interface InsertTableConfig { rows?: number; columns?: number; includeHeaders?: boolean; } interface InsertImageConfig { src: string; alt: string; caption?: string; file?: File; } interface CoreEditorCommands { toggleBold: () => void; toggleItalic: () => void; toggleUnderline: () => void; toggleStrikethrough: () => void; formatText: (format: "code") => void; setFontFamily?: (fontValue: string) => void; clearFontFamily?: () => void; getCurrentFontFamily?: () => Promise; getFontFamilyOptions?: () => readonly { value: string; label: string; fontFamily: string; cssImportUrl?: string; }[]; setFontSize?: (fontSizeValue: string) => void; clearFontSize?: () => void; getCurrentFontSize?: () => Promise; getFontSizeOptions?: () => readonly { value: string; label: string; fontSize: string; }[]; setLineHeight?: (lineHeightValue: string) => void; clearLineHeight?: () => void; getCurrentLineHeight?: () => Promise; getLineHeightOptions?: () => readonly { value: string; label: string; lineHeight: string; }[]; setTextColor?: (colorValue: string) => void; clearTextColor?: () => void; getCurrentTextColor?: () => Promise; getTextColorOptions?: () => readonly { value: string; label: string; color: string; }[]; setTextHighlight?: (highlightValue: string) => void; clearTextHighlight?: () => void; getCurrentTextHighlight?: () => Promise; getTextHighlightOptions?: () => readonly { value: string; label: string; backgroundColor: string; }[]; toggleSubscript?: () => void; toggleSuperscript?: () => void; insertLink: () => void; updateLink?: (url: string, rel?: string, target?: string) => boolean; removeLink: () => void; getCurrentLink?: () => Promise<{ url: string; rel: string | null; target: string | null; } | null>; getLinkByKey?: (linkNodeKey: string) => Promise<{ url: string; rel: string | null; target: string | null; } | null>; updateLinkByKey?: (linkNodeKey: string, url: string, rel?: string, target?: string) => boolean; removeLinkByKey?: (linkNodeKey: string) => boolean; toggleParagraph: () => void; toggleHeading: (heading: BlockHeadingLevel) => void; toggleQuote: () => void; setTextAlignment: (alignment: TextAlignment) => void; toggleCodeBlock: () => void; setCodeLanguage?: (language: string) => void; autoDetectCodeLanguage?: () => Promise; getCurrentCodeLanguage?: () => Promise; getCodeLanguageOptions?: () => string[]; copySelectedCodeBlock?: () => Promise; toggleUnorderedList: () => void; toggleOrderedList: () => void; toggleCheckList: () => void; indentList: () => void; outdentList: () => void; setOrderedListPattern?: (pattern: "decimal-alpha-roman" | "decimal-hierarchical" | "upper-roman-upper-alpha" | "upper-alpha-lower-alpha" | "decimal-leading-zero-alpha") => void; setOrderedListSuffix?: (suffix: "dot" | "paren") => void; setUnorderedListPattern?: (pattern: "disc-circle-square" | "arrow-diamond-disc" | "square-square-square" | "arrow-circle-square") => void; setCheckListVariant?: (variant: "strikethrough" | "plain") => void; insertHorizontalRule: () => void; insertTable: (config: InsertTableConfig) => void; insertImage: (config: InsertImageConfig) => void; insertEmoji?: (emoji: string) => void; insertCustomNode?: (payload: Record) => void; executeEmojiSuggestion?: (emoji: string) => boolean; closeEmojiSuggestions?: () => void; getEmojiSuggestions?: (query?: string) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; getEmojiCatalog?: () => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; resolveEmojiShortcode?: (shortcode: string) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; } | null; setEmojiCatalog?: (catalog: { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]) => void; setEmojiCatalogAdapter?: (adapter: { search: (query: string, options?: { limit?: number; }) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; resolveShortcode: (shortcode: string) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; } | null; getAll: () => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; }) => void; getEmojiCatalogAdapter?: () => { search: (query: string, options?: { limit?: number; }) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; resolveShortcode: (shortcode: string) => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; } | null; getAll: () => { emoji: string; label: string; shortcodes: string[]; keywords?: string[]; }[]; }; setImageAlignment: (alignment: ImageAlignment) => void; setImageCaption: (caption: string) => void; getImageCaption?: () => Promise; insertIframeEmbed?: (inputUrl: string, width?: number, height?: number, title?: string) => void; setIframeEmbedAlignment?: (alignment: ImageAlignment) => void; resizeIframeEmbed?: (width: number, height: number) => void; setIframeEmbedCaption?: (caption: string) => void; getIframeEmbedCaption?: () => Promise; updateIframeEmbedUrl?: (inputUrl: string) => boolean; getIframeEmbedUrl?: () => Promise; insertYouTubeEmbed?: (inputUrl: string, width?: number, height?: number, start?: number) => void; setYouTubeEmbedAlignment?: (alignment: ImageAlignment) => void; resizeYouTubeEmbed?: (width: number, height: number) => void; setYouTubeEmbedCaption?: (caption: string) => void; getYouTubeEmbedCaption?: () => Promise; updateYouTubeEmbedUrl?: (inputUrl: string) => boolean; getYouTubeEmbedUrl?: () => Promise; undo: () => void; redo: () => void; showCommandPalette: () => void; hideCommandPalette: () => void; registerCommand: (command: Record) => void; unregisterCommand: (commandId: string) => void; registerSlashCommand?: (command: Record) => void; unregisterSlashCommand?: (commandId: string) => void; setSlashCommands?: (commands: Record[]) => void; closeSlashMenu?: () => void; executeSlashCommand?: (commandId: string) => boolean; /** * Insert plain text at the current selection, replacing any selected range. * Backed by the headless slash-command extension. Used by host-injected slash * commands (see `extraSlashCommands`) to write markdown-native syntax such as * a `[[` wikilink trigger, a `![[media]]` embed, or a date at the caret. */ insertText?: (text: string) => void; } interface CoreEditorActiveStates { bold?: boolean; italic?: boolean; underline?: boolean; strikethrough?: boolean; code?: boolean; hasCustomFontFamily?: boolean; hasCustomFontSize?: boolean; hasCustomLineHeight?: boolean; hasCustomTextColor?: boolean; hasTextHighlight?: boolean; subscript?: boolean; superscript?: boolean; isLink?: boolean; isQuote?: boolean; isInCodeBlock?: boolean; unorderedList?: boolean; orderedList?: boolean; checkList?: boolean; isH1?: boolean; isH2?: boolean; isH3?: boolean; isH4?: boolean; isH5?: boolean; isH6?: boolean; isTextAlignedLeft?: boolean; isTextAlignedCenter?: boolean; isTextAlignedRight?: boolean; isTextAlignedJustify?: boolean; imageSelected?: boolean; isImageAlignedLeft?: boolean; isImageAlignedCenter?: boolean; isImageAlignedRight?: boolean; isIframeEmbedSelected?: boolean; isIframeEmbedAlignedLeft?: boolean; isIframeEmbedAlignedCenter?: boolean; isIframeEmbedAlignedRight?: boolean; isYouTubeEmbedSelected?: boolean; isYouTubeEmbedAlignedLeft?: boolean; isYouTubeEmbedAlignedCenter?: boolean; isYouTubeEmbedAlignedRight?: boolean; canUndo?: boolean; canRedo?: boolean; } interface CoreToolbarClassNames { toolbar?: string; section?: string; } type ToolbarStyleVars = Partial<{ "--luthor-toolbar-bg": string; "--luthor-toolbar-section-border": string; "--luthor-toolbar-button-fg": string; "--luthor-toolbar-button-hover-bg": string; "--luthor-toolbar-button-hover-border": string; "--luthor-toolbar-button-hover-shadow": string; "--luthor-toolbar-button-press-shadow": string; "--luthor-toolbar-button-active-bg": string; "--luthor-toolbar-button-active-border": string; "--luthor-toolbar-button-active-fg": string; "--luthor-toolbar-button-active-shadow": string; "--luthor-toolbar-button-overlay": string; "--luthor-toolbar-button-active-overlay": string; "--luthor-toolbar-color-indicator-border": string; "--luthor-toolbar-highlight-bg": string; }>; type QuoteStyleVars = Partial<{ "--luthor-quote-bg": string; "--luthor-quote-fg": string; "--luthor-quote-border": string; }>; interface DefaultSettings { font?: { color?: string; boldColor?: string; }; link?: { color?: string; }; list?: { markerColor?: string; checkboxColor?: string; }; quote?: { backgroundColor?: string; color?: string; indicatorColor?: string; }; table?: { borderColor?: string; headerBackgroundColor?: string; }; hr?: { color?: string; }; placeholder?: { color?: string; }; codeblock?: { backgroundColor?: string; }; toolbar?: { backgroundColor?: string; }; } type EditorThemeOverrides = LuthorEditorThemeOverrides; type SyntaxHighlightColorMode = "lexical" | "custom"; type SyntaxHighlightColorTokens = Partial<{ comment: string; keyword: string; string: string; number: string; function: string; variable: string; }>; type SyntaxHighlightColors = { light?: SyntaxHighlightColorTokens; dark?: SyntaxHighlightColorTokens; }; type ToolbarPosition = "top" | "bottom"; type ToolbarAlignment = "left" | "center" | "right"; type ToolbarItemType = "fontFamily" | "fontSize" | "lineHeight" | "textColor" | "textHighlight" | "bold" | "italic" | "underline" | "strikethrough" | "subscript" | "superscript" | "code" | "link" | "blockFormat" | "quote" | "alignLeft" | "alignCenter" | "alignRight" | "alignJustify" | "codeBlock" | "unorderedList" | "orderedList" | "checkList" | "indentList" | "outdentList" | "horizontalRule" | "table" | "image" | "emoji" | "embed" | "customComponent" | "undo" | "redo" | "commandPalette" | "themeToggle"; type ToolbarVisibility = Partial>; interface SlashCommandVisibilityFilters { allowlist?: readonly string[]; denylist?: readonly string[]; } type SlashCommandVisibilitySelection = Readonly>; type SlashCommandVisibility = SlashCommandVisibilityFilters | readonly SlashCommandVisibilitySelection[]; type ToolbarSection = { items: readonly ToolbarItemType[]; }; type ToolbarLayout = { sections: readonly ToolbarSection[]; }; declare const DEFAULT_TOOLBAR_LAYOUT: ToolbarLayout; declare const TRADITIONAL_TOOLBAR_LAYOUT: ToolbarLayout; /** * Copyright (c) Luthor Team and contributors. * Open source under the MIT License (LICENSE). * Fork it. Remix it. Ship it. * Build freely. Credit kindly. */ type KeyboardShortcut = { key: string; metaKey?: boolean; ctrlKey?: boolean; shiftKey?: boolean; altKey?: boolean; preventDefault?: boolean; }; type ShortcutBindingOverride = KeyboardShortcut | readonly KeyboardShortcut[] | false | null; type ShortcutConfig = { disabledCommandIds?: readonly string[]; bindings?: Readonly>; preventCollisions?: boolean; preventNativeConflicts?: boolean; }; type CommandConfig = { id: string; label: string; description?: string; category: string; action: (commands: CoreEditorCommands) => void; shortcuts?: KeyboardShortcut[]; keywords?: string[]; condition?: (commands: CoreEditorCommands) => boolean; }; type CommandGenerationOptions = { headingOptions?: readonly BlockHeadingLevel[]; paragraphLabel?: string; slashCommandVisibility?: SlashCommandVisibility; isFeatureEnabled?: (feature: string) => boolean; shortcutConfig?: ShortcutConfig; commandPaletteShortcutOnly?: boolean; }; declare function generateCommands(options?: CommandGenerationOptions): CommandConfig[]; declare function commandsToCommandPaletteItems(commands: CoreEditorCommands, options?: CommandGenerationOptions): CommandPaletteItem[]; declare function commandsToSlashCommandItems(commands: CoreEditorCommands, options?: CommandGenerationOptions): SlashCommandItem[]; declare function registerKeyboardShortcuts(commands: CoreEditorCommands, element?: HTMLElement, options?: CommandGenerationOptions & { scope?: HTMLElement | null | (() => HTMLElement | null); }): () => void; /** * Copyright (c) Luthor Team and contributors. * Open source under the MIT License (LICENSE). * Fork it. Remix it. Ship it. * Build freely. Credit kindly. */ declare const EXTENSIVE_FEATURE_KEYS: readonly ["bold", "italic", "underline", "strikethrough", "fontFamily", "fontSize", "lineHeight", "textColor", "textHighlight", "subscript", "superscript", "link", "horizontalRule", "table", "list", "history", "image", "blockFormat", "code", "codeIntelligence", "codeFormat", "tabIndent", "enterKeyBehavior", "iframeEmbed", "youTubeEmbed", "floatingToolbar", "contextMenu", "commandPalette", "slashCommand", "emoji", "draggableBlock", "customNode", "themeToggle"]; type FeatureFlag = (typeof EXTENSIVE_FEATURE_KEYS)[number]; type FeatureFlags = Record; type FeatureFlagOverrides = Partial; declare const DEFAULT_FEATURE_FLAGS: FeatureFlags; declare function resolveFeatureFlags(overrides?: FeatureFlagOverrides): FeatureFlags; declare function isFeatureEnabled(featureFlags: FeatureFlags, feature: FeatureFlag): boolean; type ExtensiveExtensionsConfig = { fontFamilyOptions?: readonly FontFamilyOption[]; fontSizeOptions?: readonly FontSizeOption[]; lineHeightOptions?: readonly LineHeightOption[]; minimumDefaultLineHeight?: string | number; featureFlags?: FeatureFlagOverrides; isDraggableBoxEnabled?: boolean; scaleByRatio?: boolean; syntaxHighlighting?: "auto" | "disabled"; maxAutoDetectCodeLength?: number; isCopyAllowed?: boolean; languageOptions?: readonly string[] | CodeLanguageOptionsConfig; showLineNumbers?: boolean; /** Maximum list sub-indent levels (excluding the top-level list). Default: 8 */ maxListIndentation?: number; }; declare function buildExtensiveExtensions({ fontFamilyOptions, fontSizeOptions, lineHeightOptions, minimumDefaultLineHeight, featureFlags, isDraggableBoxEnabled, scaleByRatio, syntaxHighlighting, maxAutoDetectCodeLength, isCopyAllowed, languageOptions, showLineNumbers, maxListIndentation, }?: ExtensiveExtensionsConfig): Extension[]; type ExtensiveExtensions = ReturnType; declare function createExtensiveExtensions(config?: ExtensiveExtensionsConfig): ExtensiveExtensions; declare const extensiveExtensions: Extension[]; type ExtensiveEditorMode = "visual-only" | "visual-editor" | "visual" | "json" | "markdown" | "html"; type ExtensiveEditorPlaceholder = string | { visual?: string; json?: string; markdown?: string; html?: string; }; interface ExtensiveEditorRef { injectJSON: (content: string) => void; getJSON: () => string; getMarkdown: () => string; getHTML: () => string; } type ImageUploadHandler = (file: File) => Promise; type GifUploadHandler = (file: File) => Promise; /** * The editor surface handed to a host-injected slash command's `action`. Kept * deliberately small: it exposes only the primitives a custom command needs to * write into the document, so presets stay markdown-safe and never reach into * Lexical directly. */ interface ExtensiveSlashCommandContext { /** * Insert plain text at the caret. The slash trigger (`/query`) has already * been removed and the caret restored to that position before `action` runs, * so the text lands exactly where the user typed the slash. */ insertText: (text: string) => void; } /** * A custom slash-menu command contributed by a preset or host. These are * appended after the built-in catalogue (and so are not subject to * {@link ExtensiveEditorProps.slashCommandVisibility}, which only filters the * built-ins) and also surface in the command palette. The host owns the curated * list, which is how Papyra adds "Link note" / "Embed media" / "Insert date" * without forking the editor. */ interface ExtensiveSlashCommand { /** Stable, unique id (e.g. `"papyra.link-note"`). */ id: string; /** Menu label. */ label: string; /** Optional one-line description shown beneath the label. */ description?: string; /** Menu group heading. Defaults to `"Insert"`. */ category?: string; /** Extra search terms for the menu's fuzzy filter. */ keywords?: string[]; /** * Runs when the command is chosen. Receives an * {@link ExtensiveSlashCommandContext} for writing into the document. May be * async (e.g. to await an upload before inserting an embed reference). */ action: (context: ExtensiveSlashCommandContext) => void | Promise; } interface ExtensiveEditorProps { className?: string; onReady?: (methods: ExtensiveEditorRef) => void; initialTheme?: "light" | "dark"; onThemeChange?: (theme: "light" | "dark") => void; theme?: Partial; defaultContent?: string; showDefaultContent?: boolean; placeholder?: ExtensiveEditorPlaceholder; defaultEditorView?: ExtensiveEditorMode; initialMode?: ExtensiveEditorMode; /** Preferred prop name for toggling editor view tabs visibility */ isEditorViewTabsVisible?: boolean; /** Backward-compatible alias for toggling editor view tabs visibility */ isEditorViewsTabVisible?: boolean; availableModes?: readonly ExtensiveEditorMode[]; variantClassName?: string; toolbarLayout?: ToolbarLayout; toolbarVisibility?: ToolbarVisibility; toolbarPosition?: ToolbarPosition; toolbarAlignment?: ToolbarAlignment; toolbarClassName?: string; toolbarStyleVars?: ToolbarStyleVars; quoteClassName?: string; quoteStyleVars?: QuoteStyleVars; defaultSettings?: DefaultSettings; editorThemeOverrides?: EditorThemeOverrides; isToolbarEnabled?: boolean; isToolbarPinned?: boolean; imageUploadHandler?: ImageUploadHandler; gifUploadHandler?: GifUploadHandler; fontFamilyOptions?: readonly FontFamilyOption[]; fontSizeOptions?: readonly FontSizeOption[]; lineHeightOptions?: readonly LineHeightOption[]; minimumDefaultLineHeight?: string | number; scaleByRatio?: boolean; headingOptions?: readonly BlockHeadingLevel[]; paragraphLabel?: string; syncHeadingOptionsWithCommands?: boolean; slashCommandVisibility?: SlashCommandVisibility; /** * Custom slash commands appended to the built-in catalogue. They bypass * {@link slashCommandVisibility} (which only filters built-ins, never the * host's own additions) and also appear in the command palette. Memoize the * array so the menu is not re-registered on every render. See * {@link ExtensiveSlashCommand}. */ extraSlashCommands?: readonly ExtensiveSlashCommand[]; shortcutConfig?: ShortcutConfig; commandPaletteShortcutOnly?: boolean; isListStyleDropdownEnabled?: boolean; /** * When enabled, clicking inside Visual Only view switches to editable Visual mode * and places the caret at the clicked coordinate (or nearest line). */ editOnClick?: boolean; isDraggableBoxEnabled?: boolean; featureFlags?: FeatureFlagOverrides; sourceMetadataMode?: SourceMetadataMode; markdownBridgeFlavor?: MarkdownBridgeFlavor; markdownSourceOfTruth?: boolean; /** * Convenience opt-out switch for preset syntax highlighting. * Defaults to true. */ isSyntaxHighlightingEnabled?: boolean; syntaxHighlightColorMode?: SyntaxHighlightColorMode; syntaxHighlightColors?: SyntaxHighlightColors; maxAutoDetectCodeLength?: number; isCopyAllowed?: boolean; languageOptions?: readonly string[] | CodeLanguageOptionsConfig; showLineNumbers?: boolean; /** Maximum list sub-indent levels (excluding top-level list). Default: 8 */ maxListIndentation?: number; /** * Additional headless extensions to register alongside the feature-gated set. * Lets a preset contribute its own custom Lexical nodes (e.g. Papyra's * `[[wikilink]]`/`![[media]]` embeds) without forking the editor. The * extensions are appended after the built-in ones and own their nodes, * commands, and rendering. */ extraExtensions?: readonly Extension$1[]; /** * Custom Lexical node classes the markdown bridge must understand to parse and * serialize a preset's extra nodes. Pair with {@link extraExtensions} (which * registers the same nodes with the live editor) and * {@link markdownExtraTransformers}. Forwarded to the markdown converter so * custom nodes survive the round-trip instead of being dropped. */ markdownExtraNodes?: MarkdownBridgeOptions["extraNodes"]; /** * Custom markdown transformers giving a preset's extra nodes a lossless * round-trip in both directions. Prepended ahead of the built-in transformer * set so preset syntax is matched first on import. */ markdownExtraTransformers?: MarkdownBridgeOptions["extraTransformers"]; } declare const ExtensiveEditor: react.ForwardRefExoticComponent>; /** * Copyright (c) Luthor Team and contributors. * Open source under the MIT License (LICENSE). * Fork it. Remix it. Ship it. * Build freely. Credit kindly. */ interface EditorPreset { id: string; label: string; description?: string; extensions?: Extension$1[]; config?: EditorConfig; theme?: LuthorTheme; toolbar?: string[]; components?: Record; css?: string; } declare const presetRegistry: Record; export { DEFAULT_FEATURE_FLAGS as $, type SlashCommandVisibilitySelection as A, type BlockHeadingLevel as B, type CoreEditorCommands as C, type DefaultSettings as D, type ExtensiveEditorProps as E, type FeatureFlagOverrides as F, type GifUploadHandler as G, type SyntaxHighlightColorMode as H, type ImageAlignment as I, type SyntaxHighlightColorTokens as J, type KeyboardShortcut as K, type SyntaxHighlightColors as L, TRADITIONAL_TOOLBAR_LAYOUT as M, type TextAlignment as N, type ToolbarAlignment as O, type ToolbarPosition as P, type QuoteStyleVars as Q, type ToolbarSection as R, type ShortcutBindingOverride as S, type ToolbarLayout as T, commandsToCommandPaletteItems as U, commandsToSlashCommandItems as V, createExtensiveExtensions as W, extensiveExtensions as X, generateCommands as Y, presetRegistry as Z, registerKeyboardShortcuts as _, type ExtensiveEditorRef as a, type ExtensiveSlashCommand as a0, type ExtensiveSlashCommandContext as a1, isFeatureEnabled as a2, resolveFeatureFlags as a3, type EditorPreset as b, type ToolbarVisibility as c, type EditorThemeOverrides as d, type CoreEditorActiveStates as e, type CoreTheme as f, type CoreEditorMode as g, type CoreToolbarClassNames as h, type ToolbarStyleVars as i, type ToolbarItemType as j, BLOCK_HEADING_LEVELS as k, type BlockFormat as l, type CommandConfig as m, type CommandGenerationOptions as n, DEFAULT_TOOLBAR_LAYOUT as o, ExtensiveEditor as p, type ExtensiveEditorMode as q, type ExtensiveExtensionsConfig as r, type FeatureFlag as s, type FeatureFlags as t, type ImageUploadHandler as u, type InsertImageConfig as v, type InsertTableConfig as w, type ShortcutConfig as x, type SlashCommandVisibility as y, type SlashCommandVisibilityFilters as z };