mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-02-23 00:32:31 +01:00
This PR adds better TypeScript types into Slate and is based on the proposal here: https://github.com/ianstormtaylor/slate/issues/3725 * Extend Slate's types like Element and Text * Supports type discrimination (ie. if an element has type === "table" then we get a reduced set of properties) * added custom types * files * more extensions * files * changed fixtures * changes eslint file * changed element.children to descendant * updated types * more type changes * changed a lot of typing, still getting building errors * extended text type in slate-react * removed type assertions * Clean up of custom types and a couple uneeded comments. * Rename headingElement-true.tsx.tsx to headingElement-true.tsx * moved basetext and baselement * Update packages/slate/src/interfaces/text.ts Co-authored-by: Brent Farese <25846953+BrentFarese@users.noreply.github.com> * Fix some type issues with core functions. * Clean up text and element files. * Convert other types to extended types. * Change the type of editor.marks to the appropriate type. * Add version 100.0.0 to package.json * Revert "Add version 100.0.0 to package.json" This reverts commit 329e44e43d968700655b1c46f968bfd3147e7339. * added custom types * files * more extensions * files * changed fixtures * changes eslint file * changed element.children to descendant * updated types * more type changes * changed a lot of typing, still getting building errors * extended text type in slate-react * removed type assertions * Clean up of custom types and a couple uneeded comments. * Rename headingElement-true.tsx.tsx to headingElement-true.tsx * moved basetext and baselement * Update packages/slate/src/interfaces/text.ts Co-authored-by: Brent Farese <25846953+BrentFarese@users.noreply.github.com> * Fix some type issues with core functions. * Clean up text and element files. * Convert other types to extended types. * Change the type of editor.marks to the appropriate type. * Run linter. * Remove key:string uknown from the base types. * Clean up types after removing key:string unknown. * Lint and prettier fixes. * Implement custom-types Co-authored-by: mdmjg <mdj308@nyu.edu> * added custom types to examples * reset yarn lock * added ts to fixtures * examples custom types * Working fix * ts-thesunny-try * Extract interface types. * Fix minor return type in create-editor. * Fix the typing issue with Location having compile time CustomTypes * Extract types for Transforms. * Update README. * Fix dependency on slate-history in slate-react Co-authored-by: mdmjg <mdj308@nyu.edu> Co-authored-by: Brent Farese <brentfarese@gmail.com> Co-authored-by: Brent Farese <25846953+BrentFarese@users.noreply.github.com> Co-authored-by: Tim Buckley <timothypbuckley@gmail.com>
126 lines
2.9 KiB
TypeScript
126 lines
2.9 KiB
TypeScript
import React, { useState, useMemo } from 'react'
|
|
import { Transforms, createEditor, Node, Element as SlateElement } from 'slate'
|
|
import {
|
|
Slate,
|
|
Editable,
|
|
withReact,
|
|
useSlateStatic,
|
|
ReactEditor,
|
|
useFocused,
|
|
useSelected,
|
|
} from 'slate-react'
|
|
|
|
const EmbedsExample = () => {
|
|
const [value, setValue] = useState<Node[]>(initialValue)
|
|
const editor = useMemo(() => withEmbeds(withReact(createEditor())), [])
|
|
return (
|
|
<Slate editor={editor} value={value} onChange={value => setValue(value)}>
|
|
<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(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 = [
|
|
{
|
|
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: '' }],
|
|
},
|
|
{
|
|
children: [
|
|
{
|
|
text:
|
|
'Try it out! This editor is built to handle Vimeo embeds, but you could handle any type.',
|
|
},
|
|
],
|
|
},
|
|
]
|
|
|
|
export default EmbedsExample
|