[WEB-755] fix: Clearing nodes to default node i.e. paragraph before converting it to other type (#3974)

* fix: clearing nodes to default node i.e paragraph before converting it to other types of nodes

For more reference on what this does, please refer https://tiptap.dev/docs/editor/api/commands/clear-nodes

* chore: clearNodes after delete in case of selections being present

* fix: hiding link selector in the bubble menu if inline code block is selected
This commit is contained in:
M. Palanikannan 2024-03-18 12:51:35 +05:30 committed by GitHub
parent e9774e1af3
commit 0759666b75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 38 deletions

View File

@ -4,18 +4,18 @@ import { findTableAncestor } from "src/lib/utils";
import { UploadImage } from "src/types/upload-image"; import { UploadImage } from "src/types/upload-image";
export const toggleHeadingOne = (editor: Editor, range?: Range) => { export const toggleHeadingOne = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().setNode("heading", { level: 1 }).run();
else editor.chain().focus().toggleHeading({ level: 1 }).run(); else editor.chain().focus().clearNodes().toggleHeading({ level: 1 }).run();
}; };
export const toggleHeadingTwo = (editor: Editor, range?: Range) => { export const toggleHeadingTwo = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().setNode("heading", { level: 2 }).run();
else editor.chain().focus().toggleHeading({ level: 2 }).run(); else editor.chain().focus().clearNodes().toggleHeading({ level: 2 }).run();
}; };
export const toggleHeadingThree = (editor: Editor, range?: Range) => { export const toggleHeadingThree = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().setNode("heading", { level: 3 }).run();
else editor.chain().focus().toggleHeading({ level: 3 }).run(); else editor.chain().focus().clearNodes().toggleHeading({ level: 3 }).run();
}; };
export const toggleBold = (editor: Editor, range?: Range) => { export const toggleBold = (editor: Editor, range?: Range) => {
@ -37,10 +37,10 @@ export const toggleCodeBlock = (editor: Editor, range?: Range) => {
// Check if code block is active then toggle code block // Check if code block is active then toggle code block
if (editor.isActive("codeBlock")) { if (editor.isActive("codeBlock")) {
if (range) { if (range) {
editor.chain().focus().deleteRange(range).toggleCodeBlock().run(); editor.chain().focus().deleteRange(range).clearNodes().toggleCodeBlock().run();
return; return;
} }
editor.chain().focus().toggleCodeBlock().run(); editor.chain().focus().clearNodes().toggleCodeBlock().run();
return; return;
} }
@ -49,32 +49,32 @@ export const toggleCodeBlock = (editor: Editor, range?: Range) => {
if (isSelectionEmpty) { if (isSelectionEmpty) {
if (range) { if (range) {
editor.chain().focus().deleteRange(range).toggleCodeBlock().run(); editor.chain().focus().deleteRange(range).clearNodes().toggleCodeBlock().run();
return; return;
} }
editor.chain().focus().toggleCodeBlock().run(); editor.chain().focus().clearNodes().toggleCodeBlock().run();
} else { } else {
if (range) { if (range) {
editor.chain().focus().deleteRange(range).toggleCode().run(); editor.chain().focus().deleteRange(range).clearNodes().toggleCode().run();
return; return;
} }
editor.chain().focus().toggleCode().run(); editor.chain().focus().clearNodes().toggleCode().run();
} }
}; };
export const toggleOrderedList = (editor: Editor, range?: Range) => { export const toggleOrderedList = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleOrderedList().run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().toggleOrderedList().run();
else editor.chain().focus().toggleOrderedList().run(); else editor.chain().focus().clearNodes().toggleOrderedList().run();
}; };
export const toggleBulletList = (editor: Editor, range?: Range) => { export const toggleBulletList = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleBulletList().run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().toggleBulletList().run();
else editor.chain().focus().toggleBulletList().run(); else editor.chain().focus().clearNodes().toggleBulletList().run();
}; };
export const toggleTaskList = (editor: Editor, range?: Range) => { export const toggleTaskList = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleTaskList().run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().toggleTaskList().run();
else editor.chain().focus().toggleTaskList().run(); else editor.chain().focus().clearNodes().toggleTaskList().run();
}; };
export const toggleStrike = (editor: Editor, range?: Range) => { export const toggleStrike = (editor: Editor, range?: Range) => {
@ -83,8 +83,8 @@ export const toggleStrike = (editor: Editor, range?: Range) => {
}; };
export const toggleBlockquote = (editor: Editor, range?: Range) => { export const toggleBlockquote = (editor: Editor, range?: Range) => {
if (range) editor.chain().focus().deleteRange(range).toggleBlockquote().run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().toggleBlockquote().run();
else editor.chain().focus().toggleBlockquote().run(); else editor.chain().focus().clearNodes().toggleBlockquote().run();
}; };
export const insertTableCommand = (editor: Editor, range?: Range) => { export const insertTableCommand = (editor: Editor, range?: Range) => {
@ -97,8 +97,8 @@ export const insertTableCommand = (editor: Editor, range?: Range) => {
} }
} }
} }
if (range) editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3 }).run(); if (range) editor.chain().focus().deleteRange(range).clearNodes().insertTable({ rows: 3, cols: 3 }).run();
else editor.chain().focus().insertTable({ rows: 3, cols: 3 }).run(); else editor.chain().focus().clearNodes().insertTable({ rows: 3, cols: 3 }).run();
}; };
export const unsetLinkEditor = (editor: Editor) => { export const unsetLinkEditor = (editor: Editor) => {

View File

@ -85,7 +85,10 @@ const getSuggestionItems =
searchTerms: ["p", "paragraph"], searchTerms: ["p", "paragraph"],
icon: <CaseSensitive className="h-3.5 w-3.5" />, icon: <CaseSensitive className="h-3.5 w-3.5" />,
command: ({ editor, range }: CommandProps) => { command: ({ editor, range }: CommandProps) => {
editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").run(); if (range) {
editor.chain().focus().deleteRange(range).clearNodes().run();
}
editor.chain().focus().clearNodes().run();
}, },
}, },
{ {

View File

@ -25,16 +25,20 @@ type EditorBubbleMenuProps = Omit<BubbleMenuProps, "children">;
export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: any) => { export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: any) => {
const items: BubbleMenuItem[] = [ const items: BubbleMenuItem[] = [
...(props.editor.isActive("code")
? []
: [
BoldItem(props.editor), BoldItem(props.editor),
ItalicItem(props.editor), ItalicItem(props.editor),
UnderLineItem(props.editor), UnderLineItem(props.editor),
StrikeThroughItem(props.editor), StrikeThroughItem(props.editor),
]),
CodeItem(props.editor), CodeItem(props.editor),
]; ];
const bubbleMenuProps: EditorBubbleMenuProps = { const bubbleMenuProps: EditorBubbleMenuProps = {
...props, ...props,
shouldShow: ({ view, state, editor }) => { shouldShow: ({ state, editor }) => {
const { selection } = state; const { selection } = state;
const { empty } = selection; const { empty } = selection;
@ -64,6 +68,7 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: any) => {
const [isLinkSelectorOpen, setIsLinkSelectorOpen] = useState(false); const [isLinkSelectorOpen, setIsLinkSelectorOpen] = useState(false);
const [isSelecting, setIsSelecting] = useState(false); const [isSelecting, setIsSelecting] = useState(false);
useEffect(() => { useEffect(() => {
function handleMouseDown() { function handleMouseDown() {
function handleMouseMove() { function handleMouseMove() {
@ -108,14 +113,16 @@ export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: any) => {
}} }}
/> />
)} )}
{!props.editor.isActive("code") && (
<LinkSelector <LinkSelector
editor={props.editor!!} editor={props.editor}
isOpen={isLinkSelectorOpen} isOpen={isLinkSelectorOpen}
setIsOpen={() => { setIsOpen={() => {
setIsLinkSelectorOpen(!isLinkSelectorOpen); setIsLinkSelectorOpen(!isLinkSelectorOpen);
setIsNodeSelectorOpen(false); setIsNodeSelectorOpen(false);
}} }}
/> />
)}
<div className="flex"> <div className="flex">
{items.map((item) => ( {items.map((item) => (
<button <button

View File

@ -84,8 +84,8 @@ export const LinkSelector: FC<LinkSelectorProps> = ({ editor, isOpen, setIsOpen
className="flex items-center rounded-sm p-1 text-custom-text-300 transition-all hover:bg-custom-background-90" className="flex items-center rounded-sm p-1 text-custom-text-300 transition-all hover:bg-custom-background-90"
type="button" type="button"
onClick={(e) => { onClick={(e) => {
e.stopPropagation();
onLinkSubmit(); onLinkSubmit();
e.stopPropagation();
}} }}
> >
<Check className="h-4 w-4" /> <Check className="h-4 w-4" />

View File

@ -26,7 +26,7 @@ export const NodeSelector: FC<NodeSelectorProps> = ({ editor, isOpen, setIsOpen
{ {
name: "Text", name: "Text",
icon: TextIcon, icon: TextIcon,
command: () => editor.chain().focus().toggleNode("paragraph", "paragraph").run(), command: () => editor.chain().focus().clearNodes().run(),
isActive: () => editor.isActive("paragraph") && !editor.isActive("bulletList") && !editor.isActive("orderedList"), isActive: () => editor.isActive("paragraph") && !editor.isActive("bulletList") && !editor.isActive("orderedList"),
}, },
HeadingOneItem(editor), HeadingOneItem(editor),