Редактор на основе React и Prosemirror, который поддерживает Outline, а также может использоваться для отображения контента только для чтения. Редактор является WYSIWYG и включает в себя инструменты форматирования, сохраняя при этом возможность писать ярлыки уценки в строке и выводить простой Markdown. См. сборник рассказов Live demo .
Важное примечание: этот проект не претендует на роль универсального редактора 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!"
/>
Клонируйте этот репозиторий и запустите Storybook с помощью yarn start
чтобы увидеть множество примеров использования.
id
Уникальный идентификатор этого редактора, используемый для сохранения настроек в локальном хранилище. Если id
не передан, редактор по умолчанию будет использовать путь к местоположению.
defaultValue
Строка уценки, представляющая начальное значение редактора. Используйте это, чтобы восстановить ранее сохраненный контент, чтобы пользователь мог продолжить редактирование.
value
Строка уценки, представляющая значение редактора. Используйте эту опцию, чтобы изменить значение редактора после его подключения. Это приведет к повторной визуализации всего редактора и поэтому подходит только в режиме readOnly
. Не передавайте значение onChange
обратно в value
, редактор сохраняет свое внутреннее состояние, и это приведет к неожиданным побочным эффектам.
placeholder
Позволяет переопределить заполнитель. По умолчанию установлено «Напишите что-нибудь приятное…».
readOnly
Если для readOnly
установлено значение false
редактор оптимизирован для композиции. Если true
редактор можно использовать для отображения ранее написанного контента — заголовки получают привязки, а ссылки становятся кликабельными.
readOnlyWriteCheckboxes
Если для readOnlyWriteCheckboxes
установлено true
, флажки по-прежнему можно устанавливать или снимать в особых случаях, в то время как readOnly
установлено значение true
, и в противном случае редактор не может быть отредактирован.
autoFocus
Если установлено true
вместе с readOnly
, установленным в false
, автоматически фокусируется на конце документа.
maxLength
Если установлено, максимальная длина символов в документе не включает синтаксис уценки.
extensions
Позволяет передавать дополнительные плагины Prosemirror базовому экземпляру Prosemirror.
disableExtensions
Список включенных имен расширений, которые нужно отключить. Удаляет соответствующие пункты меню и команды. Например, установите значение ["em", "blockquote"]
чтобы отключить курсив и кавычки.
theme
Позволяет переопределить встроенную тему для фирменного оформления редактора, например использовать собственный шрифт и фирменные цвета, чтобы редактор вписывался в ваше приложение. См. встроенную тему для примера ключей, которые необходимо предоставить.
dictionary
Позволяет переопределить встроенный словарь копирования, например, для интернационализации редактора. См. встроенный словарь для примера ключей, которые следует предоставить.
dark
Если для dark
установлено значение true
редактор будет использовать включенную темную тему по умолчанию. Смотрите источник здесь.
dir
По умолчанию: auto
Управляет направлением документа. Возможные значения:
ltr
: макет редактора оптимизирован для документов LTR, а содержимое явно помечено как LTR.rtl
: макет редактора оптимизирован для документов с письмом справа налево, а содержимое явно помечено как письмо с письмом справа налево.auto
: макет редактора определяется браузером на основе содержимого документа. tooltip
Компонент React, который будет обернут вокруг элементов, имеющих дополнительную всплывающую подсказку. Вы можете использовать это, чтобы внедрить в редактор свою собственную библиотеку подсказок — компоненту будут переданы следующие реквизиты:
tooltip
: узел React с содержимым всплывающей подсказки.placement
: Enum top
, bottom
, left
, right
children
: компонент, который обертывает всплывающая подсказка, должен быть отображен. headingsOffset
Число, которое сместит заголовки документов на несколько уровней. Например, если вы уже вложили редактор в основной заголовок h1
вы можете захотеть, чтобы пользователь мог создавать только заголовки h2
и ниже, в этом случае вы должны установить для свойства значение 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>
Если вы хотите, чтобы редактор поддерживал изображения, необходимо предоставить этот обратный вызов. Обратный вызов должен принимать один объект File
и возвращать обещание, которое преобразуется в URL-адрес, когда изображение было загружено в место хранения, например S3. например:
< Editor
uploadImage = { async file => {
const result = await s3 . upload ( file ) ;
return result . url ;
} }
/>
onBlur(): void
Этот обратный вызов срабатывает, когда пользователь теряет фокус на контенте редактора и всех связанных с ним элементах пользовательского интерфейса, таких как меню блоков и плавающие панели инструментов. Если вы хотите прослушивать события размытия только в области, доступной для редактирования, используйте реквизиты handleDOMEvents
.
onFocus(): void
Этот обратный вызов запускается, когда пользователь фокусируется на редактируемом редакторе или любых связанных с ним элементах пользовательского интерфейса, таких как меню блоков или плавающие панели инструментов. Если вы хотите прослушивать события фокуса только в области, доступной для редактирования, используйте реквизиты handleDOMEvents
.
onSave({ done: boolean }): void
Этот обратный вызов запускается, когда пользователь явно запрашивает сохранение с помощью сочетания клавиш Cmd+S
или Cmd+Enter
. Вы можете использовать это как сигнал для сохранения документа на удаленном сервере.
onCancel(): void
Этот обратный вызов запускается при нажатии Cmd+Escape
в редакторе. Вы можете использовать его для отмены редактирования.
onChange(() => value): void
Этот обратный вызов запускается, когда содержимое редактора изменяется, обычно из-за пользовательского ввода, например нажатия клавиши или использования параметров форматирования. Вы можете использовать это для локального сохранения состояния редактора.
Он возвращает функцию, которая при вызове возвращает текущее текстовое значение документа. Эта оптимизация сделана для того, чтобы избежать сериализации состояния документа в текст при каждом событии изменения, позволяя ведущему приложению выбирать, когда ему нужно сериализованное значение.
onImageUploadStart(): void
Этот обратный вызов запускается перед uploadImage
и может использоваться для отображения некоторого пользовательского интерфейса, указывающего, что загрузка выполняется.
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)
. Второй параметр — это тип всплывающего уведомления: «ошибка» или «информация».
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" ) ,
} }
/>
Компонент Editor предоставляет несколько методов взаимодействия с смонтированным редактором.
focusAtStart(): void
Поместите курсор в начало документа и сфокусируйте его.
focusAtEnd(): void
Поместите курсор в конец документа и сфокусируйте его.
getHeadings(): { title: string, level: number, id: string }[]
Возвращает массив объектов с текстовым содержимым всех заголовков документа, их уровнем в иерархии и идентификатором привязки. Это полезно для создания собственного оглавления, поскольку опция toc
была удалена в версии 10.
Этот проект использует пряжу для управления зависимостями. Вы можете использовать npm, однако он не будет учитывать файл блокировки пряжи и может установить несколько другие версии.
yarn install
При запуске в разработке Storybook включается в редакторы примеров с горячей перезагрузкой. После установки зависимостей запустите yarn start
начните работу.
При разработке с использованием yarn link
вы можете использовать yarn watch
для непрерывного восстановления изменений в dist
по мере внесения изменений.
Этот проект имеет лицензию BSD.