Skip to content

Commit

Permalink
Allow customisation of block style function & block render map
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudcolas committed Dec 12, 2016
1 parent 796f39e commit 15a6bcb
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 24 deletions.
44 changes: 44 additions & 0 deletions lib/api/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Map } from 'immutable';
import { DefaultDraftBlockRenderMap } from 'draft-js';

import { BLOCK_TYPE } from '../api/constants';

// Maximum level of nesting for unordered and ordered lists.
export const MAX_LIST_NESTING = 3;
// Frequency at which the save callback is triggered.
export const STATE_SAVE_INTERVAL = 250;

/**
* Options / configuration methods for the editor.
*/
export default {
getBlockRenderMap(BLOCK_TYPES = []) {
const renderMap = {};

renderMap[BLOCK_TYPE.BREAK] = { element: 'div' };

BLOCK_TYPES.filter(type => type.element)
.forEach((type) => {
renderMap[type.style] = { element: type.element };
});

return DefaultDraftBlockRenderMap.merge(Map(renderMap));
},

getBlockStyleFn(BLOCK_TYPES = []) {
const blockClassNames = {};

BLOCK_TYPES.filter(type => type.className)
.forEach((type) => {
blockClassNames[type.style] = type.className;
});

const blockStyleFn = (block) => {
const type = block.getType();

return blockClassNames[type] || undefined;
};

return blockStyleFn;
},
};
76 changes: 76 additions & 0 deletions lib/api/config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { List, Repeat } from 'immutable';
import {
CharacterMetadata,
ContentBlock,
} from 'draft-js';

import config, { MAX_LIST_NESTING, STATE_SAVE_INTERVAL } from '../api/config';
import { BLOCK_TYPE } from '../api/constants';

describe('config', () => {
describe('#MAX_LIST_NESTING', () => {
it('exists', () => {
expect(MAX_LIST_NESTING).toBeDefined();
});
});

describe('#STATE_SAVE_INTERVAL', () => {
it('exists', () => {
expect(STATE_SAVE_INTERVAL).toBeDefined();
});
});

describe('#getBlockRenderMap', () => {
it('exists', () => {
expect(config.getBlockRenderMap).toBeDefined();
});

it('has break', () => {
expect(config.getBlockRenderMap().get(BLOCK_TYPE.BREAK)).toEqual({ element: 'div' });
});

it('has custom block with element', () => {
expect(config.getBlockRenderMap([
{ style: 'TEST', element: 'div' },
]).get('TEST')).toEqual({ element: 'div' });
});

it('no custom block without element', () => {
expect(config.getBlockRenderMap([
{ style: 'TEST' },
]).get('TEST')).not.toBeDefined();
});
});

describe('#getBlockStyleFn', () => {
it('exists', () => {
expect(config.getBlockStyleFn).toBeDefined();
});

it('returns function', () => {
expect(config.getBlockStyleFn()).toBeInstanceOf(Function);
});

it('has custom block with className', () => {
expect(config.getBlockStyleFn([
{ style: 'TEST', className: 'test-item' },
])(new ContentBlock({
key: 'test1234',
type: 'TEST',
text: 'This is test text',
characterList: List(Repeat(CharacterMetadata.create({ entity: 'test1234' }), 'This is test text'.length)),
}))).toEqual('test-item');
});

it('no custom block without className', () => {
expect(config.getBlockStyleFn([
{ style: 'TEST' },
])(new ContentBlock({
key: 'test1234',
type: 'TEST',
text: 'This is test text',
characterList: List(Repeat(CharacterMetadata.create({ entity: 'test1234' }), 'This is test text'.length)),
}))).not.toBeDefined();
});
});
});
8 changes: 0 additions & 8 deletions lib/api/constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { Map } from 'immutable';
import { DefaultDraftBlockRenderMap } from 'draft-js';

// Originally from https://github.com/draft-js-utils/draft-js-utils/blob/master/src/Constants.js.
export const BLOCK_TYPE = {
Expand Down Expand Up @@ -38,9 +36,3 @@ export const INLINE_STYLE = {
STRIKETHROUGH: 'STRIKETHROUGH',
UNDERLINE: 'UNDERLINE',
};

const renderMap = {};

renderMap[BLOCK_TYPE.BREAK] = { element: 'div' };

export const BlockRenderMap = Map(renderMap).merge(DefaultDraftBlockRenderMap);
8 changes: 1 addition & 7 deletions lib/api/constants.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BLOCK_TYPE, ENTITY_TYPE, INLINE_STYLE, BlockRenderMap } from '../api/constants';
import { BLOCK_TYPE, ENTITY_TYPE, INLINE_STYLE } from '../api/constants';

describe('constants', () => {
describe('#BLOCK_TYPE', () => {
Expand All @@ -18,10 +18,4 @@ describe('constants', () => {
expect(INLINE_STYLE).toBeDefined();
});
});

describe('#BlockRenderMap', () => {
it('exists', () => {
expect(BlockRenderMap).toBeDefined();
});
});
});
17 changes: 13 additions & 4 deletions lib/components/DraftailEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
SelectionState,
} from 'draft-js';

import { MAX_LIST_NESTING, STATE_SAVE_INTERVAL } from '../config';
import { BLOCK_TYPE, BlockRenderMap } from '../api/constants';
import { BLOCK_TYPE } from '../api/constants';
import config, { MAX_LIST_NESTING, STATE_SAVE_INTERVAL } from '../api/config';

import DraftUtils from '../api/DraftUtils';
import conversion from '../api/conversion';
Expand Down Expand Up @@ -328,7 +328,12 @@ class DraftailEditor extends Component {
const { editorState } = this.state;
const selection = editorState.getSelection();

if (!selection.isCollapsed()) {
if (selection.isCollapsed()) {
this.setState({
activeEntityDialog: entityName,
entity: null,
});
} else {
const selectionState = editorState.getSelection();
const selStart = selectionState.getStartOffset();
const startKey = editorState.getSelection().getStartKey();
Expand Down Expand Up @@ -506,6 +511,7 @@ class DraftailEditor extends Component {
}

render() {
const { options } = this.props;
const { editorState, readOnly } = this.state;

return (
Expand All @@ -530,7 +536,8 @@ class DraftailEditor extends Component {
onTab={this.handleTabCommand}
spellCheck={false}
blockRendererFn={this.blockRenderer}
blockRenderMap={BlockRenderMap}
blockRenderMap={config.getBlockRenderMap(options.BLOCK_TYPES)}
blockStyleFn={config.getBlockStyleFn(options.BLOCK_TYPES)}
/>

{this.renderTooltip()}
Expand Down Expand Up @@ -580,6 +587,8 @@ DraftailEditor.propTypes = {
style: React.PropTypes.string.isRequired,
label: React.PropTypes.string.isRequired,
icon: React.PropTypes.string,
element: React.PropTypes.string,
className: React.PropTypes.string,
})).isRequired,
INLINE_STYLES: React.PropTypes.arrayOf(React.PropTypes.shape({
style: React.PropTypes.string.isRequired,
Expand Down
5 changes: 0 additions & 5 deletions lib/config.js

This file was deleted.

0 comments on commit 15a6bcb

Please sign in to comment.