Brak opisu

index.tsx 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React, { useState } from "react";
  2. import classnames from "classnames";
  3. import BraftEditor, { ControlType, EditorState } from "braft-editor";
  4. import styles from "./index.less";
  5. import "braft-editor/dist/index.css";
  6. // 引入表情包扩展模块样式文件
  7. import "braft-extensions/dist/emoticon.css";
  8. // 引入表情包扩展模块和默认表情包列表
  9. import Emoticon, { defaultEmoticons } from "braft-extensions/dist/emoticon";
  10. import MaxLength from "braft-extensions/dist/max-length";
  11. const lengthOptions = {
  12. defaultValue: 100 // 指定默认限制数,如不指定则为Infinity(无限)
  13. // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效,不传此属性则对所有BraftEditor有效
  14. // excludeEditors: ['editor-id-2'], // 指定该模块对哪些BraftEditor无效
  15. };
  16. BraftEditor.use(MaxLength(lengthOptions));
  17. // 转换默认表情包列表,让webpack可以正确加载到默认表情包中的图片,请确保已对png格式的文件配置了loader
  18. // 如果你使用的webpack版本不支持动态require,或者使用的其他打包工具,请勿使用此写法
  19. const emoticons = defaultEmoticons.map((item: string) =>
  20. require(`braft-extensions/dist/assets/${item}`)
  21. );
  22. // 也可以使用自己的表情包资源,不受打包工具限制
  23. // 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', ...]
  24. const emotionOptions = {
  25. // includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效,不传此属性则对所有BraftEditor有效
  26. // excludeEditors: ['editor-id-2'], // 指定该模块对哪些BraftEditor无效
  27. emoticons: emoticons, // 指定可用表情图片列表,默认为空
  28. closeOnBlur: true, // 指定是否在点击表情选择器之外的地方时关闭表情选择器,默认false
  29. closeOnSelect: false // 指定是否在选择表情后关闭表情选择器,默认false
  30. };
  31. BraftEditor.use(Emoticon(emotionOptions));
  32. export interface BaseEditorProps {
  33. value: EditorState;
  34. onChange: (editorState: EditorState) => void;
  35. contentStyle?: React.CSSProperties;
  36. controls?: ControlType[];
  37. FloatControls?: any;
  38. }
  39. export const BarftEditorPage = ({
  40. value,
  41. onChange,
  42. controls,
  43. contentStyle = {},
  44. FloatControls
  45. }: BaseEditorProps) => {
  46. const optionsControls = controls
  47. ? controls
  48. : [
  49. "bold",
  50. "italic",
  51. "underline",
  52. "separator",
  53. "link",
  54. "emoji",
  55. "separator",
  56. "media"
  57. ];
  58. const options: any = {
  59. controls: optionsControls,
  60. showControlsBar:
  61. optionsControls && optionsControls.length > 0 && !FloatControls,
  62. showFloatControls: FloatControls
  63. };
  64. const [focusState, setFocusState] = useState(false);
  65. return (
  66. <div className={styles.baseWrapper}>
  67. <BraftEditor
  68. value={value}
  69. onChange={onChange}
  70. controls={options.controls}
  71. controlBarClassName={classnames(styles.controlBar, {
  72. [styles.focus]: focusState
  73. })}
  74. controlBarStyle={options.showControlsBar ? {} : { display: "none" }}
  75. contentClassName={classnames(styles.editorContent, {
  76. [styles.focus]: focusState,
  77. [styles.hasFloatControls]: options.showFloatControls
  78. })}
  79. contentStyle={contentStyle}
  80. onFocus={() => setFocusState(true)}
  81. onBlur={() => setFocusState(false)}
  82. hooks={{
  83. "toggle-link": ({ href, target }) => {
  84. href = href.indexOf("http") === 0 ? href : `http://${href}`;
  85. return { href, target };
  86. }
  87. }}
  88. />
  89. {options.showFloatControls ? (
  90. <div className={classnames(styles.floatControls)}>
  91. {
  92. <FloatControls
  93. editorState={value}
  94. setEditorState={onChange}
  95. />
  96. }
  97. </div>
  98. ) : null}
  99. </div>
  100. );
  101. };
  102. export default BarftEditorPage;