1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-02-21 23:53:50 +01:00
slate/site/examples/editable-voids.tsx
Dylan Schiemann c4c14882ed
Update dependencies to React 18, Node 20, TS 5.2, etc. (#5528)
* incremental upgrade to React 18, TS 4.9, etc.

* update yarn config

* fix build

* minor cleanup in type definitions

* incremental updates for TS 5.0

* fix build

* upgrade to typescript 5.2

* update dependencies

* fix lint issues

* update to latest Playwright version

* update changesets dep

* update emotion/css

* incremental dependency updates

* more small dependency updates

* upgrade prettier and eslint

* fix lint issues

* update dependencies rollup

* fix @types/node resolution to restore linting

* update tiny-invariant dependency

* update dependencies

* update dependencies lerna

* upgrade react-router-dom

* update @types/react and @types/node

* update babel dependencies

* udpate simple-git-hooks

* update @types/node resolution

* update lint-staged

* remove cypress from dependency list

* update @types/node to support Node 20

* update workflows to Node 20

* set resolutions for @types/react

* downgrade @types/react to 18.2.28

* update mocha

* update rimraf

* update @types/js-dom

* remove .lintstagedrc.js

* upgrade next to latest

* v0.61.4

* update lerna

* update faker and rollup

* update immer

* fix yarn clean command

* attempt to fix integration tests

* attempt to stabilize integration tests

* wip fix integration tests

* skip unstable integration test

* Add changeset

---------

Co-authored-by: Dalibor Tosic <dalibortosic00@gmail.com>
Co-authored-by: Nikola <nikolabijelic14@gmail.com>
2023-10-20 08:34:24 -07:00

157 lines
3.4 KiB
TypeScript

import React, { useState, useMemo } from 'react'
import { Transforms, createEditor, Descendant } from 'slate'
import { Slate, Editable, useSlateStatic, withReact } from 'slate-react'
import { withHistory } from 'slate-history'
import { css } from '@emotion/css'
import RichTextEditor from './richtext'
import { Button, Icon, Toolbar } from '../components'
import { EditableVoidElement } from './custom-types.d'
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 => {
const { isVoid } = editor
editor.isVoid = element => {
return element.type === 'editable-void' ? true : isVoid(element)
}
return editor
}
const insertEditableVoid = editor => {
const text = { text: '' }
const voidNode: EditableVoidElement = {
type: 'editable-void',
children: [text],
}
Transforms.insertNodes(editor, voidNode)
}
const Element = props => {
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 }) => {
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 => {
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 => {
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