jpuri / react-draft-wysiwyg

A Wysiwyg editor build on top of ReactJS and DraftJS. https://jpuri.github.io/react-draft-wysiwyg
MIT License
6.41k stars 1.16k forks source link

How to add custom blockType in toolbar section? #528

Open ShrawanLakhe opened 6 years ago

ShrawanLakhe commented 6 years ago

I have been trying to add the custom blocktype in the toolbar menu but unable to get any success. I have tried using blockRenderMap and blockRendererFn. But it is not working. Are those supported as props in Editor element?

Can you guide me how could i acheive this? Basically I want to add a custom blocktype which when selected will output

in the editor . Below is my code:

const blockRenderMap = Immutable.Map({
  'MyCustomBlock': {
    // element is used during paste or html conversion to auto match your component;
    // it is also retained as part of this.props.children and not stripped out
    element: 'code',
    wrapper: CodeBlock
  },
});
<Editor
          toolbarClassName="toolbar-class"
          wrapperClassName="wrapper-class"
          editorClassName="editor-class"
          editorState={this.props.editorState}
          onEditorStateChange={this.props.onEditorStateChange}
          onBlur={this.props.onBlur}
          toolbar={{
            image: {
              className: 'editor_uploader',
              uploadCallback: this.uploadCallback,
              urlEnabled: true,
              alt: { present: true, mandatory: true }
            },
          }}
          toolbarCustomButtons={[<CustomOption />]}
          hashtag={{
            separator: ' ',
            trigger: '#',
            className: 'hashtag-className',
          }}
          mention={{
            separator: ' ',
            trigger: '@',
            suggestions: [
            ],
          }}
          blockRenderMap={extendedBlockRenderMap}
          blockRendererFn={myBlockRenderer}
        />

Thank you @jpuri

davidcai commented 6 years ago

Would also love to know.

nodejh commented 6 years ago

This is a hack way #412

import en from 'react-draft-wysiwyg/src/i18n/en';
import fontSize from 'img/font-size.svg';

en['components.controls.blocktype.h2'] = <img src={fontSize} alt="font size" />;
const localization = {
  locale: 'en',
  translations: en,
};
// ...
<Editor
  editorState={editorState}
  wrapperClassName="content-wrapper"
  editorClassName="content-editor"
  toolbarClassName="toolbar-wrapper"
  onEditorStateChange={this._onEditorStateChange}
  localization={localization}
  placeholder="Tell your story..."
  toolbar={TOOLBAR_OPTIONS}
/>

For i18n, first change source code src/i18n/index.js

change

import en from './en';
// ...
module.exports = {
  // ...
};

to

import en from './en';
// ...
export default {
  // ...
};

Because module.exports is now read-only in ESM.

Then

import i18n from 'react-draft-wysiwyg/src/i18n';

// For example, it will custom code icon
// The icon can be any react component
const Code = (
  <svg id='i-code' viewBox='0 0 32 32' width='20' height='20' fill='none' stroke='currentcolor' strokeLinecap='round' strokeLinejoin='round' strokeWidth='2'>
    <path d='M10 9 L3 17 10 25 M22 9 L29 17 22 25 M18 7 L14 27' />
  </svg>
);

const { locale } = this.props;  // `locale`  is a variable of language
 i18n[locale]['components.controls.blocktype.code'] = Code;
     const localization = {
      locale,
      translations: i18n[locale],
 };

<Editor
  localization={localization}
/>
jpuri commented 6 years ago

Plz use customBlockRenderFunc and customDecorators properties for this purpose. https://github.com/jpuri/react-draft-wysiwyg/blob/master/src/Editor/index.js#L82

mcuthbe commented 2 years ago

@ShrawanLakhe were you able to do this? I'm struggling with the trying to do the same. Do you have any example code?

@jpuri I don't understand your answer. Aren't decorators for searching text within the editor? How do you do that with block type?

I would think the right way to do it is with blockRenderMap to make new block types and then customBlockRenderFunc, like @ShrawanLakhe was trying and how I believe it works in draftjs. But blockRenderMap isn't allowed props on react-draft-wysiwyg...