lexical
约 2 分钟阅读
- facebook/lexicalGitHubfacebook/lexicalfacebook/lexical · MIT, FlowJS · by Facebook · React 体验 · EditorState single source of truth · reconcile DOM · 纯 JS 可使用 · 基于 contentEditable笔记:lexical
- MIT, FlowJS
- by Facebook
- React 体验
- EditorState single source of truth
- reconcile DOM
- 纯 JS 可使用
- 基于 contentEditable
- 替代 Draft.js
- 性能好
- queueMicrotask
- React 18+ concurrent 支持
- 支持 yjs 集成
- adopted by
- payloadcms
- 0 依赖
- playground.lexical.dev
- 目前还相当不成熟 - 还处于快速开发阶段
- 目前更建议使用 Tiptap
- 节点耦合插件 - #1262GitHub Issuefacebook/lexical#1262
- 无法扩展已有节点 - 做不到 Tiptap 的 Extension 效果
# react -> list,link,code,overflow,history,markdown,mark,hashtag,selection,dragon,utils,table,clipboard,rich-text,plain-text
npm add lexical @lexical/react
npm add @lexical/file
npm add y-websocket yjs @lexical/yjs依赖包lexicalnpm 包lexicalNPM@lexical/reactnpm 包@lexical/reactNPM@lexical/filenpm 包@lexical/fileNPMy-websocketnpm 包y-websocketNPMyjsnpm 包yjsNPM@lexical/yjsnpm 包@lexical/yjsNPM
- link-preview-generator
Notes
Node
- RootNode
- LineBreakNode -
\n - ElementNode - 基础类
- TextNode
- format - bold, italic, underline, strikethrough, code, subscript, superscript
- mode
- token - 内容不可编辑,作为整体删除 - tiptap atom
- inert - 类似 token,会设置 contenteditable=false
- segmented
- style - CSS 样式
- DecoratorNode - 修饰现有节点 - tiptap NodeView
interface Node {
static getType();
static clone(node: typeof this);
// ElementNode 没有 EditorConfig
// TextNode 有 EditorConfig
createDOM(config: EditorConfig): HTMLElement;
// true - replace with createDOM
updateDOM(prevNode: CustomParagraph, dom: HTMLElement, config: EditorConfig): boolean;
// for DecoratorNode<React$Node>
decorate(): React$Node;
}Node Transform
editor.registerNodeTransform(TextNode, (textNode) => {
//
});Command
// payload
const HELLO_WORLD_COMMAND: LexicalCommand<string> = createCommand();
editor.dispatchCommand(HELLO_WORLD_COMMAND, 'Hello World!');
editor.registerCommand(
HELLO_WORLD_COMMAND,
(payload: string) => {
console.log(payload); // Hello World!
return false;
},
LowPriority,
);Listener
const removeUpdateListener = editor.registerUpdateListener(({ editorState }) => {
editorState.read(() => {
// 通过 $ 前缀函数 访问上下文状态
});
editor.update(() => {
// transaction
});
});
removeUpdateListener();
// 监听内容变化
editor.registerTextContentListener((textContent) => {
console.log(textContent);
});
// 监听节点修改
editor.registerMutationListener(MyCustomNode, (mutatedNodes) => {
// mutation: created, destroyed, updated
for (let [nodeKey, mutation] of mutatedNodes) {
console.log(nodeKey, mutation);
}
});
// 只读状态变化
editor.registerReadOnlyListener((readOnly) => {
console.log(readOnly);
});
//
editor.registerDecoratorListener((decorators) => {
console.log(decorators);
});Selection
- RangeSelection
- NodeSelection
- GridSelection
- null
EditorState
关联信息
反向链接、本文链接的其他页面和外部资料。
反向链接
- Draftjs笔记 · lexical
新项目不再建议使用,使用 lexical · facebook/draft-js · 特点 · 原生 React · Facebook 开源使用 · 基于 contentEditable · 支持自定义组件 · 样式是预定义映射为 css style
参考资料
GitHub2 条
- facebook/lexicalgithub.com/facebook/lexical
- facebook/lexical#1262github.com/facebook/lexical/issues/1262
其他外链2 条
- badgen.net/bundlephobia/min/lexical?label=lexicalbadgen.net/bundlephobia/min/lexical?label=lexical
- playground.lexical.devplayground.lexical.dev/