Последняя разработка продолжается в этом филиале.
Среда, как богатый текстовый редактор, построенный на Draft-JS с акцентом на устранение использования мыши, добавив соответствующие сочетания клавиш.
Документация в процессе.
Установите бета -версию, используя
npm install medium-draft@beta
RETURN пресс.caption - может использоваться в качестве заголовка для медиа -блоков, таких как изображение или видео вместо вложенных экземпляров draft-js для простоты.block-quote-caption -заголовок для blockquote s.todo - TODO Текст с флажком.toolbarConfig для следующего блока и встроенных стилей. По умолчанию всем. С учетом регистра.block: ['ordered-list-item', 'unordered-list-item', 'blockquote', 'header-three', 'todo']inline: ['BOLD', 'ITALIC', 'UNDERLINE', 'hyperlink', 'HIGHLIGHT'] Alt/Option +
Эти команды не являются частью основного редактора, но были реализованы в примере кода, в котором используется редактор medium-draft .
localstorage .localstorage . -- текущий блок будет blockquote , он будет изменен на block-quote-caption , иначе caption .*. (An asterisk and a period) unordered-list-item .*<SPACE> (An asterisk and a space) unordered-list-item .-<SPACE> (A hyphen and a space) unordered-list-item .1. (The number 1 and a period) unordered-list-item .## - header-two .[] - todo .== - unstyled .npm install medium-draft .import Editor from 'medium-draft'<link rel="stylesheet" type="text/css" href="https://unpkg.com/medium-draft/dist/medium-draft.css"> в <head><script src="https://unpkg.com/medium-draft/dist/medium-draft.js"></script> . Средний дрэф доступен в глобальном объекте как MediumDraft . medium-draft находится на вершине draft-js с некоторыми встроенными функциональными возможностями и блоками. Его API почти такой же, как у draft-js . Вы можете взглянуть на код демо -редактора, чтобы увидеть реализацию.
Включите CSS, которая поставляется с библиотекой в вашем HTML -
< link rel =" stylesheet " type =" text/css " href =" https://unpkg.com/medium-draft/dist/medium-draft.css " > Если вы используете webpack для объединения, вы можете импортировать CSS, как это в вашем коде JS
import 'medium-draft/lib/index.css' ; Если вы используете sideButtons , вам также нужно будет включить CSS для font-awesome -
< link rel =" stylesheet " href =" //maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css " >или что -то эквивалентное.
Как минимум, вам необходимо предоставить editorState и onChange реквизиты, так же, как draft-js .
import React from 'react' ;
import ReactDOM from 'react-dom' ;
// if using webpack
// import 'medium-draft/lib/index.css';
import {
Editor ,
createEditorState ,
} from 'medium-draft' ;
class App extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
editorState : createEditorState ( ) , // for empty content
} ;
/*
this.state = {
editorState: createEditorState(data), // with content
};
*/
this . onChange = ( editorState ) => {
this . setState ( { editorState } ) ;
} ;
this . refsEditor = React . createRef ( ) ;
}
componentDidMount ( ) {
this . refsEditor . current . focus ( ) ;
}
render ( ) {
const { editorState } = this . state ;
return (
< Editor
ref = { this . refsEditor }
editorState = { editorState }
onChange = { this . onChange } />
) ;
}
} ;
ReactDOM . render (
< App /> ,
document . getElementById ( 'app' )
) ; Editor medium-draft принимает опору, называемую sideButtons . По умолчанию есть только одна кнопка (изображение), но вы можете добавить больше. Опора sideButtons должна быть массивом объектов с каждым объектом, имеющим следующую подпись:
{
"title" : "unique-button-name" ,
"component" : ButtonComponent
}Для например:
{
"title" : "Image" ,
"component" : ImageSideButton
}Пример кода:
Прямо сейчас кнопка изображения просто добавляет изображение внутри редактора с помощью URL.createObjectURL . Но если вы хотите сначала загрузить изображение на свой сервер, а затем добавить это изображение в редактор, вы можете следовать одним из двух методов:
Либо расширяйте компонент ImageSideButton по умолчанию, который поставляется со medium-draft .
Или создайте свой собственный компонент с полной функциональностью самостоятельно.
Для простоты мы будем следить за первым методом. Если вы изучите реализацию ImageSideButton , вы увидите метод onChange , который получает событие выбора файла, где выбираемые файлы доступны в качестве event.target.files . Мы просто переопределим этот метод, так как не хотим настраивать что -либо еще. Также обратите внимание, что каждый компонент боковой кнопки получает функцию getEditorState (возвращает проект editorState ), функцию setEditorState(newEditorState) (устанавливает новый редактор) и функцию close , которую вам необходимо позвонить вручную, чтобы закрыть список боковых кнопок:
import React from 'react' ;
import {
ImageSideButton ,
Block ,
addNewBlock ,
createEditorState ,
Editor ,
} from 'medium-draft' ;
import 'isomorphic-fetch' ;
class CustomImageSideButton extends ImageSideButton {
/*
We will only check for first file and also whether
it is an image or not.
*/
onChange ( e ) {
const file = e . target . files [ 0 ] ;
if ( file . type . indexOf ( 'image/' ) === 0 ) {
// This is a post request to server endpoint with image as `image`
const formData = new FormData ( ) ;
formData . append ( 'image' , file ) ;
fetch ( '/your-server-endpoint' , {
method : 'POST' ,
body : formData ,
} ) . then ( ( response ) => {
if ( response . status === 200 ) {
// Assuming server responds with
// `{ "url": "http://example-cdn.com/image.jpg"}`
return response . json ( ) . then ( data => {
if ( data . url ) {
this . props . setEditorState ( addNewBlock (
this . props . getEditorState ( ) ,
Block . IMAGE , {
src : data . url ,
}
) ) ;
}
} ) ;
}
} ) ;
}
this . props . close ( ) ;
}
}
// Now pass this component instead of default prop to Editor example above.
class App extends React . Component {
constructor ( props ) {
super ( props ) ;
this . sideButtons = [ {
title : 'Image' ,
component : CustomImageSideButton ,
} ] ;
this . state = {
editorState : createEditorState ( ) , // for empty content
} ;
/*
this.state = {
editorState: createEditorState(data), // with content
};
*/
this . onChange = ( editorState ) => {
this . setState ( { editorState } ) ;
} ;
this . refsEditor = React . createRef ( )
}
componentDidMount ( ) {
this . refsEditor . current . focus ( ) ;
}
render ( ) {
const { editorState } = this . state ;
return (
< Editor
ref = { this . refsEditor }
editorState = { editorState }
onChange = { this . onChange }
sideButtons = { this . sideButtons }
/>
) ;
}
} ;Чтобы полностью удалить боковые кнопки, так что кнопка «Кругковая добавка» никогда не появилась, просто передайте пустой массив:
sideButtons={[]}
Есть три реквизита, которые вы можете использовать для настройки кнопок на панели инструментов, которая появляется всякий раз, когда вы выбираете текст в редакторе:
blockButtonsinlineButtonstoolbarConfig Кнопки редактора уровня блока по умолчанию-это ['header-three', 'unordered-list-item', 'ordered-list-item', 'blockquote', 'todo'] и кнопки встроенных редакторов дефолта ['BOLD', 'ITALIC', 'UNDERLINE', 'HIGHLIGHT', 'hyperlink'] .
Например, если вы хотите сохранить кнопки блоков по умолчанию и добавить еще несколько, вы можете сделать что -то вроде следующего:
import { BLOCK_BUTTONS } from 'medium-draft' ;
const blockButtons = [ {
label : 'H1' ,
style : 'header-one' ,
icon : 'header' ,
description : 'Heading 1' ,
} ,
{
label : 'H2' ,
style : 'header-two' ,
icon : 'header' ,
description : 'Heading 2' ,
} ] . concat ( BLOCK_BUTTONS ) ;
// in your component
< Editor blockButtons = { blockButtons } . . . / > Если вы хотите удалить некоторые кнопки или переупорядочить их, вы можете использовать такие функции, как array.slice на блоке по умолчанию BLOCK_BUTTONS и INLINE_BUTTONS , но это, вероятно, больше проблем, чем стоит.
Для этой цели лучше использовать Prop toolbarConfig :
// custom ordering for block and inline buttons, and removes some buttons
const toolbarConfig = {
block : [ 'unordered-list-item' , 'header-one' , 'header-three' ] ,
inline : [ 'BOLD' , 'UNDERLINE' , 'hyperlink' ] ,
}
< Editor toolbarConfig = { toolbarConfig } . . . / > Строки внутри block и inline массивов должны соответствовать атрибуту style внутри blockButtons и массивов inlineButtons .
Подводя итог: если вам нужно добавить, удалить и переупорядочить кнопки, вероятно, легко использовать blockButtons , inlineButtons и toolbarConfig вместе.
Если реквизиты настройки панели инструментов недостаточно, чтобы получить желаемое поведение, вы можете ввести свою собственную панель инструментов с помощью опоры ToolbarComponent .
Этот шаблон называется инъекцией компонентов. Ваш ToolbarComponent получает те же реквизиты, что и панель инструментов по умолчанию.
Если вы хотите написать свой собственный компонент панели инструментов, хорошее место для начала - это компонент по умолчанию.
Функция для экспорта HTML доступна с версии 0.4.1 .
medium-draft использует проект-конверт (который, в свою очередь, использует React-Dom-Server), чтобы отобразить editorState в draft-js в HTML.
Экспортер не является частью основной библиотеки. Если вы хотите использовать medium-draft-exporter , следуйте этим шагам-
npm install draft-convert . draft-convert является частью peerDependencies medium-draft .
import mediumDraftExporter from 'medium-draft/lib/exporter' ;
const editorState = /* your draft editorState */ ;
const renderedHTML = mediumDraftExporter ( editorState . getCurrentContent ( ) ) ;
/* Use renderedHTML */ < script src =" https://unpkg.com/[email protected]/dist/react-dom-server.min.js " > </ script >
< script src =" https://unpkg.com/[email protected]/dist/draft-convert.min.js " > </ script >
< script src =" https://unpkg.com/medium-draft/dist/medium-draft-exporter.js " > </ script > Экспортер доступен как MediumDraftExporter Global;
var mediumDraftExporter = MediumDraftExporter . default ;
const editorState = /* your draft editorState */ ;
const renderedHTML = mediumDraftExporter ( editorState . getCurrentContent ( ) ) ;
/* Use renderedHTML */ medium-draft-exporter также поставляется с предустановленным CSS, если вы хотите применить некоторые основные стили к learned HTML.
В WebPack, как часть вашей страницы HTML, используйте это-
import 'medium-draft/lib/basic.css'В браузере, на вашей странице HTML, вы можете включить эту ссылку на таблицу стилей
< link rel =" stylesheet " type =" text/css " href =" https://unpkg.com/medium-draft/dist/basic.css " >medium-draft-exporter в editorState Функция для экспорта HTML доступна с версии 0.5.3 .
medium-draft использует проект-конверт (который, в свою очередь, использует React-Dom-Server), чтобы отобразить editorState в draft-js в HTML.
Импортер не является частью основной библиотеки. Если вы хотите использовать medium-draft-importer , выполните следующие действия-
npm install draft-convert . draft-convert является частью peerDependencies medium-draft .
import { convertToRaw } from 'draft-js' ;
import { createEditorState } from 'medium-draft' ;
import mediumDraftImporter from 'medium-draft/lib/importer' ;
const html = /* your previously exported html */ ;
const editorState = createEditorState ( convertToRaw ( mediumDraftImporter ( html ) ) ) ;
// Use this editorState < script src =" https://unpkg.com/[email protected]/dist/react-dom-server.min.js " > </ script >
< script src =" https://unpkg.com/[email protected]/dist/draft-convert.min.js " > </ script >
< script src =" https://unpkg.com/medium-draft/dist/medium-draft-importer.js " > </ script > Импортер доступен в качестве MediumDraftImporter Global;
const { convertToRaw } = Draft ;
const { createEditorState } = MediumDraft ;
const mediumDraftImporter = MediumDraftImporter . default ;
const html = /* your previously exported html */ ;
const editorState = createEditorState ( convertToRaw ( mediumDraftImporter ( html ) ) ) ;
// Use this editorStatemedium-draft . git clone https://github.com/brijeshb42/medium-draft.git .npm install react react-dom draft-convert && npm install .npm run dev . Это запустит локальный сервер на порту 8080 .npm run build . Грань