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 })} /> ))} ))} + )} diff --git a/packages/editor/src/core/components/menus/menu-items.ts b/packages/editor/src/core/components/menus/menu-items.ts index 0469fb9e004..21a43580c76 100644 --- a/packages/editor/src/core/components/menus/menu-items.ts +++ b/packages/editor/src/core/components/menus/menu-items.ts @@ -1,4 +1,3 @@ -import { Selection } from "@tiptap/pm/state"; import { Editor } from "@tiptap/react"; import { BoldIcon, @@ -21,12 +20,14 @@ import { CaseSensitive, LucideIcon, Palette, + AlignCenter, } from "lucide-react"; // helpers import { insertImage, insertTableCommand, setText, + setTextAlign, toggleBackgroundColor, toggleBlockquote, toggleBold, @@ -46,24 +47,20 @@ import { toggleUnderline, } from "@/helpers/editor-commands"; // types -import { TColorEditorCommands, TNonColorEditorCommands } from "@/types"; +import { TCommandWithProps, TEditorCommands } from "@/types"; -export type EditorMenuItem = { +type isActiveFunction = (params?: TCommandWithProps) => boolean; +type commandFunction = (params?: TCommandWithProps) => void; + +export type EditorMenuItem = { + key: T; name: string; - command: (...args: any) => void; + command: commandFunction; icon: LucideIcon; -} & ( - | { - key: TNonColorEditorCommands; - isActive: () => boolean; - } - | { - key: TColorEditorCommands; - isActive: (color: string | undefined) => boolean; - } -); - -export const TextItem = (editor: Editor): EditorMenuItem => ({ + isActive: isActiveFunction; +}; + +export const TextItem = (editor: Editor): EditorMenuItem<"text"> => ({ key: "text", name: "Text", isActive: () => editor.isActive("paragraph"), @@ -71,7 +68,7 @@ export const TextItem = (editor: Editor): EditorMenuItem => ({ icon: CaseSensitive, }); -export const HeadingOneItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingOneItem = (editor: Editor): EditorMenuItem<"h1"> => ({ key: "h1", name: "Heading 1", isActive: () => editor.isActive("heading", { level: 1 }), @@ -79,7 +76,7 @@ export const HeadingOneItem = (editor: Editor): EditorMenuItem => ({ icon: Heading1, }); -export const HeadingTwoItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingTwoItem = (editor: Editor): EditorMenuItem<"h2"> => ({ key: "h2", name: "Heading 2", isActive: () => editor.isActive("heading", { level: 2 }), @@ -87,7 +84,7 @@ export const HeadingTwoItem = (editor: Editor): EditorMenuItem => ({ icon: Heading2, }); -export const HeadingThreeItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingThreeItem = (editor: Editor): EditorMenuItem<"h3"> => ({ key: "h3", name: "Heading 3", isActive: () => editor.isActive("heading", { level: 3 }), @@ -95,7 +92,7 @@ export const HeadingThreeItem = (editor: Editor): EditorMenuItem => ({ icon: Heading3, }); -export const HeadingFourItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingFourItem = (editor: Editor): EditorMenuItem<"h4"> => ({ key: "h4", name: "Heading 4", isActive: () => editor.isActive("heading", { level: 4 }), @@ -103,7 +100,7 @@ export const HeadingFourItem = (editor: Editor): EditorMenuItem => ({ icon: Heading4, }); -export const HeadingFiveItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingFiveItem = (editor: Editor): EditorMenuItem<"h5"> => ({ key: "h5", name: "Heading 5", isActive: () => editor.isActive("heading", { level: 5 }), @@ -111,7 +108,7 @@ export const HeadingFiveItem = (editor: Editor): EditorMenuItem => ({ icon: Heading5, }); -export const HeadingSixItem = (editor: Editor): EditorMenuItem => ({ +export const HeadingSixItem = (editor: Editor): EditorMenuItem<"h6"> => ({ key: "h6", name: "Heading 6", isActive: () => editor.isActive("heading", { level: 6 }), @@ -119,7 +116,7 @@ export const HeadingSixItem = (editor: Editor): EditorMenuItem => ({ icon: Heading6, }); -export const BoldItem = (editor: Editor): EditorMenuItem => ({ +export const BoldItem = (editor: Editor): EditorMenuItem<"bold"> => ({ key: "bold", name: "Bold", isActive: () => editor?.isActive("bold"), @@ -127,7 +124,7 @@ export const BoldItem = (editor: Editor): EditorMenuItem => ({ icon: BoldIcon, }); -export const ItalicItem = (editor: Editor): EditorMenuItem => ({ +export const ItalicItem = (editor: Editor): EditorMenuItem<"italic"> => ({ key: "italic", name: "Italic", isActive: () => editor?.isActive("italic"), @@ -135,7 +132,7 @@ export const ItalicItem = (editor: Editor): EditorMenuItem => ({ icon: ItalicIcon, }); -export const UnderLineItem = (editor: Editor): EditorMenuItem => ({ +export const UnderLineItem = (editor: Editor): EditorMenuItem<"underline"> => ({ key: "underline", name: "Underline", isActive: () => editor?.isActive("underline"), @@ -143,7 +140,7 @@ export const UnderLineItem = (editor: Editor): EditorMenuItem => ({ icon: UnderlineIcon, }); -export const StrikeThroughItem = (editor: Editor): EditorMenuItem => ({ +export const StrikeThroughItem = (editor: Editor): EditorMenuItem<"strikethrough"> => ({ key: "strikethrough", name: "Strikethrough", isActive: () => editor?.isActive("strike"), @@ -151,7 +148,7 @@ export const StrikeThroughItem = (editor: Editor): EditorMenuItem => ({ icon: StrikethroughIcon, }); -export const BulletListItem = (editor: Editor): EditorMenuItem => ({ +export const BulletListItem = (editor: Editor): EditorMenuItem<"bulleted-list"> => ({ key: "bulleted-list", name: "Bulleted list", isActive: () => editor?.isActive("bulletList"), @@ -159,7 +156,7 @@ export const BulletListItem = (editor: Editor): EditorMenuItem => ({ icon: ListIcon, }); -export const NumberedListItem = (editor: Editor): EditorMenuItem => ({ +export const NumberedListItem = (editor: Editor): EditorMenuItem<"numbered-list"> => ({ key: "numbered-list", name: "Numbered list", isActive: () => editor?.isActive("orderedList"), @@ -167,7 +164,7 @@ export const NumberedListItem = (editor: Editor): EditorMenuItem => ({ icon: ListOrderedIcon, }); -export const TodoListItem = (editor: Editor): EditorMenuItem => ({ +export const TodoListItem = (editor: Editor): EditorMenuItem<"to-do-list"> => ({ key: "to-do-list", name: "To-do list", isActive: () => editor.isActive("taskItem"), @@ -175,7 +172,7 @@ export const TodoListItem = (editor: Editor): EditorMenuItem => ({ icon: CheckSquare, }); -export const QuoteItem = (editor: Editor): EditorMenuItem => ({ +export const QuoteItem = (editor: Editor): EditorMenuItem<"quote"> => ({ key: "quote", name: "Quote", isActive: () => editor?.isActive("blockquote"), @@ -183,7 +180,7 @@ export const QuoteItem = (editor: Editor): EditorMenuItem => ({ icon: QuoteIcon, }); -export const CodeItem = (editor: Editor): EditorMenuItem => ({ +export const CodeItem = (editor: Editor): EditorMenuItem<"code"> => ({ key: "code", name: "Code", isActive: () => editor?.isActive("code") || editor?.isActive("codeBlock"), @@ -191,7 +188,7 @@ export const CodeItem = (editor: Editor): EditorMenuItem => ({ icon: CodeIcon, }); -export const TableItem = (editor: Editor): EditorMenuItem => ({ +export const TableItem = (editor: Editor): EditorMenuItem<"table"> => ({ key: "table", name: "Table", isActive: () => editor?.isActive("table"), @@ -199,32 +196,39 @@ export const TableItem = (editor: Editor): EditorMenuItem => ({ icon: TableIcon, }); -export const ImageItem = (editor: Editor) => - ({ - key: "image", - name: "Image", - isActive: () => editor?.isActive("image") || editor?.isActive("imageComponent"), - command: (savedSelection: Selection | null) => insertImage({ editor, event: "insert", pos: savedSelection?.from }), - icon: ImageIcon, - }) as const; +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 }), + icon: ImageIcon, +}); -export const TextColorItem = (editor: Editor): EditorMenuItem => ({ +export const TextColorItem = (editor: Editor): EditorMenuItem<"text-color"> => ({ key: "text-color", name: "Color", - isActive: (color) => editor.getAttributes("textStyle").color === color, - command: (color: string) => toggleTextColor(color, editor), + isActive: ({ color }) => editor.getAttributes("textStyle").color === color, + command: ({ color }) => toggleTextColor(color, editor), icon: Palette, }); -export const BackgroundColorItem = (editor: Editor): EditorMenuItem => ({ +export const BackgroundColorItem = (editor: Editor): EditorMenuItem<"background-color"> => ({ key: "background-color", name: "Background color", - isActive: (color) => editor.getAttributes("textStyle").backgroundColor === color, - command: (color: string) => toggleBackgroundColor(color, editor), + isActive: ({ color }) => editor.getAttributes("textStyle").backgroundColor === color, + command: ({ color }) => toggleBackgroundColor(color, editor), icon: Palette, }); -export const getEditorMenuItems = (editor: Editor | null): EditorMenuItem[] => { +export const TextAlignItem = (editor: Editor): EditorMenuItem<"text-align"> => ({ + key: "text-align", + name: "Text align", + isActive: ({ alignment }) => editor.isActive({ textAlign: alignment }), + command: ({ alignment }) => setTextAlign(alignment, editor), + icon: AlignCenter, +}); + +export const getEditorMenuItems = (editor: Editor | null): EditorMenuItem[] => { if (!editor) return []; return [ @@ -248,5 +252,6 @@ export const getEditorMenuItems = (editor: Editor | null): EditorMenuItem[] => { ImageItem(editor), TextColorItem(editor), BackgroundColorItem(editor), + TextAlignItem(editor), ]; }; diff --git a/packages/editor/src/core/extensions/core-without-props.ts b/packages/editor/src/core/extensions/core-without-props.ts index b04625eb7ba..d2afc690f92 100644 --- a/packages/editor/src/core/extensions/core-without-props.ts +++ b/packages/editor/src/core/extensions/core-without-props.ts @@ -18,6 +18,7 @@ import { CustomQuoteExtension } from "./quote"; import { TableHeader, TableCell, TableRow, Table } from "./table"; import { CustomTextColorExtension } from "./custom-text-color"; import { CustomBackgroundColorExtension } from "./custom-background-color"; +import { CustomTextAlignExtension } from "./text-align"; export const CoreEditorExtensionsWithoutProps = [ StarterKit.configure({ @@ -87,6 +88,7 @@ export const CoreEditorExtensionsWithoutProps = [ CustomMentionWithoutProps(), CustomTextColorExtension, CustomBackgroundColorExtension, + CustomTextAlignExtension, ]; export const DocumentEditorExtensionsWithoutProps = [IssueWidgetWithoutProps()]; diff --git a/packages/editor/src/core/extensions/extensions.tsx b/packages/editor/src/core/extensions/extensions.tsx index dff2792d550..82fdee0d0c2 100644 --- a/packages/editor/src/core/extensions/extensions.tsx +++ b/packages/editor/src/core/extensions/extensions.tsx @@ -18,6 +18,7 @@ import { CustomLinkExtension, CustomMention, CustomQuoteExtension, + CustomTextAlignExtension, CustomTextColorExtension, CustomTypographyExtension, DropHandlerExtension, @@ -157,5 +158,6 @@ export const CoreEditorExtensions = (args: TArguments) => { CharacterCount, CustomTextColorExtension, CustomBackgroundColorExtension, + CustomTextAlignExtension, ]; }; diff --git a/packages/editor/src/core/extensions/index.ts b/packages/editor/src/core/extensions/index.ts index d9f9b973c97..e63f5a909f3 100644 --- a/packages/editor/src/core/extensions/index.ts +++ b/packages/editor/src/core/extensions/index.ts @@ -16,10 +16,10 @@ export * from "./custom-text-color"; export * from "./drop"; export * from "./enter-key-extension"; export * from "./extensions"; +export * from "./headers"; export * from "./horizontal-rule"; export * from "./keymap"; export * from "./quote"; export * from "./read-only-extensions"; export * from "./side-menu"; -export * from "./slash-commands"; -export * from "./headers"; +export * from "./text-align"; diff --git a/packages/editor/src/core/extensions/read-only-extensions.tsx b/packages/editor/src/core/extensions/read-only-extensions.tsx index 8bfa0509a08..e453c11eb5a 100644 --- a/packages/editor/src/core/extensions/read-only-extensions.tsx +++ b/packages/editor/src/core/extensions/read-only-extensions.tsx @@ -23,6 +23,7 @@ import { CustomReadOnlyImageExtension, CustomTextColorExtension, CustomBackgroundColorExtension, + CustomTextAlignExtension, } from "@/extensions"; // helpers import { isValidHttpUrl } from "@/helpers/common"; @@ -126,5 +127,6 @@ export const CoreReadOnlyEditorExtensions = (props: Props) => { CustomTextColorExtension, CustomBackgroundColorExtension, HeadingListExtension, + CustomTextAlignExtension, ]; }; diff --git a/packages/editor/src/core/extensions/text-align.ts b/packages/editor/src/core/extensions/text-align.ts new file mode 100644 index 00000000000..45cbf981020 --- /dev/null +++ b/packages/editor/src/core/extensions/text-align.ts @@ -0,0 +1,6 @@ +import TextAlign from "@tiptap/extension-text-align"; + +export const CustomTextAlignExtension = TextAlign.configure({ + alignments: ["left", "center", "right"], + types: ["heading", "paragraph"], +}); diff --git a/packages/editor/src/core/helpers/editor-commands.ts b/packages/editor/src/core/helpers/editor-commands.ts index f4ebb6c2f2d..e495af96f73 100644 --- a/packages/editor/src/core/helpers/editor-commands.ts +++ b/packages/editor/src/core/helpers/editor-commands.ts @@ -180,3 +180,7 @@ export const toggleBackgroundColor = (color: string | undefined, editor: Editor, } } }; + +export const setTextAlign = (alignment: string, editor: Editor) => { + editor.chain().focus().setTextAlign(alignment).run(); +}; diff --git a/packages/editor/src/core/hooks/use-editor.ts b/packages/editor/src/core/hooks/use-editor.ts index beee9c929d0..9154f830608 100644 --- a/packages/editor/src/core/hooks/use-editor.ts +++ b/packages/editor/src/core/hooks/use-editor.ts @@ -139,13 +139,7 @@ export const useEditor = (props: CustomEditorProps) => { const item = getEditorMenuItem(itemKey); if (item) { - if (item.key === "image") { - item.command(savedSelectionRef.current); - } else if (itemKey === "text-color" || itemKey === "background-color") { - item.command(props.color); - } else { - item.command(); - } + item.command(props); } else { console.warn(`No command found for item: ${itemKey}`); } @@ -158,11 +152,7 @@ export const useEditor = (props: CustomEditorProps) => { const item = getEditorMenuItem(itemKey); if (!item) return false; - if (itemKey === "text-color" || itemKey === "background-color") { - return item.isActive(props.color); - } else { - return item.isActive(""); - } + return item.isActive(props); }, onHeadingChange: (callback: (headings: IMarking[]) => void) => { // Subscribe to update event emitted from headers extension diff --git a/packages/editor/src/core/types/editor.ts b/packages/editor/src/core/types/editor.ts index 31b315c1ca2..a777c000aa0 100644 --- a/packages/editor/src/core/types/editor.ts +++ b/packages/editor/src/core/types/editor.ts @@ -1,4 +1,5 @@ import { JSONContent } from "@tiptap/core"; +import { Selection } from "@tiptap/pm/state"; // helpers import { IMarking } from "@/helpers/scroll-to-node"; // types @@ -6,15 +7,62 @@ import { IMentionHighlight, IMentionSuggestion, TAIHandler, - TColorEditorCommands, TDisplayConfig, - TEditorCommands, TEmbedConfig, TExtensions, TFileHandler, - TNonColorEditorCommands, TServerHandler, } from "@/types"; + +export type TEditorCommands = + | "text" + | "h1" + | "h2" + | "h3" + | "h4" + | "h5" + | "h6" + | "bold" + | "italic" + | "underline" + | "strikethrough" + | "bulleted-list" + | "numbered-list" + | "to-do-list" + | "quote" + | "code" + | "table" + | "image" + | "divider" + | "issue-embed" + | "text-color" + | "background-color" + | "text-align"; + +export type TCommandExtraProps = { + image: { + savedSelection: Selection | null; + }; + "text-color": { + color: string | undefined; + }; + "background-color": { + color: string | undefined; + }; + "text-align": { + alignment: string; + }; +}; + +// 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 + +type TCommandWithPropsWithItemKey = T extends keyof TCommandExtraProps + ? { itemKey: T } & TCommandExtraProps[T] + : { itemKey: T }; + // editor refs export type EditorReadOnlyRefApi = { getMarkDown: () => string; @@ -37,26 +85,8 @@ export type EditorReadOnlyRefApi = { export interface EditorRefApi extends EditorReadOnlyRefApi { setEditorValueAtCursorPosition: (content: string) => void; - executeMenuItemCommand: ( - props: - | { - itemKey: TNonColorEditorCommands; - } - | { - itemKey: TColorEditorCommands; - color: string | undefined; - } - ) => void; - isMenuItemActive: ( - props: - | { - itemKey: TNonColorEditorCommands; - } - | { - itemKey: TColorEditorCommands; - color: string | undefined; - } - ) => boolean; + executeMenuItemCommand: (props: TCommandWithPropsWithItemKey) => void; + isMenuItemActive: (props: TCommandWithPropsWithItemKey) => boolean; onStateChange: (callback: () => void) => () => void; setFocusAtPosition: (position: number) => void; isEditorReadyToDiscard: () => boolean; diff --git a/packages/editor/src/core/types/slash-commands-suggestion.ts b/packages/editor/src/core/types/slash-commands-suggestion.ts index ce3408a34f0..91c93203af4 100644 --- a/packages/editor/src/core/types/slash-commands-suggestion.ts +++ b/packages/editor/src/core/types/slash-commands-suggestion.ts @@ -1,32 +1,7 @@ import { CSSProperties } from "react"; import { Editor, Range } from "@tiptap/core"; - -export type TEditorCommands = - | "text" - | "h1" - | "h2" - | "h3" - | "h4" - | "h5" - | "h6" - | "bold" - | "italic" - | "underline" - | "strikethrough" - | "bulleted-list" - | "numbered-list" - | "to-do-list" - | "quote" - | "code" - | "table" - | "image" - | "divider" - | "issue-embed" - | "text-color" - | "background-color"; - -export type TColorEditorCommands = Extract; -export type TNonColorEditorCommands = Exclude; +// types +import { TEditorCommands } from "@/types"; export type CommandProps = { editor: Editor; diff --git a/packages/editor/src/styles/editor.css b/packages/editor/src/styles/editor.css index 20d6b5fa0c6..c85814b3370 100644 --- a/packages/editor/src/styles/editor.css +++ b/packages/editor/src/styles/editor.css @@ -192,7 +192,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p { /* Overwrite tippy-box original max-width */ .tippy-box { - max-width: 400px !important; + max-width: 600px !important; } .fade-in { diff --git a/space/core/components/editor/lite-text-editor.tsx b/space/core/components/editor/lite-text-editor.tsx index 4cd6d82e879..0e3f34293b5 100644 --- a/space/core/components/editor/lite-text-editor.tsx +++ b/space/core/components/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"; // components import { IssueCommentToolbar } from "@/components/editor"; // helpers @@ -30,11 +30,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 (
@@ -54,18 +55,19 @@ 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, + }); }} isSubmitting={isSubmitting} showSubmitButton={showSubmitButton} handleSubmit={(e) => rest.onEnterKeyPress?.(e)} isCommentEmpty={isEmpty} - editorRef={isMutableRefObject(ref) ? ref : null} + editorRef={editorRef} />
); diff --git a/space/core/components/editor/toolbar.tsx b/space/core/components/editor/toolbar.tsx index beccc8cb763..4593aaf6539 100644 --- a/space/core/components/editor/toolbar.tsx +++ b/space/core/components/editor/toolbar.tsx @@ -2,21 +2,21 @@ import React, { useEffect, useState, useCallback } from "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"; // helpers import { cn } from "@/helpers/common.helper"; type Props = { - executeCommand: (commandKey: TEditorCommands) => void; + executeCommand: (item: ToolbarMenuItem) => void; handleSubmit: (event: React.MouseEvent) => void; isCommentEmpty: boolean; isSubmitting: boolean; showSubmitButton: boolean; - editorRef: React.MutableRefObject | null; + editorRef: EditorRefApi | null; }; const toolbarItems = TOOLBAR_ITEMS.lite; @@ -28,24 +28,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]); @@ -61,35 +62,39 @@ export const IssueCommentToolbar: React.FC = (props) => { "pl-0": index === 0, })} > - {toolbarItems[key].map((item) => ( - - {item.name} - {item.shortcut && {item.shortcut.join(" + ")}} -

- } - > - -
- ))} + + + ); + })} ))} 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(" + ")}} -

- } - > - -
- ))} + + + ); + })} ))} 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) => { } > ))} - + { + 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}