123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- import React, { useState } from "react";
- import classnames from "classnames";
- import BraftEditor, { ControlType, EditorState } from "braft-editor";
- import styles from "./index.less";
- import "braft-editor/dist/index.css";
-
- // 引入表情包扩展模块样式文件
- import "braft-extensions/dist/emoticon.css";
- // 引入表情包扩展模块和默认表情包列表
- import Emoticon, { defaultEmoticons } from "braft-extensions/dist/emoticon";
- import MaxLength from "braft-extensions/dist/max-length";
-
- const lengthOptions = {
- defaultValue: 100 // 指定默认限制数,如不指定则为Infinity(无限)
- // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效,不传此属性则对所有BraftEditor有效
- // excludeEditors: ['editor-id-2'], // 指定该模块对哪些BraftEditor无效
- };
- BraftEditor.use(MaxLength(lengthOptions));
-
- // 转换默认表情包列表,让webpack可以正确加载到默认表情包中的图片,请确保已对png格式的文件配置了loader
- // 如果你使用的webpack版本不支持动态require,或者使用的其他打包工具,请勿使用此写法
- const emoticons = defaultEmoticons.map((item: string) =>
- require(`braft-extensions/dist/assets/${item}`)
- );
-
- // 也可以使用自己的表情包资源,不受打包工具限制
- // const emoticons = ['http://path/to/emoticon-1.png', 'http://path/to/emoticon-2.png', 'http://path/to/emoticon-3.png', 'http://path/to/emoticon-4.png', ...]
-
- const emotionOptions = {
- // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效,不传此属性则对所有BraftEditor有效
- // excludeEditors: ['editor-id-2'], // 指定该模块对哪些BraftEditor无效
- emoticons: emoticons, // 指定可用表情图片列表,默认为空
- closeOnBlur: true, // 指定是否在点击表情选择器之外的地方时关闭表情选择器,默认false
- closeOnSelect: false // 指定是否在选择表情后关闭表情选择器,默认false
- };
-
- BraftEditor.use(Emoticon(emotionOptions));
-
- export interface BaseEditorProps {
- value: EditorState;
- onChange: (editorState: EditorState) => void;
- contentStyle?: React.CSSProperties;
- controls?: ControlType[];
- FloatControls?: any;
-
- blockRenderMap?: any;
- blockRendererFn?: any;
- draftProps?: any;
- placeholder?: string;
- converts?: any;
- }
-
- export const BarftEditorPage = ({
- value,
- onChange,
- controls,
- contentStyle = {},
- FloatControls,
- draftProps,
- placeholder,
- blockRenderMap,
- blockRendererFn,
- converts,
- }: BaseEditorProps) => {
- const optionsControls = controls
- ? controls
- : [
- "bold",
- "italic",
- "underline",
- "separator",
- "link",
- "emoji",
- "separator",
- "media"
- ];
- const options: any = {
- controls: optionsControls,
- showControlsBar:
- optionsControls && optionsControls.length > 0 && !FloatControls,
- showFloatControls: FloatControls
- };
-
- const [focusState, setFocusState] = useState(false);
-
- return (
- <div className={styles.baseWrapper}>
- <BraftEditor
- value={value}
- onChange={onChange}
- controls={options.controls}
- controlBarClassName={classnames(styles.controlBar, {
- [styles.focus]: focusState
- })}
- controlBarStyle={options.showControlsBar ? {} : { display: "none" }}
- contentClassName={classnames(styles.editorContent, {
- [styles.focus]: focusState,
- [styles.hasFloatControls]: options.showFloatControls
- })}
- contentStyle={contentStyle}
- onFocus={() => setFocusState(true)}
- onBlur={() => setFocusState(false)}
- hooks={{
- "toggle-link": ({ href, target }) => {
- href = href.indexOf("http") === 0 ? href : `http://${href}`;
- return { href, target };
- }
- }}
- {...{
- blockRenderMap,
- blockRendererFn,
- converts,
- placeholder,
- draftProps,
- }}
- />
- {options.showFloatControls ? (
- <div className={classnames(styles.floatControls)}>
- {
- <FloatControls
- editorState={value}
- setEditorState={onChange}
- />
- }
- </div>
- ) : null}
- </div>
- );
- };
-
- export default BarftEditorPage;
|