简体   繁体   English

如何在 react-draft-wysiwyg 中添加自定义下拉菜单?

[英]How to add custom dropdown menu in react-draft-wysiwyg?

I need to add custom dropdown menu in toolbar section.我需要在工具栏部分添加自定义下拉菜单。

here attached image similar to want dropdown menu this is possible ?这里附加的图像类似于想要下拉菜单,这可能吗?

<img src="https://i.imgur.com/OhYeFsL.png" alt="Dropdown menu editor">

find the detailed image below找到下面的详细图片

在此处输入图片说明

I used react-draft-wysiwyg content editor.我使用了 react-draft-wysiwyg 内容编辑器。

https://github.com/jpuri/react-draft-wysiwyg https://github.com/jpuri/react-draft-wysiwyg

https://jpuri.github.io/react-draft-wysiwyg/#/d https://jpuri.github.io/react-draft-wysiwyg/#/d

add custom dropdown menu in toolbar section.在工具栏部分添加自定义下拉菜单。

I hope this is still relevant, but here is my way.我希望这仍然相关,但这是我的方式。

For the custom dropdown, I created a new component and used method for "adding new option to the toolbar" from the documentation https://jpuri.github.io/react-draft-wysiwyg/#/docs对于自定义下拉列表,我创建了一个新组件并使用了文档https://jpuri.github.io/react-draft-wysiwyg/#/docs 中“向工具栏添加新选项”的方法

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { EditorState, Modifier } from 'draft-js';

class Placeholders extends Component {
  static propTypes = {
    onChange: PropTypes.func,
    editorState: PropTypes.object,
  }

  state = {
    open: false
  }

  openPlaceholderDropdown = () => this.setState({open: !this.state.open})

  addPlaceholder = (placeholder) => {
    const { editorState, onChange } = this.props;
    const contentState = Modifier.replaceText(
    editorState.getCurrentContent(),
    editorState.getSelection(),
    placeholder,
    editorState.getCurrentInlineStyle(),
    );
    onChange(EditorState.push(editorState, contentState, 'insert-characters'));
  }

  placeholderOptions = [
    {key: "firstName", value: "{{firstName}}", text: "First Name"},
    {key: "lastName", value: "{{lastName}}", text: "Last name"},
    {key: "company", value: "{{company}}", text: "Company"},
    {key: "address", value: "{{address}}", text: "Address"},
    {key: "zip", value: "{{zip}}", text: "Zip"},
    {key: "city", value: "{{city}}", text: "City"}
  ]

  listItem = this.placeholderOptions.map(item => (
    <li 
      onClick={this.addPlaceholder.bind(this, item.value)} 
      key={item.key}
      className="rdw-dropdownoption-default placeholder-li"
    >{item.text}</li>
  ))

  render() {
    return (
      <div onClick={this.openPlaceholderDropdown} className="rdw-block-wrapper" aria-label="rdw-block-control">
        <div className="rdw-dropdown-wrapper rdw-block-dropdown" aria-label="rdw-dropdown">
          <div className="rdw-dropdown-selectedtext" title="Placeholders">
            <span>Placeholder</span> 
            <div className={`rdw-dropdown-caretto${this.state.open? "close": "open"}`}></div>
          </div>
          <ul className={`rdw-dropdown-optionwrapper ${this.state.open? "": "placeholder-ul"}`}>
            {this.listItem}
          </ul>
        </div>
      </div>
    );
  }
}

export default Placeholders;

I used a custom dropdown for adding placeholders.我使用自定义下拉菜单来添加占位符。 But the essence still stays the same because I use the example from the documentation for a custom button.但本质仍然保持不变,因为我使用了自定义按钮文档中的示例。

To render the button itself I used the same styling, classes, and structure as is used for the other dropdown buttons.为了呈现按钮本身,我使用了与其他下拉按钮相同的样式、类和结构。 I just switched the anchor tag to div tag and added custom classes for hover style and carrot change.我只是将锚标记切换为 div 标记,并为悬停样式和胡萝卜更改添加了自定义类。 I also used events to toggle classes.我还使用事件来切换类。

  .placeholder-ul{
    visibility: hidden;
  }
  .placeholder-li:hover {
    background: #F1F1F1;
  }

Lastly, don't forget to import and add a custom button to the editor.最后,不要忘记将自定义按钮导入并添加到编辑器。

<Editor
   editorState={this.state.editorState}
   onEditorStateChange={this.onEditorStateChange}
   toolbarCustomButtons={[<Placeholders />]}
/>

I'v used Tomas his code and updated it a bit to TypeScript / Function components.我使用了 Tomas 他的代码并将其更新为 TypeScript/Function 组件。 Can concur that this solution is still working in 2020 with Draft.js v0.10.5可以同意这个解决方案在 2020 年仍然可以使用 Draft.js v0.10.5

type ReplacementsProps = {
  onChange?: (editorState: EditorState) => void,
  editorState: EditorState,
}


export const Replacements = ({onChange, editorState}: ReplacementsProps) => {
  const [open, setOpen] = useState<boolean>(false);

  const addPlaceholder = (placeholder: string): void => {
    const contentState = Modifier.replaceText(
      editorState.getCurrentContent(),
      editorState.getSelection(),
      placeholder,
      editorState.getCurrentInlineStyle(),
    );
    const result = EditorState.push(editorState, contentState, 'insert-characters');
    if (onChange) {
      onChange(result);
    }
  };

  return (
    <div onClick={() => setOpen(!open)} className="rdw-block-wrapper" aria-label="rdw-block-control" role="button" tabIndex={0}>
      <div className="rdw-dropdown-wrapper rdw-block-dropdown" aria-label="rdw-dropdown" style={{width: 180}}>
        <div className="rdw-dropdown-selectedtext">
          <span>YOuR TITLE HERE</span>
          <div className={`rdw-dropdown-caretto${open ? 'close' : 'open'}`} />
        </div>
        <ul className={`rdw-dropdown-optionwrapper ${open ? '' : 'placeholder-ul'}`}>
          {placeholderOptions.map(item => (
            <li
              onClick={() => addPlaceholder(item.value)}
              key={item.value}
              className="rdw-dropdownoption-default placeholder-li"
            >
              {item.text}
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM