1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-02-22 08:02:25 +01:00
slate/site/examples/embeds.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

130 lines
2.9 KiB
TypeScript

import React, { useMemo } from 'react'
import {
Transforms,
createEditor,
Element as SlateElement,
Descendant,
} from 'slate'
import {
Slate,
Editable,
withReact,
useSlateStatic,
ReactEditor,
} from 'slate-react'
const EmbedsExample = () => {
const editor = useMemo(() => withEmbeds(withReact(createEditor())), [])
return (
<Slate editor={editor} initialValue={initialValue}>
<Editable
renderElement={props => <Element {...props} />}
placeholder="Enter some text..."
/>
</Slate>
)
}
const withEmbeds = editor => {
const { isVoid } = editor
editor.isVoid = element => (element.type === 'video' ? true : isVoid(element))
return editor
}
const Element = props => {
const { attributes, children, element } = props
switch (element.type) {
case 'video':
return <VideoElement {...props} />
default:
return <p {...attributes}>{children}</p>
}
}
const VideoElement = ({ attributes, children, element }) => {
const editor = useSlateStatic()
const { url } = element
return (
<div {...attributes}>
<div contentEditable={false}>
<div
style={{
padding: '75% 0 0 0',
position: 'relative',
}}
>
<iframe
src={`${url}?title=0&byline=0&portrait=0`}
frameBorder="0"
style={{
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
}}
/>
</div>
<UrlInput
url={url}
onChange={val => {
const path = ReactEditor.findPath(editor, element)
const newProperties: Partial<SlateElement> = {
url: val,
}
Transforms.setNodes<SlateElement>(editor, newProperties, {
at: path,
})
}}
/>
</div>
{children}
</div>
)
}
const UrlInput = ({ url, onChange }) => {
const [value, setValue] = React.useState(url)
return (
<input
value={value}
onClick={e => e.stopPropagation()}
style={{
marginTop: '5px',
boxSizing: 'border-box',
}}
onChange={e => {
const newUrl = e.target.value
setValue(newUrl)
onChange(newUrl)
}}
/>
)
}
const initialValue: Descendant[] = [
{
type: 'paragraph',
children: [
{
text: 'In addition to simple image nodes, you can actually create complex embedded nodes. For example, this one contains an input element that lets you change the video being rendered!',
},
],
},
{
type: 'video',
url: 'https://player.vimeo.com/video/26689853',
children: [{ text: '' }],
},
{
type: 'paragraph',
children: [
{
text: 'Try it out! This editor is built to handle Vimeo embeds, but you could handle any type.',
},
],
},
]
export default EmbedsExample