import {MarkdownEditor} from '@primer/react/drafts'
MarkdownEditor
is a full-featured editor for GitHub Flavored Markdown, with support for:
@
mentions, and #
references)Enter
)A Label
is always required for accessibility:
{/ prettier-ignore-start /}
const renderMarkdown = async (markdown) => {// In production code, this would make a query to some external API endpoint to renderreturn 'Rendered Markdown.'}const MinimalExample = () => {const [value, setValue] = React.useState('')return (<MarkdownEditor value={value} onChange={setValue} onRenderPreview={renderMarkdown}><MarkdownEditor.Label>Minimal Example</MarkdownEditor.Label></MarkdownEditor>)}render(MinimalExample)
{/ prettier-ignore-end /}
{/ prettier-ignore-start /}
const renderMarkdown = async (markdown) => 'Rendered Markdown.'const uploadFile = async (file) => ({url: `https://example.com/${encodeURIComponent(file.name)}`,file,})const emojis = [{name: '+1', character: '👍'},{name: '-1', character: '👎'},{name: 'heart', character: '❤️'},{name: 'wave', character: '👋'},{name: 'raised_hands', character: '🙌'},{name: 'pray', character: '🙏'},{name: 'clap', character: '👏'},{name: 'ok_hand', character: '👌'},{name: 'point_up', character: '☝️'},{name: 'point_down', character: '👇'},{name: 'point_left', character: '👈'},{name: 'point_right', character: '👉'},{name: 'raised_hand', character: '✋'},{name: 'thumbsup', character: '👍'},{name: 'thumbsdown', character: '👎'},]const references = [{id: '1', titleText: 'Add logging functionality', titleHtml: 'Add logging functionality'},{id: '2',titleText: 'Error: `Failed to install` when installing',titleHtml: 'Error: <code>Failed to install</code> when installing',},{id: '3', titleText: 'Add error-handling functionality', titleHtml: 'Add error-handling functionality'},]const mentionables = [{identifier: 'monalisa', description: 'Monalisa Octocat'},{identifier: 'github', description: 'GitHub'},{identifier: 'primer', description: 'Primer'},]const savedReplies = [{name: 'Duplicate', content: 'Duplicate of #'},{name: 'Welcome', content: 'Welcome to the project!\n\nPlease be sure to read the contributor guidelines.'},{name: 'Thanks', content: 'Thanks for your contribution!'},]const MinimalExample = () => {const [value, setValue] = React.useState('')return (<MarkdownEditorvalue={value}onChange={setValue}onRenderPreview={renderMarkdown}onUploadFile={uploadFile}emojiSuggestions={emojis}referenceSuggestions={references}mentionSuggestions={mentionables}savedReplies={savedReplies}><MarkdownEditor.Label>Suggestions, File Uploads, and Saved Replies Example</MarkdownEditor.Label></MarkdownEditor>)}render(MinimalExample)
{/ prettier-ignore-end /}
{/ prettier-ignore-start /}
const renderMarkdown = async (markdown) => 'Rendered Markdown.'const MinimalExample = () => {const [value, setValue] = React.useState('')return (<MarkdownEditor value={value} onChange={setValue} onRenderPreview={renderMarkdown}><MarkdownEditor.Label visuallyHidden>Custom Buttons</MarkdownEditor.Label><MarkdownEditor.Toolbar><MarkdownEditor.ToolbarButton icon={SquirrelIcon} aria-label="Custom button 1" /><MarkdownEditor.DefaultToolbarButtons /><MarkdownEditor.ToolbarButton icon={BugIcon} aria-label="Custom button 2" /></MarkdownEditor.Toolbar><MarkdownEditor.Actions><MarkdownEditor.ActionButton variant="danger">Cancel</MarkdownEditor.ActionButton><MarkdownEditor.ActionButton variant="primary">Submit</MarkdownEditor.ActionButton></MarkdownEditor.Actions></MarkdownEditor>)}render(MinimalExample)
{/ prettier-ignore-end /}
Name | Type | Default | Description |
---|---|---|---|
value Required | string | Current value of the editor as a multiline markdown string. | |
onChange Required | (newMarkdown: string) => void | Called when the value changes. | |
onRenderPreview Required | (markdown: string) => Promise<string> | Accepts Markdown and returns rendered HTML. To prevent XSS attacks, the HTML should be sanitized and/or come from a trusted source. | |
children Required | React.ReactNode | ||
disabled | boolean | Disable the editor and all related buttons. Users can still switch between preview & edit modes. | |
placeholder | string | Placeholder text to show when the editor is empty. By default, no placeholder will be shown. | |
maxLength | number | Maximum number of characters the markdown can hold (includes formatting characters like `*`). | |
fullHeight | boolean | Force the editor to take up the full height of the container and disallow resizing. Only use when the container height is tall enough that the user will never want to expand the input further, ie when it takes the full height of the viewport. | |
aria-describedby | string | ||
viewMode | 'preview' | 'edit' | ||
onChangeViewMode | (newViewMode: 'preview' | 'edit') => void | ||
onPrimaryAction | () => void | ||
minHeightLines | number | 5 | |
maxHeightLines | number | 35 | |
emojiSuggestions | SuggestionOptions<Emoji> | ||
mentionSuggestions | SuggestionOptions<Mentionable> | ||
referenceSuggestions | SuggestionOptions<Reference> | ||
onUploadFile | (file: File) => Promise<FileUploadResult> | ||
acceptedFileTypes | FileType[] | ||
monospace | boolean | ||
required | boolean | ||
name | string | ||
savedReplies | SavedReply[] | ||
pasteUrlsAsPlainText | boolean |