1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-02-21 07:32:24 +01:00
slate/site/examples/ts/markdown-preview.tsx
Ravi Lamkoti 01dc30b81d
Add Javascript Examples Support (#5722)
* chore: moved all ts files for examples to examples/ts

* add: tsc to eject js and jsx output

* example: add js transpiled examples

* example: update example site to show both js and ts code

* chore: fix yarn lint

* fix(example): getAllExamplesPath
2024-09-26 00:24:11 -07:00

129 lines
3.2 KiB
TypeScript

import Prism from 'prismjs'
import 'prismjs/components/prism-markdown'
import React, { useCallback, useMemo } from 'react'
import { Slate, Editable, withReact } from 'slate-react'
import { Text, createEditor, Descendant } from 'slate'
import { withHistory } from 'slate-history'
import { css } from '@emotion/css'
const MarkdownPreviewExample = () => {
const renderLeaf = useCallback(props => <Leaf {...props} />, [])
const editor = useMemo(() => withHistory(withReact(createEditor())), [])
const decorate = useCallback(([node, path]) => {
const ranges = []
if (!Text.isText(node)) {
return ranges
}
const getLength = token => {
if (typeof token === 'string') {
return token.length
} else if (typeof token.content === 'string') {
return token.content.length
} else {
return token.content.reduce((l, t) => l + getLength(t), 0)
}
}
const tokens = Prism.tokenize(node.text, Prism.languages.markdown)
let start = 0
for (const token of tokens) {
const length = getLength(token)
const end = start + length
if (typeof token !== 'string') {
ranges.push({
[token.type]: true,
anchor: { path, offset: start },
focus: { path, offset: end },
})
}
start = end
}
return ranges
}, [])
return (
<Slate editor={editor} initialValue={initialValue}>
<Editable
decorate={decorate}
renderLeaf={renderLeaf}
placeholder="Write some markdown..."
/>
</Slate>
)
}
const Leaf = ({ attributes, children, leaf }) => {
return (
<span
{...attributes}
className={css`
font-weight: ${leaf.bold && 'bold'};
font-style: ${leaf.italic && 'italic'};
text-decoration: ${leaf.underlined && 'underline'};
${leaf.title &&
css`
display: inline-block;
font-weight: bold;
font-size: 20px;
margin: 20px 0 10px 0;
`}
${leaf.list &&
css`
padding-left: 10px;
font-size: 20px;
line-height: 10px;
`}
${leaf.hr &&
css`
display: block;
text-align: center;
border-bottom: 2px solid #ddd;
`}
${leaf.blockquote &&
css`
display: inline-block;
border-left: 2px solid #ddd;
padding-left: 10px;
color: #aaa;
font-style: italic;
`}
${leaf.code &&
css`
font-family: monospace;
background-color: #eee;
padding: 3px;
`}
`}
>
{children}
</span>
)
}
const initialValue: Descendant[] = [
{
type: 'paragraph',
children: [
{
text: 'Slate is flexible enough to add **decorations** that can format text based on its content. For example, this editor has **Markdown** preview decorations on it, to make it _dead_ simple to make an editor with built-in Markdown previewing.',
},
],
},
{
type: 'paragraph',
children: [{ text: '## Try it out!' }],
},
{
type: 'paragraph',
children: [{ text: 'Try it out for yourself!' }],
},
]
export default MarkdownPreviewExample