From e2bcf25f33ec3bebabe4f47c754c046f0ee51fe7 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Wed, 16 Oct 2024 18:47:35 +0530
Subject: [PATCH 1/8] feat: text alignment for editors
---
packages/editor/package.json | 1 +
.../menus/bubble-menu/alignment-selector.tsx | 89 ++++++++++++
.../menus/bubble-menu/color-selector.tsx | 4 +-
.../menus/bubble-menu/node-selector.tsx | 4 +-
.../components/menus/bubble-menu/root.tsx | 8 +-
.../src/core/components/menus/menu-items.ts | 99 +++++++-------
.../src/core/extensions/core-without-props.ts | 2 +
.../editor/src/core/extensions/extensions.tsx | 2 +
packages/editor/src/core/extensions/index.ts | 4 +-
.../core/extensions/read-only-extensions.tsx | 2 +
.../editor/src/core/extensions/text-align.ts | 6 +
.../src/core/helpers/editor-commands.ts | 4 +
packages/editor/src/core/hooks/use-editor.ts | 14 +-
packages/editor/src/core/types/editor.ts | 76 +++++++----
.../core/types/slash-commands-suggestion.ts | 29 +---
packages/editor/src/styles/editor.css | 2 +-
.../components/editor/lite-text-editor.tsx | 20 +--
space/core/components/editor/toolbar.tsx | 95 ++++++-------
.../peek-overview/comment/add-comment.tsx | 2 +-
space/core/constants/editor.ts | 126 +++++++++++++----
.../lite-text-editor/lite-text-editor.tsx | 23 ++--
.../editor/lite-text-editor/toolbar.tsx | 95 ++++++-------
.../pages/editor/header/color-dropdown.tsx | 12 +-
.../pages/editor/header/toolbar.tsx | 33 +++--
web/core/constants/editor.ts | 127 ++++++++++++++----
yarn.lock | 36 ++---
26 files changed, 593 insertions(+), 322 deletions(-)
create mode 100644 packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
create mode 100644 packages/editor/src/core/extensions/text-align.ts
diff --git a/packages/editor/package.json b/packages/editor/package.json
index a152342a061..95cfe280b26 100644
--- a/packages/editor/package.json
+++ b/packages/editor/package.json
@@ -48,6 +48,7 @@
"@tiptap/extension-placeholder": "^2.3.0",
"@tiptap/extension-task-item": "^2.1.13",
"@tiptap/extension-task-list": "^2.1.13",
+ "@tiptap/extension-text-align": "^2.8.0",
"@tiptap/extension-text-style": "^2.7.1",
"@tiptap/extension-underline": "^2.1.13",
"@tiptap/pm": "^2.1.13",
diff --git a/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
new file mode 100644
index 00000000000..5f10f63bb8e
--- /dev/null
+++ b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
@@ -0,0 +1,89 @@
+import { Editor } from "@tiptap/core";
+import { AlignCenter, AlignLeft, AlignRight, LucideIcon } from "lucide-react";
+// components
+import { TextAlignItem } from "@/components/menus";
+// helpers
+import { cn } from "@/helpers/common";
+// types
+import { TEditorCommands } from "@/types";
+
+type Props = {
+ editor: Editor;
+};
+
+export const TextAlignmentSelector: React.FC = (props) => {
+ const { editor } = props;
+
+ const menuItem = TextAlignItem(editor);
+
+ const textAlignmentOptions: {
+ itemKey: TEditorCommands;
+ renderKey: string;
+ icon: LucideIcon;
+ command: () => void;
+ isActive: () => boolean;
+ }[] = [
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-left",
+ icon: AlignLeft,
+ command: () =>
+ menuItem.command({
+ alignment: "left",
+ }),
+ isActive: () =>
+ menuItem.isActive({
+ alignment: "left",
+ }),
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-center",
+ icon: AlignCenter,
+ command: () =>
+ menuItem.command({
+ alignment: "center",
+ }),
+ isActive: () =>
+ menuItem.isActive({
+ alignment: "center",
+ }),
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-right",
+ icon: AlignRight,
+ command: () =>
+ menuItem.command({
+ alignment: "right",
+ }),
+ isActive: () =>
+ menuItem.isActive({
+ alignment: "right",
+ }),
+ },
+ ];
+
+ return (
+
+ {textAlignmentOptions.map((item) => (
+
+ ))}
+
+ );
+};
diff --git a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
index 12495213d6d..93374b0ea2e 100644
--- a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
+++ b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
@@ -64,7 +64,7 @@ export const BubbleMenuColorSelector: FC = (props) => {
style={{
backgroundColor: color.textColor,
}}
- onClick={() => TextColorItem(editor).command(color.key)}
+ onClick={() => TextColorItem(editor).command({ color: color.key })}
/>
))}
- }
- >
- executeCommand(item.key)}
- className={cn(
- "grid place-items-center aspect-square rounded-sm p-0.5 text-custom-text-400 hover:bg-custom-background-80",
- {
- "bg-custom-background-80 text-custom-text-100": activeStates[item.key],
- }
- )}
+ {toolbarItems[key].map((item) => {
+ const isItemActive = activeStates[item.renderKey];
+
+ return (
+
+ {item.name}
+ {item.shortcut && {item.shortcut.join(" + ")}}
+
+ }
>
-
-
-
- ))}
+ executeCommand(item)}
+ className={cn(
+ "grid place-items-center aspect-square rounded-sm p-0.5 text-custom-text-400 hover:bg-custom-background-80",
+ {
+ "bg-custom-background-80 text-custom-text-100": isItemActive,
+ }
+ )}
+ >
+
+
+
+ );
+ })}
))}
diff --git a/space/core/components/issues/peek-overview/comment/add-comment.tsx b/space/core/components/issues/peek-overview/comment/add-comment.tsx
index f6c8a452b52..3623f398641 100644
--- a/space/core/components/issues/peek-overview/comment/add-comment.tsx
+++ b/space/core/components/issues/peek-overview/comment/add-comment.tsx
@@ -91,7 +91,7 @@ export const AddComment: React.FC = observer((props) => {
}
onChange={(comment_json, comment_html) => onChange(comment_html)}
isSubmitting={isSubmitting}
- placeholder="Add Comment..."
+ placeholder="Add comment..."
uploadFile={async (file) => {
const { asset_id } = await uploadCommentAsset(file, anchor);
setUploadAssetIds((prev) => [...prev, asset_id]);
diff --git a/space/core/constants/editor.ts b/space/core/constants/editor.ts
index 4c6bef2ccf3..155b49e8167 100644
--- a/space/core/constants/editor.ts
+++ b/space/core/constants/editor.ts
@@ -1,5 +1,9 @@
import {
+ AlignCenter,
+ AlignLeft,
+ AlignRight,
Bold,
+ CaseSensitive,
Code2,
Heading1,
Heading2,
@@ -19,30 +23,99 @@ import {
Underline,
} from "lucide-react";
// editor
-import { TEditorCommands } from "@plane/editor";
+import { TCommandExtraProps, TEditorCommands } from "@plane/editor";
type TEditorTypes = "lite" | "document";
-export type ToolbarMenuItem = {
- key: TEditorCommands;
+// Utility type to enforce the necessary extra props or make extraProps optional
+type ExtraPropsForCommand = T extends keyof TCommandExtraProps
+ ? TCommandExtraProps[T]
+ : object; // Default to empty object for commands without extra props
+
+export type ToolbarMenuItem = {
+ itemKey: T;
+ renderKey: string;
name: string;
icon: LucideIcon;
shortcut?: string[];
editors: TEditorTypes[];
+ extraProps?: ExtraPropsForCommand;
};
-export const BASIC_MARK_ITEMS: ToolbarMenuItem[] = [
- { key: "h1", name: "Heading 1", icon: Heading1, editors: ["document"] },
- { key: "h2", name: "Heading 2", icon: Heading2, editors: ["document"] },
- { key: "h3", name: "Heading 3", icon: Heading3, editors: ["document"] },
- { key: "h4", name: "Heading 4", icon: Heading4, editors: ["document"] },
- { key: "h5", name: "Heading 5", icon: Heading5, editors: ["document"] },
- { key: "h6", name: "Heading 6", icon: Heading6, editors: ["document"] },
- { key: "bold", name: "Bold", icon: Bold, shortcut: ["Cmd", "B"], editors: ["lite", "document"] },
- { key: "italic", name: "Italic", icon: Italic, shortcut: ["Cmd", "I"], editors: ["lite", "document"] },
- { key: "underline", name: "Underline", icon: Underline, shortcut: ["Cmd", "U"], editors: ["lite", "document"] },
+export const TYPOGRAPHY_ITEMS: ToolbarMenuItem<"text" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6">[] = [
+ { itemKey: "text", renderKey: "text", name: "Text", icon: CaseSensitive, editors: ["document"] },
+ { itemKey: "h1", renderKey: "h1", name: "Heading 1", icon: Heading1, editors: ["document"] },
+ { itemKey: "h2", renderKey: "h2", name: "Heading 2", icon: Heading2, editors: ["document"] },
+ { itemKey: "h3", renderKey: "h3", name: "Heading 3", icon: Heading3, editors: ["document"] },
+ { itemKey: "h4", renderKey: "h4", name: "Heading 4", icon: Heading4, editors: ["document"] },
+ { itemKey: "h5", renderKey: "h5", name: "Heading 5", icon: Heading5, editors: ["document"] },
+ { itemKey: "h6", renderKey: "h6", name: "Heading 6", icon: Heading6, editors: ["document"] },
+];
+
+export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-left",
+ name: "Left align",
+ icon: AlignLeft,
+ shortcut: ["Cmd", "Shift", "L"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "left",
+ },
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-center",
+ name: "Center align",
+ icon: AlignCenter,
+ shortcut: ["Cmd", "Shift", "E"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "center",
+ },
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-right",
+ name: "Right align",
+ icon: AlignRight,
+ shortcut: ["Cmd", "Shift", "R"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "right",
+ },
+ },
+];
+
+const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strikethrough">[] = [
+ {
+ itemKey: "bold",
+ renderKey: "bold",
+ name: "Bold",
+ icon: Bold,
+ shortcut: ["Cmd", "B"],
+ editors: ["lite", "document"],
+ },
+ {
+ itemKey: "italic",
+ renderKey: "italic",
+ name: "Italic",
+ icon: Italic,
+ shortcut: ["Cmd", "I"],
+ editors: ["lite", "document"],
+ },
+ {
+ itemKey: "underline",
+ renderKey: "underline",
+ name: "Underline",
+ icon: Underline,
+ shortcut: ["Cmd", "U"],
+ editors: ["lite", "document"],
+ },
{
- key: "strikethrough",
+ itemKey: "strikethrough",
+ renderKey: "strikethrough",
name: "Strikethrough",
icon: Strikethrough,
shortcut: ["Cmd", "Shift", "S"],
@@ -50,23 +123,26 @@ export const BASIC_MARK_ITEMS: ToolbarMenuItem[] = [
},
];
-export const LIST_ITEMS: ToolbarMenuItem[] = [
+const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-list">[] = [
{
- key: "bulleted-list",
+ itemKey: "bulleted-list",
+ renderKey: "bulleted-list",
name: "Bulleted list",
icon: List,
shortcut: ["Cmd", "Shift", "7"],
editors: ["lite", "document"],
},
{
- key: "numbered-list",
+ itemKey: "numbered-list",
+ renderKey: "numbered-list",
name: "Numbered list",
icon: ListOrdered,
shortcut: ["Cmd", "Shift", "8"],
editors: ["lite", "document"],
},
{
- key: "to-do-list",
+ itemKey: "to-do-list",
+ renderKey: "to-do-list",
name: "To-do list",
icon: ListTodo,
shortcut: ["Cmd", "Shift", "9"],
@@ -74,14 +150,14 @@ export const LIST_ITEMS: ToolbarMenuItem[] = [
},
];
-export const USER_ACTION_ITEMS: ToolbarMenuItem[] = [
- { key: "quote", name: "Quote", icon: Quote, editors: ["lite", "document"] },
- { key: "code", name: "Code", icon: Code2, editors: ["lite", "document"] },
+export const USER_ACTION_ITEMS: ToolbarMenuItem<"quote" | "code">[] = [
+ { itemKey: "quote", renderKey: "quote", name: "Quote", icon: Quote, editors: ["lite", "document"] },
+ { itemKey: "code", renderKey: "code", name: "Code", icon: Code2, editors: ["lite", "document"] },
];
-export const COMPLEX_ITEMS: ToolbarMenuItem[] = [
- { key: "table", name: "Table", icon: Table, editors: ["document"] },
- { key: "image", name: "Image", icon: Image, editors: ["lite", "document"] },
+export const COMPLEX_ITEMS: ToolbarMenuItem<"table" | "image">[] = [
+ { itemKey: "table", renderKey: "table", name: "Table", icon: Table, editors: ["document"] },
+ { itemKey: "image", renderKey: "image", name: "Image", icon: Image, editors: ["lite", "document"] },
];
export const TOOLBAR_ITEMS: {
@@ -91,12 +167,14 @@ export const TOOLBAR_ITEMS: {
} = {
lite: {
basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes("lite")),
+ alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("lite")),
list: LIST_ITEMS.filter((item) => item.editors.includes("lite")),
userAction: USER_ACTION_ITEMS.filter((item) => item.editors.includes("lite")),
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("lite")),
},
document: {
basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes("document")),
+ alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("lite")),
list: LIST_ITEMS.filter((item) => item.editors.includes("document")),
userAction: USER_ACTION_ITEMS.filter((item) => item.editors.includes("document")),
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("document")),
diff --git a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx
index 3e64e83a334..0822f1a97d3 100644
--- a/web/core/components/editor/lite-text-editor/lite-text-editor.tsx
+++ b/web/core/components/editor/lite-text-editor/lite-text-editor.tsx
@@ -1,6 +1,6 @@
import React from "react";
// editor
-import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef, TNonColorEditorCommands } from "@plane/editor";
+import { EditorRefApi, ILiteTextEditor, LiteTextEditorWithRef } from "@plane/editor";
// types
import { IUserLite } from "@plane/types";
// components
@@ -61,12 +61,12 @@ export const LiteTextEditor = React.forwardRef(ref: React.ForwardedRef): ref is React.MutableRefObject {
return !!ref && typeof ref === "object" && "current" in ref;
}
+ // derived values
+ const isEmpty = isCommentEmpty(props.initialValue);
+ const editorRef = isMutableRefObject(ref) ? ref.current : null;
return (
@@ -89,19 +89,20 @@ export const LiteTextEditor = React.forwardRef
{
- if (isMutableRefObject(ref)) {
- ref.current?.executeMenuItemCommand({
- itemKey: key as TNonColorEditorCommands,
- });
- }
+ executeCommand={(item) => {
+ // TODO: update this while toolbar homogenization
+ // @ts-expect-error type mismatch here
+ editorRef?.executeMenuItemCommand({
+ itemKey: item.itemKey,
+ ...item.extraProps,
+ });
}}
handleAccessChange={handleAccessChange}
handleSubmit={(e) => rest.onEnterKeyPress?.(e)}
isCommentEmpty={isEmpty}
isSubmitting={isSubmitting}
showAccessSpecifier={showAccessSpecifier}
- editorRef={isMutableRefObject(ref) ? ref : null}
+ editorRef={editorRef}
showSubmitButton={showSubmitButton}
/>
diff --git a/web/core/components/editor/lite-text-editor/toolbar.tsx b/web/core/components/editor/lite-text-editor/toolbar.tsx
index ecf8c3283c8..1951a3170e4 100644
--- a/web/core/components/editor/lite-text-editor/toolbar.tsx
+++ b/web/core/components/editor/lite-text-editor/toolbar.tsx
@@ -3,25 +3,25 @@
import React, { useEffect, useState, useCallback } from "react";
import { Globe2, Lock, LucideIcon } from "lucide-react";
// editor
-import { EditorRefApi, TEditorCommands, TNonColorEditorCommands } from "@plane/editor";
+import { EditorRefApi } from "@plane/editor";
// ui
import { Button, Tooltip } from "@plane/ui";
// constants
-import { TOOLBAR_ITEMS } from "@/constants/editor";
+import { TOOLBAR_ITEMS, ToolbarMenuItem } from "@/constants/editor";
import { EIssueCommentAccessSpecifier } from "@/constants/issue";
// helpers
import { cn } from "@/helpers/common.helper";
type Props = {
accessSpecifier?: EIssueCommentAccessSpecifier;
- executeCommand: (commandKey: TEditorCommands) => void;
+ executeCommand: (item: ToolbarMenuItem) => void;
handleAccessChange?: (accessKey: EIssueCommentAccessSpecifier) => void;
handleSubmit: (event: React.MouseEvent) => void;
isCommentEmpty: boolean;
isSubmitting: boolean;
showAccessSpecifier: boolean;
showSubmitButton: boolean;
- editorRef: React.MutableRefObject | null;
+ editorRef: EditorRefApi | null;
};
type TCommentAccessType = {
@@ -63,24 +63,25 @@ export const IssueCommentToolbar: React.FC = (props) => {
// Function to update active states
const updateActiveStates = useCallback(() => {
- if (editorRef?.current) {
- const newActiveStates: Record = {};
- Object.values(toolbarItems)
- .flat()
- .forEach((item) => {
- // Assert that editorRef.current is not null
- newActiveStates[item.key] = (editorRef.current as EditorRefApi).isMenuItemActive({
- itemKey: item.key as TNonColorEditorCommands,
- });
+ if (!editorRef) return;
+ const newActiveStates: Record = {};
+ Object.values(toolbarItems)
+ .flat()
+ .forEach((item) => {
+ // TODO: update this while toolbar homogenization
+ // @ts-expect-error type mismatch here
+ newActiveStates[item.renderKey] = editorRef.isMenuItemActive({
+ itemKey: item.itemKey,
+ ...item.extraProps,
});
- setActiveStates(newActiveStates);
- }
+ });
+ setActiveStates(newActiveStates);
}, [editorRef]);
// useEffect to call updateActiveStates when isActive prop changes
useEffect(() => {
- if (!editorRef?.current) return;
- const unsubscribe = editorRef.current.onStateChange(updateActiveStates);
+ if (!editorRef) return;
+ const unsubscribe = editorRef.onStateChange(updateActiveStates);
updateActiveStates();
return () => unsubscribe();
}, [editorRef, updateActiveStates]);
@@ -122,35 +123,39 @@ export const IssueCommentToolbar: React.FC = (props) => {
"pl-0": index === 0,
})}
>
- {toolbarItems[key].map((item) => (
-
- {item.name}
- {item.shortcut && {item.shortcut.join(" + ")}}
-
- }
- >
- executeCommand(item.key)}
- className={cn(
- "grid place-items-center aspect-square rounded-sm p-0.5 text-custom-text-400 hover:bg-custom-background-80",
- {
- "bg-custom-background-80 text-custom-text-100": activeStates[item.key],
- }
- )}
+ {toolbarItems[key].map((item) => {
+ const isItemActive = activeStates[item.renderKey];
+
+ return (
+
+ {item.name}
+ {item.shortcut && {item.shortcut.join(" + ")}}
+
+ }
>
-
-
-
- ))}
+ executeCommand(item)}
+ className={cn(
+ "grid place-items-center aspect-square rounded-sm p-0.5 text-custom-text-400 hover:bg-custom-background-80",
+ {
+ "bg-custom-background-80 text-custom-text-100": isItemActive,
+ }
+ )}
+ >
+
+
+
+ );
+ })}
))}
diff --git a/web/core/components/pages/editor/header/color-dropdown.tsx b/web/core/components/pages/editor/header/color-dropdown.tsx
index 68de2dc36b0..2809336c17d 100644
--- a/web/core/components/pages/editor/header/color-dropdown.tsx
+++ b/web/core/components/pages/editor/header/color-dropdown.tsx
@@ -4,13 +4,19 @@ import { memo } from "react";
import { ALargeSmall, Ban } from "lucide-react";
import { Popover } from "@headlessui/react";
// plane editor
-import { COLORS_LIST, TColorEditorCommands } from "@plane/editor";
+import { COLORS_LIST, TEditorCommands } from "@plane/editor";
// helpers
import { cn } from "@/helpers/common.helper";
type Props = {
- handleColorSelect: (key: TColorEditorCommands, color: string | undefined) => void;
- isColorActive: (key: TColorEditorCommands, color: string | undefined) => boolean;
+ handleColorSelect: (
+ key: Extract,
+ color: string | undefined
+ ) => void;
+ isColorActive: (
+ key: Extract,
+ color: string | undefined
+ ) => boolean;
};
export const ColorDropdown: React.FC = memo((props) => {
diff --git a/web/core/components/pages/editor/header/toolbar.tsx b/web/core/components/pages/editor/header/toolbar.tsx
index 447616b532f..6e4ffdd5f85 100644
--- a/web/core/components/pages/editor/header/toolbar.tsx
+++ b/web/core/components/pages/editor/header/toolbar.tsx
@@ -3,7 +3,7 @@
import React, { useEffect, useState, useCallback } from "react";
import { Check, ChevronDown } from "lucide-react";
// editor
-import { EditorRefApi, TNonColorEditorCommands } from "@plane/editor";
+import { EditorRefApi } from "@plane/editor";
// ui
import { CustomMenu, Tooltip } from "@plane/ui";
// components
@@ -36,11 +36,13 @@ const ToolbarButton: React.FC = React.memo((props) => {
}
>
+ // TODO: update this while toolbar homogenization
+ // @ts-expect-error type mismatch here
executeCommand({
- itemKey: item.key as TNonColorEditorCommands,
+ itemKey: item.itemKey,
+ ...item.extraProps,
})
}
className={cn("grid size-7 place-items-center rounded text-custom-text-300 hover:bg-custom-background-80", {
@@ -66,15 +68,20 @@ export const PageToolbar: React.FC = ({ editorRef }) => {
const [activeStates, setActiveStates] = useState>({});
const updateActiveStates = useCallback(() => {
+ // console.log("Updating status");
const newActiveStates: Record = {};
Object.values(toolbarItems)
.flat()
.forEach((item) => {
- newActiveStates[item.key] = editorRef.isMenuItemActive({
- itemKey: item.key as TNonColorEditorCommands,
+ // TODO: update this while toolbar homogenization
+ // @ts-expect-error type mismatch here
+ newActiveStates[item.renderKey] = editorRef.isMenuItemActive({
+ itemKey: item.itemKey,
+ ...item.extraProps,
});
});
setActiveStates(newActiveStates);
+ // console.log("newActiveStates", newActiveStates);
}, [editorRef]);
useEffect(() => {
@@ -85,7 +92,8 @@ export const PageToolbar: React.FC = ({ editorRef }) => {
const activeTypography = TYPOGRAPHY_ITEMS.find((item) =>
editorRef.isMenuItemActive({
- itemKey: item.key as TNonColorEditorCommands,
+ itemKey: item.itemKey,
+ ...item.extraProps,
})
);
@@ -105,11 +113,12 @@ export const PageToolbar: React.FC = ({ editorRef }) => {
>
{TYPOGRAPHY_ITEMS.map((item) => (
editorRef.executeMenuItemCommand({
- itemKey: item.key as TNonColorEditorCommands,
+ itemKey: item.itemKey,
+ ...item.extraProps,
})
}
>
@@ -117,7 +126,9 @@ export const PageToolbar: React.FC = ({ editorRef }) => {
{item.name}
- {activeTypography?.key === item.key && }
+ {activeTypography?.itemKey === item.itemKey && (
+
+ )}
))}
@@ -139,9 +150,9 @@ export const PageToolbar: React.FC = ({ editorRef }) => {
{toolbarItems[key].map((item) => (
))}
diff --git a/web/core/constants/editor.ts b/web/core/constants/editor.ts
index aa270a661d0..f4c5929579b 100644
--- a/web/core/constants/editor.ts
+++ b/web/core/constants/editor.ts
@@ -1,5 +1,8 @@
import { Styles, StyleSheet } from "@react-pdf/renderer";
import {
+ AlignCenter,
+ AlignLeft,
+ AlignRight,
Bold,
CaseSensitive,
Code2,
@@ -21,7 +24,7 @@ import {
Underline,
} from "lucide-react";
// editor
-import { TEditorCommands, TEditorFontStyle } from "@plane/editor";
+import { TCommandExtraProps, TEditorCommands, TEditorFontStyle } from "@plane/editor";
// ui
import { MonospaceIcon, SansSerifIcon, SerifIcon } from "@plane/ui";
// helpers
@@ -29,30 +32,95 @@ import { convertRemToPixel } from "@/helpers/common.helper";
type TEditorTypes = "lite" | "document";
-export type ToolbarMenuItem = {
- key: TEditorCommands;
+// Utility type to enforce the necessary extra props or make extraProps optional
+type ExtraPropsForCommand
= T extends keyof TCommandExtraProps
+ ? TCommandExtraProps[T]
+ : object; // Default to empty object for commands without extra props
+
+export type ToolbarMenuItem = {
+ itemKey: T;
+ renderKey: string;
name: string;
icon: LucideIcon;
shortcut?: string[];
editors: TEditorTypes[];
+ extraProps?: ExtraPropsForCommand;
};
-export const TYPOGRAPHY_ITEMS: ToolbarMenuItem[] = [
- { key: "text", name: "Text", icon: CaseSensitive, editors: ["document"] },
- { key: "h1", name: "Heading 1", icon: Heading1, editors: ["document"] },
- { key: "h2", name: "Heading 2", icon: Heading2, editors: ["document"] },
- { key: "h3", name: "Heading 3", icon: Heading3, editors: ["document"] },
- { key: "h4", name: "Heading 4", icon: Heading4, editors: ["document"] },
- { key: "h5", name: "Heading 5", icon: Heading5, editors: ["document"] },
- { key: "h6", name: "Heading 6", icon: Heading6, editors: ["document"] },
+export const TYPOGRAPHY_ITEMS: ToolbarMenuItem<"text" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6">[] = [
+ { itemKey: "text", renderKey: "text", name: "Text", icon: CaseSensitive, editors: ["document"] },
+ { itemKey: "h1", renderKey: "h1", name: "Heading 1", icon: Heading1, editors: ["document"] },
+ { itemKey: "h2", renderKey: "h2", name: "Heading 2", icon: Heading2, editors: ["document"] },
+ { itemKey: "h3", renderKey: "h3", name: "Heading 3", icon: Heading3, editors: ["document"] },
+ { itemKey: "h4", renderKey: "h4", name: "Heading 4", icon: Heading4, editors: ["document"] },
+ { itemKey: "h5", renderKey: "h5", name: "Heading 5", icon: Heading5, editors: ["document"] },
+ { itemKey: "h6", renderKey: "h6", name: "Heading 6", icon: Heading6, editors: ["document"] },
];
-const BASIC_MARK_ITEMS: ToolbarMenuItem[] = [
- { key: "bold", name: "Bold", icon: Bold, shortcut: ["Cmd", "B"], editors: ["lite", "document"] },
- { key: "italic", name: "Italic", icon: Italic, shortcut: ["Cmd", "I"], editors: ["lite", "document"] },
- { key: "underline", name: "Underline", icon: Underline, shortcut: ["Cmd", "U"], editors: ["lite", "document"] },
+export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-left",
+ name: "Left align",
+ icon: AlignLeft,
+ shortcut: ["Cmd", "Shift", "L"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "left",
+ },
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-center",
+ name: "Center align",
+ icon: AlignCenter,
+ shortcut: ["Cmd", "Shift", "E"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "center",
+ },
+ },
+ {
+ itemKey: "text-align",
+ renderKey: "text-align-right",
+ name: "Right align",
+ icon: AlignRight,
+ shortcut: ["Cmd", "Shift", "R"],
+ editors: ["lite", "document"],
+ extraProps: {
+ alignment: "right",
+ },
+ },
+];
+
+const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strikethrough">[] = [
+ {
+ itemKey: "bold",
+ renderKey: "bold",
+ name: "Bold",
+ icon: Bold,
+ shortcut: ["Cmd", "B"],
+ editors: ["lite", "document"],
+ },
+ {
+ itemKey: "italic",
+ renderKey: "italic",
+ name: "Italic",
+ icon: Italic,
+ shortcut: ["Cmd", "I"],
+ editors: ["lite", "document"],
+ },
+ {
+ itemKey: "underline",
+ renderKey: "underline",
+ name: "Underline",
+ icon: Underline,
+ shortcut: ["Cmd", "U"],
+ editors: ["lite", "document"],
+ },
{
- key: "strikethrough",
+ itemKey: "strikethrough",
+ renderKey: "strikethrough",
name: "Strikethrough",
icon: Strikethrough,
shortcut: ["Cmd", "Shift", "S"],
@@ -60,23 +128,26 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem[] = [
},
];
-const LIST_ITEMS: ToolbarMenuItem[] = [
+const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-list">[] = [
{
- key: "bulleted-list",
+ itemKey: "bulleted-list",
+ renderKey: "bulleted-list",
name: "Bulleted list",
icon: List,
shortcut: ["Cmd", "Shift", "7"],
editors: ["lite", "document"],
},
{
- key: "numbered-list",
+ itemKey: "numbered-list",
+ renderKey: "numbered-list",
name: "Numbered list",
icon: ListOrdered,
shortcut: ["Cmd", "Shift", "8"],
editors: ["lite", "document"],
},
{
- key: "to-do-list",
+ itemKey: "to-do-list",
+ renderKey: "to-do-list",
name: "To-do list",
icon: ListTodo,
shortcut: ["Cmd", "Shift", "9"],
@@ -84,29 +155,31 @@ const LIST_ITEMS: ToolbarMenuItem[] = [
},
];
-const USER_ACTION_ITEMS: ToolbarMenuItem[] = [
- { key: "quote", name: "Quote", icon: Quote, editors: ["lite", "document"] },
- { key: "code", name: "Code", icon: Code2, editors: ["lite", "document"] },
+const USER_ACTION_ITEMS: ToolbarMenuItem<"quote" | "code">[] = [
+ { itemKey: "quote", renderKey: "quote", name: "Quote", icon: Quote, editors: ["lite", "document"] },
+ { itemKey: "code", renderKey: "code", name: "Code", icon: Code2, editors: ["lite", "document"] },
];
-const COMPLEX_ITEMS: ToolbarMenuItem[] = [
- { key: "table", name: "Table", icon: Table, editors: ["document"] },
- { key: "image", name: "Image", icon: Image, editors: ["lite", "document"] },
+const COMPLEX_ITEMS: ToolbarMenuItem<"table" | "image">[] = [
+ { itemKey: "table", renderKey: "table", name: "Table", icon: Table, editors: ["document"] },
+ { itemKey: "image", renderKey: "image", name: "Image", icon: Image, editors: ["lite", "document"], extraProps: {} },
];
export const TOOLBAR_ITEMS: {
[editorType in TEditorTypes]: {
- [key: string]: ToolbarMenuItem[];
+ [key: string]: ToolbarMenuItem[];
};
} = {
lite: {
basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes("lite")),
+ alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("lite")),
list: LIST_ITEMS.filter((item) => item.editors.includes("lite")),
userAction: USER_ACTION_ITEMS.filter((item) => item.editors.includes("lite")),
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("lite")),
},
document: {
basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes("document")),
+ alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("document")),
list: LIST_ITEMS.filter((item) => item.editors.includes("document")),
userAction: USER_ACTION_ITEMS.filter((item) => item.editors.includes("document")),
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("document")),
diff --git a/yarn.lock b/yarn.lock
index 99246b4d462..cc440f7afee 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3596,6 +3596,11 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.8.0.tgz#b4124b638ee50251cae0bad9280a07350dc39e76"
integrity sha512-2Zkq0UojPh+Y4trJcNSsjkdHsYczxFReUqhzl5T0/OuPzIcDYL2OicUrsp36y16KKnH+WSOUOR8twDfR9LHygg==
+"@tiptap/extension-text-align@^2.8.0":
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-text-align/-/extension-text-align-2.8.0.tgz#831f0e1adf14f48be35a57b40e6e680ca69c53d3"
+ integrity sha512-Y6s/DF+P4lxpAnvSrnmt4xGwQT/AJJJm0aA1wu5GuPKpAQ+K4C7K6rE6uGNAXtR39GlewC7KdmcvA+CYhL8xlw==
+
"@tiptap/extension-text-style@^2.7.1":
version "2.8.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text-style/-/extension-text-style-2.8.0.tgz#32e30ccf3853202eba2169ba5db30b9470df9644"
@@ -11320,16 +11325,7 @@ streamx@^2.15.0, streamx@^2.20.0:
optionalDependencies:
bare-events "^2.2.0"
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -11416,14 +11412,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0:
dependencies:
safe-buffer "~5.2.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -12662,16 +12651,7 @@ word-wrap@^1.2.5:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
- integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
- dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
-
-wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
From 5eaf9fd0554f85a71e6c9af6274c9f78c1e54074 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 18 Oct 2024 13:37:08 +0530
Subject: [PATCH 2/8] fix: text alignment types
---
packages/editor/src/core/components/menus/menu-items.ts | 3 ++-
packages/editor/src/core/extensions/text-align.ts | 2 ++
packages/editor/src/core/types/editor.ts | 5 +++--
space/core/constants/editor.ts | 2 +-
4 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/packages/editor/src/core/components/menus/menu-items.ts b/packages/editor/src/core/components/menus/menu-items.ts
index 21a43580c76..87dba2697df 100644
--- a/packages/editor/src/core/components/menus/menu-items.ts
+++ b/packages/editor/src/core/components/menus/menu-items.ts
@@ -200,7 +200,8 @@ export const ImageItem = (editor: Editor): EditorMenuItem<"image"> => ({
key: "image",
name: "Image",
isActive: () => editor?.isActive("image") || editor?.isActive("imageComponent"),
- command: ({ savedSelection }) => insertImage({ editor, event: "insert", pos: savedSelection?.from }),
+ command: ({ savedSelection }) =>
+ insertImage({ editor, event: "insert", pos: savedSelection?.from ?? editor.state.selection.from }),
icon: ImageIcon,
});
diff --git a/packages/editor/src/core/extensions/text-align.ts b/packages/editor/src/core/extensions/text-align.ts
index 45cbf981020..bfe62f6c04b 100644
--- a/packages/editor/src/core/extensions/text-align.ts
+++ b/packages/editor/src/core/extensions/text-align.ts
@@ -1,5 +1,7 @@
import TextAlign from "@tiptap/extension-text-align";
+export type TTextAlign = "left" | "center" | "right";
+
export const CustomTextAlignExtension = TextAlign.configure({
alignments: ["left", "center", "right"],
types: ["heading", "paragraph"],
diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts
index a777c000aa0..932f346d7b6 100644
--- a/packages/editor/src/core/types/editor.ts
+++ b/packages/editor/src/core/types/editor.ts
@@ -13,6 +13,7 @@ import {
TFileHandler,
TServerHandler,
} from "@/types";
+import { TTextAlign } from "@/extensions";
export type TEditorCommands =
| "text"
@@ -50,14 +51,14 @@ export type TCommandExtraProps = {
color: string | undefined;
};
"text-align": {
- alignment: string;
+ alignment: TTextAlign;
};
};
// Create a utility type that maps a command to its extra props or an empty object if none are defined
export type TCommandWithProps = T extends keyof TCommandExtraProps
? TCommandExtraProps[T] // If the command has extra props, include them
- : {}; // Otherwise, just return the command type with no extra props
+ : object; // Otherwise, just return the command type with no extra props
type TCommandWithPropsWithItemKey = T extends keyof TCommandExtraProps
? { itemKey: T } & TCommandExtraProps[T]
diff --git a/space/core/constants/editor.ts b/space/core/constants/editor.ts
index 155b49e8167..3579e2ced4c 100644
--- a/space/core/constants/editor.ts
+++ b/space/core/constants/editor.ts
@@ -174,7 +174,7 @@ export const TOOLBAR_ITEMS: {
},
document: {
basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes("document")),
- alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("lite")),
+ alignment: TEXT_ALIGNMENT_ITEMS.filter((item) => item.editors.includes("document")),
list: LIST_ITEMS.filter((item) => item.editors.includes("document")),
userAction: USER_ACTION_ITEMS.filter((item) => item.editors.includes("document")),
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("document")),
From 7d7cbffeb622da6d76c838ca79839851a7406652 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 18 Oct 2024 14:16:43 +0530
Subject: [PATCH 3/8] fix: build errors
---
.../components/menus/bubble-menu/node-selector.tsx | 2 +-
.../extensions/custom-image/components/image-node.tsx | 4 ++--
.../core/extensions/slash-commands/command-menu.tsx | 4 ++--
.../editor/src/core/extensions/slash-commands/root.tsx | 4 ++--
packages/editor/src/core/hooks/use-editor.ts | 10 ++++++++--
5 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx
index 21647b5098d..a121c48ef12 100644
--- a/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx
+++ b/packages/editor/src/core/components/menus/bubble-menu/node-selector.tsx
@@ -46,7 +46,7 @@ export const BubbleMenuNodeSelector: FC = (props) => {
CodeItem(editor),
];
- const activeItem = items.filter((item) => item.isActive("")).pop() ?? {
+ const activeItem = items.filter((item) => item.isActive()).pop() ?? {
name: "Multiple",
};
diff --git a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
index f743b0a3c1d..dcdf9d0a4fc 100644
--- a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
+++ b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
@@ -1,10 +1,10 @@
import { useEffect, useRef, useState } from "react";
import { Node as ProsemirrorNode } from "@tiptap/pm/model";
-import { Editor, NodeViewWrapper } from "@tiptap/react";
+import { Editor, NodeViewProps, NodeViewWrapper } from "@tiptap/react";
// extensions
import { CustomImageBlock, CustomImageUploader, ImageAttributes } from "@/extensions/custom-image";
-export type CustomImageNodeViewProps = {
+export type CustomImageNodeViewProps = NodeViewProps & {
getPos: () => number;
editor: Editor;
node: ProsemirrorNode & {
diff --git a/packages/editor/src/core/extensions/slash-commands/command-menu.tsx b/packages/editor/src/core/extensions/slash-commands/command-menu.tsx
index c6363bc51c7..d6148b69aef 100644
--- a/packages/editor/src/core/extensions/slash-commands/command-menu.tsx
+++ b/packages/editor/src/core/extensions/slash-commands/command-menu.tsx
@@ -3,12 +3,12 @@ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react
import { TSlashCommandSection } from "./command-items-list";
import { CommandMenuItem } from "./command-menu-item";
-type Props = {
+export type SlashCommandsMenuProps = {
items: TSlashCommandSection[];
command: any;
};
-export const SlashCommandsMenu = (props: Props) => {
+export const SlashCommandsMenu = (props: SlashCommandsMenuProps) => {
const { items: sections, command } = props;
// states
const [selectedIndex, setSelectedIndex] = useState({
diff --git a/packages/editor/src/core/extensions/slash-commands/root.tsx b/packages/editor/src/core/extensions/slash-commands/root.tsx
index df70820dcf5..a99cbc5f903 100644
--- a/packages/editor/src/core/extensions/slash-commands/root.tsx
+++ b/packages/editor/src/core/extensions/slash-commands/root.tsx
@@ -6,7 +6,7 @@ import tippy from "tippy.js";
import { ISlashCommandItem } from "@/types";
// components
import { getSlashCommandFilteredSections } from "./command-items-list";
-import { SlashCommandsMenu } from "./command-menu";
+import { SlashCommandsMenu, SlashCommandsMenuProps } from "./command-menu";
export type SlashCommandOptions = {
suggestion: Omit;
@@ -55,7 +55,7 @@ interface CommandListInstance {
}
const renderItems = () => {
- let component: ReactRenderer | null = null;
+ let component: ReactRenderer | null = null;
let popup: any | null = null;
return {
onStart: (props: { editor: Editor; clientRect?: (() => DOMRect | null) | null }) => {
diff --git a/packages/editor/src/core/hooks/use-editor.ts b/packages/editor/src/core/hooks/use-editor.ts
index 9154f830608..30ca68f9dd1 100644
--- a/packages/editor/src/core/hooks/use-editor.ts
+++ b/packages/editor/src/core/hooks/use-editor.ts
@@ -6,7 +6,7 @@ import { EditorProps } from "@tiptap/pm/view";
import { useEditor as useTiptapEditor, Editor } from "@tiptap/react";
import * as Y from "yjs";
// components
-import { getEditorMenuItems } from "@/components/menus";
+import { EditorMenuItem, getEditorMenuItems } from "@/components/menus";
// extensions
import { CoreEditorExtensions } from "@/extensions";
// helpers
@@ -139,7 +139,13 @@ export const useEditor = (props: CustomEditorProps) => {
const item = getEditorMenuItem(itemKey);
if (item) {
- item.command(props);
+ if (item.key === "image") {
+ (item as EditorMenuItem<"image">).command({
+ savedSelection: savedSelectionRef.current,
+ });
+ } else {
+ item.command(props);
+ }
} else {
console.warn(`No command found for item: ${itemKey}`);
}
From e4cb32e48614e93ccb7d0038534743c868c23547 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 18 Oct 2024 16:20:30 +0530
Subject: [PATCH 4/8] fix: build error
---
.../src/core/components/menus/bubble-menu/color-selector.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
index d40e30a0bd4..bc7f5a56f12 100644
--- a/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
+++ b/packages/editor/src/core/components/menus/bubble-menu/color-selector.tsx
@@ -16,8 +16,8 @@ type Props = {
export const BubbleMenuColorSelector: FC = (props) => {
const { editor, isOpen, setIsOpen } = props;
- const activeTextColor = COLORS_LIST.find((c) => TextColorItem(editor).isActive(c.key));
- const activeBackgroundColor = COLORS_LIST.find((c) => BackgroundColorItem(editor).isActive(c.key));
+ const activeTextColor = COLORS_LIST.find((c) => TextColorItem(editor).isActive({ color: c.key }));
+ const activeBackgroundColor = COLORS_LIST.find((c) => BackgroundColorItem(editor).isActive({ color: c.key }));
return (
From 32cbc5648786d39ab226384dc43b9ee2ba63bec0 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 25 Oct 2024 18:05:25 +0530
Subject: [PATCH 5/8] fix: toolbar movement post alignment selection
---
.../menus/bubble-menu/alignment-selector.tsx | 6 ++++--
.../src/core/components/menus/bubble-menu/root.tsx | 12 ++++++++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
index 5f10f63bb8e..e3ccc6cf62b 100644
--- a/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
+++ b/packages/editor/src/core/components/menus/bubble-menu/alignment-selector.tsx
@@ -9,10 +9,11 @@ import { TEditorCommands } from "@/types";
type Props = {
editor: Editor;
+ onClose: () => void;
};
export const TextAlignmentSelector: React.FC = (props) => {
- const { editor } = props;
+ const { editor, onClose } = props;
const menuItem = TextAlignItem(editor);
@@ -71,8 +72,9 @@ export const TextAlignmentSelector: React.FC = (props) => {
key={item.renderKey}
type="button"
onClick={(e) => {
- item.command();
e.stopPropagation();
+ item.command();
+ onClose();
}}
className={cn(
"size-7 grid place-items-center rounded text-custom-text-300 hover:bg-custom-background-80 active:bg-custom-background-80 transition-colors",
diff --git a/packages/editor/src/core/components/menus/bubble-menu/root.tsx b/packages/editor/src/core/components/menus/bubble-menu/root.tsx
index 3328182e26c..18079f089e1 100644
--- a/packages/editor/src/core/components/menus/bubble-menu/root.tsx
+++ b/packages/editor/src/core/components/menus/bubble-menu/root.tsx
@@ -1,5 +1,5 @@
import { FC, useEffect, useState } from "react";
-import { BubbleMenu, BubbleMenuProps, isNodeSelection } from "@tiptap/react";
+import { BubbleMenu, BubbleMenuProps, Editor, isNodeSelection } from "@tiptap/react";
// components
import {
BoldItem,
@@ -152,7 +152,15 @@ export const EditorBubbleMenu: FC = (props: any) => {
))}
-
+ {
+ const editor = props.editor as Editor;
+ if (!editor) return;
+ const pos = editor.state.selection.to;
+ editor.commands.setTextSelection(pos ?? 0);
+ }}
+ />
>
)}
From 7763569a4190c35bb85ce8711a5ea21a02c5f5c7 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 25 Oct 2024 18:51:38 +0530
Subject: [PATCH 6/8] fix: callout type
---
packages/editor/src/core/types/editor.ts | 3 +-
yarn.lock | 263 +++++++++++++++++++----
2 files changed, 226 insertions(+), 40 deletions(-)
diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts
index 932f346d7b6..447f09789fc 100644
--- a/packages/editor/src/core/types/editor.ts
+++ b/packages/editor/src/core/types/editor.ts
@@ -38,7 +38,8 @@ export type TEditorCommands =
| "issue-embed"
| "text-color"
| "background-color"
- | "text-align";
+ | "text-align"
+ | "callout";
export type TCommandExtraProps = {
image: {
diff --git a/yarn.lock b/yarn.lock
index 55c723f91e0..cb6f87170ed 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2941,10 +2941,10 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz#719df7fb41766bc143369eaa0dd56d8dc87c9958"
integrity sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==
-"@storybook/addon-actions@8.3.5":
- version "8.3.5"
- resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.3.5.tgz#03fdb891114439ed47cb7df6ef21826530449db7"
- integrity sha512-t8D5oo+4XfD+F8091wLa2y/CDd/W2lExCeol5Vm1tp5saO+u6f2/d7iykLhTowWV84Uohi3D073uFeyTAlGebg==
+"@storybook/addon-actions@8.3.6":
+ version "8.3.6"
+ resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.3.6.tgz#80c5dbfc2278d72dc461a954bb729165ee1dfecb"
+ integrity sha512-nOqgl0WoZK2KwjaABaXMoIgrIHOQl9inOzJvqQau0HOtsvnXGXYfJXYnpjZenoZDoZXKbUDl0U2haDFx2a2fJw==
dependencies:
"@storybook/global" "^5.0.0"
"@types/uuid" "^9.0.1"
@@ -3597,22 +3597,15 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.9.1.tgz#e0ca3ec1379dbc39a98070c650d3759df85db794"
integrity sha512-vmUkclPi02iVf+uu74iyUp5xGNib0Gxs73DJ1z+a7CzjuLRqqCa/KEde95CR0Y//DaK/Csz4DOSUyTfLCMvpWg==
-<<<<<<< HEAD
"@tiptap/extension-text-align@^2.8.0":
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text-align/-/extension-text-align-2.8.0.tgz#831f0e1adf14f48be35a57b40e6e680ca69c53d3"
- integrity sha512-Y6s/DF+P4lxpAnvSrnmt4xGwQT/AJJJm0aA1wu5GuPKpAQ+K4C7K6rE6uGNAXtR39GlewC7KdmcvA+CYhL8xlw==
+ version "2.9.1"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-text-align/-/extension-text-align-2.9.1.tgz#5f7920a16c95b283c961cf1e22357bdc355c1626"
+ integrity sha512-oUp0XnwJpAImcOVV68vsY2CpkHpRZ3gzWfIRTuy+aYitQim3xDKis/qfWQUWZsANp9/TZ0VyjtkZxNMwOfcu1g==
-"@tiptap/extension-text-style@^2.7.1":
- version "2.8.0"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text-style/-/extension-text-style-2.8.0.tgz#32e30ccf3853202eba2169ba5db30b9470df9644"
- integrity sha512-jJp0vcZ2Ty7RvIL0VU6dm1y+fTfXq1lN2GwtYzYM0ueFuESa+Qo8ticYOImyWZ3wGJGVrjn7OV9r0ReW0/NYkQ==
-=======
"@tiptap/extension-text-style@^2.7.1", "@tiptap/extension-text-style@^2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text-style/-/extension-text-style-2.9.1.tgz#b9fc9cd8e90747357fbd4cac541a33aaa8b76875"
integrity sha512-LAxc0SeeiPiAVBwksczeA7BJSZb6WtVpYhy5Esvy9K0mK5kttB4KxtnXWeQzMIJZQbza65yftGKfQlexf/Y7yg==
->>>>>>> 6d08cf27576d9662e554524c62c2ad85c2fc0e09
"@tiptap/extension-text@^2.9.1":
version "2.9.1"
@@ -3792,6 +3785,57 @@
dependencies:
"@types/node" "*"
+"@types/d3-array@^3.0.3":
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5"
+ integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==
+
+"@types/d3-color@*":
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2"
+ integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==
+
+"@types/d3-ease@^3.0.0":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b"
+ integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==
+
+"@types/d3-interpolate@^3.0.1":
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c"
+ integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==
+ dependencies:
+ "@types/d3-color" "*"
+
+"@types/d3-path@*":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.0.tgz#2b907adce762a78e98828f0b438eaca339ae410a"
+ integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==
+
+"@types/d3-scale@^4.0.2":
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb"
+ integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==
+ dependencies:
+ "@types/d3-time" "*"
+
+"@types/d3-shape@^3.1.0":
+ version "3.1.6"
+ resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72"
+ integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==
+ dependencies:
+ "@types/d3-path" "*"
+
+"@types/d3-time@*", "@types/d3-time@^3.0.0":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be"
+ integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==
+
+"@types/d3-timer@^3.0.0":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70"
+ integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==
+
"@types/debug@^4.0.0":
version "4.1.12"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"
@@ -3839,9 +3883,9 @@
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0":
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz#91f06cda1049e8f17eeab364798ed79c97488a1c"
- integrity sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz#3c9997ae9d00bc236e45c6374e84f2596458d9db"
+ integrity sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==
dependencies:
"@types/node" "*"
"@types/qs" "*"
@@ -3992,11 +4036,11 @@
"@types/node" "*"
"@types/node@*", "@types/node@^22.0.0", "@types/node@^22.5.4":
- version "22.7.9"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.9.tgz#2bf2797b5e84702d8262ea2cf843c3c3c880d0e9"
- integrity sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==
+ version "22.8.0"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.0.tgz#193c6f82f9356ce0e6bba86b59f2ffe06e7e320b"
+ integrity sha512-84rafSBHC/z1i1E3p0cJwKA+CfYDNSXX9WSZBRopjIzLET8oNt6ht2tei4C7izwDeEiLLfdeSVBv1egOH916hg==
dependencies:
- undici-types "~6.19.2"
+ undici-types "~6.19.8"
"@types/node@18.14.1":
version "18.14.1"
@@ -4014,9 +4058,9 @@
integrity sha512-DZxSZWXxFfOlx7k7Rv4LAyiMroaxa3Ly/7OOzZO8cBNho0YzAi4qlbrx8W27JGqG57IgR/6J7r+nOJWw6kcvZA==
"@types/node@^20.14.9", "@types/node@^20.5.2":
- version "20.17.0"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.0.tgz#d0620ba0fe4cf2a0f12351c7bdd805fc4e1f036b"
- integrity sha512-a7zRo0f0eLo9K5X9Wp5cAqTUNGzuFLDG2R7C4HY2BhcMAsxgSPuRvAC1ZB6QkuUQXf0YZAgfOX2ZyrBa2n4nHQ==
+ version "20.17.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.1.tgz#2b968e060dfb04b7f9550fe3db5f552721c14566"
+ integrity sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==
dependencies:
undici-types "~6.19.2"
@@ -5709,11 +5753,23 @@ d3-array@2, d3-array@^2.3.0:
dependencies:
internmap "^1.0.0"
+"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
+ integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
+ dependencies:
+ internmap "1 - 2"
+
"d3-color@1 - 2", d3-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e"
integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==
+"d3-color@1 - 3":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
+ integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
+
d3-delaunay@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-5.3.0.tgz#b47f05c38f854a4e7b3cea80e0bb12e57398772d"
@@ -5721,11 +5777,21 @@ d3-delaunay@^5.3.0:
dependencies:
delaunator "4"
+d3-ease@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
+ integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
+
"d3-format@1 - 2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767"
integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==
+"d3-format@1 - 3":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
+ integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
+
d3-format@^1.4.4:
version "1.4.5"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4"
@@ -5738,11 +5804,23 @@ d3-format@^1.4.4:
dependencies:
d3-color "1 - 2"
+"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
+ integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
+ dependencies:
+ d3-color "1 - 3"
+
d3-path@1:
version "1.0.9"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
+d3-path@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
+ integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==
+
d3-scale-chromatic@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz#c13f3af86685ff91323dc2f0ebd2dabbd72d8bab"
@@ -5762,6 +5840,17 @@ d3-scale@^3.2.3:
d3-time "^2.1.1"
d3-time-format "2 - 3"
+d3-scale@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
+ integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
+ dependencies:
+ d3-array "2.10.0 - 3"
+ d3-format "1 - 3"
+ d3-interpolate "1.2.0 - 3"
+ d3-time "2.1.1 - 3"
+ d3-time-format "2 - 4"
+
d3-shape@^1.3.5:
version "1.3.7"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
@@ -5769,6 +5858,13 @@ d3-shape@^1.3.5:
dependencies:
d3-path "1"
+d3-shape@^3.1.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5"
+ integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==
+ dependencies:
+ d3-path "^3.1.0"
+
"d3-time-format@2 - 3", d3-time-format@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6"
@@ -5776,6 +5872,13 @@ d3-shape@^1.3.5:
dependencies:
d3-time "1 - 2"
+"d3-time-format@2 - 4":
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
+ integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
+ dependencies:
+ d3-time "1 - 3"
+
"d3-time@1 - 2", d3-time@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
@@ -5783,11 +5886,23 @@ d3-shape@^1.3.5:
dependencies:
d3-array "2"
+"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
+ integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
+ dependencies:
+ d3-array "2 - 3"
+
d3-time@^1.0.10, d3-time@^1.0.11:
version "1.1.0"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1"
integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==
+d3-timer@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
+ integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
+
damerau-levenshtein@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
@@ -5866,6 +5981,11 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
+decimal.js-light@^2.4.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
+ integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
+
decimal.js@^10.4.3:
version "10.4.3"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
@@ -6738,6 +6858,11 @@ event-target-shim@^5.0.0:
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
+eventemitter3@^4.0.1:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
+ integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+
events@^3.2.0, events@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
@@ -6822,6 +6947,11 @@ fast-deep-equal@^3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+fast-equals@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d"
+ integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==
+
fast-fifo@^1.2.0, fast-fifo@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c"
@@ -7663,6 +7793,11 @@ internal-slot@^1.0.7:
hasown "^2.0.0"
side-channel "^1.0.4"
+"internmap@1 - 2":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
+ integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
+
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
@@ -9746,9 +9881,9 @@ postgres-range@^1.1.1:
integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==
posthog-js@^1.131.3:
- version "1.174.4"
- resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.174.4.tgz#67abe7ba9c3b99db8fb472be0017b7d45217184f"
- integrity sha512-wfnSp1nDYHvV4+qy+UnDTED3afe8tVOiLa4Y83RLI2HZdMKovnLq11GJX6cYJ99+hs88HyGD1XmNTxShIQoOhQ==
+ version "1.176.0"
+ resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.176.0.tgz#39841ab213aa9c5500982659dc6d537a407f7205"
+ integrity sha512-T5XKNtRzp7q6CGb7Vc7wAI76rWap9fiuDUPxPsyPBPDkreKya91x9RIsSapAVFafwD1AEin1QMczCmt9Le9BWw==
dependencies:
core-js "^3.38.1"
fflate "^0.4.8"
@@ -9979,9 +10114,9 @@ prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, pr
prosemirror-view "^1.27.0"
prosemirror-tables@^1.4.0:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.5.1.tgz#75e6ace7427834f2150f9f08bf8fa400429f5238"
- integrity sha512-zL0vI0rGdhLLKXaZU1Jw1I8RuXwa5bv4aEY6G9TdynNRIU2FodtfI/YdhqVlimilhOIBGMbhvTvnQy5fvbHt2A==
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.6.0.tgz#b05fbb1172d55dd22ad2662af8e243c969bbbfdd"
+ integrity sha512-eirSS2fwVYzKhvM2qeXSn9ix/SBn7QOLDftPQ4ImEQIevFDiSKAB6Lbrmm/WEgrbTDbCm+xhSq4gOD9w7wT59Q==
dependencies:
prosemirror-keymap "^1.1.2"
prosemirror-model "^1.8.1"
@@ -10340,6 +10475,15 @@ react-selecto@^1.25.0:
dependencies:
selecto "~1.26.3"
+react-smooth@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.1.tgz#6200d8699bfe051ae40ba187988323b1449eab1a"
+ integrity sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==
+ dependencies:
+ fast-equals "^5.0.1"
+ prop-types "^15.8.1"
+ react-transition-group "^4.4.5"
+
react-style-singleton@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
@@ -10423,6 +10567,27 @@ recast@^0.23.5:
tiny-invariant "^1.3.3"
tslib "^2.0.1"
+recharts-scale@^0.4.4:
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9"
+ integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==
+ dependencies:
+ decimal.js-light "^2.4.1"
+
+recharts@^2.12.7:
+ version "2.13.0"
+ resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.13.0.tgz#a293322ea357491393cc7ad6fcbb1e5f8e99bc93"
+ integrity sha512-sbfxjWQ+oLWSZEWmvbq/DFVdeRLqqA6d0CDjKx2PkxVVdoXo16jvENCE+u/x7HxOO+/fwx//nYRwb8p8X6s/lQ==
+ dependencies:
+ clsx "^2.0.0"
+ eventemitter3 "^4.0.1"
+ lodash "^4.17.21"
+ react-is "^18.3.1"
+ react-smooth "^4.0.0"
+ recharts-scale "^0.4.4"
+ tiny-invariant "^1.3.1"
+ victory-vendor "^36.6.8"
+
redent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
@@ -11575,17 +11740,17 @@ tiptap-markdown@^0.8.9:
markdown-it-task-lists "^2.1.1"
prosemirror-markdown "^1.11.1"
-tldts-core@^6.1.54:
- version "6.1.54"
- resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.54.tgz#a3c3b5f45a64a1f9ea4bb32a94642218c7b7baa5"
- integrity sha512-5cc42+0G0EjYRDfIJHKraaT3I5kPm7j6or3Zh1T9sF+Ftj1T+isT4thicUyQQ1bwN7/xjHQIuY2fXCoXP8Haqg==
+tldts-core@^6.1.55:
+ version "6.1.55"
+ resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.55.tgz#cab0d412672fca9c77d3c51312c69bb5b5ee95c2"
+ integrity sha512-BL+BuKHHaOpntE5BGI6naXjULU6aRlgaYdfDHR3T/hdbNTWkWUZ9yuc11wGnwgpvRwlyUiIK+QohYK3olaVU6Q==
tldts@^6.1.32:
- version "6.1.54"
- resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.54.tgz#782594001a7b95e577b4cc391c0f0ed7c8307d37"
- integrity sha512-rDaL1t59gb/Lg0HPMUGdV1vAKLQcXwU74D26aMaYV4QW7mnMvShd1Vmkg3HYAPWx2JCTUmsrXt/Yl9eJ5UFBQw==
+ version "6.1.55"
+ resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.55.tgz#9a27d1708652bbae93d4b842dc2f8554fdabffc6"
+ integrity sha512-HxQR/9roQ07Pwc8RyyrJMAxRz5/ssoF3qIPPUiIo3zUt6yMdmYZjM2OZIFMiZ3jHyz9jrGHEHuQZrUhoc1LkDw==
dependencies:
- tldts-core "^6.1.54"
+ tldts-core "^6.1.55"
to-regex-range@^5.0.1:
version "5.0.1"
@@ -11903,7 +12068,7 @@ undefsafe@^2.0.5:
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
-undici-types@~6.19.2:
+undici-types@~6.19.2, undici-types@~6.19.8:
version "6.19.8"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
@@ -12203,6 +12368,26 @@ vfile@^5.0.0:
unist-util-stringify-position "^3.0.0"
vfile-message "^3.0.0"
+victory-vendor@^36.6.8:
+ version "36.9.2"
+ resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.9.2.tgz#668b02a448fa4ea0f788dbf4228b7e64669ff801"
+ integrity sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==
+ dependencies:
+ "@types/d3-array" "^3.0.3"
+ "@types/d3-ease" "^3.0.0"
+ "@types/d3-interpolate" "^3.0.1"
+ "@types/d3-scale" "^4.0.2"
+ "@types/d3-shape" "^3.1.0"
+ "@types/d3-time" "^3.0.0"
+ "@types/d3-timer" "^3.0.0"
+ d3-array "^3.1.6"
+ d3-ease "^3.0.1"
+ d3-interpolate "^3.0.1"
+ d3-scale "^4.0.2"
+ d3-shape "^3.1.0"
+ d3-time "^3.0.0"
+ d3-timer "^3.0.1"
+
vite-compatible-readable-stream@^3.6.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/vite-compatible-readable-stream/-/vite-compatible-readable-stream-3.6.1.tgz#27267aebbdc9893c0ddf65a421279cbb1e31d8cd"
From 3e8dc95bb776bac9ecd9ccaf220197e90ca88800 Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 25 Oct 2024 19:06:33 +0530
Subject: [PATCH 7/8] fix: image node types
---
.../core/extensions/custom-image/components/image-node.tsx | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
index e68201adf4c..4dd5e055df1 100644
--- a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
+++ b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
@@ -3,16 +3,18 @@ import { Editor, NodeViewProps, NodeViewWrapper } from "@tiptap/react";
// extensions
import { CustomImageBlock, CustomImageUploader, ImageAttributes } from "@/extensions/custom-image";
-export type CustomImageNodeViewProps = NodeViewProps & {
+export type CustomImageComponentProps = {
getPos: () => number;
editor: Editor;
node: NodeViewProps["node"] & {
attrs: ImageAttributes;
};
- updateAttributes: (attrs: ImageAttributes) => void;
+ updateAttributes: (attrs: Partial) => void;
selected: boolean;
};
+type CustomImageNodeViewProps = NodeViewProps & CustomImageComponentProps;
+
export const CustomImageNode = (props: CustomImageNodeViewProps) => {
const { getPos, editor, node, updateAttributes, selected } = props;
const { src: remoteImageSrc } = node.attrs;
@@ -53,7 +55,6 @@ export const CustomImageNode = (props: CustomImageNodeViewProps) => {
imageFromFileSystem={imageFromFileSystem}
editorContainer={editorContainer}
editor={editor}
- // @ts-expect-error function not expected here, but will still work
src={editor?.commands?.getImageSource?.(remoteImageSrc)}
getPos={getPos}
node={node}
From e2a281212414b506be7da7554145a92437cf12bf Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal
Date: Fri, 25 Oct 2024 19:07:48 +0530
Subject: [PATCH 8/8] chore: add ts error warning
---
.../src/core/extensions/custom-image/components/image-node.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
index 4dd5e055df1..566c624c6ee 100644
--- a/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
+++ b/packages/editor/src/core/extensions/custom-image/components/image-node.tsx
@@ -13,7 +13,7 @@ export type CustomImageComponentProps = {
selected: boolean;
};
-type CustomImageNodeViewProps = NodeViewProps & CustomImageComponentProps;
+export type CustomImageNodeViewProps = NodeViewProps & CustomImageComponentProps;
export const CustomImageNode = (props: CustomImageNodeViewProps) => {
const { getPos, editor, node, updateAttributes, selected } = props;
@@ -55,6 +55,7 @@ export const CustomImageNode = (props: CustomImageNodeViewProps) => {
imageFromFileSystem={imageFromFileSystem}
editorContainer={editorContainer}
editor={editor}
+ // @ts-expect-error function not expected here, but will still work
src={editor?.commands?.getImageSource?.(remoteImageSrc)}
getPos={getPos}
node={node}