diff --git a/examples/hovering-menu/index.js b/examples/hovering-menu/index.js index 474bb1228..1c67c8390 100644 --- a/examples/hovering-menu/index.js +++ b/examples/hovering-menu/index.js @@ -2,10 +2,12 @@ import { Editor } from 'slate-react' import { State } from 'slate' -import Portal from 'react-portal' import React from 'react' +import ReactDOM from 'react-dom' import initialState from './state.json' +const root = document.querySelector('main') + /** * Define a schema. * @@ -21,6 +23,67 @@ const schema = { } } +function Menu({ menuRef, onChange, state }) { + /** + * Check if the current selection has a mark with `type` in it. + * + * @param {String} type + * @return {Boolean} + */ + + function hasMark(type) { + return state.activeMarks.some(mark => mark.type == type) + } + + /** + * When a mark button is clicked, toggle the current mark. + * + * @param {Event} e + * @param {String} type + */ + + function onClickMark(e, type) { + e.preventDefault() + const change = state + .change() + .toggleMark(type) + onChange(change) + } + + /** + * Render a mark-toggling toolbar button. + * + * @param {String} type + * @param {String} icon + * @return {Element} + */ + + function renderMarkButton(type, icon) { + const isActive = hasMark(type) + function onMouseDown(e) { + onClickMark(e, type) + } + + return ( + + {icon} + + ) + } + + return ( + ReactDOM.createPortal( +
+ {renderMarkButton('bold', 'format_bold')} + {renderMarkButton('italic', 'format_italic')} + {renderMarkButton('underlined', 'format_underlined')} + {renderMarkButton('code', 'code')} +
, root + ) + ) +} + + /** * The hovering menu example. * @@ -51,18 +114,6 @@ class HoveringMenu extends React.Component { this.updateMenu() } - /** - * 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.activeMarks.some(mark => mark.type == type) - } - /** * On change. * @@ -74,29 +125,11 @@ class HoveringMenu extends React.Component { } /** - * When a mark button is clicked, toggle the current mark. + * Set menu ref * - * @param {Event} e - * @param {String} type */ - onClickMark = (e, type) => { - e.preventDefault() - const change = this.state.state - .change() - .toggleMark(type) - this.onChange(change) - } - - /** - * When the portal opens, cache the menu element. - * - * @param {Element} portal - */ - - onOpen = (portal) => { - this.setState({ menu: portal.firstChild }) - } + menuRef = el => this.menu = el /** * Render. @@ -107,64 +140,18 @@ class HoveringMenu extends React.Component { render() { return (
- {this.renderMenu()} - {this.renderEditor()} -
- ) - } - - /** - * Render the hovering menu. - * - * @return {Element} - */ - - renderMenu = () => { - return ( - -
- {this.renderMarkButton('bold', 'format_bold')} - {this.renderMarkButton('italic', 'format_italic')} - {this.renderMarkButton('underlined', 'format_underlined')} - {this.renderMarkButton('code', 'code')} -
-
- ) - } - - /** - * 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 the Slate editor. - * - * @return {Element} - */ - - renderEditor = () => { - return ( -
- +
+ +
) } @@ -174,7 +161,8 @@ class HoveringMenu extends React.Component { */ updateMenu = () => { - const { menu, state } = this.state + const { state } = this.state + const menu = this.menu if (!menu) return if (state.isBlurred || state.isEmpty) {