Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

adding-support-for-paragraph - making blockTypes configurable #205

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions examples/rich/rich.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,30 @@
<script type="text/babel">
'use strict';

const {Editor, EditorState, RichUtils} = Draft;
const {
Editor,
EditorState,
RichUtils,
DefaultDraftBlockRenderMap,
DefaultDraftInlineStyle
} = Draft;

class RichEditorExample extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};
this.state = {
editorState: EditorState.createEmpty(),
customBlockMap: DefaultDraftBlockRenderMap.merge(Immutable.Map({
'paragraph': Immutable.Map({
wrapper: null,
element: 'p'
}),
'unstyled': Immutable.Map({
wrapper: null,
element: 'p'
})
}))
};

this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => this.setState({editorState});
Expand Down Expand Up @@ -77,7 +95,7 @@
}

render() {
const {editorState} = this.state;
const {editorState, customBlockMap} = this.state;

// If the user changes block type before entering any text, we can
// either style the placeholder or hide it. Let's just hide it now.
Expand All @@ -101,6 +119,7 @@
/>
<div className={className} onClick={this.focus}>
<Editor
customBlockMap={customBlockMap}
blockStyleFn={getBlockStyle}
customStyleMap={styleMap}
editorState={editorState}
Expand Down Expand Up @@ -157,6 +176,7 @@
}

