mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-03-14 18:29:43 +01:00
* fix: types for richtext.tsx * fix: types for check-lists, code-highlighting and custom placeholder * fix: types for editable-voids, embeds, forced-layout, hovering-toolbar * fix: types for remaining examples * fix: typescript error for files in image element * fix: types for examples and some minor fixes * fix: normalize-tokens.ts type * fix: types for [example].tsx
167 lines
3.6 KiB
TypeScript
167 lines
3.6 KiB
TypeScript
import { css } from '@emotion/css'
|
|
import React, { MouseEvent, useMemo, useState } from 'react'
|
|
import { createEditor, Descendant, Transforms } from 'slate'
|
|
import { withHistory } from 'slate-history'
|
|
import {
|
|
Editable,
|
|
RenderElementProps,
|
|
Slate,
|
|
useSlateStatic,
|
|
withReact,
|
|
} from 'slate-react'
|
|
|
|
import { Button, Icon, Toolbar } from './components'
|
|
import { CustomEditor, EditableVoidElement } from './custom-types.d'
|
|
import RichTextEditor from './richtext'
|
|
|
|
const EditableVoidsExample = () => {
|
|
const editor = useMemo(
|
|
() => withEditableVoids(withHistory(withReact(createEditor()))),
|
|
[]
|
|
)
|
|
|
|
return (
|
|
<Slate editor={editor} initialValue={initialValue}>
|
|
<Toolbar>
|
|
<InsertEditableVoidButton />
|
|
</Toolbar>
|
|
|
|
<Editable
|
|
renderElement={props => <Element {...props} />}
|
|
placeholder="Enter some text..."
|
|
/>
|
|
</Slate>
|
|
)
|
|
}
|
|
|
|
const withEditableVoids = (editor: CustomEditor) => {
|
|
const { isVoid } = editor
|
|
|
|
editor.isVoid = element => {
|
|
return element.type === 'editable-void' ? true : isVoid(element)
|
|
}
|
|
|
|
return editor
|
|
}
|
|
|
|
const insertEditableVoid = (editor: CustomEditor) => {
|
|
const text = { text: '' }
|
|
const voidNode: EditableVoidElement = {
|
|
type: 'editable-void',
|
|
children: [text],
|
|
}
|
|
Transforms.insertNodes(editor, voidNode)
|
|
}
|
|
|
|
const Element = (props: RenderElementProps) => {
|
|
const { attributes, children, element } = props
|
|
|
|
switch (element.type) {
|
|
case 'editable-void':
|
|
return <EditableVoid {...props} />
|
|
default:
|
|
return <p {...attributes}>{children}</p>
|
|
}
|
|
}
|
|
|
|
const unsetWidthStyle = css`
|
|
width: unset;
|
|
`
|
|
|
|
const EditableVoid = ({
|
|
attributes,
|
|
children,
|
|
element,
|
|
}: RenderElementProps) => {
|
|
const [inputValue, setInputValue] = useState('')
|
|
|
|
return (
|
|
// Need contentEditable=false or Firefox has issues with certain input types.
|
|
<div {...attributes} contentEditable={false}>
|
|
<div
|
|
className={css`
|
|
box-shadow: 0 0 0 3px #ddd;
|
|
padding: 8px;
|
|
`}
|
|
>
|
|
<h4>Name:</h4>
|
|
<input
|
|
className={css`
|
|
margin: 8px 0;
|
|
`}
|
|
type="text"
|
|
value={inputValue}
|
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setInputValue(e.target.value)
|
|
}}
|
|
/>
|
|
<h4>Left or right handed:</h4>
|
|
<input
|
|
className={unsetWidthStyle}
|
|
type="radio"
|
|
name="handedness"
|
|
value="left"
|
|
/>{' '}
|
|
Left
|
|
<br />
|
|
<input
|
|
className={unsetWidthStyle}
|
|
type="radio"
|
|
name="handedness"
|
|
value="right"
|
|
/>{' '}
|
|
Right
|
|
<h4>Tell us about yourself:</h4>
|
|
<div
|
|
className={css`
|
|
padding: 20px;
|
|
border: 2px solid #ddd;
|
|
`}
|
|
>
|
|
<RichTextEditor />
|
|
</div>
|
|
</div>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const InsertEditableVoidButton = () => {
|
|
const editor = useSlateStatic()
|
|
return (
|
|
<Button
|
|
onMouseDown={(event: MouseEvent<HTMLSpanElement>) => {
|
|
event.preventDefault()
|
|
insertEditableVoid(editor)
|
|
}}
|
|
>
|
|
<Icon>add</Icon>
|
|
</Button>
|
|
)
|
|
}
|
|
|
|
const initialValue: Descendant[] = [
|
|
{
|
|
type: 'paragraph',
|
|
children: [
|
|
{
|
|
text: 'In addition to nodes that contain editable text, you can insert void nodes, which can also contain editable elements, inputs, or an entire other Slate editor.',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'editable-void',
|
|
children: [{ text: '' }],
|
|
},
|
|
{
|
|
type: 'paragraph',
|
|
children: [
|
|
{
|
|
text: '',
|
|
},
|
|
],
|
|
},
|
|
]
|
|
|
|
export default EditableVoidsExample
|