From 0de23750c3fba5908844185e3dbe88f06a897989 Mon Sep 17 00:00:00 2001 From: Lakhan Baheti Date: Wed, 3 Sep 2025 20:12:59 +0530 Subject: [PATCH 1/4] chore: add collaborative document editor extended props --- .../ce/extensions/rich-text-extensions.tsx | 2 +- .../editor/src/ce/types/editor-extended.ts | 2 + .../src/core/extensions/trailing-node.ts | 64 +++++++++++++++++++ packages/editor/src/core/types/editor.ts | 3 +- packages/editor/src/index.ts | 3 + 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 packages/editor/src/core/extensions/trailing-node.ts diff --git a/packages/editor/src/ce/extensions/rich-text-extensions.tsx b/packages/editor/src/ce/extensions/rich-text-extensions.tsx index 520dfa10e87..7ade9e6187c 100644 --- a/packages/editor/src/ce/extensions/rich-text-extensions.tsx +++ b/packages/editor/src/ce/extensions/rich-text-extensions.tsx @@ -6,7 +6,7 @@ import { IEditorProps, TExtensions } from "@/types"; export type TRichTextEditorAdditionalExtensionsProps = Pick< IEditorProps, - "disabledExtensions" | "flaggedExtensions" | "fileHandler" + "disabledExtensions" | "flaggedExtensions" | "fileHandler" | "extendedEditorProps" >; /** diff --git a/packages/editor/src/ce/types/editor-extended.ts b/packages/editor/src/ce/types/editor-extended.ts index 98f9c7ece87..0c3868112cc 100644 --- a/packages/editor/src/ce/types/editor-extended.ts +++ b/packages/editor/src/ce/types/editor-extended.ts @@ -2,6 +2,8 @@ export type IEditorExtensionOptions = unknown; export type IEditorPropsExtended = unknown; +export type ICollaborativeDocumentEditorPropsExtended = unknown; + export type TExtendedEditorCommands = never; export type TExtendedCommandExtraProps = unknown; diff --git a/packages/editor/src/core/extensions/trailing-node.ts b/packages/editor/src/core/extensions/trailing-node.ts new file mode 100644 index 00000000000..d62ba13d93c --- /dev/null +++ b/packages/editor/src/core/extensions/trailing-node.ts @@ -0,0 +1,64 @@ +import { Extension } from "@tiptap/core"; +import { Plugin, PluginKey } from "@tiptap/pm/state"; + +function nodeEqualsType({ types, node }) { + return (Array.isArray(types) && types.includes(node.type)) || node.type === types; +} + +export interface TrailingNodeOptions { + node: string; + notAfter: string[]; +} + +export const TrailingNode = Extension.create({ + name: "trailingNode", + + addOptions() { + return { + node: "paragraph", + notAfter: ["paragraph"], + }; + }, + + addProseMirrorPlugins() { + const plugin = new PluginKey(this.name); + const disabledNodes = Object.entries(this.editor.schema.nodes) + .map(([, value]) => value) + .filter((node) => this.options.notAfter.includes(node.name)); + + return [ + new Plugin({ + key: plugin, + appendTransaction: (_, __, state) => { + const { doc, tr, schema } = state; + const shouldInsertNodeAtEnd = plugin.getState(state); + const endPosition = doc.content.size; + const type = schema.nodes[this.options.node]; + + if (!shouldInsertNodeAtEnd) { + return; + } + + // eslint-disable-next-line consistent-return + return tr.insert(endPosition, type.create()); + }, + state: { + init: (_, state) => { + const lastNode = state.tr.doc.lastChild; + + return !nodeEqualsType({ node: lastNode, types: disabledNodes }); + }, + apply: (tr, value) => { + if (!tr.docChanged) { + return value; + } + + const lastNode = tr.doc.lastChild; + + return !nodeEqualsType({ node: lastNode, types: disabledNodes }); + }, + }, + }), + ]; + }, +}); \ No newline at end of file diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index 33fb71f6c3a..5cc03a427f0 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -6,7 +6,7 @@ import type { NodeViewProps as TNodeViewProps } from "@tiptap/react"; // extension types import type { TTextAlign } from "@/extensions"; // plane editor imports -import type { IEditorPropsExtended, TExtendedEditorCommands } from "@/plane-editor/types/editor-extended"; +import type { IEditorPropsExtended, TExtendedEditorCommands, ICollaborativeDocumentEditorPropsExtended } from "@/plane-editor/types/editor-extended"; // types import type { IMarking, @@ -178,6 +178,7 @@ export type ICollaborativeDocumentEditorProps = Omit & { diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index 1872f35c726..d3483219bea 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -18,3 +18,6 @@ export { ADDITIONAL_EXTENSIONS } from "@/plane-editor/constants/extensions"; // types export * from "@/types"; + +// additional exports +export { TrailingNode } from "./core/extensions/trailing-node"; \ No newline at end of file From 9a2ece5feb04f9246f28e54aadfc9308dbb5a73d Mon Sep 17 00:00:00 2001 From: Lakhan Baheti Date: Thu, 4 Sep 2025 17:22:59 +0530 Subject: [PATCH 2/4] fix: additional rich text extension props --- .../editor/src/core/components/editors/rich-text/editor.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/editor/src/core/components/editors/rich-text/editor.tsx b/packages/editor/src/core/components/editors/rich-text/editor.tsx index 02c0db55d6c..f110c789b2b 100644 --- a/packages/editor/src/core/components/editors/rich-text/editor.tsx +++ b/packages/editor/src/core/components/editors/rich-text/editor.tsx @@ -17,6 +17,7 @@ const RichTextEditor: React.FC = (props) => { extensions: externalExtensions = [], fileHandler, flaggedExtensions, + extendedEditorProps, } = props; const getExtensions = useCallback(() => { @@ -30,11 +31,12 @@ const RichTextEditor: React.FC = (props) => { disabledExtensions, fileHandler, flaggedExtensions, + extendedEditorProps, }), ]; return extensions; - }, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler, flaggedExtensions]); + }, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler, flaggedExtensions, extendedEditorProps]); return ( From 2994e51c2a2e1296d4eb03cf7a2ad01294385532 Mon Sep 17 00:00:00 2001 From: Lakhan Baheti Date: Thu, 4 Sep 2025 17:46:46 +0530 Subject: [PATCH 3/4] fix: formatting --- packages/editor/src/core/extensions/trailing-node.ts | 2 +- packages/editor/src/core/types/editor.ts | 6 +++++- packages/editor/src/index.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/editor/src/core/extensions/trailing-node.ts b/packages/editor/src/core/extensions/trailing-node.ts index d62ba13d93c..34e0edf37e0 100644 --- a/packages/editor/src/core/extensions/trailing-node.ts +++ b/packages/editor/src/core/extensions/trailing-node.ts @@ -61,4 +61,4 @@ export const TrailingNode = Extension.create({ }), ]; }, -}); \ No newline at end of file +}); diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index 5cc03a427f0..8642dbadc34 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -6,7 +6,11 @@ import type { NodeViewProps as TNodeViewProps } from "@tiptap/react"; // extension types import type { TTextAlign } from "@/extensions"; // plane editor imports -import type { IEditorPropsExtended, TExtendedEditorCommands, ICollaborativeDocumentEditorPropsExtended } from "@/plane-editor/types/editor-extended"; +import type { + IEditorPropsExtended, + TExtendedEditorCommands, + ICollaborativeDocumentEditorPropsExtended, +} from "@/plane-editor/types/editor-extended"; // types import type { IMarking, diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index d3483219bea..3cf3b6fcef3 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -20,4 +20,4 @@ export { ADDITIONAL_EXTENSIONS } from "@/plane-editor/constants/extensions"; export * from "@/types"; // additional exports -export { TrailingNode } from "./core/extensions/trailing-node"; \ No newline at end of file +export { TrailingNode } from "./core/extensions/trailing-node"; From ef7d4302dc82d896db1376da2f54199e3c2aca25 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Wed, 10 Sep 2025 16:17:34 +0530 Subject: [PATCH 4/4] chore: add types to the trailing node extension --- .../editor/src/core/extensions/trailing-node.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/editor/src/core/extensions/trailing-node.ts b/packages/editor/src/core/extensions/trailing-node.ts index 34e0edf37e0..27e3e85ebfa 100644 --- a/packages/editor/src/core/extensions/trailing-node.ts +++ b/packages/editor/src/core/extensions/trailing-node.ts @@ -1,8 +1,13 @@ import { Extension } from "@tiptap/core"; +import { NodeType, Node as ProseMirrorNode } from "@tiptap/pm/model"; import { Plugin, PluginKey } from "@tiptap/pm/state"; +// constants +import { CORE_EXTENSIONS } from "@/constants/extension"; -function nodeEqualsType({ types, node }) { - return (Array.isArray(types) && types.includes(node.type)) || node.type === types; +function nodeEqualsType({ types, node }: { types: NodeType[]; node: ProseMirrorNode | null }) { + // TODO: check this logic, might be wrong + // @ts-expect-error - logic might be wrong + return (Array.isArray(types) && types.includes(node?.type)) || node?.type === types; } export interface TrailingNodeOptions { @@ -15,8 +20,8 @@ export const TrailingNode = Extension.create({ addOptions() { return { - node: "paragraph", - notAfter: ["paragraph"], + node: CORE_EXTENSIONS.PARAGRAPH, + notAfter: [CORE_EXTENSIONS.PARAGRAPH], }; },