A simple counter plugin for all your counting needs. You can even set a limit to change the color past a certain threshold.
To use, simply import and instantiate the counter plugin, and then use one of the available counter components in your JSX. Out of the box, the following counters are included:
The Custom Counter allows you to bring your own counting function. This will be a function that takes plain text (as a string) from the editor as input and returns a numerical value.
npm install @draft-js-plugins/editor
npm install @draft-js-plugins/counter
// It is important to import the Editor which accepts plugins.
import Editor from '@draft-js-plugins/editor';
import createCounterPlugin from '@draft-js-plugins/counter';
import React from 'react';
// Creates an Instance. At this step, a configuration object can be passed in
// as an argument.
const counterPlugin = createCounterPlugin();
// Extract a counter from the plugin.
const { CharCounter } = counterPlugin;
// The Editor accepts an array of plugins. In this case, only the counterPlugin is
// passed in, although it is possible to pass in multiple plugins.
// The Counter is placed after the Editor.
const MyEditor = ({ editorState, onChange }) => (
<div>
<Editor
editorState={editorState}
onChange={onChange}
plugins={[counterPlugin]}
/>
<CharCounter editorState={this.state.editorState} limit={200} />
</div>
);
export default MyEditor;
The plugin ships with a default styling available at this location in the installed package: node_modules/@draft-js-plugins/counter/lib/plugin.css
npm i style-loader css-loader --save-dev
module.exports = {
module: {
loaders: [
{
test: /plugin\.css$/,
loaders: ['style-loader', 'css'],
},
],
},
};
import '@draft-js-plugins/counter/lib/plugin.css';
import React, { Component } from 'react';
import Editor, { createEditorStateWithText } from '@draft-js-plugins/editor';
import createCounterPlugin from '@draft-js-plugins/counter';
import editorStyles from './editorStyles.module.css';
const counterPlugin = createCounterPlugin();
const { CharCounter, WordCounter, LineCounter, CustomCounter } = counterPlugin;
const plugins = [counterPlugin];
const text = `This editor has counters below!
Try typing here and watch the numbers go up. 🙌
Note that the color changes when you pass one of the following limits:
- 200 characters
- 30 words
- 10 lines
`;
export default class SimpleCounterEditor extends Component {
state = {
editorState: createEditorStateWithText(text),
};
onChange = (editorState) => {
this.setState({ editorState });
};
focus = () => {
this.editor.focus();
};
customCountFunction(str) {
const wordArray = str.match(/\S+/g); // matches words according to whitespace
return wordArray ? wordArray.length : 0;
}
render() {
return (
<div>
<div className={editorStyles.editor} onClick={this.focus}>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={plugins}
ref={(element) => {
this.editor = element;
}}
/>
</div>
<div>
<CharCounter limit={200} /> characters
</div>
<div>
<WordCounter limit={30} /> words
</div>
<div>
<LineCounter limit={10} /> lines
</div>
<div>
<CustomCounter limit={40} countFunction={this.customCountFunction} />
<span> words (custom function)</span>
</div>
<br />
<br />
</div>
);
}
}
.editor {
box-sizing: border-box;
border: 1px solid #ddd;
cursor: text;
padding: 16px;
border-radius: 2px;
margin-bottom: 2em;
box-shadow: inset 0px 1px 8px -3px #ABABAB;
background: #fefefe;
}
.editor :global(.public-DraftEditor-content) {
min-height: 140px;
}
import React, { Component } from 'react';
import Editor, { createEditorStateWithText } from '@draft-js-plugins/editor';
import createCounterPlugin from '@draft-js-plugins/counter';
import editorStyles from './editorStyles.module.css';
import counterStyles from './counterStyles.module.css';
const theme = {
counter: counterStyles.counter,
counterOverLimit: counterStyles.counterOverLimit,
};
const counterPlugin = createCounterPlugin({ theme });
const { CharCounter, WordCounter, LineCounter, CustomCounter } = counterPlugin;
const plugins = [counterPlugin];
const text = `This editor has counters below!
Try typing here and watch the numbers go up. 🙌
Note that the color changes when you pass one of the following limits:
- 200 characters
- 30 words
- 10 lines
`;
export default class CustomCounterEditor extends Component {
state = {
editorState: createEditorStateWithText(text),
};
onChange = (editorState) => {
this.setState({ editorState });
};
focus = () => {
this.editor.focus();
};
// eslint-disable-next-line class-methods-use-this
customCountFunction(str) {
const wordArray = str.match(/\S+/g); // matches words according to whitespace
return wordArray ? wordArray.length : 0;
}
render() {
return (
<div>
<div className={editorStyles.editor} onClick={this.focus}>
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
plugins={plugins}
ref={(element) => {
this.editor = element;
}}
/>
</div>
<div>
<CharCounter limit={200} /> characters
</div>
<div>
<WordCounter limit={30} /> words
</div>
<div>
<LineCounter limit={10} /> lines
</div>
<div>
<CustomCounter limit={40} countFunction={this.customCountFunction} />
<span> words (custom function)</span>
</div>
<br />
<br />
</div>
);
}
}
.counter {
color: white;
background-color: #353535;
display: inline-block;
min-width: 50px;
border-radius: 10px;
padding: 2px;
text-align: center;
margin-bottom: 5px;
}
.counterOverLimit {
color: tomato;
background-color: #353535;
display: inline-block;
min-width: 50px;
border-radius: 10px;
padding: 2px;
text-align: center;
margin-bottom: 5px;
}
.editor {
box-sizing: border-box;
border: 1px solid #ddd;
cursor: text;
padding: 16px;
border-radius: 2px;
margin-bottom: 2em;
box-shadow: inset 0px 1px 8px -3px #ABABAB;
background: #fefefe;
}
.editor :global(.public-DraftEditor-content) {
min-height: 140px;
}