[WIKI-632] chore: accept additional props for document collaborative editor (#7718)
* chore: add collaborative document editor extended props * fix: additional rich text extension props * fix: formatting * chore: add types to the trailing node extension --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
This commit is contained in:
parent
0f7bfdde91
commit
11cd8d11e4
6 changed files with 84 additions and 3 deletions
|
|
@ -6,7 +6,7 @@ import { IEditorProps, TExtensions } from "@/types";
|
|||
|
||||
export type TRichTextEditorAdditionalExtensionsProps = Pick<
|
||||
IEditorProps,
|
||||
"disabledExtensions" | "flaggedExtensions" | "fileHandler"
|
||||
"disabledExtensions" | "flaggedExtensions" | "fileHandler" | "extendedEditorProps"
|
||||
>;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ export type IEditorExtensionOptions = unknown;
|
|||
|
||||
export type IEditorPropsExtended = unknown;
|
||||
|
||||
export type ICollaborativeDocumentEditorPropsExtended = unknown;
|
||||
|
||||
export type TExtendedEditorCommands = never;
|
||||
|
||||
export type TExtendedCommandExtraProps = unknown;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const RichTextEditor: React.FC<IRichTextEditorProps> = (props) => {
|
|||
extensions: externalExtensions = [],
|
||||
fileHandler,
|
||||
flaggedExtensions,
|
||||
extendedEditorProps,
|
||||
} = props;
|
||||
|
||||
const getExtensions = useCallback(() => {
|
||||
|
|
@ -30,11 +31,12 @@ const RichTextEditor: React.FC<IRichTextEditorProps> = (props) => {
|
|||
disabledExtensions,
|
||||
fileHandler,
|
||||
flaggedExtensions,
|
||||
extendedEditorProps,
|
||||
}),
|
||||
];
|
||||
|
||||
return extensions;
|
||||
}, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler, flaggedExtensions]);
|
||||
}, [dragDropEnabled, disabledExtensions, externalExtensions, fileHandler, flaggedExtensions, extendedEditorProps]);
|
||||
|
||||
return (
|
||||
<EditorWrapper {...props} extensions={getExtensions()}>
|
||||
|
|
|
|||
69
packages/editor/src/core/extensions/trailing-node.ts
Normal file
69
packages/editor/src/core/extensions/trailing-node.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
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 }: { 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 {
|
||||
node: string;
|
||||
notAfter: string[];
|
||||
}
|
||||
|
||||
export const TrailingNode = Extension.create<TrailingNodeOptions>({
|
||||
name: "trailingNode",
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
node: CORE_EXTENSIONS.PARAGRAPH,
|
||||
notAfter: [CORE_EXTENSIONS.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 });
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
},
|
||||
});
|
||||
|
|
@ -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 } from "@/plane-editor/types/editor-extended";
|
||||
import type {
|
||||
IEditorPropsExtended,
|
||||
TExtendedEditorCommands,
|
||||
ICollaborativeDocumentEditorPropsExtended,
|
||||
} from "@/plane-editor/types/editor-extended";
|
||||
// types
|
||||
import type {
|
||||
IMarking,
|
||||
|
|
@ -176,6 +180,7 @@ export type ICollaborativeDocumentEditorProps = Omit<IEditorProps, "initialValue
|
|||
realtimeConfig: TRealtimeConfig;
|
||||
serverHandler?: TServerHandler;
|
||||
user: TUserDetails;
|
||||
extendedDocumentEditorProps?: ICollaborativeDocumentEditorPropsExtended;
|
||||
};
|
||||
|
||||
export type IDocumentEditorProps = Omit<IEditorProps, "initialValue" | "onEnterKeyPress" | "value"> & {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue