mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-02 19:52:32 +02:00
add start of image example
This commit is contained in:
172
examples/images/index.js
Normal file
172
examples/images/index.js
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
import Editor, { Mark, Raw } from '../..'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import state from './state.json'
|
||||
import { Map } from 'immutable'
|
||||
|
||||
/**
|
||||
* The images example.
|
||||
*
|
||||
* @type {Component} Images
|
||||
*/
|
||||
|
||||
class Images extends React.Component {
|
||||
|
||||
state = {
|
||||
state: Raw.deserialize(state)
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert an image with `src` at the current selection.
|
||||
*
|
||||
* @param {String} src
|
||||
*/
|
||||
|
||||
insertImage(src) {
|
||||
let { state } = this.state
|
||||
|
||||
if (state.isExpanded) {
|
||||
state = state
|
||||
.transform()
|
||||
.delete()
|
||||
.apply()
|
||||
}
|
||||
|
||||
const { anchorBlock, selection } = state
|
||||
|
||||
if (anchorBlock.text == '') {
|
||||
state = state
|
||||
.transform()
|
||||
.setBlock('image', { src })
|
||||
.apply()
|
||||
}
|
||||
|
||||
else if (selection.isAtEndOf(anchorBlock)) {
|
||||
state = state
|
||||
.transform()
|
||||
.splitBlock()
|
||||
.setBlock('image', { src })
|
||||
.apply()
|
||||
}
|
||||
|
||||
else if (selection.isAtStartOf(anchorBlock)) {
|
||||
state = state
|
||||
.transform()
|
||||
.splitBlock()
|
||||
.moveToStartOfPreviousBlock()
|
||||
.setBlock('image', { src })
|
||||
.apply()
|
||||
}
|
||||
|
||||
else {
|
||||
state = state
|
||||
.transform()
|
||||
.splitBlock()
|
||||
.splitBlock()
|
||||
.moveToStartOfPreviousBlock()
|
||||
.setBlock('image', { src })
|
||||
.apply()
|
||||
}
|
||||
|
||||
this.setState({ state })
|
||||
}
|
||||
|
||||
/**
|
||||
* On clicking the image button, prompt for an image and insert it.
|
||||
*
|
||||
* @param {Event} e
|
||||
*/
|
||||
|
||||
onClickImage(e) {
|
||||
e.preventDefault()
|
||||
const src = window.prompt('Enter the URL of the image:')
|
||||
if (!src) return
|
||||
this.insertImage(src)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the app.
|
||||
*
|
||||
* @return {Element} element
|
||||
*/
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{this.renderToolbar()}
|
||||
{this.renderEditor()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the toolbar.
|
||||
*
|
||||
* @return {Element} element
|
||||
*/
|
||||
|
||||
renderToolbar() {
|
||||
return (
|
||||
<div className="menu toolbar-menu">
|
||||
<span className="button" onMouseDown={e => this.onClickImage(e)}>
|
||||
<span className="material-icons">image</span>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the editor.
|
||||
*
|
||||
* @return {Element} element
|
||||
*/
|
||||
|
||||
renderEditor() {
|
||||
return (
|
||||
<div className="editor">
|
||||
<Editor
|
||||
state={this.state.state}
|
||||
renderNode={node => this.renderNode(node)}
|
||||
onChange={(state) => {
|
||||
console.groupCollapsed('Change!')
|
||||
console.log('Document:', state.document.toJS())
|
||||
console.log('Selection:', state.selection.toJS())
|
||||
console.log('Content:', Raw.serialize(state))
|
||||
console.groupEnd()
|
||||
this.setState({ state })
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render our custom `node`.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @return {Element} element
|
||||
*/
|
||||
|
||||
renderNode(node) {
|
||||
switch (node.type) {
|
||||
case 'image': {
|
||||
return (props) => {
|
||||
const { data } = props.node
|
||||
const src = data.get('src')
|
||||
return <img src={src} />
|
||||
}
|
||||
}
|
||||
case 'paragraph': {
|
||||
return (props) => <p>{props.children}</p>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*/
|
||||
|
||||
export default Images
|
49
examples/images/state.json
Normal file
49
examples/images/state.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "paragraph",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "In addition to nodes that contain editable text, you can also create other types of nodes, like images or videos."
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "image",
|
||||
"data": {
|
||||
"src": "https://img.washingtonpost.com/wp-apps/imrs.php?src=https://img.washingtonpost.com/news/speaking-of-science/wp-content/uploads/sites/36/2015/10/as12-49-7278-1024x1024.jpg&w=1484"
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "block",
|
||||
"type": "paragraph",
|
||||
"nodes": [
|
||||
{
|
||||
"kind": "text",
|
||||
"ranges": [
|
||||
{
|
||||
"text": "This example shows images in action. It features two ways to add images. You can either add an image via the toolbar icon above, or if you want in on a little secret, copy an image URL to your keyboard and paste it anywhere in the editor!"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user