This page is the full API map for @lyfie/luthor-headless.
createEditorSystemcreateExtensionRichText and richTextExtensionmarkdownToJSON, jsonToMarkdown, htmlToJSON, jsonToHTMLappendMetadataEnvelopes, extractMetadataEnvelopes, rehydrateDocumentFromEnvelopesdefaultLuthorTheme, mergeThemes, createEditorThemeStyleVarsclearLexicalSelection, resolveLinkNodeKeyFromAnchorimport {
createEditorSystem,
RichText,
richTextExtension,
boldExtension,
italicExtension,
} from '@lyfie/luthor-headless';
const extensions = [richTextExtension, boldExtension, italicExtension] as const;
const { Provider, useEditor } = createEditorSystem<typeof extensions>();
function Toolbar() {
const { commands, activeStates } = useEditor();
return (
<div>
<button onClick={() => commands.toggleBold?.()} aria-pressed={activeStates.bold === true}>Bold</button>
<button onClick={() => commands.toggleItalic?.()} aria-pressed={activeStates.italic === true}>Italic</button>
</div>
);
}
export function Editor() {
return (
<Provider extensions={extensions}>
<Toolbar />
<RichText placeholder="Write..." />
</Provider>
);
}createEditorSystem return shapecreateEditorSystem<typeof extensions>() returns:
Provider
extensions, optional config, childrenuseEditor
commandsactiveStatesstateQuerieslisteners.registerUpdate(...)listeners.registerPaste(...)export.toJSON()import.fromJSON(...)editor / lexicalextensions, hasExtension(name), pluginsRichText propsRichText and RichTextConfig share these props:
placeholder?: ReactElement | stringcontentEditable?: ReactElementclassName?: stringclassNames?: { container?: string; contentEditable?: string; placeholder?: string }styles?: { container?: CSSProperties; contentEditable?: CSSProperties; placeholder?: CSSProperties }nonEditableVisualMode?: booleanonEditIntent?: ({ clientX, clientY }) => voiderrorBoundary?: React.ComponentType<{ children; onError }>boldExtension, italicExtension, underlineExtension, strikethroughExtensionsubscriptExtension, superscriptExtension, codeFormatExtensionfontFamilyExtension, fontSizeExtension, lineHeightExtensiontextColorExtension, textHighlightExtensionlinkExtension, blockFormatExtension, listExtension, tabIndentExtensionhorizontalRuleExtension, tableExtension, enterKeyBehaviorExtensioncodeExtension, codeIntelligenceExtensionhistoryExtensioncommandPaletteExtensionslashCommandExtensionfloatingToolbarExtensioncontextMenuExtensiondraggableBlockExtensionemojiExtensionimageExtensioniframeEmbedExtensionyouTubeEmbedExtensioncreateCustomNodeExtension(...)createExtension(...)BaseExtension (advanced class-based extension model)FontFamilyConfig, FontFamilyOption, FontCssLoadStrategyFontSizeConfig, FontSizeOptionLineHeightConfig, LineHeightOptionTextColorConfig, TextColorOptionTextHighlightConfig, TextHighlightOptionCodeExtensionConfigCodeIntelligenceConfig, CodeIntelligenceCommandsCodeHighlightProvider, CodeHighlightProviderConfigCodeLanguageOptionsMode, CodeLanguageOptionsConfigTableConfigDraggableConfigmedia/typesEmojiConfig, EmojiCommands, EmojiStateQueriesEmojiCatalogAdapter, EmojiCatalogItem, EmojiSuggestionStateLIGHTWEIGHT_EMOJI_CATALOGimport { jsonToHTML, jsonToMarkdown } from '@lyfie/luthor-headless';
function SaveButton() {
const { export: exportApi } = useEditor();
const save = () => {
const json = exportApi.toJSON();
console.log({
json,
markdown: jsonToMarkdown(json),
html: jsonToHTML(json),
});
};
return <button onClick={save}>Save</button>;
}createExtension)import { $createParagraphNode, $getRoot } from 'lexical';
import { createExtension, ExtensionCategory } from '@lyfie/luthor-headless';
export const clearDocumentExtension = createExtension({
name: 'clearDocument',
category: [ExtensionCategory.Toolbar],
commands: (editor) => ({
clearDocument: () => {
editor.update(() => {
const root = $getRoot();
root.clear();
root.append($createParagraphNode());
});
},
}),
});createExtension(...) for straightforward command/plugin additions.BaseExtension when you need: