|
@@ -1,7 +1,7 @@
|
|
|
import React from 'react';
|
|
|
import theme from 'react-quill/dist/quill.snow.css';
|
|
|
import { message } from 'antd';
|
|
|
-import ReactQuill,{Quill} from 'react-quill';
|
|
|
+import ReactQuill, { Quill } from 'react-quill';
|
|
|
import ajax from 'jquery/src/ajax/xhr.js';
|
|
|
import $ from 'jquery/src/ajax';
|
|
|
import audioIcon from '../../image/audio.png';
|
|
@@ -9,26 +9,26 @@ import audioIcon from '../../image/audio.png';
|
|
|
|
|
|
let BlockEmbed = Quill.import('blots/block/embed');
|
|
|
class AppPanelEmbed extends BlockEmbed {
|
|
|
- static create(value) {
|
|
|
- const node = super.create(value);
|
|
|
- node.setAttribute('contenteditable', 'false');
|
|
|
- node.setAttribute('width', '100%');
|
|
|
- // 设置自定义html
|
|
|
- node.innerHTML = this.transformValue(value)
|
|
|
- return node;
|
|
|
- }
|
|
|
+ static create(value) {
|
|
|
+ const node = super.create(value);
|
|
|
+ node.setAttribute('contenteditable', 'false');
|
|
|
+ node.setAttribute('width', '100%');
|
|
|
+ // 设置自定义html
|
|
|
+ node.innerHTML = this.transformValue(value)
|
|
|
+ return node;
|
|
|
+ }
|
|
|
|
|
|
- static transformValue(value) {
|
|
|
- let handleArr = value.split('\n')
|
|
|
- handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
|
|
|
- .replace(/[\s]+$/, ''))
|
|
|
- return handleArr.join('')
|
|
|
- }
|
|
|
+ static transformValue(value) {
|
|
|
+ let handleArr = value.split('\n')
|
|
|
+ handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
|
|
|
+ .replace(/[\s]+$/, ''))
|
|
|
+ return handleArr.join('')
|
|
|
+ }
|
|
|
|
|
|
- // 返回节点自身的value值 用于撤销操作
|
|
|
- static value(node) {
|
|
|
- return node.innerHTML
|
|
|
- }
|
|
|
+ // 返回节点自身的value值 用于撤销操作
|
|
|
+ static value(node) {
|
|
|
+ return node.innerHTML
|
|
|
+ }
|
|
|
}
|
|
|
// blotName
|
|
|
AppPanelEmbed.blotName = 'AppPanelEmbed';
|
|
@@ -38,236 +38,240 @@ AppPanelEmbed.className = 'embed-innerApp';
|
|
|
AppPanelEmbed.tagName = 'p';
|
|
|
Quill.register(AppPanelEmbed);
|
|
|
|
|
|
-var RichTextUploadUrl, RichTextUploadSign;
|
|
|
+var RichTextUploadUrl, RichTextUploadSign, RichTextUploadId;
|
|
|
//上传图片
|
|
|
-function uploadImg(s,_this) {
|
|
|
- let myform = new FormData()
|
|
|
- let file = document.getElementById(_this.props.id + "fileToUpload").files[0];
|
|
|
- if (!file) { return; };
|
|
|
- if(file.size > 52428800){
|
|
|
- message.warning('图片大小不能超过50M');
|
|
|
- return
|
|
|
+function uploadImg(s, _this) {
|
|
|
+ let myform = new FormData()
|
|
|
+ let file = document.getElementById(_this.props.id + "fileToUpload").files[0];
|
|
|
+ if (!file) { return; };
|
|
|
+ if (file.size > 52428800) {
|
|
|
+ message.warning('图片大小不能超过50M');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ myform.append('file', file);
|
|
|
+ myform.append('sign', RichTextUploadSign);
|
|
|
+ myform.append('id', RichTextUploadId);
|
|
|
+ $.ajax({
|
|
|
+ method: "post",
|
|
|
+ dataType: "json",
|
|
|
+ url: location.origin + RichTextUploadUrl,
|
|
|
+ data: myform,
|
|
|
+ contentType: false,
|
|
|
+ processData: false,
|
|
|
+ success: function (data) {
|
|
|
+ if (data.error && data.error.length) {
|
|
|
+ message.warning(data.error[0].message);
|
|
|
+ document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
+ } else {
|
|
|
+ const cursorPosition = s.quill.getSelection().index
|
|
|
+ s.quill.insertEmbed(
|
|
|
+ cursorPosition,
|
|
|
+ 'AppPanelEmbed',
|
|
|
+ `<img style="width: 100%" src="${globalConfig.avatarUploadHost + data.data}"/>`
|
|
|
+ );
|
|
|
+ s.quill.setSelection(cursorPosition + 1);
|
|
|
+ document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ error: function (XMLHttpRequest, textStatus, errorThrown) {
|
|
|
+ //查看错误信息
|
|
|
+ message("上传失败");
|
|
|
+ document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
}
|
|
|
- myform.append('file', file);
|
|
|
- myform.append('sign', RichTextUploadSign);
|
|
|
- $.ajax({
|
|
|
- method: "post",
|
|
|
- dataType: "json",
|
|
|
- url: location.origin + RichTextUploadUrl,
|
|
|
- data: myform,
|
|
|
- contentType: false,
|
|
|
- processData: false,
|
|
|
- success: function (data) {
|
|
|
- if (data.error && data.error.length) {
|
|
|
- message.warning(data.error[0].message);
|
|
|
- document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
- } else {
|
|
|
- const cursorPosition = s.quill.getSelection().index
|
|
|
- s.quill.insertEmbed(
|
|
|
- cursorPosition,
|
|
|
- 'AppPanelEmbed',
|
|
|
- `<img style="width: 100%" src="${globalConfig.avatarUploadHost + data.data}"/>`
|
|
|
- );
|
|
|
- s.quill.setSelection(cursorPosition + 1);
|
|
|
- document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
- };
|
|
|
- },
|
|
|
- error: function(XMLHttpRequest, textStatus, errorThrown){
|
|
|
- //查看错误信息
|
|
|
- message("上传失败");
|
|
|
- document.getElementById(_this.props.id + "fileToUpload").value = ''
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
}
|
|
|
//图片文件选择
|
|
|
function fileSelect() {
|
|
|
- let _this = this.options._this;
|
|
|
- let uploader = document.getElementById(_this.props.id + "fileToUpload");
|
|
|
- if (!uploader.onchange) {
|
|
|
- uploader.onchange = () => {
|
|
|
- uploadImg(this,_this)
|
|
|
- }
|
|
|
+ let _this = this.options._this;
|
|
|
+ let uploader = document.getElementById(_this.props.id + "fileToUpload");
|
|
|
+ if (!uploader.onchange) {
|
|
|
+ uploader.onchange = () => {
|
|
|
+ uploadImg(this, _this)
|
|
|
}
|
|
|
- uploader.click();
|
|
|
+ }
|
|
|
+ uploader.click();
|
|
|
}
|
|
|
//音频文件选择
|
|
|
function fileSelectAudio() {
|
|
|
- let _this = this.options._this;
|
|
|
- let uploader = document.getElementById(_this.props.id + "fileToUploadAudio");
|
|
|
- if (!uploader.onchange) {
|
|
|
- uploader.onchange = () => {
|
|
|
- uploadAudio(this,_this)
|
|
|
- }
|
|
|
+ let _this = this.options._this;
|
|
|
+ let uploader = document.getElementById(_this.props.id + "fileToUploadAudio");
|
|
|
+ if (!uploader.onchange) {
|
|
|
+ uploader.onchange = () => {
|
|
|
+ uploadAudio(this, _this)
|
|
|
}
|
|
|
- uploader.click();
|
|
|
+ }
|
|
|
+ uploader.click();
|
|
|
}
|
|
|
//音频文件上传
|
|
|
-function uploadAudio(s,_this) {
|
|
|
- let myform = new FormData()
|
|
|
- let file = document.getElementById(_this.props.id + "fileToUploadAudio").files[0]
|
|
|
- if (!file) { return; };
|
|
|
- if(file.size > 52428800){
|
|
|
- message.warning('音频大小不能超过50M');
|
|
|
- return
|
|
|
- }
|
|
|
- myform.append('file', file);
|
|
|
- myform.append('sign', RichTextUploadSign);
|
|
|
- $.ajax({
|
|
|
- method: "post",
|
|
|
- dataType: "json",
|
|
|
- url: location.origin + RichTextUploadUrl,
|
|
|
- data: myform,
|
|
|
- contentType: false,
|
|
|
- processData: false,
|
|
|
- success: function (data) {
|
|
|
- if (data.error && data.error.length) {
|
|
|
- message.warning(data.error[0].message);
|
|
|
- document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
- } else {
|
|
|
- const cursorPosition = s.quill.getSelection().index
|
|
|
- s.quill.insertEmbed(
|
|
|
- cursorPosition,
|
|
|
- 'AppPanelEmbed',
|
|
|
- `<audio src="${globalConfig.avatarUploadHost + data.data}" controls="controls">Your browser does not support the audio element.</audio>`
|
|
|
- );
|
|
|
- s.quill.setSelection(cursorPosition + 1)
|
|
|
- document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
- };
|
|
|
+function uploadAudio(s, _this) {
|
|
|
+ let myform = new FormData()
|
|
|
+ let file = document.getElementById(_this.props.id + "fileToUploadAudio").files[0]
|
|
|
+ if (!file) { return; };
|
|
|
+ if (file.size > 52428800) {
|
|
|
+ message.warning('音频大小不能超过50M');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ myform.append('file', file);
|
|
|
+ myform.append('sign', RichTextUploadSign);
|
|
|
+ myform.append('id', RichTextUploadId);
|
|
|
+ $.ajax({
|
|
|
+ method: "post",
|
|
|
+ dataType: "json",
|
|
|
+ url: location.origin + RichTextUploadUrl,
|
|
|
+ data: myform,
|
|
|
+ contentType: false,
|
|
|
+ processData: false,
|
|
|
+ success: function (data) {
|
|
|
+ if (data.error && data.error.length) {
|
|
|
+ message.warning(data.error[0].message);
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
+ } else {
|
|
|
+ const cursorPosition = s.quill.getSelection().index
|
|
|
+ s.quill.insertEmbed(
|
|
|
+ cursorPosition,
|
|
|
+ 'AppPanelEmbed',
|
|
|
+ `<audio src="${globalConfig.avatarUploadHost + data.data}" controls="controls">Your browser does not support the audio element.</audio>`
|
|
|
+ );
|
|
|
+ s.quill.setSelection(cursorPosition + 1)
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
+ };
|
|
|
|
|
|
- },
|
|
|
- error: function(XMLHttpRequest, textStatus, errorThrown){
|
|
|
- document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
- //查看错误信息
|
|
|
- message("上传失败");
|
|
|
- }
|
|
|
- })
|
|
|
+ },
|
|
|
+ error: function (XMLHttpRequest, textStatus, errorThrown) {
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadAudio").value = ''
|
|
|
+ //查看错误信息
|
|
|
+ message("上传失败");
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
//视频文件选择
|
|
|
function fileSelectVideo() {
|
|
|
- let _this = this.options._this;
|
|
|
- let uploader = document.getElementById(_this.props.id + "fileToUploadVideo");
|
|
|
- if (!uploader.onchange) {
|
|
|
- uploader.onchange = () => {
|
|
|
- uploadVideo(this,_this)
|
|
|
- }
|
|
|
+ let _this = this.options._this;
|
|
|
+ let uploader = document.getElementById(_this.props.id + "fileToUploadVideo");
|
|
|
+ if (!uploader.onchange) {
|
|
|
+ uploader.onchange = () => {
|
|
|
+ uploadVideo(this, _this)
|
|
|
}
|
|
|
- uploader.click();
|
|
|
+ }
|
|
|
+ uploader.click();
|
|
|
}
|
|
|
//视频文件上传
|
|
|
-function uploadVideo(s,_this) {
|
|
|
- let myform = new FormData()
|
|
|
- let file = document.getElementById(_this.props.id + "fileToUploadVideo").files[0]
|
|
|
- if (!file) { return; };
|
|
|
- if(file.size > 52428800){
|
|
|
- message.warning('视频大小不能超过50M');
|
|
|
- return
|
|
|
- }
|
|
|
- myform.append('file', file);
|
|
|
- myform.append('sign', RichTextUploadSign);
|
|
|
- $.ajax({
|
|
|
- method: "post",
|
|
|
- dataType: "json",
|
|
|
- url: location.origin + RichTextUploadUrl,
|
|
|
- data: myform,
|
|
|
- contentType: false,
|
|
|
- processData: false,
|
|
|
- success: function (data) {
|
|
|
- if (data.error && data.error.length) {
|
|
|
- message.warning(data.error[0].message);
|
|
|
- document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
- } else {
|
|
|
- const cursorPosition = s.quill.getSelection().index
|
|
|
- s.quill.insertEmbed(
|
|
|
- cursorPosition,
|
|
|
- 'AppPanelEmbed',
|
|
|
- `<video style="width:100%" controls="" autoPlay="" name="media">
|
|
|
+function uploadVideo(s, _this) {
|
|
|
+ let myform = new FormData()
|
|
|
+ let file = document.getElementById(_this.props.id + "fileToUploadVideo").files[0]
|
|
|
+ if (!file) { return; };
|
|
|
+ if (file.size > 52428800) {
|
|
|
+ message.warning('视频大小不能超过50M');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ myform.append('file', file);
|
|
|
+ myform.append('sign', RichTextUploadSign);
|
|
|
+ myform.append('id', RichTextUploadId);
|
|
|
+ $.ajax({
|
|
|
+ method: "post",
|
|
|
+ dataType: "json",
|
|
|
+ url: location.origin + RichTextUploadUrl,
|
|
|
+ data: myform,
|
|
|
+ contentType: false,
|
|
|
+ processData: false,
|
|
|
+ success: function (data) {
|
|
|
+ if (data.error && data.error.length) {
|
|
|
+ message.warning(data.error[0].message);
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
+ } else {
|
|
|
+ const cursorPosition = s.quill.getSelection().index
|
|
|
+ s.quill.insertEmbed(
|
|
|
+ cursorPosition,
|
|
|
+ 'AppPanelEmbed',
|
|
|
+ `<video style="width:100%" controls="" autoPlay="" name="media">
|
|
|
<source src=${globalConfig.avatarUploadHost + data.data} type="video/mp4">
|
|
|
</video>`
|
|
|
- );
|
|
|
- s.quill.setSelection(cursorPosition + 1);
|
|
|
- document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
- };
|
|
|
+ );
|
|
|
+ s.quill.setSelection(cursorPosition + 1);
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
+ };
|
|
|
|
|
|
- },
|
|
|
- error: function(XMLHttpRequest, textStatus, errorThrown){
|
|
|
- document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
- //查看错误信息
|
|
|
- }
|
|
|
- })
|
|
|
+ },
|
|
|
+ error: function (XMLHttpRequest, textStatus, errorThrown) {
|
|
|
+ document.getElementById(_this.props.id + "fileToUploadVideo").value = ''
|
|
|
+ //查看错误信息
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
const Editors = React.createClass({
|
|
|
- getInitialState() {
|
|
|
- return {
|
|
|
- value: null,
|
|
|
- theBool: true
|
|
|
- }
|
|
|
- },
|
|
|
- handleRichText(value) {
|
|
|
- this.setState({ value: value });
|
|
|
- this.props.handleRichText(value);
|
|
|
- // this.props.handleRichText(value.replace(/iframe/g, 'video'));
|
|
|
- },
|
|
|
- componentDidMount() {
|
|
|
- document.getElementsByClassName( 'ql-audio')[this.props.id || 0].style = `background: url(${audioIcon}) no-repeat;background-size: contain;`
|
|
|
- },
|
|
|
- componentWillMount() {
|
|
|
- RichTextUploadUrl = this.props.uploadUrl;
|
|
|
- RichTextUploadSign = this.props.uploadSign;
|
|
|
- },
|
|
|
- componentWillReceiveProps(nextProps) {
|
|
|
- this.state.theBool = true;
|
|
|
- // if(nextProps.textContent){
|
|
|
- this.state.value = nextProps.textContent || '';
|
|
|
- // }
|
|
|
- },
|
|
|
- render() {
|
|
|
- const modules = {
|
|
|
- toolbar: {
|
|
|
- container: [
|
|
|
- [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
|
|
|
- [{ 'header': [1, 2, 3, false] }],
|
|
|
- ['bold', 'italic', 'underline', 'strike', 'blockquote'], // toggled buttons
|
|
|
- // [{ 'header': 1 }, { 'header': 2 }], // custom button values
|
|
|
- [{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
|
|
- // [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
|
|
|
- [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
|
|
|
- // [{ 'direction': 'rtl' }], // text direction
|
|
|
- [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
|
|
|
- // [{ 'font': [] }],
|
|
|
- [{ 'align': [] }],
|
|
|
- ['link', 'image','video'],
|
|
|
- ['clean'],
|
|
|
- ['audio'],
|
|
|
- ],
|
|
|
- handlers: { 'image': fileSelect ,'video': fileSelectVideo,'audio':fileSelectAudio},
|
|
|
- _this:this
|
|
|
- },
|
|
|
- };
|
|
|
- const formats = [
|
|
|
- 'size', 'header',
|
|
|
- 'bold', 'italic', 'underline', 'strike', 'blockquote',
|
|
|
- 'list', 'bullet', 'indent',
|
|
|
- 'color', 'background',
|
|
|
- 'align',
|
|
|
- 'link', 'image','video','AppPanelEmbed','clean'
|
|
|
- ];
|
|
|
- return (
|
|
|
- <div>
|
|
|
- <ReactQuill
|
|
|
- theme="snow"
|
|
|
- value={this.state.value}
|
|
|
- modules={modules}
|
|
|
- formats={formats}
|
|
|
- placeholder='请填写内容!'
|
|
|
- onChange={this.handleRichText}
|
|
|
- />
|
|
|
- <input accept="image/*" type="file" name={this.props.id + "fileToUpload"} id={this.props.id + "fileToUpload"} placeholder='请填写内容!' style={{ "display": "none" }} />
|
|
|
- <input accept="video/*" type="file" name={this.props.id + "fileToUploadVideo"} id={this.props.id + "fileToUploadVideo"} placeholder='请填写视频!' style={{ "display": "none" }} />
|
|
|
- <input accept="audio/*" type="file" name={this.props.id + "fileToUploadAudio"} id={this.props.id + "fileToUploadAudio"} placeholder='请选择音频!' style={{ "display": "none" }} />
|
|
|
- </div>
|
|
|
- )
|
|
|
- },
|
|
|
+ getInitialState() {
|
|
|
+ return {
|
|
|
+ value: null,
|
|
|
+ theBool: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleRichText(value) {
|
|
|
+ this.setState({ value: value });
|
|
|
+ this.props.handleRichText(value);
|
|
|
+ // this.props.handleRichText(value.replace(/iframe/g, 'video'));
|
|
|
+ },
|
|
|
+ componentDidMount() {
|
|
|
+ document.getElementsByClassName('ql-audio')[this.props.id || 0].style = `background: url(${audioIcon}) no-repeat;background-size: contain;`
|
|
|
+ },
|
|
|
+ componentWillMount() {
|
|
|
+ RichTextUploadUrl = this.props.uploadUrl;
|
|
|
+ RichTextUploadSign = this.props.uploadSign;
|
|
|
+ },
|
|
|
+ componentWillReceiveProps(nextProps) {
|
|
|
+ RichTextUploadId = nextProps.uploadId;
|
|
|
+ this.state.theBool = true;
|
|
|
+ // if(nextProps.textContent){
|
|
|
+ this.state.value = nextProps.textContent || '';
|
|
|
+ // }
|
|
|
+ },
|
|
|
+ render() {
|
|
|
+ const modules = {
|
|
|
+ toolbar: {
|
|
|
+ container: [
|
|
|
+ [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
|
|
|
+ [{ 'header': [1, 2, 3, false] }],
|
|
|
+ ['bold', 'italic', 'underline', 'strike', 'blockquote'], // toggled buttons
|
|
|
+ // [{ 'header': 1 }, { 'header': 2 }], // custom button values
|
|
|
+ [{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
|
|
+ // [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
|
|
|
+ [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
|
|
|
+ // [{ 'direction': 'rtl' }], // text direction
|
|
|
+ [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
|
|
|
+ // [{ 'font': [] }],
|
|
|
+ [{ 'align': [] }],
|
|
|
+ ['link', 'image', 'video'],
|
|
|
+ ['clean'],
|
|
|
+ ['audio'],
|
|
|
+ ],
|
|
|
+ handlers: { 'image': fileSelect, 'video': fileSelectVideo, 'audio': fileSelectAudio },
|
|
|
+ _this: this
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const formats = [
|
|
|
+ 'size', 'header',
|
|
|
+ 'bold', 'italic', 'underline', 'strike', 'blockquote',
|
|
|
+ 'list', 'bullet', 'indent',
|
|
|
+ 'color', 'background',
|
|
|
+ 'align',
|
|
|
+ 'link', 'image', 'video', 'AppPanelEmbed', 'clean'
|
|
|
+ ];
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <ReactQuill
|
|
|
+ theme="snow"
|
|
|
+ value={this.state.value}
|
|
|
+ modules={modules}
|
|
|
+ formats={formats}
|
|
|
+ placeholder='请填写内容!'
|
|
|
+ onChange={this.handleRichText}
|
|
|
+ />
|
|
|
+ <input accept="image/*" type="file" name={this.props.id + "fileToUpload"} id={this.props.id + "fileToUpload"} placeholder='请填写内容!' style={{ "display": "none" }} />
|
|
|
+ <input accept="video/*" type="file" name={this.props.id + "fileToUploadVideo"} id={this.props.id + "fileToUploadVideo"} placeholder='请填写视频!' style={{ "display": "none" }} />
|
|
|
+ <input accept="audio/*" type="file" name={this.props.id + "fileToUploadAudio"} id={this.props.id + "fileToUploadAudio"} placeholder='请选择音频!' style={{ "display": "none" }} />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
export default Editors;
|