基于 React 和 Prosemirror 的编辑器,为 Outline 提供支持,也可用于以只读方式显示内容。该编辑器是所见即所得的,包括格式化工具,同时保留内联编写 Markdown 快捷方式和输出纯 Markdown 的能力。请参阅现场演示故事书。
重要提示:该项目并不试图成为一个通用的 Markdown 编辑器。它是为 Outline 知识库构建的,虽然欢迎其他人在您自己的产品中分叉或使用此包,但开发决策以 Outline 的需求为中心。
yarn add rich-markdown-editor或者
npm install rich-markdown-editor请注意, react 、 react-dom和styled-components是必需的对等依赖项。
import Editor from "rich-markdown-editor" ;
< Editor
defaultValue = "Hello world!"
/>克隆此存储库并使用yarn start运行 Storybook 以查看各种示例用法。
id该编辑器的唯一 ID,用于将设置保留在本地存储中。如果没有传递id ,则编辑器将默认使用位置路径名。
defaultValue表示编辑器初始值的 Markdown 字符串。使用此属性可以恢复以前保存的内容,以便用户继续编辑。
value表示编辑器值的 Markdown 字符串。使用此属性可以更改安装后的编辑器的值,这将重新渲染整个编辑器,因此仅适用于readOnly模式。不要将onChange的值通过管道传回value ,编辑器会保留其自己的内部状态,这将导致意外的副作用。
placeholder允许覆盖占位符。默认是“写一些不错的东西......”。
readOnly将readOnly设置为false时,编辑器会针对组合进行优化。当true时,编辑器可用于显示以前编写的内容 - 标题获得锚点并且链接变得可点击。
readOnlyWriteCheckboxes将readOnlyWriteCheckboxes设置为true时,作为特殊情况,仍然可以选中或取消选中复选框,而readOnly设置为true时,编辑器将无法进行编辑。
autoFocus当设置true和readOnly设置为false时,自动聚焦在文档末尾。
maxLength设置时会在文档上强制执行最大字符长度,不包括 Markdown 语法。
extensions允许将其他 Prosemirror 插件传递到底层 Prosemirror 实例。
disableExtensions要禁用的包含的扩展名称列表。删除相应的菜单项和命令。例如,设置为["em", "blockquote"]以禁用斜体文本和块引用。
theme允许覆盖内置主题来品牌化编辑器,例如使用您自己的字体和品牌颜色使编辑器适合您的应用程序。有关应提供的键的示例,请参阅内置主题。
dictionary允许覆盖内置的复制字典,例如国际化编辑器。有关应提供的键的示例,请参阅内置字典。
dark将dark设置为true编辑器将使用包含的默认深色主题。请参阅此处的来源。
dir默认值: auto
控制文档的方向。可能的值为:
ltr :编辑器布局针对 LTR 文档进行了优化,内容明确标记为 LTR。rtl :编辑器布局针对 RTL 文档进行了优化,内容明确标记为 RTL。auto :编辑器布局由浏览器根据文档内容决定。 tooltip一个 React 组件,将包裹在具有可选工具提示的项目周围。您可以使用它将您自己的工具提示库注入编辑器 - 该组件将传递以下属性:
tooltip :带有工具提示内容的 React 节点placement :枚举top 、 bottom 、 left 、 rightchildren :工具提示包裹的组件,必须渲染headingsOffset将文档标题偏移多个级别的数字。例如,如果您已经将编辑器嵌套在主h1标题下,您可能希望用户只能创建h2标题及以下标题,在这种情况下,您可以将 prop 设置为1 。
scrollTo表示标题锚点的字符串 - 文档将平滑滚动,以便标题在视口中可见。
embeds可以选择定义嵌入,当matcher函数返回真值时,嵌入将被插入以代替链接。匹配器方法的返回值将在props.attrs.matches下的组件上可用。如果提供了title和icon ,则嵌入也会出现在块菜单中。
< Editor
embeds = { [
{
title : "Google Doc" ,
keywords : "google docs gdocs" ,
icon : < GoogleDocIcon /> ,
defaultHidden : false ,
matcher : href => href . matches ( / docs.google.com / i ) ,
component : GoogleDocEmbed
}
] }
/>uploadImage(file: Blob): Promise<string>如果您希望编辑器支持图像,则必须提供此回调。当图像上传到存储位置(例如 S3)时,回调应该接受单个File对象并返回一个解析为 url 的承诺。例如:
< Editor
uploadImage = { async file => {
const result = await s3 . upload ( file ) ;
return result . url ;
} }
/> onBlur(): void当用户失去对编辑器 contenteditable 和所有关联的 UI 元素(例如块菜单和浮动工具栏)的焦点时,会触发此回调。如果您只想侦听可内容编辑区域上的模糊事件,请使用handleDOMEvents属性。
onFocus(): void当用户获得焦点在编辑器 contenteditable 或任何关联的 UI 元素(例如块菜单或浮动工具栏)上时,会触发此回调。如果您只想侦听可内容编辑区域上的焦点事件,请使用handleDOMEvents属性。
onSave({ done: boolean }): void当用户使用键盘快捷键Cmd+S或Cmd+Enter显式请求保存时,会触发此回调。您可以使用它作为将文档保存到远程服务器的信号。
onCancel(): void当在编辑器中按下Cmd+Escape时会触发此回调。您可以使用它来取消编辑。
onChange(() => value): void当编辑器的内容发生更改时(通常是由于用户输入(例如击键或使用格式设置选项)而发生更改),会触发此回调。您可以使用它在本地保留编辑器状态。
它返回一个函数,该函数在调用时返回文档的当前文本值。进行此优化是为了避免在每次更改事件时将文档状态序列化为文本,从而允许主机应用程序选择何时需要序列化值。
onImageUploadStart(): void此回调在uploadImage之前触发,可用于显示一些指示上传正在进行的 UI。
onImageUploadStop(): void图片上传成功或失败时触发。
onSearchLink(term: string): Promise<{ title: string, subtitle?: string, url: string }[]>该编辑器提供了搜索链接以从格式工具栏插入的功能。如果提供此回调,它应该接受搜索词作为唯一参数,并返回解析为对象数组的承诺。例如:
< Editor
onSearchLink = { async searchTerm => {
const results = await MyAPI . search ( searchTerm ) ;
return results . map ( result => {
title : result . name ,
subtitle : `Created ${ result . createdAt } ` ,
url : result . url
} )
} }
/> onCreateLink(title: string): Promise<string>该编辑器提供了从格式工具栏创建链接的功能,以便即时创建文档。如果提供此回调,它应该接受链接“标题”作为唯一参数,并返回一个解析为所创建链接的 url 的承诺,例如:
< Editor
onCreateLink = { async title => {
const url = await MyAPI . create ( {
title
} ) ;
return url ;
} }
/> onShowToast(message: string, type: ToastType): void当编辑器希望向用户显示消息时触发。连接到应用程序的通知系统,或者简单地使用window.alert(message) 。第二个参数是 toast 的类型:“error”或“info”。
onClickLink(href: string, event: MouseEvent): void此回调允许覆盖链接处理。通常情况下,您希望外部链接打开一个新窗口,并让内部链接使用像react-router这样的东西来导航。如果未提供回调,则打开新选项卡的默认行为将应用于所有链接。例如:
import { history } from "react-router" ;
< Editor
onClickLink = { ( href , event ) => {
if ( isInternalLink ( href ) ) {
history . push ( href ) ;
} else {
window . location . href = href ;
}
} }
/> onHoverLink(event: MouseEvent): boolean此回调允许检测用户何时将鼠标悬停在文档中的链接上。
< Editor
onHoverLink = { event => {
console . log ( `Hovered link ${ event . target . href } ` ) ;
} }
/> onClickHashtag(tag: string, event: MouseEvent): void此回调允许处理单击文档文本中的主题标签。如果未提供回调,则主题标签将呈现为常规文本,因此您可以通过传递此属性来选择是否支持它们。
import { history } from "react-router" ;
< Editor
onClickHashtag = { tag => {
history . push ( `/hashtags/ ${ tag } ` ) ;
} }
/> handleDOMEvents: {[name: string]: (view: EditorView, event: Event) => boolean;}该对象将事件名称( focus 、 paste 、 touchstart等)映射到回调函数。
< Editor
handleDOMEvents = { {
focus : ( ) => console . log ( "FOCUS" ) ,
blur : ( ) => console . log ( "BLUR" ) ,
paste : ( ) => console . log ( "PASTE" ) ,
touchstart : ( ) => console . log ( "TOUCH START" ) ,
} }
/>编辑器组件公开了一些与已安装的编辑器交互的方法。
focusAtStart(): void将光标置于文档的开头并将其聚焦。
focusAtEnd(): void将光标置于文档末尾并聚焦。
getHeadings(): { title: string, level: number, id: string }[]返回一个对象数组,其中包含文档中所有标题的文本内容、它们在层次结构中的级别以及锚点 ID。这对于构建您自己的目录非常有用,因为 v10 中删除了toc选项。
该项目使用yarn来管理依赖关系。您可以使用 npm,但它不会尊重纱线锁定文件,并且可能安装略有不同的版本。
yarn install
在开发中运行时,Storybook 包含在具有热重载的示例编辑器中。安装依赖项后,运行yarn start即可开始。
使用yarn link进行开发时,您可以在进行更改时使用yarn watch不断将更改重建为dist 。
该项目已获得 BSD 许可。