2023-04-26 02:37:29 +00:00
|
|
|
import { createSignal, Show } from 'solid-js'
|
|
|
|
import type { Editor } from '@tiptap/core'
|
|
|
|
import { Icon } from '../_shared/Icon'
|
|
|
|
import { InlineForm } from './InlineForm'
|
|
|
|
import styles from './EditorFloatingMenu.module.scss'
|
|
|
|
import HTMLParser from 'html-to-json-parser'
|
|
|
|
|
|
|
|
type FloatingMenuProps = {
|
|
|
|
editor: Editor
|
|
|
|
ref: (el: HTMLDivElement) => void
|
|
|
|
}
|
|
|
|
|
|
|
|
const embedData = async (data) => {
|
|
|
|
const result = await HTMLParser(data, false)
|
2023-05-01 18:32:32 +00:00
|
|
|
|
|
|
|
if (typeof result === 'string') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-04-26 02:37:29 +00:00
|
|
|
if (result && 'type' in result && result.type === 'iframe') {
|
|
|
|
return result.attributes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-01 18:32:32 +00:00
|
|
|
const validateEmbed = async (value: string): Promise<string> => {
|
|
|
|
const iframeData = await HTMLParser(value, false)
|
|
|
|
|
|
|
|
if (typeof iframeData === 'string') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iframeData && iframeData.type !== 'iframe') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-26 02:37:29 +00:00
|
|
|
export const EditorFloatingMenu = (props: FloatingMenuProps) => {
|
|
|
|
const [inlineEditorOpen, setInlineEditorOpen] = createSignal<boolean>(false)
|
|
|
|
|
|
|
|
const handleEmbedFormSubmit = async (value: string) => {
|
|
|
|
// TODO: add support instagram embed (blockquote)
|
2023-05-01 18:32:32 +00:00
|
|
|
const { src } = (await embedData(value)) as { src: string }
|
|
|
|
props.editor.chain().focus().setIframe({ src }).run()
|
2023-04-26 02:37:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div ref={props.ref} class={styles.editorFloatingMenu}>
|
|
|
|
<button type="button" onClick={() => setInlineEditorOpen(true)}>
|
|
|
|
<Icon name="editor-plus" />
|
|
|
|
</button>
|
|
|
|
<Show when={inlineEditorOpen()}>
|
|
|
|
<InlineForm
|
|
|
|
variant="inFloating"
|
|
|
|
onClose={() => setInlineEditorOpen(false)}
|
|
|
|
validate={validateEmbed}
|
|
|
|
onSubmit={handleEmbedFormSubmit}
|
|
|
|
/>
|
|
|
|
</Show>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|