Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1592b59
chore: upgrade to tiptap v3
aaryan610 Jul 31, 2025
2dbfb54
chore: update starter kit
aaryan610 Jul 31, 2025
c97d40f
chore: tippy to floating-ui migration for mentions
aaryan610 Aug 1, 2025
5eac500
fix: merge conflicts resolved from preview
aaryan610 Aug 23, 2025
16e489a
chore: update remaining floating menus
aaryan610 Aug 23, 2025
cbfc39b
chore: update setEditorValue function
aaryan610 Aug 23, 2025
cd48989
fix: potential bugs
aaryan610 Aug 24, 2025
b2c23d1
chore: extract out common floating ui positioning logic
aaryan610 Aug 24, 2025
a0c14f1
Merge branch 'preview' into chore/tiptap-v3
Palanikannan1437 Sep 25, 2025
63d2299
fix: storage api
Palanikannan1437 Sep 25, 2025
e3c9b3b
Merge branch 'preview' of https://github.com/makeplane/plane into cho…
aaryan610 Sep 26, 2025
5a2184a
fix: bubble menu
aaryan610 Sep 26, 2025
5f58830
fix: type errors
aaryan610 Sep 29, 2025
e45f958
fix: type errors
aaryan610 Sep 29, 2025
d2b939e
fix: merge conflicts resolved from preview
aaryan610 Sep 29, 2025
7380696
chore: upgrade tiptap-markdown package
aaryan610 Sep 29, 2025
d277a52
fix: mentions close callback
aaryan610 Sep 29, 2025
de51429
chore: update bubbling sequence
aaryan610 Sep 29, 2025
605ac3c
chore: update package.json
aaryan610 Sep 29, 2025
b007c43
chore: update tiptap catalogs
aaryan610 Sep 29, 2025
fe93c1d
fix: merge conflicts resolved from preview
aaryan610 Sep 30, 2025
2ad7440
fix: add error handling
aaryan610 Sep 30, 2025
8d9b772
fix: file plugin types
aaryan610 Sep 30, 2025
25de9dc
fix: merge conflicts resolved from preview
aaryan610 Sep 30, 2025
73f54d9
chore: update live package.json
aaryan610 Sep 30, 2025
42dc2f9
fix: broken lock file
sriramveeraghanta Sep 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions apps/live/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"@plane/editor": "workspace:*",
"@plane/logger": "workspace:*",
"@plane/types": "workspace:*",
"@tiptap/core": "^2.22.3",
"@tiptap/html": "^2.22.3",
"@tiptap/core": "catalog:",
"@tiptap/html": "catalog:",
"axios": "catalog:",
"compression": "1.8.1",
"cors": "^2.8.5",
Expand All @@ -43,7 +43,8 @@
"pino-http": "^10.3.0",
"pino-pretty": "^11.2.2",
"uuid": "catalog:",
"y-prosemirror": "^1.2.15",
"ws": "^8.18.3",
"y-prosemirror": "^1.3.7",
"y-protocols": "^1.0.6",
"yjs": "^13.6.20",
"zod": "^3.25.76"
Expand All @@ -59,11 +60,7 @@
"@types/pino-http": "^5.8.4",
"@types/uuid": "^9.0.1",
"@types/ws": "^8.18.1",
"concurrently": "^9.0.1",
"nodemon": "^3.1.7",
"ts-node": "^10.9.2",
"tsdown": "catalog:",
"typescript": "catalog:",
"ws": "^8.18.3"
"typescript": "catalog:"
}
}
2 changes: 1 addition & 1 deletion apps/web/ce/hooks/use-editor-flagging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type TEditorFlaggingHookProps = {
/**
* @description extensions disabled in various editors
*/
export const useEditorFlagging = (props: TEditorFlaggingHookProps): TEditorFlaggingHookReturnType => ({
export const useEditorFlagging = (_props: TEditorFlaggingHookProps): TEditorFlaggingHookReturnType => ({
document: {
disabled: ["ai", "collaboration-cursor"],
flagged: [],
Expand Down
41 changes: 20 additions & 21 deletions packages/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"./styles": "./dist/styles/index.css"
},
"scripts": {
"build": "tsdown",
"build": "tsc && tsdown",
"dev": "tsdown --watch",
"check:lint": "eslint . --max-warnings 30",
"check:types": "tsc --noEmit",
Expand All @@ -46,25 +46,23 @@
"@plane/types": "workspace:*",
"@plane/ui": "workspace:*",
"@plane/utils": "workspace:*",
"@tiptap/core": "^2.22.3",
"@tiptap/extension-blockquote": "^2.22.3",
"@tiptap/extension-character-count": "^2.22.3",
"@tiptap/extension-collaboration": "^2.22.3",
"@tiptap/extension-emoji": "^2.22.3",
"@tiptap/extension-image": "^2.22.3",
"@tiptap/extension-list-item": "^2.22.3",
"@tiptap/extension-mention": "^2.22.3",
"@tiptap/extension-placeholder": "^2.22.3",
"@tiptap/extension-task-item": "^2.22.3",
"@tiptap/extension-task-list": "^2.22.3",
"@tiptap/extension-text-align": "^2.22.3",
"@tiptap/extension-text-style": "^2.22.3",
"@tiptap/extension-underline": "^2.22.3",
"@tiptap/html": "^2.22.3",
"@tiptap/pm": "^2.22.3",
"@tiptap/react": "^2.22.3",
"@tiptap/starter-kit": "^2.22.3",
"@tiptap/suggestion": "^2.22.3",
"@tiptap/core": "catalog:",
"@tiptap/extension-blockquote": "^3.5.3",
"@tiptap/extension-collaboration": "^3.5.3",
"@tiptap/extension-emoji": "^3.5.3",
"@tiptap/extension-image": "^3.5.3",
"@tiptap/extension-list-item": "^3.5.3",
"@tiptap/extension-mention": "^3.5.3",
"@tiptap/extension-task-item": "^3.5.3",
"@tiptap/extension-task-list": "^3.5.3",
"@tiptap/extension-text-align": "^3.5.3",
"@tiptap/extension-text-style": "^3.5.3",
"@tiptap/extensions": "^3.5.3",
"@tiptap/html": "catalog:",
"@tiptap/pm": "^3.5.3",
"@tiptap/react": "^3.5.3",
"@tiptap/starter-kit": "^3.5.3",
"@tiptap/suggestion": "^3.5.3",
"emoji-regex": "^10.3.0",
"highlight.js": "^11.8.0",
"is-emoji-supported": "^0.0.5",
Expand All @@ -74,7 +72,7 @@
"lucide-react": "catalog:",
"prosemirror-codemark": "^0.4.2",
"tippy.js": "^6.3.7",
"tiptap-markdown": "^0.8.10",
"tiptap-markdown": "^0.9.0",
"uuid": "catalog:",
"y-indexeddb": "^9.0.12",
"y-prosemirror": "^1.2.15",
Expand All @@ -88,6 +86,7 @@
"@types/node": "18.15.3",
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@types/uuid": "^8.3.4",
"postcss": "^8.4.38",
"tsdown": "catalog:",
"typescript": "catalog:"
Expand Down
24 changes: 16 additions & 8 deletions packages/editor/src/ce/constants/utility.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { ExtensionFileSetStorageKey } from "@/plane-editor/types/storage";
// plane imports
import { ADDITIONAL_EXTENSIONS, CORE_EXTENSIONS } from "@plane/utils";
// plane editor imports
import type { ExtensionFileSetStorageKey } from "@/plane-editor/types/storage";

export const NODE_FILE_MAP: {
[key: string]: {
fileSetName: ExtensionFileSetStorageKey;
};
} = {
image: {
export type NodeFileMapType = Partial<
Record<
CORE_EXTENSIONS | ADDITIONAL_EXTENSIONS,
{
fileSetName: ExtensionFileSetStorageKey;
}
>
>;

export const NODE_FILE_MAP: NodeFileMapType = {
[CORE_EXTENSIONS.IMAGE]: {
fileSetName: "deletedImageSet",
},
imageComponent: {
[CORE_EXTENSIONS.CUSTOM_IMAGE]: {
fileSetName: "deletedImageSet",
},
};
18 changes: 0 additions & 18 deletions packages/editor/src/ce/types/storage.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,4 @@
import { CharacterCountStorage } from "@tiptap/extension-character-count";
// constants
import type { EmojiStorage } from "@tiptap/extension-emoji";
import { CORE_EXTENSIONS } from "@/constants/extension";
// extensions
import type { HeadingExtensionStorage } from "@/extensions";
import type { CustomImageExtensionStorage } from "@/extensions/custom-image/types";
import type { CustomLinkStorage } from "@/extensions/custom-link";
import type { ImageExtensionStorage } from "@/extensions/image";
import type { UtilityExtensionStorage } from "@/extensions/utility";

export type ExtensionStorageMap = {
[CORE_EXTENSIONS.CUSTOM_IMAGE]: CustomImageExtensionStorage;
[CORE_EXTENSIONS.IMAGE]: ImageExtensionStorage;
[CORE_EXTENSIONS.CUSTOM_LINK]: CustomLinkStorage;
[CORE_EXTENSIONS.HEADINGS_LIST]: HeadingExtensionStorage;
[CORE_EXTENSIONS.UTILITY]: UtilityExtensionStorage;
[CORE_EXTENSIONS.EMOJI]: EmojiStorage;
[CORE_EXTENSIONS.CHARACTER_COUNT]: CharacterCountStorage;
};

export type ExtensionFileSetStorageKey = Extract<keyof ImageExtensionStorage, "deletedImageSet">;
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import { FC, useCallback, useEffect, useRef, useState } from "react";

// components
import { LinkView, LinkViewProps } from "@/components/links";
import { CORE_EXTENSIONS } from "@/constants/extension";
// components
import { getExtensionStorage } from "@/helpers/get-extension-storage";

type Props = {
editor: Editor;
Expand All @@ -22,7 +19,7 @@ export const LinkViewContainer: FC<Props> = ({ editor, containerRef }) => {
const editorState = useEditorState({
editor,
selector: ({ editor }: { editor: Editor }) => ({
linkExtensionStorage: getExtensionStorage(editor, CORE_EXTENSIONS.CUSTOM_LINK),
linkExtensionStorage: editor.storage.link,
}),
});

Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/core/components/menus/ai-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useCallback, useEffect, useRef, useState } from "react";
import tippy, { Instance } from "tippy.js";
import tippy, { type Instance } from "tippy.js";
// plane utils
import { cn } from "@plane/utils";
// types
import { TAIHandler } from "@/types";
import type { TAIHandler } from "@/types";

type Props = {
menu: TAIHandler["menu"];
Expand Down
32 changes: 12 additions & 20 deletions packages/editor/src/core/components/menus/block-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import {
useFloating,
autoUpdate,
offset,
flip,
shift,
autoUpdate,
useDismiss,
useInteractions,
FloatingPortal,
} from "@floating-ui/react";
import type { Editor } from "@tiptap/react";
import { Copy, LucideIcon, Trash2 } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
// constants
import { cn } from "@plane/utils";
// constants
import { CORE_EXTENSIONS } from "@/constants/extension";
import { IEditorProps } from "@/types";
// types
import type { IEditorProps } from "@/types";

type Props = {
disabledExtensions?: IEditorProps["disabledExtensions"];
editor: Editor;
flaggedExtensions?: IEditorProps["flaggedExtensions"];
disabledExtensions?: IEditorProps["disabledExtensions"];
};

export const BlockMenu = (props: Props) => {
Expand Down Expand Up @@ -74,15 +75,6 @@ export const BlockMenu = (props: Props) => {
// Set the virtual reference as the reference element
refs.setReference(virtualReferenceRef.current);

// Ensure the targeted block is selected
const rect = dragHandle.getBoundingClientRect();
const coords = { left: rect.left + rect.width / 2, top: rect.top + rect.height / 2 };
const posAtCoords = editor.view.posAtCoords(coords);
if (posAtCoords) {
const $pos = editor.state.doc.resolve(posAtCoords.pos);
const nodePos = $pos.before($pos.depth);
editor.chain().setNodeSelection(nodePos).run();
}
// Show the menu
openBlockMenu();
return;
Expand All @@ -93,9 +85,10 @@ export const BlockMenu = (props: Props) => {
closeBlockMenu();
}
},
[editor, refs, openBlockMenu, closeBlockMenu]
[refs, openBlockMenu, closeBlockMenu]
);

// Set up event listeners
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
Expand All @@ -106,10 +99,11 @@ export const BlockMenu = (props: Props) => {
const handleScroll = () => {
closeBlockMenu();
};

document.addEventListener("click", handleClickDragHandle);
document.addEventListener("contextmenu", handleClickDragHandle);
document.addEventListener("keydown", handleKeyDown);
document.addEventListener("scroll", handleScroll, true); // Using capture phase
document.addEventListener("scroll", handleScroll, true);

return () => {
document.removeEventListener("click", handleClickDragHandle);
Expand Down Expand Up @@ -200,6 +194,7 @@ export const BlockMenu = (props: Props) => {
if (!isOpen) {
return null;
}

return (
<FloatingPortal>
<div
Expand All @@ -209,7 +204,6 @@ export const BlockMenu = (props: Props) => {
}}
style={{
...floatingStyles,
zIndex: 99,
animationFillMode: "forwards",
transitionTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)", // Expo ease out
}}
Expand All @@ -218,13 +212,11 @@ export const BlockMenu = (props: Props) => {
"transition-all duration-300 transform origin-top-right",
isAnimatedIn ? "opacity-100 scale-100" : "opacity-0 scale-75"
)}
data-prevent-outside-click
{...getFloatingProps()}
>
{MENU_ITEMS.map((item) => {
if (item.isDisabled) {
return null;
}
if (item.isDisabled) return null;

return (
<button
key={item.key}
Expand Down
Loading
Loading