Skip to content

Commit

Permalink
fix: inline codes now exitable with right arrow key and inclusive (#3446
Browse files Browse the repository at this point in the history
)

* 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
  • Loading branch information
Palanikannan1437 authored Jan 24, 2024
1 parent c1598c3 commit e23e4bc
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 18 deletions.
1 change: 0 additions & 1 deletion packages/editor/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
32 changes: 28 additions & 4 deletions packages/editor/core/src/lib/editor-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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) => {
Expand Down
86 changes: 75 additions & 11 deletions packages/editor/core/src/ui/extensions/code-inline/index.tsx
Original file line number Diff line number Diff line change
@@ -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({
Expand All @@ -15,6 +83,7 @@ export const CustomCodeInlineExtension = Code.extend({
}),
];
},

addPasteRules() {
return [
markPasteRule({
Expand All @@ -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",
},
});
4 changes: 2 additions & 2 deletions packages/editor/core/src/ui/menus/menu-items/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand All @@ -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,
});
Expand Down

0 comments on commit e23e4bc

Please sign in to comment.