1
0
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:
Ian Storm Taylor
2016-07-13 16:19:49 -07:00
parent 9793b11140
commit ab12518a4b
8 changed files with 298 additions and 126 deletions

View File

@@ -5,7 +5,7 @@ import keycode from 'keycode'
import initialState from './state.json'
/**
* Node renderers.
* Define a set of node renderers.
*
* @type {Object}
*/

View File

@@ -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

View File

@@ -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 })
}
}
/**

View File

@@ -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)
};

View File

@@ -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)
};

View File

@@ -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()
}
}
/**

View File

@@ -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}
*/

View File

@@ -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]
}
}
/**