From c218c1721e651625998ac3298b65b142127e19fb Mon Sep 17 00:00:00 2001 From: Ian Storm Taylor Date: Wed, 13 Jul 2016 15:12:47 -0700 Subject: [PATCH] cleanup the rich text example --- examples/rich-text/index.js | 240 +++++++++++++++++++++++++----------- 1 file changed, 168 insertions(+), 72 deletions(-) diff --git a/examples/rich-text/index.js b/examples/rich-text/index.js index 74390800f..74128a8c4 100644 --- a/examples/rich-text/index.js +++ b/examples/rich-text/index.js @@ -1,11 +1,11 @@ -import { Editor, Mark, Placeholder, Raw, Utils } from '../..' +import { Editor, Mark, Raw, Utils } from '../..' import React from 'react' import initialState from './state.json' import keycode from 'keycode' /** - * Node renderers. + * Defin a set of node renderers. * * @type {Object} */ @@ -20,7 +20,7 @@ const NODES = { } /** - * Mark renderers. + * Define a set of mark renderers. * * @type {Object} */ @@ -51,94 +51,58 @@ const MARKS = { class RichText extends React.Component { + /** + * Deserialize the initial editor state. + * + * @type {Object} + */ + state = { state: Raw.deserialize(initialState) }; - render = () => { - return ( -
- {this.renderToolbar()} - {this.renderEditor()} -
- ) - } - - renderToolbar = () => { - return ( -
- {this.renderMarkButton('bold', 'format_bold')} - {this.renderMarkButton('italic', 'format_italic')} - {this.renderMarkButton('underlined', 'format_underlined')} - {this.renderMarkButton('code', 'code')} - {this.renderBlockButton('heading-one', 'looks_one')} - {this.renderBlockButton('heading-two', 'looks_two')} - {this.renderBlockButton('block-quote', 'format_quote')} - {this.renderBlockButton('numbered-list', 'format_list_numbered')} - {this.renderBlockButton('bulleted-list', 'format_list_bulleted')} -
- ) - } - - renderMarkButton = (type, icon) => { - const isActive = this.hasMark(type) - const onMouseDown = e => this.onClickMark(e, type) - - return ( - - {icon} - - ) - } - - renderBlockButton = (type, icon) => { - const isActive = this.hasBlock(type) - const onMouseDown = e => this.onClickBlock(e, type) - - return ( - - {icon} - - ) - } - - renderEditor = () => { - return ( -
- -
- ) - } - - renderNode = (node) => { - return NODES[node.type] - } - - renderMark = (mark) => { - return MARKS[mark.type] - } + /** + * Check if the current selection has a mark with `type` in it. + * + * @param {String} type + * @return {Boolean} + */ hasMark = (type) => { const { state } = this.state return state.marks.some(mark => mark.type == type) } + /** + * Check if the any of the currently selected blocks are of `type`. + * + * @param {String} type + * @return {Boolean} + */ + hasBlock = (type) => { const { state } = this.state return state.blocks.some(node => node.type == type) } + /** + * On change, save the new state. + * + * @param {State} state + */ + onChange = (state) => { this.setState({ state }) } + /** + * On key down, if it's a formatting command toggle a mark. + * + * @param {Event} e + * @param {State} state + * @return {State} + */ + onKeyDown = (e, state) => { if (!Utils.Key.isCommand(e)) return const key = keycode(e.which) @@ -170,6 +134,13 @@ class RichText extends React.Component { return state } + /** + * When a mark button is clicked, toggle the current mark. + * + * @param {Event} e + * @param {String} type + */ + onClickMark = (e, type) => { e.preventDefault() const isActive = this.hasMark(type) @@ -183,6 +154,13 @@ class RichText extends React.Component { this.setState({ state }) } + /** + * When a block button is clicked, toggle the block type. + * + * @param {Event} e + * @param {String} type + */ + onClickBlock = (e, type) => { e.preventDefault() const isActive = this.hasBlock(type) @@ -196,6 +174,124 @@ class RichText extends React.Component { this.setState({ state }) } + /** + * Render. + * + * @return {Element} + */ + + render = () => { + return ( +
+ {this.renderToolbar()} + {this.renderEditor()} +
+ ) + } + + /** + * Render the toolbar. + * + * @return {Element} + */ + + renderToolbar = () => { + return ( +
+ {this.renderMarkButton('bold', 'format_bold')} + {this.renderMarkButton('italic', 'format_italic')} + {this.renderMarkButton('underlined', 'format_underlined')} + {this.renderMarkButton('code', 'code')} + {this.renderBlockButton('heading-one', 'looks_one')} + {this.renderBlockButton('heading-two', 'looks_two')} + {this.renderBlockButton('block-quote', 'format_quote')} + {this.renderBlockButton('numbered-list', 'format_list_numbered')} + {this.renderBlockButton('bulleted-list', 'format_list_bulleted')} +
+ ) + } + + /** + * Render a mark-toggling toolbar button. + * + * @param {String} type + * @param {String} icon + * @return {Element} + */ + + renderMarkButton = (type, icon) => { + const isActive = this.hasMark(type) + const onMouseDown = e => this.onClickMark(e, type) + + return ( + + {icon} + + ) + } + + /** + * Render a block-toggling toolbar button. + * + * @param {String} type + * @param {String} icon + * @return {Element} + */ + + renderBlockButton = (type, icon) => { + const isActive = this.hasBlock(type) + const onMouseDown = e => this.onClickBlock(e, type) + + return ( + + {icon} + + ) + } + + /** + * Render the Slate editor. + * + * @return {Element} + */ + + renderEditor = () => { + return ( +
+ +
+ ) + } + + /** + * Return a node renderer for a Slate `node`. + * + * @param {Node} node + * @return {Component or Void} + */ + + renderNode = (node) => { + return NODES[node.type] + } + + /** + * Return a mark renderer for a Slate `mark`. + * + * @param {Mark} mark + * @return {Object or Void} + */ + + renderMark = (mark) => { + return MARKS[mark.type] + } + } /**