const BLOCK_TYPES = [
{label: 'p', style: 'paragraph'},
{label: 'H1', style: 'header-one'},
{label: 'H2', style: 'header-two'},
{label: 'H3', style: 'header-three'},
Expand Down
5 changes: 5 additions & 0 deletions src/Draft.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

'use strict';

const DefaultDraftBlockRenderMap = require('DefaultDraftBlockRenderMap');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI the rest of the imports are alphabetical order.

const DefaultDraftInlineStyle = require('DefaultDraftInlineStyle');
const BlockMapBuilder = require('BlockMapBuilder');
const CharacterMetadata = require('CharacterMetadata');
const CompositeDraftDecorator = require('CompositeDraftDecorator');
Expand Down Expand Up @@ -55,6 +57,9 @@ const DraftPublic = {
Modifier: DraftModifier,
RichUtils: RichTextEditorUtil,

DefaultDraftBlockRenderMap,
DefaultDraftInlineStyle,

convertFromHTML: convertFromHTMLToContentBlocks,
convertFromRaw: convertFromRawToDraftState,
convertToRaw: convertFromDraftStateToRaw,
Expand Down
5 changes: 5 additions & 0 deletions src/component/base/DraftEditor.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

'use strict';

const DefaultDraftBlockRenderMap = require('DefaultDraftBlockRenderMap');
const DefaultDraftInlineStyle = require('DefaultDraftInlineStyle');
const DraftEditorCompositionHandler = require('DraftEditorCompositionHandler');
const DraftEditorContents = require('DraftEditorContents.react');
Expand All @@ -38,6 +39,7 @@ import type ContentBlock from 'ContentBlock';
import type {DraftEditorModes} from 'DraftEditorModes';
import type {DraftEditorProps} from 'DraftEditorProps';
import type {DraftScrollPosition} from 'DraftScrollPosition';
import type {DraftBlockRenderMap} from 'DraftBlockRenderMap';

const isIE = UserAgent.isBrowser('IE');

Expand All @@ -58,6 +60,7 @@ const handlerMap = {
type DefaultProps = {
blockRendererFn?: (block: ContentBlock) => ?Object;
blockStyleFn?: (type: number) => string,
customBlockMap: DraftBlockRenderMap,
keyBindingFn?: (e: SyntheticKeyboardEvent) => ?string,
readOnly?: boolean,
spellCheck?: boolean,
Expand All @@ -78,6 +81,7 @@ class DraftEditor
state: State;

static defaultProps = {
customBlockMap: DefaultDraftBlockRenderMap,
blockRendererFn: emptyFunction.thatReturnsNull,
blockStyleFn: emptyFunction.thatReturns(''),
keyBindingFn: getDefaultKeyBinding,
Expand Down Expand Up @@ -280,6 +284,7 @@ class DraftEditor
<DraftEditorContents
blockRendererFn={nullthrows(this.props.blockRendererFn)}
blockStyleFn={nullthrows(this.props.blockStyleFn)}
customBlockMap={nullthrows(this.props.customBlockMap)}
customStyleMap={
{...DefaultDraftInlineStyle, ...this.props.customStyleMap}
}
Expand Down
6 changes: 6 additions & 0 deletions src/component/base/DraftEditorProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {DraftDragType} from 'DraftDragType';
import type {DraftTextAlignment} from 'DraftTextAlignment';
import type EditorState from 'EditorState';
import type SelectionState from 'SelectionState';
import type {DraftBlockRenderMap} from 'DraftBlockRenderMap';

export type DraftEditorProps = {
/**
Expand Down Expand Up @@ -129,4 +130,9 @@ export type DraftEditorProps = {
// Provide a map of inline style names corresponding to CSS style objects
// that will be rendered for matching ranges.
customStyleMap?: Object,

// Provide a map of configurable blockRenderTypes, each type then define
// a mapping element tag and/or a react element wrapper that is used for
// rendering and paste processing
customBlockMap: DraftBlockRenderMap,
};
16 changes: 11 additions & 5 deletions src/component/contents/DraftEditorContents.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ const EditorState = require('EditorState');
const React = require('React');

const cx = require('cx');
const getElementForBlockType = require('getElementForBlockType');
const getWrapperTemplateForBlockType = require('getWrapperTemplateForBlockType');
const DefaultDraftBlockRenderMap = require('DefaultDraftBlockRenderMap');
const joinClasses = require('joinClasses');
const nullthrows = require('nullthrows');

Expand Down Expand Up @@ -136,10 +135,17 @@ class DraftEditorContents extends React.Component {
tree: editorState.getBlockTree(key),
};

wrapperTemplate = getWrapperTemplateForBlockType(blockType);
const draftBlockRenderMap = this.props.customBlockMap;

wrapperTemplate = draftBlockRenderMap.getIn([blockType, 'wrapper']);

const useNewWrapper = wrapperTemplate !== currentWrapperTemplate;

const Element = getElementForBlockType(blockType);
const unstyledElement = draftBlockRenderMap.getIn(['unstyled', 'element']) ||
DefaultDraftBlockRenderMap.getIn(['unstyled', 'element']);

const Element = draftBlockRenderMap.getIn([blockType, 'element']) || unstyledElement;

const depth = block.getDepth();
let className = this.props.blockStyleFn(block);

Expand Down Expand Up @@ -173,7 +179,7 @@ class DraftEditorContents extends React.Component {
};
}

// $FlowFixMe: Support DOM elements in React.createElement
// FlowFixMe: Support DOM elements in React.createElement
child = React.createElement(
Element,
childProps,
Expand Down
2 changes: 1 addition & 1 deletion src/component/handlers/edit/editOnPaste.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function editOnPaste(e: SyntheticClipboardEvent): void {

// If there is html paste data, try to parse that.
if (html) {
var htmlFragment = DraftPasteProcessor.processHTML(html);
var htmlFragment = DraftPasteProcessor.processHTML(html, this.props.customBlockMap);
if (htmlFragment) {
var htmlMap = BlockMapBuilder.createFromArray(htmlFragment);
this.update(insertFragment(this.props.editorState, htmlMap));
Expand Down
43 changes: 0 additions & 43 deletions src/component/utils/getElementForBlockType.js

This file was deleted.

43 changes: 0 additions & 43 deletions src/component/utils/getWrapperTemplateForBlockType.js

This file was deleted.

31 changes: 31 additions & 0 deletions src/model/constants/DraftBlockTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule DraftBlockTag
* @flow
*/

'use strict';

/**
* The list of default valid block tags.
*/
export type DraftBlockTag = (
'div' |
'p' |
'h1' |
'h2' |
'h3' |
'h4' |
'h5' |
'h6' |
'li' |
'blockquote' |
'pre' |
'figure'
);
2 changes: 0 additions & 2 deletions src/model/constants/DraftBlockType.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/
export type DraftBlockType = (
'unstyled' |
'paragraph' |
'header-one' |
'header-two' |
'header-three' |
Expand All @@ -27,7 +26,6 @@ export type DraftBlockType = (
'unordered-list-item' |
'ordered-list-item' |
'blockquote' |
'pullquote' |
'code-block' |
'media'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paragraph and pullquote were never used / referenced and were causing static type errors using flow. If any application requires it it can then use the configurable API to include it as demonstrated on the rich.html example file

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

);
Loading