forked from github/plane
[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:
parent
e9774e1af3
commit
0759666b75
@ -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) => {
|
||||||
|
@ -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();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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" />
|
||||||
|
@ -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),
|
||||||
|
Loading…
Reference in New Issue
Block a user