Skip to content

Latest commit

 

History

History
 
 

editor-quill

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Editor Quill

Renders the Quill Editor and returns its content on change.

Data Structure

  id: 5, // unique ID for each block (and so also for each EditorQuill)
  data: {
    value: '<p>Hello World. <b>This is bold.</b></p>' // can be html or plain text
  }

UI

Toolbar

The Toolbar (see Custom Toolbar Docu) is handled by the Component itself but can be replaced by the User (see Customization).

Styling

The Editor Quill provides a snow (see more here) and core theme (enables customization).

Nested Ordered Lists

In order to display only numbers on each list-level of the order list, one has to add the following code to the styles.scss:

.ql-editor ol {
  @for $i from 1 through 8 {
    li.ql-indent-#{$i} {
      &:before {
        content: counter(list-#{$i}, decimal) '.' // eg. 1. instead of a.
      }
    }
  }
}

Customization

One can customize the toolbar component and other behavioural aspects of the EditorQuill component. All that is needed is a property called blockConfig.

props.blockConfig = {
  placeholderText: 'Enter text...',
  ... // see a list of more available properties below
}

The following data properties are allowed and can be used:

  • icons: customize the icons quill renders for the format buttons (eg. for ql-bold)
  • onBlur, onFocus, onKeyPress, onKeyDown, onKeyUp: event listeners
  • placeholderText: will overwrite the placeholder text when the editor is empty
  • scrollingContainer: DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars. Read more about it here and here
  • toolbar: custom Toolbar component
  • toolbarCallback: this callback allows the developer to use a callback to get data from the custom Toolbar to the LovelyEditor (eg. onClick on a custom button in the custom Toolbar)
  • toolbarSelector: css selector of the new Toolbar component (tells Quill to use it)
  • theme: supports either snow or core (Docs). Use core to customize the theme of the Editor. An example can be found in the Storybook with Font-Awesome icons.

Basic Customization Example Code

import { EditorQuill } from './'

const exampleBlock = {
  id: 5,
  data: {
    value: '<p>Hello World. <b>This is bold.</b></p>'
  },
}

const blockConfig = {
  theme: 'snow'
}

<EditorQuill
  block={exampleBlock}
  blockConfig={blockConfig}
  onChange={this.onChange}
/>

Customize Icons

The following example illustrates how to replace the button icons with FontAwesome ones. There are more formats available, beside the ones illustrated below.

import { EditorQuill } from './'

const exampleBlock = {
  id: 5,
  data: {
    value: '<p>Hello World. <b>This is bold.</b></p>'
  },
}

const blockConfig = {
  icons: {
    bold: '<i class="fa fa-bold" aria-hidden="true"></i>',
    italic: '<i class="fa fa-italic" aria-hidden="true"></i>',
    underline: '<i class="fa fa-underline" aria-hidden="true"></i>',
    list: {
      bullet: '<i class="fa fa-list-ul"></i>',
      ordered: '<i class="fa fa-list-ol"></i>',
    },
    indent: {
      '+1': '<i class="fa fa-indent" aria-hidden="true"></i>',
      '-1': '<i class="fa fa-indent fa-rotate-180" style="padding-top: 2px;" />'
    }
  },
}

<EditorQuill
  block={exampleBlock}
  blockConfig={blockConfig}
  onChange={this.onChange}
/>

Customize Toolbar

Usually the toolbar of quill is handled by the itself, but one can decide to overwrite it and render a custom toolbar instead.

Attention: One needs to take care of applying the correct classNames (eg. ql-bold) for buttons, selects and other action items in the custom Toolbar. Only then will Quill recognize them as such.

The current implementation level of the customization allows only to replace the UI basically, but no deep integration in custom Toolbar actions are available (eg. custom formatting). One can add additional buttons (eg. Close-Button for the Block) which are not related to the Editor per se.

Toolbar Example Code

import { EditorQuill } from './'

const customQuillToolbar = (props) => {
  const onClick = () => {
    props.onToolbarClick('customQuillToolbar >> Toolbar clicked')
  }

  return (
    <div className="ql-toolbar" id="customToolbar" >
      <select className="ql-header" defaultValue="">
        <option value="1" />
        <option value="2" />
        <option value="3" />
        <option value="" />
      </select>
      <button onClick={onClick}>Click Me</button>
    </div>
  )
}

class Wrapper extends React.Component {

  onToolbarAction(toolbarAction) {
    // do something...
  }

  render() {
    const exampleBlock = {
      id: 5,
      data: {
        value: '<p>Hello World. <b>This is bold.</b></p>'
      },
    }
    const blockConfig = {
      toolbar: customQuillToolbar,
      toolbarCallback: this.onToolbarAction,
      toolbarSelector: '#customToolbar'
    }

    return (
      <EditorQuill
        block={exampleBlock}
        blockConfig={blockConfig}
        onChange={this.onChange}
      />
    )
  }  
}

Data Handling and Performance

Data Imports

The Quill component can import html content (eg. <p><b>Hello World</b></p>). Quill is able to import a delta, html or plain text.

Copy & Paste

  • Word
    • (Basic) Copy & Paste Support
    • not all Word-Styles can be imported and processed by Quill
  • Pages
    • (Basic) Copy & Paste Support
    • Some Headings-Formates (like Title, Headings) are not processed as such. They are imported as bold text.
  • PDF
    • (Basic) Copy & Paste Support
    • Some Headings-Formates (like Title, Headings) are not processed as such. They are imported as bold text.

Images are not supported by now and stripped away by not allowing the images format. Read more here.

Nested Lists

Quill handles nested lists differently. Imaging you import a list like this one:

<ul>
  <li>Coffee</li>
  <li>Tea
    <ul>
    <li>Black tea</li>
    <li>Green tea</li>
    </ul>
  </li>
  <li>Milk</li>
</ul>

Quill will import and handle it further on like this:

<ul>
  <li>Coffee</li>
  <li>Tea</li>
  <li class="ql-indent-1">Black tea</li>
  <li class="ql-indent-1">Green tea</li>
  <li>Milk </li>
</ul>

Performance

The Component emits changes to the Editor with the Help of Lodash's debounce feature. Lodash creates a debounced function that delays invoking onChange until after wait milliseconds have elapsed since the last time the debounced function was invoked. Currently this is set to 300ms. We wait for max 1000ms before the delayed onChange is invoked.

Known Issues

  • React-Quill (1.1.0) and Android: One cannot add new empty lines to an Editor with existing content, when the last chars have strong styling. Additionally, the cursor jumps to a new line, when there is more content after <strong>-paragraph.

Example Code

import { EditorQuill } from './'

const exampleBlock = {
  id: 5,
  data: {
    value: '<p>Hello World. <b>This is bold.</b></p>'
  },
}

<EditorQuill
  block={exampleBlock}
  onChange={this.onChange}
/>

Additional Research

Custom Dropdown Examples (but with snow styling)

How to customize the Dropdown (with examples)

How to write custom modules