基于 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
、 right
children
:工具提示包裹的组件,必须渲染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 许可。