mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-19 13:41:19 +02:00
clean up examples
This commit is contained in:
@@ -5,7 +5,7 @@ import keycode from 'keycode'
|
||||
import initialState from './state.json'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
@@ -6,7 +6,7 @@ import keycode from 'keycode'
|
||||
import initialState from './state.json'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -16,7 +16,7 @@ const NODES = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark renderers.
|
||||
* Define a set of mark renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -34,22 +34,42 @@ const MARKS = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Example.
|
||||
* The code highlighting example.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class CodeHighlighting extends React.Component {
|
||||
|
||||
/**
|
||||
* Deserialize the raw initial state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
||||
/**
|
||||
* On change, save the new state.
|
||||
*
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onKeyDown = (e, state, editor) => {
|
||||
/**
|
||||
* On key down inside code blocks, insert soft new lines.
|
||||
*
|
||||
* @param {Event} e
|
||||
* @param {State} state
|
||||
* @return {State}
|
||||
*/
|
||||
|
||||
onKeyDown = (e, state) => {
|
||||
const key = keycode(e.which)
|
||||
if (key != 'enter') return
|
||||
const { startBlock } = state
|
||||
@@ -62,6 +82,12 @@ class CodeHighlighting extends React.Component {
|
||||
return transform.apply()
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* @return {Component}
|
||||
*/
|
||||
|
||||
render = () => {
|
||||
return (
|
||||
<div className="editor">
|
||||
@@ -77,15 +103,36 @@ class CodeHighlighting extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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] || {}
|
||||
}
|
||||
|
||||
renderDecorations = (text, state, editor) => {
|
||||
/**
|
||||
* Render decorations on `text` nodes inside code blocks.
|
||||
*
|
||||
* @param {Text} text
|
||||
* @return {Characters}
|
||||
*/
|
||||
|
||||
renderDecorations = (text, state) => {
|
||||
const { document } = state
|
||||
const block = document.getClosestBlock(text)
|
||||
if (block.type != 'code') return text.characters
|
||||
|
@@ -6,7 +6,7 @@ import position from 'selection-position'
|
||||
import initialState from './state.json'
|
||||
|
||||
/**
|
||||
* Mark renderers.
|
||||
* Define a set of mark renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -30,17 +30,27 @@ const MARKS = {
|
||||
}
|
||||
|
||||
/**
|
||||
* The rich text example.
|
||||
* The hovering menu example.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class HoveringMenu extends React.Component {
|
||||
|
||||
/**
|
||||
* Deserialize the raw initial state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
||||
/**
|
||||
* On update, update the menu.
|
||||
*/
|
||||
|
||||
componentDidMount = () => {
|
||||
this.updateMenu()
|
||||
}
|
||||
@@ -49,6 +59,64 @@ 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.marks.some(mark => mark.type == type)
|
||||
}
|
||||
|
||||
/**
|
||||
* On change, save the new state.
|
||||
*
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ 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)
|
||||
let { state } = this.state
|
||||
|
||||
state = state
|
||||
.transform()
|
||||
[isActive ? 'unmark' : 'mark'](type)
|
||||
.apply()
|
||||
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
/**
|
||||
* When the portal opens, cache the menu element.
|
||||
*
|
||||
* @param {Element} portal
|
||||
*/
|
||||
|
||||
onOpen = (portal) => {
|
||||
this.setState({ menu: portal.firstChild })
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
render = () => {
|
||||
return (
|
||||
<div>
|
||||
@@ -58,6 +126,12 @@ class HoveringMenu extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the hovering menu.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
renderMenu = () => {
|
||||
const { state } = this.state
|
||||
const isOpen = state.isExpanded && state.isFocused
|
||||
@@ -73,6 +147,14 @@ class HoveringMenu extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
@@ -84,6 +166,12 @@ class HoveringMenu extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the Slate editor.
|
||||
*
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
renderEditor = () => {
|
||||
return (
|
||||
<div className="editor">
|
||||
@@ -96,10 +184,21 @@ class HoveringMenu extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a mark renderer for a Slate `mark`.
|
||||
*
|
||||
* @param {Mark} mark
|
||||
* @return {Object or Void}
|
||||
*/
|
||||
|
||||
renderMark = (mark) => {
|
||||
return MARKS[mark.type]
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the menu's absolute position.
|
||||
*/
|
||||
|
||||
updateMenu = () => {
|
||||
const { menu, state } = this.state
|
||||
if (!menu) return
|
||||
@@ -115,32 +214,6 @@ class HoveringMenu extends React.Component {
|
||||
menu.style.left = `${rect.left + window.scrollX - menu.offsetWidth / 2 + rect.width / 2}px`
|
||||
}
|
||||
|
||||
hasMark = (type) => {
|
||||
const { state } = this.state
|
||||
return state.marks.some(mark => mark.type == type)
|
||||
}
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onClickMark = (e, type) => {
|
||||
e.preventDefault()
|
||||
const isActive = this.hasMark(type)
|
||||
let { state } = this.state
|
||||
|
||||
state = state
|
||||
.transform()
|
||||
[isActive ? 'unmark' : 'mark'](type)
|
||||
.apply()
|
||||
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onOpen = (el) => {
|
||||
this.setState({ menu: el.firstChild })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -6,7 +6,7 @@ import initialState from './state.json'
|
||||
import { Map } from 'immutable'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -29,6 +29,12 @@ const NODES = {
|
||||
|
||||
class Images extends React.Component {
|
||||
|
||||
/**
|
||||
* Deserialize the raw initial state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
@@ -6,7 +6,7 @@ import initialState from './state.json'
|
||||
import { Map } from 'immutable'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -28,6 +28,12 @@ const NODES = {
|
||||
|
||||
class Links extends React.Component {
|
||||
|
||||
/**
|
||||
* Deserialize the raw initial state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
@@ -4,7 +4,7 @@ import React from 'react'
|
||||
import initialState from './state.json'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -29,7 +29,7 @@ const NODES = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark renderers.
|
||||
* Define a set of mark renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -157,17 +157,58 @@ const RULES = [
|
||||
const serializer = new Html(RULES)
|
||||
|
||||
/**
|
||||
* The rich text example.
|
||||
* The pasting html example.
|
||||
*
|
||||
* @type {Component}
|
||||
*/
|
||||
|
||||
class PasteHtml extends React.Component {
|
||||
|
||||
/**
|
||||
* Deserialize the raw initial state.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
||||
/**
|
||||
* On change, save the new state.
|
||||
*
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
/**
|
||||
* On paste, deserialize the HTML and then insert the fragment.
|
||||
*
|
||||
* @param {Event} e
|
||||
* @param {Object} paste
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onPaste = (e, paste, state) => {
|
||||
if (paste.type != 'html') return
|
||||
const { html } = paste
|
||||
const { document } = serializer.deserialize(html)
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.insertFragment(document)
|
||||
.apply()
|
||||
}
|
||||
|
||||
/**
|
||||
* Render.
|
||||
*
|
||||
* @return {Component}
|
||||
*/
|
||||
|
||||
render = () => {
|
||||
return (
|
||||
<div className="editor">
|
||||
@@ -182,29 +223,28 @@ class PasteHtml extends React.Component {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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]
|
||||
}
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
onPaste = (e, paste, state, editor) => {
|
||||
if (paste.type != 'html') return
|
||||
const { html } = paste
|
||||
const { document } = serializer.deserialize(html)
|
||||
|
||||
return state
|
||||
.transform()
|
||||
.insertFragment(document)
|
||||
.apply()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,7 +5,7 @@ import initialState from './state.json'
|
||||
import keycode from 'keycode'
|
||||
|
||||
/**
|
||||
* Defin a set of node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
@@ -5,7 +5,7 @@ import initialState from './state.json'
|
||||
import keycode from 'keycode'
|
||||
|
||||
/**
|
||||
* Node renderers.
|
||||
* Define a set of node renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -17,7 +17,7 @@ const NODES = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark renderers.
|
||||
* Define a set of mark renderers.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
@@ -46,75 +46,6 @@ class Tables extends React.Component {
|
||||
state: Raw.deserialize(initialState)
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the example.
|
||||
*
|
||||
* @return {Component} component
|
||||
*/
|
||||
|
||||
render = () => {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
renderNode={this.renderNode}
|
||||
renderMark={this.renderMark}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a `node`.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
renderNode = (node) => {
|
||||
return NODES[node.type]
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a `mark`.
|
||||
*
|
||||
* @param {Mark} mark
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
renderMark = (mark) => {
|
||||
return MARKS[mark.type]
|
||||
}
|
||||
|
||||
/**
|
||||
* On change.
|
||||
*
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
/**
|
||||
* On key down, check for our specific key shortcuts.
|
||||
*
|
||||
* @param {Event} e
|
||||
* @param {State} state
|
||||
* @return {State or Null} state
|
||||
*/
|
||||
|
||||
onKeyDown = (e, state) => {
|
||||
if (state.startBlock.type != 'table-cell') return
|
||||
switch (keycode(e.which)) {
|
||||
case 'backspace': return this.onBackspace(e, state)
|
||||
case 'delete': return this.onDelete(e, state)
|
||||
case 'enter': return this.onEnter(e, state)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On backspace, do nothing if at the start of a table cell.
|
||||
*
|
||||
@@ -129,6 +60,16 @@ class Tables extends React.Component {
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
* On change.
|
||||
*
|
||||
* @param {State} state
|
||||
*/
|
||||
|
||||
onChange = (state) => {
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
/**
|
||||
* On delete, do nothing if at the end of a table cell.
|
||||
*
|
||||
@@ -156,6 +97,65 @@ class Tables extends React.Component {
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
* On key down, check for our specific key shortcuts.
|
||||
*
|
||||
* @param {Event} e
|
||||
* @param {State} state
|
||||
* @return {State or Null} state
|
||||
*/
|
||||
|
||||
onKeyDown = (e, state) => {
|
||||
if (state.startBlock.type != 'table-cell') return
|
||||
switch (keycode(e.which)) {
|
||||
case 'backspace': return this.onBackspace(e, state)
|
||||
case 'delete': return this.onDelete(e, state)
|
||||
case 'enter': return this.onEnter(e, state)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the example.
|
||||
*
|
||||
* @return {Component} component
|
||||
*/
|
||||
|
||||
render = () => {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
renderNode={this.renderNode}
|
||||
renderMark={this.renderMark}
|
||||
onKeyDown={this.onKeyDown}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user