This is a modified clone of Rich Markdown Editor.
yarn add @4giving/r-m-e
or
npm install @4giving/r-m-e
Note that react
, react-dom
, and styled-components
are required peer dependencies.
import Editor from '@4giving/r-m-e';
<Editor defaultValue="Hello world!" />;
See a working example in the example directory with many example props.
A unique id for this editor, used to persist settings such as collapsed headings. If no id
is passed then the editor will default to using the location pathname.
A markdown string that represents the initial value of the editor. Use this to prop to restore previously saved content for the user to continue editing.
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.
Allows overriding of the placeholder. The default is "Write something nice…".
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.
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.
When set true
together with readOnly
set to false
, focus at the end of the
document automatically.
Allows additional Prosemirror plugins to be passed to the underlying Prosemirror instance.
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.
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.
With dark
set to true
the editor will use a default dark theme that's included. See the source here.
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
: Enumtop
,bottom
,left
,right
children
: The component that the tooltip wraps, must be rendered
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
.
A string representing a heading anchor – the document will smooth scroll so that the heading is visible in the viewport.
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 />,
matcher: href => href.matches(/docs.google.com/i),
component: GoogleDocEmbed
}
]}
/>
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.
This callback is triggered when the Cmd+Escape
is hit within the editor. You may use it to cancel editing.
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, see the inbuilt example.
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.
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;
}
}}
/>;
This callback allows detecting when the user hovers over a link in the document.
<Editor
onHoverLink={event => {
console.log(`Hovered link ${event.target.href}`);
}}
/>
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')
}}
/>
This allows you to get a method that will insert an image url string for you, removing the reliance of image uploading through this tool.
<Editor
insertImageHandler={handler => {
handler('https://picsum.photos/600/600');
}}
/>
The Editor component exposes a few methods for interacting with the mounted editor.
Place the cursor at the start of the document and focus it.
Place the cursor at the end of the document and focus it.
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 webpack-serve is included to serve an example editor with hot reloading. After installing dependencies run yarn start
to get going.
This project is BSD licensed.