mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-11 17:53:59 +02:00
cleanup, update code highlighting example
This commit is contained in:
@@ -5,64 +5,68 @@ import React from 'react'
|
|||||||
import initialState from './state.json'
|
import initialState from './state.json'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a set of node renderers.
|
* Define a code block component.
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @param {Object} props
|
||||||
|
* @return {Element}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const NODES = {
|
function CodeBlock(props) {
|
||||||
code: (props) => {
|
const { attributes, children, editor, node } = props
|
||||||
const { attributes, children, editor, node } = props
|
const language = node.data.get('language')
|
||||||
const language = node.data.get('language')
|
|
||||||
|
|
||||||
function onChange(e) {
|
function onChange(e) {
|
||||||
const state = editor.getState()
|
const state = editor.getState()
|
||||||
const next = state
|
const next = state
|
||||||
.transform()
|
.transform()
|
||||||
.setNodeByKey(node.key, {
|
.setNodeByKey(node.key, {
|
||||||
data: {
|
data: {
|
||||||
language: e.target.value
|
language: e.target.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.apply()
|
.apply()
|
||||||
editor.onChange(next)
|
editor.onChange(next)
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ position: 'relative' }}>
|
|
||||||
<pre>
|
|
||||||
<code {...props.attributes}>{props.children}</code>
|
|
||||||
</pre>
|
|
||||||
<div
|
|
||||||
contentEditable={false}
|
|
||||||
style={{ position: 'absolute', top: '5px', right: '5px' }}
|
|
||||||
>
|
|
||||||
<select value={language} onChange={onChange} >
|
|
||||||
<option value="css">CSS</option>
|
|
||||||
<option value="js">JavaScript</option>
|
|
||||||
<option value="html">HTML</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: 'relative' }}>
|
||||||
|
<pre>
|
||||||
|
<code {...props.attributes}>{props.children}</code>
|
||||||
|
</pre>
|
||||||
|
<div
|
||||||
|
contentEditable={false}
|
||||||
|
style={{ position: 'absolute', top: '5px', right: '5px' }}
|
||||||
|
>
|
||||||
|
<select value={language} onChange={onChange} >
|
||||||
|
<option value="css">CSS</option>
|
||||||
|
<option value="js">JavaScript</option>
|
||||||
|
<option value="html">HTML</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a set of mark renderers.
|
* Define a schema.
|
||||||
*
|
*
|
||||||
* @type {Object}
|
* @type {Object}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const MARKS = {
|
const schema = {
|
||||||
'highlight-comment': {
|
nodes: {
|
||||||
opacity: '0.33'
|
code: CodeBlock
|
||||||
},
|
},
|
||||||
'highlight-keyword': {
|
marks: {
|
||||||
fontWeight: 'bold'
|
'highlight-comment': {
|
||||||
},
|
opacity: '0.33'
|
||||||
'highlight-punctuation': {
|
},
|
||||||
opacity: '0.75'
|
'highlight-keyword': {
|
||||||
|
fontWeight: 'bold'
|
||||||
|
},
|
||||||
|
'highlight-punctuation': {
|
||||||
|
opacity: '0.75'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,9 +129,8 @@ class CodeHighlighting extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div className="editor">
|
<div className="editor">
|
||||||
<Editor
|
<Editor
|
||||||
|
schema={schema}
|
||||||
state={this.state.state}
|
state={this.state.state}
|
||||||
renderNode={this.renderNode}
|
|
||||||
renderMark={this.renderMark}
|
|
||||||
renderDecorations={this.renderDecorations}
|
renderDecorations={this.renderDecorations}
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
@@ -136,28 +139,6 @@ 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] || {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render decorations on `text` nodes inside code blocks.
|
* Render decorations on `text` nodes inside code blocks.
|
||||||
*
|
*
|
||||||
|
@@ -291,34 +291,6 @@ class Editor extends React.Component {
|
|||||||
return text.characters
|
return text.characters
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Render a `mark`, cascading through the plugins.
|
|
||||||
*
|
|
||||||
* @param {Mark} mark
|
|
||||||
* @param {Set} marks
|
|
||||||
* @return {Component or Object or String}
|
|
||||||
*/
|
|
||||||
|
|
||||||
renderMark = (mark, marks) => {
|
|
||||||
for (const plugin of this.state.plugins) {
|
|
||||||
if (!plugin.renderMark) continue
|
|
||||||
let ret = plugin.renderMark(mark, marks, this.state.state, this)
|
|
||||||
|
|
||||||
// Handle React components that aren't stateless functions.
|
|
||||||
if (isReactComponent(ret)) return ret
|
|
||||||
|
|
||||||
// Handle all other types...
|
|
||||||
switch (typeOf(ret)) {
|
|
||||||
case 'function':
|
|
||||||
return ret
|
|
||||||
case 'object':
|
|
||||||
return props => <span style={ret}>{props.children}</span>
|
|
||||||
case 'string':
|
|
||||||
return props => <span className={ret}>{props.children}</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the editor's current plugins from `props` when they change.
|
* Resolve the editor's current plugins from `props` when they change.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user