mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
Test video embed on the text editor
This commit is contained in:
parent
fbbd641655
commit
98361707da
@ -9,6 +9,7 @@ import Placeholder from '@tiptap/extension-placeholder';
|
|||||||
import CharacterCount from '@tiptap/extension-character-count';
|
import CharacterCount from '@tiptap/extension-character-count';
|
||||||
import Underline from '@tiptap/extension-underline';
|
import Underline from '@tiptap/extension-underline';
|
||||||
import Link from '@tiptap/extension-link';
|
import Link from '@tiptap/extension-link';
|
||||||
|
import Iframe from './iframe';
|
||||||
import { MenuBar } from './menu-bar';
|
import { MenuBar } from './menu-bar';
|
||||||
import { WarningOctagon } from 'phosphor-react';
|
import { WarningOctagon } from 'phosphor-react';
|
||||||
|
|
||||||
@ -51,7 +52,8 @@ export const FabTextEditor: React.FC<FabTextEditorProps> = ({ label, paragraphTo
|
|||||||
}),
|
}),
|
||||||
CharacterCount.configure({
|
CharacterCount.configure({
|
||||||
limit
|
limit
|
||||||
})
|
}),
|
||||||
|
Iframe
|
||||||
],
|
],
|
||||||
content,
|
content,
|
||||||
onUpdate: ({ editor }) => {
|
onUpdate: ({ editor }) => {
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
import { Node } from '@tiptap/core';
|
||||||
|
|
||||||
|
export interface IframeOptions {
|
||||||
|
allowFullscreen: boolean,
|
||||||
|
HTMLAttributes: {
|
||||||
|
[key: string]: any
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@tiptap/core' {
|
||||||
|
interface Commands<ReturnType> {
|
||||||
|
iframe: {
|
||||||
|
/**
|
||||||
|
* Add an iframe to embed a video
|
||||||
|
*/
|
||||||
|
setIframe: (options: { src: string }) => ReturnType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Node.create<IframeOptions>({
|
||||||
|
name: 'iframe',
|
||||||
|
|
||||||
|
group: 'block',
|
||||||
|
|
||||||
|
atom: true,
|
||||||
|
|
||||||
|
addOptions () {
|
||||||
|
return {
|
||||||
|
allowFullscreen: true,
|
||||||
|
HTMLAttributes: {
|
||||||
|
class: 'fab-textEditor-video'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
addAttributes () {
|
||||||
|
return {
|
||||||
|
src: {
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
frameborder: {
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
allowfullscreen: {
|
||||||
|
default: this.options.allowFullscreen,
|
||||||
|
parseHTML: () => this.options.allowFullscreen
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
parseHTML () {
|
||||||
|
return [{
|
||||||
|
tag: 'iframe'
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHTML ({ HTMLAttributes }) {
|
||||||
|
return ['div', this.options.HTMLAttributes, ['iframe', HTMLAttributes]];
|
||||||
|
},
|
||||||
|
|
||||||
|
addCommands () {
|
||||||
|
return {
|
||||||
|
setIframe: (options: { src: string }) => ({ tr, dispatch }) => {
|
||||||
|
const { selection } = tr;
|
||||||
|
const node = this.type.create(options);
|
||||||
|
|
||||||
|
if (dispatch) {
|
||||||
|
tr.replaceRangeWith(selection.from, selection.to, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
@ -2,17 +2,18 @@ import React, { useCallback, useState, useEffect } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import useOnclickOutside from 'react-cool-onclickoutside';
|
import useOnclickOutside from 'react-cool-onclickoutside';
|
||||||
import { Editor } from '@tiptap/react';
|
import { Editor } from '@tiptap/react';
|
||||||
import { TextAa, TextBolder, TextItalic, TextUnderline, LinkSimpleHorizontal, ListBullets, Quotes, Trash, CheckCircle } from 'phosphor-react';
|
import { TextAa, TextBolder, TextItalic, TextUnderline, LinkSimpleHorizontal, ListBullets, Quotes, Trash, CheckCircle, VideoCamera } from 'phosphor-react';
|
||||||
|
|
||||||
interface MenuBarProps {
|
interface MenuBarProps {
|
||||||
paragraphTools?: boolean,
|
paragraphTools?: boolean,
|
||||||
|
extra?: boolean,
|
||||||
editor?: Editor,
|
editor?: Editor,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component is the menu bar for the WYSIWYG text editor
|
* This component is the menu bar for the WYSIWYG text editor
|
||||||
*/
|
*/
|
||||||
export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools }) => {
|
export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools, extra }) => {
|
||||||
const { t } = useTranslation('shared');
|
const { t } = useTranslation('shared');
|
||||||
|
|
||||||
const [linkMenu, setLinkMenu] = useState<boolean>(false);
|
const [linkMenu, setLinkMenu] = useState<boolean>(false);
|
||||||
@ -83,6 +84,11 @@ export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools }) => {
|
|||||||
setLinkMenu(false);
|
setLinkMenu(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add iFrame
|
||||||
|
const addIframe = () => {
|
||||||
|
editor.chain().focus().setIframe({ src: 'https://www.youtube.com/embed/XIMLoLxmTDw' }).run();
|
||||||
|
};
|
||||||
|
|
||||||
if (!editor) {
|
if (!editor) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -144,6 +150,16 @@ export const MenuBar: React.FC<MenuBarProps> = ({ editor, paragraphTools }) => {
|
|||||||
>
|
>
|
||||||
<LinkSimpleHorizontal size={24} />
|
<LinkSimpleHorizontal size={24} />
|
||||||
</button>
|
</button>
|
||||||
|
{ extra &&
|
||||||
|
(<>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
onClick={() => addIframe()}
|
||||||
|
>
|
||||||
|
<VideoCamera size={24} />
|
||||||
|
</button>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div ref={ref} className={`fab-textEditor-linkMenu ${linkMenu ? 'is-active' : ''}`}>
|
<div ref={ref} className={`fab-textEditor-linkMenu ${linkMenu ? 'is-active' : ''}`}>
|
||||||
<div className="url">
|
<div className="url">
|
||||||
|
@ -144,6 +144,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-video {
|
||||||
|
position: relative;
|
||||||
|
height: 0;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
padding-bottom: calc(100 / 16 * 9);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
&-error {
|
&-error {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 4.5rem;
|
top: 4.5rem;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user