forked from github/plane
[WEB-372] fix: horizontal rule extension now always divider adds below nodes (#3890)
* fix: horizontal rule extension now always divider adds below nodes * chore: removing duplicate horizontal rule extension
This commit is contained in:
parent
3d09a69d58
commit
cace132a2a
@ -0,0 +1,111 @@
|
|||||||
|
import { isNodeSelection, mergeAttributes, Node, nodeInputRule } from "@tiptap/core";
|
||||||
|
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
||||||
|
|
||||||
|
export interface HorizontalRuleOptions {
|
||||||
|
HTMLAttributes: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@tiptap/core" {
|
||||||
|
interface Commands<ReturnType> {
|
||||||
|
horizontalRule: {
|
||||||
|
/**
|
||||||
|
* Add a horizontal rule
|
||||||
|
*/
|
||||||
|
setHorizontalRule: () => ReturnType;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CustomHorizontalRule = Node.create<HorizontalRuleOptions>({
|
||||||
|
name: "horizontalRule",
|
||||||
|
|
||||||
|
addOptions() {
|
||||||
|
return {
|
||||||
|
HTMLAttributes: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
group: "block",
|
||||||
|
|
||||||
|
parseHTML() {
|
||||||
|
return [{ tag: "hr" }];
|
||||||
|
},
|
||||||
|
|
||||||
|
renderHTML({ HTMLAttributes }) {
|
||||||
|
return ["hr", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
|
||||||
|
},
|
||||||
|
|
||||||
|
addCommands() {
|
||||||
|
return {
|
||||||
|
setHorizontalRule:
|
||||||
|
() =>
|
||||||
|
({ chain, state }) => {
|
||||||
|
const { selection } = state;
|
||||||
|
const { $from: $originFrom, $to: $originTo } = selection;
|
||||||
|
|
||||||
|
const currentChain = chain();
|
||||||
|
|
||||||
|
if ($originFrom.parentOffset === 0) {
|
||||||
|
currentChain.insertContentAt(
|
||||||
|
{
|
||||||
|
from: Math.max($originFrom.pos - 1, 0),
|
||||||
|
to: $originTo.pos,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: this.name,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (isNodeSelection(selection)) {
|
||||||
|
currentChain.insertContentAt($originTo.pos, {
|
||||||
|
type: this.name,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
currentChain.insertContent({ type: this.name });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
currentChain
|
||||||
|
// set cursor after horizontal rule
|
||||||
|
.command(({ tr, dispatch }) => {
|
||||||
|
if (dispatch) {
|
||||||
|
const { $to } = tr.selection;
|
||||||
|
const posAfter = $to.end();
|
||||||
|
|
||||||
|
if ($to.nodeAfter) {
|
||||||
|
if ($to.nodeAfter.isTextblock) {
|
||||||
|
tr.setSelection(TextSelection.create(tr.doc, $to.pos + 1));
|
||||||
|
} else if ($to.nodeAfter.isBlock) {
|
||||||
|
tr.setSelection(NodeSelection.create(tr.doc, $to.pos));
|
||||||
|
} else {
|
||||||
|
tr.setSelection(TextSelection.create(tr.doc, $to.pos));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add node after horizontal rule if it’s the end of the document
|
||||||
|
const node = $to.parent.type.contentMatch.defaultType?.create();
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
tr.insert(posAfter, node);
|
||||||
|
tr.setSelection(TextSelection.create(tr.doc, posAfter + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.scrollIntoView();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
addInputRules() {
|
||||||
|
return [
|
||||||
|
nodeInputRule({
|
||||||
|
find: /^(?:---|—-|___\s|\*\*\*\s)$/,
|
||||||
|
type: this.type,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
});
|
@ -27,6 +27,7 @@ import { RestoreImage } from "src/types/restore-image";
|
|||||||
import { CustomLinkExtension } from "src/ui/extensions/custom-link";
|
import { CustomLinkExtension } from "src/ui/extensions/custom-link";
|
||||||
import { CustomCodeInlineExtension } from "src/ui/extensions/code-inline";
|
import { CustomCodeInlineExtension } from "src/ui/extensions/code-inline";
|
||||||
import { CustomTypographyExtension } from "src/ui/extensions/typography";
|
import { CustomTypographyExtension } from "src/ui/extensions/typography";
|
||||||
|
import { CustomHorizontalRule } from "./horizontal-rule/horizontal-rule";
|
||||||
|
|
||||||
export const CoreEditorExtensions = (
|
export const CoreEditorExtensions = (
|
||||||
mentionConfig: {
|
mentionConfig: {
|
||||||
@ -55,9 +56,7 @@ export const CoreEditorExtensions = (
|
|||||||
},
|
},
|
||||||
code: false,
|
code: false,
|
||||||
codeBlock: false,
|
codeBlock: false,
|
||||||
horizontalRule: {
|
horizontalRule: false,
|
||||||
HTMLAttributes: { class: "mt-4 mb-4" },
|
|
||||||
},
|
|
||||||
blockquote: false,
|
blockquote: false,
|
||||||
dropcursor: {
|
dropcursor: {
|
||||||
color: "rgba(var(--color-text-100))",
|
color: "rgba(var(--color-text-100))",
|
||||||
@ -67,6 +66,10 @@ export const CoreEditorExtensions = (
|
|||||||
CustomQuoteExtension.configure({
|
CustomQuoteExtension.configure({
|
||||||
HTMLAttributes: { className: "border-l-4 border-custom-border-300" },
|
HTMLAttributes: { className: "border-l-4 border-custom-border-300" },
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
CustomHorizontalRule.configure({
|
||||||
|
HTMLAttributes: { class: "mt-4 mb-4" },
|
||||||
|
}),
|
||||||
CustomKeymap,
|
CustomKeymap,
|
||||||
ListKeymap,
|
ListKeymap,
|
||||||
CustomLinkExtension.configure({
|
CustomLinkExtension.configure({
|
||||||
|
Loading…
Reference in New Issue
Block a user