mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-03-28 00:05:54 +00:00
129 lines
2.7 KiB
TypeScript
129 lines
2.7 KiB
TypeScript
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { createEditor} from 'slate';
|
|
import { withReact, Slate, Editable, RenderElementProps, RenderLeafProps } from 'slate-react';
|
|
|
|
type ExtendedRenderElementProps = RenderElementProps & { mode?: string }
|
|
|
|
export const renderElement = ({
|
|
attributes,
|
|
children,
|
|
element,
|
|
mode
|
|
}: ExtendedRenderElementProps) => {
|
|
switch (element.type) {
|
|
case 'block-quote':
|
|
return <blockquote {...attributes}>{children}</blockquote>
|
|
case 'heading-2':
|
|
return (
|
|
<h2
|
|
className="h2"
|
|
{...attributes}
|
|
style={{ textAlign: element.textAlign }}
|
|
>
|
|
{children}
|
|
</h2>
|
|
)
|
|
case 'heading-3':
|
|
return (
|
|
<h3
|
|
className="h3"
|
|
{...attributes}
|
|
style={{ textAlign: element.textAlign }}
|
|
>
|
|
{children}
|
|
</h3>
|
|
)
|
|
case 'code-block':
|
|
return (
|
|
<pre {...attributes} className="code-block">
|
|
<code>{children}</code>
|
|
</pre>
|
|
)
|
|
case 'code-line':
|
|
return <div {...attributes}>{children}</div>
|
|
case 'link':
|
|
return (
|
|
<a href={element.url} {...attributes}>
|
|
{children}
|
|
</a>
|
|
)
|
|
default:
|
|
return (
|
|
<p
|
|
className={`paragraph${mode ? `-${mode}` : ''}`}
|
|
{...attributes}
|
|
style={{ textAlign: element.textAlign }}
|
|
>
|
|
{children}
|
|
</p>
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
export const renderLeaf = ({ attributes, children, leaf }: RenderLeafProps) => {
|
|
let el = children
|
|
|
|
if (leaf.bold) {
|
|
el = <strong>{el}</strong>
|
|
}
|
|
|
|
if (leaf.italic) {
|
|
el = <em>{el}</em>
|
|
}
|
|
|
|
if (leaf.underline) {
|
|
el = <u>{el}</u>
|
|
}
|
|
|
|
if (leaf.link) {
|
|
el = (
|
|
<a href={leaf.link} {...attributes}>
|
|
{el}
|
|
</a>
|
|
)
|
|
}
|
|
|
|
return <span {...attributes}>{el}</span>
|
|
}
|
|
|
|
interface ReadOnlySlateProps {
|
|
content: any
|
|
mode?: string
|
|
}
|
|
const ReadOnlySlate: React.FC<ReadOnlySlateProps> = ({ content, mode }) => {
|
|
const [load, setLoad] = useState(false)
|
|
const editor = useMemo(() => withReact(createEditor()), [])
|
|
const value = useMemo(() => content, [content])
|
|
|
|
const performUpdate = useCallback(async()=> {
|
|
setLoad(true)
|
|
await new Promise<void>((res)=> {
|
|
setTimeout(() => {
|
|
res()
|
|
}, 250);
|
|
})
|
|
setLoad(false)
|
|
}, [])
|
|
useEffect(()=> {
|
|
|
|
|
|
|
|
|
|
performUpdate()
|
|
}, [value])
|
|
|
|
if(load) return null
|
|
|
|
return (
|
|
<Slate editor={editor} value={value} onChange={() => {}}>
|
|
<Editable
|
|
readOnly
|
|
renderElement={(props) => renderElement({ ...props, mode })}
|
|
renderLeaf={renderLeaf}
|
|
/>
|
|
</Slate>
|
|
)
|
|
}
|
|
|
|
export default ReadOnlySlate; |