forked from github/plane
added usage of common dependance for slash commands
This commit is contained in:
parent
d9c3407eed
commit
ede27b7b17
@ -2,6 +2,21 @@ import { Editor, Range } from "@tiptap/core";
|
|||||||
import { UploadImage } from "../types/upload-image";
|
import { UploadImage } from "../types/upload-image";
|
||||||
import { startImageUpload } from "../ui/plugins/upload-image";
|
import { startImageUpload } from "../ui/plugins/upload-image";
|
||||||
|
|
||||||
|
export const toggleHeadingOne = (editor: Editor, range?: Range) => {
|
||||||
|
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
|
||||||
|
else editor.chain().focus().toggleHeading({ level: 1 }).run()
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toggleHeadingTwo = (editor: Editor, range?: Range) => {
|
||||||
|
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
|
||||||
|
else editor.chain().focus().toggleHeading({ level: 2 }).run()
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toggleHeadingThree = (editor: Editor, range?: Range) => {
|
||||||
|
if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
|
||||||
|
else editor.chain().focus().toggleHeading({ level: 3 }).run()
|
||||||
|
};
|
||||||
|
|
||||||
export const toggleBold = (editor: Editor, range?: Range) => {
|
export const toggleBold = (editor: Editor, range?: Range) => {
|
||||||
if (range) editor.chain().focus().deleteRange(range).toggleBold().run();
|
if (range) editor.chain().focus().deleteRange(range).toggleBold().run();
|
||||||
else editor.chain().focus().toggleBold().run();
|
else editor.chain().focus().toggleBold().run();
|
||||||
@ -31,6 +46,11 @@ export const toggleBulletList = (editor: Editor, range?: Range) => {
|
|||||||
else editor.chain().focus().toggleBulletList().run();
|
else editor.chain().focus().toggleBulletList().run();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const toggleTaskList = (editor: Editor, range?: Range) => {
|
||||||
|
if (range) editor.chain().focus().deleteRange(range).toggleTaskList().run();
|
||||||
|
else editor.chain().focus().toggleTaskList().run()
|
||||||
|
};
|
||||||
|
|
||||||
export const toggleStrike = (editor: Editor, range?: Range) => {
|
export const toggleStrike = (editor: Editor, range?: Range) => {
|
||||||
if (range) editor.chain().focus().deleteRange(range).toggleStrike().run();
|
if (range) editor.chain().focus().deleteRange(range).toggleStrike().run();
|
||||||
else editor.chain().focus().toggleStrike().run();
|
else editor.chain().focus().toggleStrike().run();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { BoldIcon, QuoteIcon, ImageIcon, TableIcon, ListIcon, ListOrderedIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, CodeIcon } from "lucide-react";
|
import { BoldIcon, Heading1, CheckSquare, Heading2, Heading3, QuoteIcon, ImageIcon, TableIcon, ListIcon, ListOrderedIcon, ItalicIcon, UnderlineIcon, StrikethroughIcon, CodeIcon } from "lucide-react";
|
||||||
import { Editor } from "@tiptap/react";
|
import { Editor } from "@tiptap/react";
|
||||||
import { UploadImage } from "../../../types/upload-image";
|
import { UploadImage } from "../../../types/upload-image";
|
||||||
import { insertImageCommand, insertTableCommand, toggleBlockquote, toggleBold, toggleBulletList, toggleCode, toggleItalic, toggleOrderedList, toggleStrike, toggleUnderline, } from "../../../lib/editor-commands";
|
import { insertImageCommand, insertTableCommand, toggleBlockquote, toggleBold, toggleBulletList, toggleCode, toggleHeadingOne, toggleHeadingThree, toggleHeadingTwo, toggleItalic, toggleOrderedList, toggleStrike, toggleTaskList, toggleUnderline, } from "../../../lib/editor-commands";
|
||||||
|
|
||||||
export interface EditorMenuItem {
|
export interface EditorMenuItem {
|
||||||
name: string;
|
name: string;
|
||||||
@ -10,6 +10,27 @@ export interface EditorMenuItem {
|
|||||||
icon: typeof BoldIcon;
|
icon: typeof BoldIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const HeadingOneItem = (editor: Editor): EditorMenuItem => ({
|
||||||
|
name: "H1",
|
||||||
|
isActive: () => editor.isActive("heading", { level: 1 }),
|
||||||
|
command: () => toggleHeadingOne(editor),
|
||||||
|
icon: Heading1,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const HeadingTwoItem = (editor: Editor): EditorMenuItem => ({
|
||||||
|
name: "H2",
|
||||||
|
isActive: () => editor.isActive("heading", { level: 2 }),
|
||||||
|
command: () => toggleHeadingTwo(editor),
|
||||||
|
icon: Heading2,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const HeadingThreeItem = (editor: Editor): EditorMenuItem => ({
|
||||||
|
name: "H3",
|
||||||
|
isActive: () => editor.isActive("heading", { level: 3 }),
|
||||||
|
command: () => toggleHeadingThree(editor),
|
||||||
|
icon: Heading3,
|
||||||
|
})
|
||||||
|
|
||||||
export const BoldItem = (editor: Editor): EditorMenuItem => ({
|
export const BoldItem = (editor: Editor): EditorMenuItem => ({
|
||||||
name: "bold",
|
name: "bold",
|
||||||
isActive: () => editor?.isActive("bold"),
|
isActive: () => editor?.isActive("bold"),
|
||||||
@ -52,6 +73,13 @@ export const BulletListItem = (editor: Editor): EditorMenuItem => ({
|
|||||||
icon: ListIcon,
|
icon: ListIcon,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const TodoListItem = (editor: Editor): EditorMenuItem => ({
|
||||||
|
name: "To-do List",
|
||||||
|
isActive: () => editor.isActive("taskItem"),
|
||||||
|
command: () => toggleTaskList(editor),
|
||||||
|
icon: CheckSquare,
|
||||||
|
})
|
||||||
|
|
||||||
export const NumberedListItem = (editor: Editor): EditorMenuItem => ({
|
export const NumberedListItem = (editor: Editor): EditorMenuItem => ({
|
||||||
name: "ordered-list",
|
name: "ordered-list",
|
||||||
isActive: () => editor?.isActive("orderedList"),
|
isActive: () => editor?.isActive("orderedList"),
|
||||||
|
@ -6,7 +6,6 @@ import { InputRule } from "@tiptap/core";
|
|||||||
|
|
||||||
import ts from "highlight.js/lib/languages/typescript";
|
import ts from "highlight.js/lib/languages/typescript";
|
||||||
|
|
||||||
// import "highlight.js/styles/github-dark.css";
|
|
||||||
import SlashCommand from "./slash-command";
|
import SlashCommand from "./slash-command";
|
||||||
import { UploadImage } from "../";
|
import { UploadImage } from "../";
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ import {
|
|||||||
ImageIcon,
|
ImageIcon,
|
||||||
Table,
|
Table,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { UploadImage } from "..";
|
import { UploadImage } from "../";
|
||||||
import { cn, insertTableCommand, startImageUpload, toggleBulletList } from "@plane/editor-core";
|
import { cn, insertTableCommand, toggleBlockquote, toggleBulletList, toggleOrderedList, toggleTaskList, insertImageCommand, toggleHeadingOne, toggleHeadingTwo, toggleHeadingThree } from "@plane/editor-core";
|
||||||
|
|
||||||
interface CommandItemProps {
|
interface CommandItemProps {
|
||||||
title: string;
|
title: string;
|
||||||
@ -78,7 +78,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["title", "big", "large"],
|
searchTerms: ["title", "big", "large"],
|
||||||
icon: <Heading1 size={18} />,
|
icon: <Heading1 size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
|
toggleHeadingOne(editor, range);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -87,7 +87,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["subtitle", "medium"],
|
searchTerms: ["subtitle", "medium"],
|
||||||
icon: <Heading2 size={18} />,
|
icon: <Heading2 size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
|
toggleHeadingTwo(editor, range);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["subtitle", "small"],
|
searchTerms: ["subtitle", "small"],
|
||||||
icon: <Heading3 size={18} />,
|
icon: <Heading3 size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
|
toggleHeadingThree(editor, range);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["todo", "task", "list", "check", "checkbox"],
|
searchTerms: ["todo", "task", "list", "check", "checkbox"],
|
||||||
icon: <CheckSquare size={18} />,
|
icon: <CheckSquare size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
editor.chain().focus().deleteRange(range).toggleTaskList().run();
|
toggleTaskList(editor, range)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -114,7 +114,6 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["unordered", "point"],
|
searchTerms: ["unordered", "point"],
|
||||||
icon: <List size={18} />,
|
icon: <List size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
// editor.chain().focus().deleteRange(range).toggleBulletList().run();
|
|
||||||
toggleBulletList(editor, range);
|
toggleBulletList(editor, range);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -134,12 +133,6 @@ const getSuggestionItems =
|
|||||||
icon: <Table size={18} />,
|
icon: <Table size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
insertTableCommand(editor, range);
|
insertTableCommand(editor, range);
|
||||||
// editor
|
|
||||||
// .chain()
|
|
||||||
// .focus()
|
|
||||||
// .deleteRange(range)
|
|
||||||
// .insertTable({ rows: 3, cols: 3, withHeaderRow: true })
|
|
||||||
// .run();
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -148,8 +141,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["ordered"],
|
searchTerms: ["ordered"],
|
||||||
icon: <ListOrdered size={18} />,
|
icon: <ListOrdered size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
// @ts-ignore
|
toggleOrderedList(editor, range)
|
||||||
editor.chain().focus().deleteRange(range).toggleOrderedList().run();
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -158,8 +150,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["blockquote"],
|
searchTerms: ["blockquote"],
|
||||||
icon: <TextQuote size={18} />,
|
icon: <TextQuote size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) =>
|
command: ({ editor, range }: CommandProps) =>
|
||||||
// @ts-ignore
|
toggleBlockquote(editor, range)
|
||||||
editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Code",
|
title: "Code",
|
||||||
@ -175,19 +166,7 @@ const getSuggestionItems =
|
|||||||
searchTerms: ["photo", "picture", "media"],
|
searchTerms: ["photo", "picture", "media"],
|
||||||
icon: <ImageIcon size={18} />,
|
icon: <ImageIcon size={18} />,
|
||||||
command: ({ editor, range }: CommandProps) => {
|
command: ({ editor, range }: CommandProps) => {
|
||||||
editor.chain().focus().deleteRange(range).run();
|
insertImageCommand(editor, uploadFile, setIsSubmitting, range);
|
||||||
// upload image
|
|
||||||
const input = document.createElement("input");
|
|
||||||
input.type = "file";
|
|
||||||
input.accept = "image/*";
|
|
||||||
input.onchange = async () => {
|
|
||||||
if (input.files?.length) {
|
|
||||||
const file = input.files[0];
|
|
||||||
const pos = editor.view.state.selection.from;
|
|
||||||
startImageUpload(file, editor.view, pos, uploadFile, setIsSubmitting);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
input.click();
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
].filter((item) => {
|
].filter((item) => {
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
import { cn } from "@plane/editor-core";
|
import { BulletListItem, cn, CodeItem, HeadingOneItem, HeadingThreeItem, HeadingTwoItem, NumberedListItem, QuoteItem, TodoListItem } from "@plane/editor-core";
|
||||||
import { Editor } from "@tiptap/core";
|
import { Editor } from "@tiptap/react";
|
||||||
import {
|
import {
|
||||||
Check,
|
Check,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
Heading1,
|
|
||||||
Heading2,
|
|
||||||
Heading3,
|
|
||||||
TextQuote,
|
|
||||||
ListOrdered,
|
|
||||||
TextIcon,
|
TextIcon,
|
||||||
Code,
|
|
||||||
CheckSquare,
|
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { Dispatch, FC, SetStateAction } from "react";
|
import { Dispatch, FC, SetStateAction } from "react";
|
||||||
|
|
||||||
@ -33,55 +26,14 @@ export const NodeSelector: FC<NodeSelectorProps> = ({ editor, isOpen, setIsOpen
|
|||||||
!editor.isActive("bulletList") &&
|
!editor.isActive("bulletList") &&
|
||||||
!editor.isActive("orderedList"),
|
!editor.isActive("orderedList"),
|
||||||
},
|
},
|
||||||
{
|
HeadingOneItem(editor),
|
||||||
name: "H1",
|
HeadingTwoItem(editor),
|
||||||
icon: Heading1,
|
HeadingThreeItem(editor),
|
||||||
command: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
|
TodoListItem(editor),
|
||||||
isActive: () => editor.isActive("heading", { level: 1 }),
|
BulletListItem(editor),
|
||||||
},
|
NumberedListItem(editor),
|
||||||
{
|
QuoteItem(editor),
|
||||||
name: "H2",
|
CodeItem(editor),
|
||||||
icon: Heading2,
|
|
||||||
command: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
||||||
isActive: () => editor.isActive("heading", { level: 2 }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "H3",
|
|
||||||
icon: Heading3,
|
|
||||||
command: () => editor.chain().focus().toggleHeading({ level: 3 }).run(),
|
|
||||||
isActive: () => editor.isActive("heading", { level: 3 }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "To-do List",
|
|
||||||
icon: CheckSquare,
|
|
||||||
command: () => editor.chain().focus().toggleTaskList().run(),
|
|
||||||
isActive: () => editor.isActive("taskItem"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Bullet List",
|
|
||||||
icon: ListOrdered,
|
|
||||||
command: () => editor.chain().focus().toggleBulletList().run(),
|
|
||||||
isActive: () => editor.isActive("bulletList"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Numbered List",
|
|
||||||
icon: ListOrdered,
|
|
||||||
command: () => editor.chain().focus().toggleOrderedList().run(),
|
|
||||||
isActive: () => editor.isActive("orderedList"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Quote",
|
|
||||||
icon: TextQuote,
|
|
||||||
command: () =>
|
|
||||||
editor.chain().focus().toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
|
|
||||||
isActive: () => editor.isActive("blockquote"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Code",
|
|
||||||
icon: Code,
|
|
||||||
command: () => editor.chain().focus().toggleCodeBlock().run(),
|
|
||||||
isActive: () => editor.isActive("codeBlock"),
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const activeItem = items.filter((item) => item.isActive()).pop() ?? {
|
const activeItem = items.filter((item) => item.isActive()).pop() ?? {
|
||||||
|
Loading…
Reference in New Issue
Block a user