fix: inline codes now exitable with right arrow key and inclusive (#3446)

* fix: inline codes now exitable with right arrow key and inclusive

* regression: toggle inline code on bubble menu selection

* feat: added different code block behaviour on selection and not selection

* fix: blockquote toggling and isActive state fixed
This commit is contained in:
M. Palanikannan 2024-01-24 14:59:48 +05:30 committed by GitHub
parent c1598c3d38
commit e23e4bc392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 105 additions and 18 deletions

View File

@ -30,7 +30,6 @@
"dependencies": {
"@tiptap/core": "^2.1.13",
"@tiptap/extension-blockquote": "^2.1.13",
"@tiptap/extension-code": "^2.1.13",
"@tiptap/extension-code-block-lowlight": "^2.1.13",
"@tiptap/extension-color": "^2.1.13",
"@tiptap/extension-image": "^2.1.13",

View File

@ -34,8 +34,32 @@ export const toggleUnderline = (editor: Editor, range?: Range) => {
};
export const toggleCodeBlock = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
else editor.chain().focus().toggleCodeBlock().run();
// Check if code block is active then toggle code block
if (editor.isActive("codeBlock")) {
if (range) {
editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
return;
}
editor.chain().focus().toggleCodeBlock().run();
return;
}
// Check if user hasn't selected any text
const isSelectionEmpty = editor.state.selection.empty;
if (isSelectionEmpty) {
if (range) {
editor.chain().focus().deleteRange(range).toggleCodeBlock().run();
return;
}
editor.chain().focus().toggleCodeBlock().run();
} else {
if (range) {
editor.chain().focus().deleteRange(range).toggleCode().run();
return;
}
editor.chain().focus().toggleCode().run();
}
};
export const toggleOrderedList = (editor: Editor, range?: Range) => {
@ -59,8 +83,8 @@ export const toggleStrike = (editor: Editor, range?: Range) => {
};
export const toggleBlockquote = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").toggleBlockquote().run();
else editor.chain().focus().toggleNode("paragraph", "paragraph").toggleBlockquote().run();
if (range) editor.chain().focus().deleteRange(range).toggleBlockquote().run();
else editor.chain().focus().toggleBlockquote().run();
};
export const insertTableCommand = (editor: Editor, range?: Range) => {

View File

@ -1,12 +1,80 @@
import { markInputRule, markPasteRule } from "@tiptap/core";
import Code from "@tiptap/extension-code";
import { Mark, markInputRule, markPasteRule, mergeAttributes } from "@tiptap/core";
export const inputRegex = /(?<!`)`([^`]*)`(?!`)/;
export const pasteRegex = /(?<!`)`([^`]+)`(?!`)/g;
export interface CodeOptions {
HTMLAttributes: Record<string, any>;
}
declare module "@tiptap/core" {
interface Commands<ReturnType> {
code: {
/**
* Set a code mark
*/
setCode: () => ReturnType;
/**
* Toggle inline code
*/
toggleCode: () => ReturnType;
/**
* Unset a code mark
*/
unsetCode: () => ReturnType;
};
}
}
export const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/;
export const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g;
export const CustomCodeInlineExtension = Mark.create<CodeOptions>({
name: "code",
addOptions() {
return {
HTMLAttributes: {
class: "rounded-md bg-custom-primary-30 mx-1 px-1 py-[2px] font-mono font-medium text-custom-text-1000",
spellcheck: "false",
},
};
},
excludes: "_",
code: true,
export const CustomCodeInlineExtension = Code.extend({
exitable: true,
inclusive: false,
parseHTML() {
return [{ tag: "code" }];
},
renderHTML({ HTMLAttributes }) {
return ["code", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
},
addCommands() {
return {
setCode:
() =>
({ commands }) =>
commands.setMark(this.name),
toggleCode:
() =>
({ commands }) =>
commands.toggleMark(this.name),
unsetCode:
() =>
({ commands }) =>
commands.unsetMark(this.name),
};
},
addKeyboardShortcuts() {
return {
"Mod-e": () => this.editor.commands.toggleCode(),
};
},
addInputRules() {
return [
markInputRule({
@ -15,6 +83,7 @@ export const CustomCodeInlineExtension = Code.extend({
}),
];
},
addPasteRules() {
return [
markPasteRule({
@ -23,9 +92,4 @@ export const CustomCodeInlineExtension = Code.extend({
}),
];
},
}).configure({
HTMLAttributes: {
class: "rounded-md bg-custom-primary-30 mx-1 px-1 py-[2px] font-mono font-medium text-custom-text-1000",
spellcheck: "false",
},
});

View File

@ -106,7 +106,7 @@ export const TodoListItem = (editor: Editor): EditorMenuItem => ({
export const CodeItem = (editor: Editor): EditorMenuItem => ({
name: "code",
isActive: () => editor?.isActive("code"),
isActive: () => editor?.isActive("code") || editor?.isActive("codeBlock"),
command: () => toggleCodeBlock(editor),
icon: CodeIcon,
});
@ -120,7 +120,7 @@ export const NumberedListItem = (editor: Editor): EditorMenuItem => ({
export const QuoteItem = (editor: Editor): EditorMenuItem => ({
name: "quote",
isActive: () => editor?.isActive("quote"),
isActive: () => editor?.isActive("blockquote"),
command: () => toggleBlockquote(editor),
icon: QuoteIcon,
});