import React, { useMemo, useState } from 'react' import imageExtensions from 'image-extensions' import isUrl from 'is-url' import { Transforms, createEditor, Descendant } from 'slate' import { Editable, Slate, useFocused, useSelected, useSlateStatic, withReact, } from 'slate-react' import { withHistory } from 'slate-history' import { css } from 'emotion' import { Button, Icon, Toolbar } from '../components' import { ImageElement } from './custom-types' const ImagesExample = () => { const [value, setValue] = useState(initialValue) const editor = useMemo( () => withImages(withHistory(withReact(createEditor()))), [] ) return ( setValue(value)}> } placeholder="Enter some text..." /> ) } const withImages = editor => { const { insertData, isVoid } = editor editor.isVoid = element => { return element.type === 'image' ? true : isVoid(element) } editor.insertData = data => { const text = data.getData('text/plain') const { files } = data if (files && files.length > 0) { for (const file of files) { const reader = new FileReader() const [mime] = file.type.split('/') if (mime === 'image') { reader.addEventListener('load', () => { const url = reader.result insertImage(editor, url) }) reader.readAsDataURL(file) } } } else if (isImageUrl(text)) { insertImage(editor, text) } else { insertData(data) } } return editor } const insertImage = (editor, url) => { const text = { text: '' } const image: ImageElement = { type: 'image', url, children: [text] } Transforms.insertNodes(editor, image) } const Element = props => { const { attributes, children, element } = props switch (element.type) { case 'image': return default: return

{children}

} } const Image = ({ attributes, children, element }) => { const selected = useSelected() const focused = useFocused() return (
{children}
) } const InsertImageButton = () => { const editor = useSlateStatic() return ( ) } const isImageUrl = url => { if (!url) return false if (!isUrl(url)) return false const ext = new URL(url).pathname.split('.').pop() return imageExtensions.includes(ext) } const initialValue: Descendant[] = [ { type: 'paragraph', children: [ { text: 'In addition to nodes that contain editable text, you can also create other types of nodes, like images or videos.', }, ], }, { type: 'image', url: 'https://source.unsplash.com/kFrdX5IeQzI', children: [{ text: '' }], }, { type: 'paragraph', children: [ { 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 clipboard and paste it anywhere in the editor!', }, ], }, ] export default ImagesExample