From 96f9769e3637f3dee54a7eb35f91da0c942997f9 Mon Sep 17 00:00:00 2001 From: Darginec05 Date: Sun, 31 Mar 2024 16:33:59 +0200 Subject: [PATCH] added custom plugin example --- packages/development/next-env.d.ts | 5 ++ web/src/examples/withCustomPlugin.tsx | 82 ++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 packages/development/next-env.d.ts diff --git a/packages/development/next-env.d.ts b/packages/development/next-env.d.ts new file mode 100644 index 000000000..4f11a03dc --- /dev/null +++ b/packages/development/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/web/src/examples/withCustomPlugin.tsx b/web/src/examples/withCustomPlugin.tsx index 5c22445ee..b94f60759 100644 --- a/web/src/examples/withCustomPlugin.tsx +++ b/web/src/examples/withCustomPlugin.tsx @@ -1,6 +1,11 @@ // import { Inter } from 'next/font/google'; -import { useState } from 'react'; -import YooptaEditor, { generateId } from '@yoopta/editor'; +import { CSSProperties, ReactNode, useState } from 'react'; +import YooptaEditor, { + createYooptaPlugin, + generateId, + YooptaBaseElement, + RenderYooptaElementProps, +} from '@yoopta/editor'; import Paragraph from '@yoopta/paragraph'; import Blockquote from '@yoopta/blockquote'; @@ -17,8 +22,78 @@ import { HeadingOne, HeadingThree, HeadingTwo } from '@yoopta/headings'; import ActionMenu from '@yoopta/action-menu-list'; import { uploadToCloudinary } from '@/utils/cloudinary'; import Toolbar from '@yoopta/toolbar'; -import { yooptaInitData, YooptaValue } from '@/utils/initialData'; +import { YooptaValue } from '@/utils/initialData'; import { AccordionPlugin } from '@/components/CustomAccordeonPlugin/CustomAccordeonPlugin'; +import { Transforms } from 'slate'; + +/** Custom plugin */ +export type DividerElement = YooptaBaseElement<'divider'>; + +type DividerRenderProps = RenderYooptaElementProps; + +const dividerRootStyles: CSSProperties = { + display: 'flex', + width: '100%', + alignItems: 'center', + position: 'relative', +}; + +const dividerStyles: CSSProperties = { + position: 'absolute', + width: '100%', +}; + +const DividerRender = ({ attributes, element, children, HTMLAttributes }: DividerRenderProps) => { + return ( +
+
+ {children} +
+ ); +}; + +const Divider = createYooptaPlugin({ + type: 'divider', + shortcut: ['---', 'divider'], + renderer: () => DividerRender, + extendEditor(editor) { + const { isVoid } = editor; + + editor.isVoid = (element) => { + return element.type === Divider.getPlugin.type ? true : isVoid(element); + }; + + return editor; + }, + defineElement: (): DividerElement => ({ + id: generateId(), + type: 'divider', + nodeType: 'void', + children: [{ text: '' }], + }), + createElement: (editor, elementData) => { + const node: DividerElement = { ...Divider.getPlugin.defineElement(), ...elementData }; + + Transforms.setNodes(editor, node, { + at: editor.selection?.anchor, + }); + }, + exports: { + html: { + serialize: (node, children) => { + return `
`; + }, + deserialize: { + nodeName: 'HR', + }, + }, + }, + options: { + searchString: 'divider', + displayLabel: 'Divider', + }, +}); +/** */ const plugins = [ AccordionPlugin, @@ -33,6 +108,7 @@ const plugins = [ NumberedList, BulletedList, TodoList, + Divider, Embed.extend({ options: { maxWidth: 650,