A React and Prosemirror based editor that powers Outline and can also be used for displaying content in a read-only fashion.The editor is WYSIWYG and includes formatting tools whilst retaining the ability to write markdown shortcuts inline and output plain Markdown.
Important Note: This project is not attempting to be an all-purpose Markdown editor. It is built for the Outline knowledge base, and whilst others are welcome to fork or use this package in your own products, development decisions are centered around the needs of Outline.
yarn add rich-markdown-editor
or
npm install rich-markdown-editor
Note that react
, react-dom
, and styled-components
are required peer dependencies.
import Editor from "rich-markdown-editor";
<Editor
defaultValue="Hello world!"
/>
Clone this repo and run the Storybook with yarn start
to see a wide variety of example usage.
id
A unique id for this editor, used to persist settings in local storage. If no id
is passed then the editor will default to using the location pathname.
defaultValue
A markdown string that represents the initial value of the editor. Use this to prop to restorepreviously saved content for the user to continue editing.
value
A markdown string that represents the value of the editor. Use this prop to change the value of the editor once mounted, this will re-render the entire editor and as such is only suitable when also in readOnly
mode. Do not pipe the value of onChange
back into value
, the editor keeps it's own internal state and this will result in unexpected side effects.
placeholder
Allows overriding of the placeholder. The default is "Write something nice…".
readOnly
With readOnly
set to false
the editor is optimized for composition. When true
the editor can be used to display previously written content – headings gain anchors and links become clickable.
readOnlyWriteCheckboxes
With readOnlyWriteCheckboxes
set to true
checkboxes can still be checked or unchecked as a special case while readOnly
is set to true
and the editor is otherwise unable to be edited.
autoFocus
When set true
together with readOnly
set to false
, focus at the end of thedocument automatically.
maxLength
When set enforces a maximum character length on the document, not including markdown syntax.
extensions
Allows additional Prosemirror plugins to be passed to the underlying Prosemirror instance.
disableExtensions
List of included extension names to disable. Removes corresponding menu items and commands. E.g. set to ["em", "blockquote"]
to disable italic text and blockquotes.
theme
Allows overriding the inbuilt theme to brand the editor, for example use your own font face and brand colors to have the editor fit within your application. See the inbuilt theme for an example of the keys that should be provided.
dictionary
Allows overriding the inbuilt copy dictionary, for example to internationalize the editor. See the inbuilt dictionary for an example of the keys that should be provided.
dark
With dark
set to true
the editor will use a default dark theme that's included. See the source here.
dir
Default: auto
Controls direction of the document. Possible values are:
ltr
: Editor layout is optimized for LTR documents and the content is explicitly marked as LTR.rtl
: Editor layout is optimized for RTL documents and the content is explicitly marked as RTL.auto
: Editor layout is decided by the browser based on document content.tooltip
A React component that will be wrapped around items that have an optional tooltip. You can use this to inject your own tooltip library into the editor – the component will be passed the following props:
tooltip
: A React node with the tooltip contentplacement
: Enum top
, bottom
, left
, right
children
: The component that the tooltip wraps, must be renderedheadingsOffset
A number that will offset the document headings by a number of levels. For example, if you already nest the editor under a main h1
title you might want the user to only be able to create h2
headings and below, in this case you would set the prop to 1
.
scrollTo
A string representing a heading anchor – the document will smooth scroll so that the heading is visiblein the viewport.
embeds
Optionally define embeds which will be inserted in place of links when the matcher
function returns a truthy value. The matcher method's return value will be available on the component under props.attrs.matches
. If title
and icon
are provided then the embed will also appear in the block menu.
<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>
If you want the editor to support images then this callback must be provided. The callback should accept a single File
object and return a promise the resolves to a url when the image has been uploaded to a storage location, for example S3. eg:
<Editor
uploadImage={async file => {
const result = await s3.upload(file);
return result.url;
}}
/>
onBlur(): void
This callback is triggered when the user loses focus on the editor contenteditable and allassociated UI elements such as the block menu and floating toolbars. If you want to listenfor blur events on only the contenteditable area then use handleDOMEvents
props.
onFocus(): void
This callback is triggered when the user gains focus on the editor contenteditable or anyassociated UI elements such as the block menu or floating toolbars. If you want to listenfor focus events on only the contenteditable area then use handleDOMEvents
props.
onSave({ done: boolean }): void
This callback is triggered when the user explicitly requests to save using a keyboard shortcut, Cmd+S
or Cmd+Enter
. You can use this as a signal to save the document to a remote server.
onCancel(): void
This callback is triggered when the Cmd+Escape
is hit within the editor. You may use it to cancel editing.
onChange(() => value): void
This callback is triggered when the contents of the editor changes, usually due to user input such as a keystroke or using formatting options. You may use this to locally persist the editors state.
It returns a function which when called returns the current text value of the document. This optimization is made to avoid serializing the state of the document to text on every change event, allowing the host app to choose when it needs the serialized value.
onImageUploadStart(): void
This callback is triggered before uploadImage
and can be used to show some UI that indicates an upload is in progress.
onImageUploadStop(): void
Triggered once an image upload has succeeded or failed.
onSearchLink(term: string): Promise<{ title: string, subtitle?: string, url: string }[]>
The editor provides an ability to search for links to insert from the formatting toolbar. If this callback is provided it should accept a search term as the only parameter and return a promise that resolves to an array of objects. eg:
<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>
The editor provides an ability to create links from the formatting toolbar for on-the-fly document createion. If this callback is provided it should accept a link "title" as the only parameter and return a promise that resolves to a url for the created link, eg:
<Editor
onCreateLink={async title => {
const url = await MyAPI.create({
title
});
return url;
}}
/>
onShowToast(message: string, type: ToastType): void
Triggered when the editor wishes to show a message to the user. Hook into your app'snotification system, or simplisticly use window.alert(message)
. The second parameteris the type of toast: 'error' or 'info'.
onClickLink(href: string, event: MouseEvent): void
This callback allows overriding of link handling. It's often the case that you want to have external links open a new window and have internal links use something like react-router
to navigate. If no callback is provided then default behavior of opening a new tab will apply to all links. eg:
import { history } from "react-router";
<Editor
onClickLink={(href, event) => {
if (isInternalLink(href)) {
history.push(href);
} else {
window.location.href = href;
}
}}
/>
onHoverLink(event: MouseEvent): boolean
This callback allows detecting when the user hovers over a link in the document.
<Editor
onHoverLink={event => {
console.log(`Hovered link ${event.target.href}`);
}}
/>
onClickHashtag(tag: string, event: MouseEvent): void
This callback allows handling of clicking on hashtags in the document text. If no callback is provided then hashtags will render as regular text, so you can choose if to support them or not by passing this prop.
import { history } from "react-router";
<Editor
onClickHashtag={tag => {
history.push(`/hashtags/${tag}`);
}}
/>
handleDOMEvents: {[name: string]: (view: EditorView, event: Event) => boolean;}
This object maps event names (focus
, paste
, touchstart
, etc.) to callback functions.
<Editor
handleDOMEvents={{
focus: () => console.log("FOCUS"),
blur: () => console.log("BLUR"),
paste: () => console.log("PASTE"),
touchstart: () => console.log("TOUCH START"),
}}
/>
The Editor component exposes a few methods for interacting with the mounted editor.
focusAtStart(): void
Place the cursor at the start of the document and focus it.
focusAtEnd(): void
Place the cursor at the end of the document and focus it.
getHeadings(): { title: string, level: number, id: string }[]
Returns an array of objects with the text content of all the headings in the document,their level in the hierarchy, and the anchor id. This is useful to construct your own table of contents since the toc
option was removed in v10.
This project uses yarn to manage dependencies. You can use npm however it will not respect the yarn lock file and may install slightly different versions.
yarn install
When running in development Storybook is included to example editors with hot reloading. After installing dependencies run yarn start
to get going.
When developing using yarn link
, you can use yarn watch
to continuously rebuild on change into dist
as you make changes.
This project is BSD licensed.
图文混排的界面,常见于新闻、帖子的详情页渲染。 由于小程序端的限制,uni-app的富文本的处理与普通网页不同。 有rich-text组件、v-html、和uParse三类方案。 1.rich-text rich-text是uni-app的内置组件,提供了高性能的富文本渲染模式。 API参考https://uniapp.dcloud.io/component/rich-text rich-text
由于小程序端的限制,uni-app的富文本的处理与普通网页不同。 有rich-text组件、v-html、和uParse三类方案。 1. rich-text rich-text是uni-app的内置组件,提供了高性能的富文本渲染模式。 API参考https://uniapp.dcloud.io/component/rich-text rich-text的优势是全端支持、高性能。有个缺陷是只能整体设
前言 作为一个有博客也有公众号还需要每天写一些接口文档的高级技术工人,每天对于写作的需求量还是很大的。在用markdown之前一直在用各种奇奇怪怪的方式来写文档,其中不乏word、txt等传统方式。倒不是说人们常用的传统的方式不对,想表达的是markdown较其他的编辑方式有其自己的优点。 如果你 有写文档或写作的需求 对格式有一定的要求,但不是很要求精准的格式 希望注重于写作内容本身,想要在格式
When I decided to learn and use Markdown as my daily note-taking method, I realized there are too many editors and not all of them are handy or easy to use. So I tried what I can found on Windows plat
Rich 是一个 Python 库,可以为你在终端中提供富文本和精美格式。 Rich API 可以很容易的在终端输出添加各种颜色和不同风格。Rich 还可以绘制漂亮的表格、进度条、markdown、突出显示语法的源代码及回溯等等,不胜枚举。 兼容性 Rich 适用于 Linux,OSX 和 Windows。真彩色/表情符号可与新的 Windows 终端一起使用,Windows 的经典终端仅限 8
用 silverlight 开发的 HTML 编辑器 在线演示:http://michaelsync.net/2008/05/04/silverlight-rich-text-editor-demo
Weex 富文本的通用解决方案,支持 文字、图标、链接、标签 形式的混排 规则 使用统一规范,前后端约定相关字段 wxc-rich-text用于支持一行通用图文混排情况 wxc-special-rich-text用于支持两行特殊情况(一个 tag 或 icon 加两行文本情况) Demo 使用方法 <template> <div> <wxc-rich-text :config-list
The Enhanced Media Embed plugin makes it easy to add an enhanced content creation experience in your website or app with enriched media previews from the most popular web sources. Facebook, YouTube, F
Spring Rich Client 是基于 Spring 开发的框架,用来开发专业的、企业级的富客户端应用程序。
Rich HTML TIcker is a practical script for displaying ordinary, rich HTML content in a rotated fashion on your page. The ticker contents can either be defined inline on the page, or within an external