[WIKI-578] refactor: editor types structure #7536

This commit is contained in:
Aaryan Khandelwal 2025-08-04 18:01:51 +05:30 committed by GitHub
parent fa150c2b47
commit 7ead606798
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 103 additions and 111 deletions

View file

@ -30,6 +30,7 @@ const DocumentEditor = (props: IDocumentEditorProps) => {
flaggedExtensions, flaggedExtensions,
forwardedRef, forwardedRef,
id, id,
isTouchDevice,
handleEditorReady, handleEditorReady,
mentionHandler, mentionHandler,
onChange, onChange,
@ -96,6 +97,7 @@ const DocumentEditor = (props: IDocumentEditorProps) => {
editor={editor} editor={editor}
editorContainerClassName={cn(editorContainerClassName, "document-editor")} editorContainerClassName={cn(editorContainerClassName, "document-editor")}
id={id} id={id}
isTouchDevice={!!isTouchDevice}
/> />
); );
}; };

View file

@ -1,14 +1,14 @@
import { Editor, EditorContent } from "@tiptap/react"; import { type Editor, EditorContent } from "@tiptap/react";
import { FC, ReactNode } from "react"; import { FC, ReactNode } from "react";
interface EditorContentProps { type Props = {
children?: ReactNode; children?: ReactNode;
editor: Editor | null; editor: Editor | null;
id: string; id: string;
tabIndex?: number; tabIndex?: number;
} };
export const EditorContentWrapper: FC<EditorContentProps> = (props) => { export const EditorContentWrapper: FC<Props> = (props) => {
const { editor, children, tabIndex, id } = props; const { editor, children, tabIndex, id } = props;
return ( return (

View file

@ -4,12 +4,12 @@ import { FC, useCallback, useEffect, useRef, useState } from "react";
// components // components
import { LinkView, LinkViewProps } from "@/components/links"; import { LinkView, LinkViewProps } from "@/components/links";
interface LinkViewContainerProps { type Props = {
editor: Editor; editor: Editor;
containerRef: React.RefObject<HTMLDivElement>; containerRef: React.RefObject<HTMLDivElement>;
} };
export const LinkViewContainer: FC<LinkViewContainerProps> = ({ editor, containerRef }) => { export const LinkViewContainer: FC<Props> = ({ editor, containerRef }) => {
const [linkViewProps, setLinkViewProps] = useState<LinkViewProps>(); const [linkViewProps, setLinkViewProps] = useState<LinkViewProps>();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [virtualElement, setVirtualElement] = useState<Element | null>(null); const [virtualElement, setVirtualElement] = useState<Element | null>(null);

View file

@ -6,13 +6,13 @@ import { LinkViewProps, LinkViews } from "@/components/links";
// helpers // helpers
import { isValidHttpUrl } from "@/helpers/common"; import { isValidHttpUrl } from "@/helpers/common";
interface InputViewProps { type InputViewProps = {
label: string; label: string;
value: string; value: string;
placeholder: string; placeholder: string;
onChange: (value: string) => void; onChange: (value: string) => void;
autoFocus?: boolean; autoFocus?: boolean;
} };
const InputView = ({ label, value, placeholder, onChange, autoFocus }: InputViewProps) => ( const InputView = ({ label, value, placeholder, onChange, autoFocus }: InputViewProps) => (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
@ -28,10 +28,10 @@ const InputView = ({ label, value, placeholder, onChange, autoFocus }: InputView
</div> </div>
); );
interface LinkEditViewProps { type LinkEditViewProps = {
viewProps: LinkViewProps; viewProps: LinkViewProps;
switchView: (view: LinkViews) => void; switchView: (view: LinkViews) => void;
} };
export const LinkEditView = ({ viewProps }: LinkEditViewProps) => { export const LinkEditView = ({ viewProps }: LinkEditViewProps) => {
const { editor, from, to, url: initialUrl, text: initialText, closeLinkView } = viewProps; const { editor, from, to, url: initialUrl, text: initialText, closeLinkView } = viewProps;

View file

@ -5,7 +5,7 @@ import { LinkEditView, LinkPreview } from "@/components/links";
export type LinkViews = "LinkPreview" | "LinkEditView"; export type LinkViews = "LinkPreview" | "LinkEditView";
export interface LinkViewProps { export type LinkViewProps = {
view?: LinkViews; view?: LinkViews;
editor: Editor; editor: Editor;
from: number; from: number;
@ -13,7 +13,7 @@ export interface LinkViewProps {
url: string; url: string;
text?: string; text?: string;
closeLinkView: () => void; closeLinkView: () => void;
} };
export const LinkView = (props: LinkViewProps & { style: CSSProperties }) => { export const LinkView = (props: LinkViewProps & { style: CSSProperties }) => {
const [currentView, setCurrentView] = useState<LinkViews>(props.view ?? "LinkPreview"); const [currentView, setCurrentView] = useState<LinkViews>(props.view ?? "LinkPreview");

View file

@ -1,15 +1,15 @@
import { Editor } from "@tiptap/react"; import type { Editor } from "@tiptap/react";
import { Copy, LucideIcon, Trash2 } from "lucide-react"; import { Copy, LucideIcon, Trash2 } from "lucide-react";
import { useCallback, useEffect, useRef } from "react"; import { useCallback, useEffect, useRef } from "react";
import tippy, { Instance } from "tippy.js"; import tippy, { Instance } from "tippy.js";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
interface BlockMenuProps { type Props = {
editor: Editor; editor: Editor;
} };
export const BlockMenu = (props: BlockMenuProps) => { export const BlockMenu = (props: Props) => {
const { editor } = props; const { editor } = props;
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
const popup = useRef<Instance | null>(null); const popup = useRef<Instance | null>(null);

View file

@ -29,7 +29,7 @@ import { TextAlignmentSelector } from "./alignment-selector";
type EditorBubbleMenuProps = Omit<BubbleMenuProps, "children">; type EditorBubbleMenuProps = Omit<BubbleMenuProps, "children">;
export interface EditorStateType { export type EditorStateType = {
code: boolean; code: boolean;
bold: boolean; bold: boolean;
italic: boolean; italic: boolean;
@ -47,7 +47,7 @@ export interface EditorStateType {
backgroundColor: string; backgroundColor: string;
} }
| undefined; | undefined;
} };
export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: { editor: Editor }) => { export const EditorBubbleMenu: FC<EditorBubbleMenuProps> = (props: { editor: Editor }) => {
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);

View file

@ -2,9 +2,9 @@ import { Mark, markInputRule, markPasteRule, mergeAttributes } from "@tiptap/cor
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
export interface CodeOptions { type InlineCodeOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {
@ -28,7 +28,7 @@ declare module "@tiptap/core" {
export const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/; export const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/;
const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g; const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g;
export const CustomCodeInlineExtension = Mark.create<CodeOptions>({ export const CustomCodeInlineExtension = Mark.create<InlineCodeOptions>({
name: CORE_EXTENSIONS.CODE_INLINE, name: CORE_EXTENSIONS.CODE_INLINE,
addOptions() { addOptions() {

View file

@ -3,10 +3,10 @@
import { CodeBlockOptions, CodeBlock } from "./code-block"; import { CodeBlockOptions, CodeBlock } from "./code-block";
import { LowlightPlugin } from "./lowlight-plugin"; import { LowlightPlugin } from "./lowlight-plugin";
export interface CodeBlockLowlightOptions extends CodeBlockOptions { type CodeBlockLowlightOptions = CodeBlockOptions & {
lowlight: any; lowlight: any;
defaultLanguage: string | null | undefined; defaultLanguage: string | null | undefined;
} };
export const CodeBlockLowlight = CodeBlock.extend<CodeBlockLowlightOptions>({ export const CodeBlockLowlight = CodeBlock.extend<CodeBlockLowlightOptions>({
addOptions() { addOptions() {

View file

@ -1,6 +1,6 @@
"use client"; "use client";
import { Node as ProseMirrorNode } from "@tiptap/pm/model"; import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
import { NodeViewWrapper, NodeViewContent } from "@tiptap/react"; import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
import ts from "highlight.js/lib/languages/typescript"; import ts from "highlight.js/lib/languages/typescript";
import { common, createLowlight } from "lowlight"; import { common, createLowlight } from "lowlight";
@ -15,11 +15,11 @@ import { cn } from "@plane/utils";
const lowlight = createLowlight(common); const lowlight = createLowlight(common);
lowlight.register("ts", ts); lowlight.register("ts", ts);
interface CodeBlockComponentProps { type Props = {
node: ProseMirrorNode; node: ProseMirrorNode;
} };
export const CodeBlockComponent: React.FC<CodeBlockComponentProps> = ({ node }) => { export const CodeBlockComponent: React.FC<Props> = ({ node }) => {
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const copyToClipboard = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { const copyToClipboard = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {

View file

@ -3,7 +3,7 @@ import { Plugin, PluginKey } from "@tiptap/pm/state";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
export interface CodeBlockOptions { export type CodeBlockOptions = {
/** /**
* Adds a prefix to language classes that are applied to code tags. * Adds a prefix to language classes that are applied to code tags.
* Defaults to `'language-'`. * Defaults to `'language-'`.
@ -22,8 +22,8 @@ export interface CodeBlockOptions {
/** /**
* Custom HTML attributes that should be added to the rendered HTML tag. * Custom HTML attributes that should be added to the rendered HTML tag.
*/ */
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {

View file

@ -10,12 +10,12 @@ import { autolink } from "./helpers/autolink";
import { clickHandler } from "./helpers/clickHandler"; import { clickHandler } from "./helpers/clickHandler";
import { pasteHandler } from "./helpers/pasteHandler"; import { pasteHandler } from "./helpers/pasteHandler";
export interface LinkProtocolOptions { type LinkProtocolOptions = {
scheme: string; scheme: string;
optionalSlashes?: boolean; optionalSlashes?: boolean;
} };
export interface LinkOptions { type LinkOptions = {
/** /**
* If enabled, it adds links as you type. * If enabled, it adds links as you type.
*/ */
@ -40,14 +40,14 @@ export interface LinkOptions {
/** /**
* A list of HTML attributes to be rendered. * A list of HTML attributes to be rendered.
*/ */
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
/** /**
* A validation function that modifies link verification for the auto linker. * A validation function that modifies link verification for the auto linker.
* @param url - The url to be validated. * @param url - The url to be validated.
* @returns - True if the url is valid, false otherwise. * @returns - True if the url is valid, false otherwise.
*/ */
validate?: (url: string) => boolean; validate?: (url: string) => boolean;
} };
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {

View file

@ -1,28 +1,17 @@
import { computePosition, flip, shift } from "@floating-ui/dom"; import { computePosition, flip, shift } from "@floating-ui/dom";
import { Editor, posToDOMRect } from "@tiptap/react"; import { type Editor, posToDOMRect } from "@tiptap/react";
import { SuggestionKeyDownProps } from "@tiptap/suggestion"; import { SuggestionKeyDownProps } from "@tiptap/suggestion";
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react"; import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
// plane imports // plane imports
import { cn } from "@plane/utils"; import { cn } from "@plane/utils";
export interface EmojiItem { export type EmojiItem = {
name: string; name: string;
emoji: string; emoji: string;
shortcodes: string[]; shortcodes: string[];
tags: string[]; tags: string[];
fallbackImage?: string; fallbackImage?: string;
} };
export interface EmojiListProps {
items: EmojiItem[];
command: (item: { name: string }) => void;
editor: Editor;
query: string;
}
export interface EmojiListRef {
onKeyDown: (props: SuggestionKeyDownProps) => boolean;
}
const updatePosition = (editor: Editor, element: HTMLElement) => { const updatePosition = (editor: Editor, element: HTMLElement) => {
const virtualElement = { const virtualElement = {
@ -43,7 +32,18 @@ const updatePosition = (editor: Editor, element: HTMLElement) => {
}); });
}; };
export const EmojiList = forwardRef<EmojiListRef, EmojiListProps>((props, ref) => { export type EmojiListRef = {
onKeyDown: (props: SuggestionKeyDownProps) => boolean;
};
type Props = {
items: EmojiItem[];
command: (item: { name: string }) => void;
editor: Editor;
query: string;
};
export const EmojiList = forwardRef<EmojiListRef, Props>((props, ref) => {
const { items, command, editor, query } = props; const { items, command, editor, query } = props;
const [selectedIndex, setSelectedIndex] = useState<number>(0); const [selectedIndex, setSelectedIndex] = useState<number>(0);
const [isVisible, setIsVisible] = useState(false); const [isVisible, setIsVisible] = useState(false);

View file

@ -65,11 +65,11 @@ export type EmojiItem = {
/** /**
* Store some custom data * Store some custom data
*/ */
[key: string]: any; [key: string]: unknown;
}; };
export type EmojiOptions = { export type EmojiOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
emojis: EmojiItem[]; emojis: EmojiItem[];
enableEmoticons: boolean; enableEmoticons: boolean;
forceFallbackImages: boolean; forceFallbackImages: boolean;

View file

@ -2,13 +2,8 @@ import { Extension } from "@tiptap/core";
import { Plugin, PluginKey } from "@tiptap/pm/state"; import { Plugin, PluginKey } from "@tiptap/pm/state";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
// types
export interface IMarking { import type { IMarking } from "@/types";
type: "heading";
level: number;
text: string;
sequence: number;
}
export type HeadingExtensionStorage = { export type HeadingExtensionStorage = {
headings: IMarking[]; headings: IMarking[];

View file

@ -3,9 +3,9 @@ import { NodeSelection, TextSelection } from "@tiptap/pm/state";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
export interface HorizontalRuleOptions { type HorizontalRuleOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {

View file

@ -9,9 +9,9 @@ import { TableCellSelectionOutlinePlugin } from "./plugins/selection-outline/plu
import { DEFAULT_COLUMN_WIDTH } from "./table"; import { DEFAULT_COLUMN_WIDTH } from "./table";
import { isCellSelection } from "./table/utilities/helpers"; import { isCellSelection } from "./table/utilities/helpers";
export interface TableCellOptions { type TableCellOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
export const TableCell = Node.create<TableCellOptions>({ export const TableCell = Node.create<TableCellOptions>({
name: CORE_EXTENSIONS.TABLE_CELL, name: CORE_EXTENSIONS.TABLE_CELL,

View file

@ -4,9 +4,9 @@ import { CORE_EXTENSIONS } from "@/constants/extension";
// local imports // local imports
import { DEFAULT_COLUMN_WIDTH } from "./table"; import { DEFAULT_COLUMN_WIDTH } from "./table";
export interface TableHeaderOptions { type TableHeaderOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
export const TableHeader = Node.create<TableHeaderOptions>({ export const TableHeader = Node.create<TableHeaderOptions>({
name: CORE_EXTENSIONS.TABLE_HEADER, name: CORE_EXTENSIONS.TABLE_HEADER,

View file

@ -2,9 +2,9 @@ import { mergeAttributes, Node } from "@tiptap/core";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
export interface TableRowOptions { type TableRowOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
} };
export const TableRow = Node.create<TableRowOptions>({ export const TableRow = Node.create<TableRowOptions>({
name: CORE_EXTENSIONS.TABLE_ROW, name: CORE_EXTENSIONS.TABLE_ROW,

View file

@ -32,14 +32,14 @@ import { insertLineAboveTableAction } from "./utilities/insert-line-above-table-
import { insertLineBelowTableAction } from "./utilities/insert-line-below-table-action"; import { insertLineBelowTableAction } from "./utilities/insert-line-below-table-action";
import { DEFAULT_COLUMN_WIDTH } from "."; import { DEFAULT_COLUMN_WIDTH } from ".";
export interface TableOptions { type TableOptions = {
HTMLAttributes: Record<string, any>; HTMLAttributes: Record<string, unknown>;
resizable: boolean; resizable: boolean;
handleWidth: number; handleWidth: number;
cellMinWidth: number; cellMinWidth: number;
lastColumnResizable: boolean; lastColumnResizable: boolean;
allowTableNodeSelection: boolean; allowTableNodeSelection: boolean;
} };
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {

View file

@ -3,7 +3,7 @@ import { Fragment, Node as ProsemirrorNode, NodeType } from "@tiptap/pm/model";
export function createCell( export function createCell(
cellType: NodeType, cellType: NodeType,
cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode>, cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode>,
attrs?: Record<string, any> attrs?: Record<string, unknown>
): ProsemirrorNode | null | undefined { ): ProsemirrorNode | null | undefined {
if (cellContent) { if (cellContent) {
return cellType.createChecked(attrs, cellContent); return cellType.createChecked(attrs, cellContent);

View file

@ -1,4 +1,4 @@
import { Editor, findParentNodeClosestToPos, KeyboardShortcutCommand } from "@tiptap/core"; import { type Editor, findParentNodeClosestToPos, type KeyboardShortcutCommand } from "@tiptap/core";
import type { Node as ProseMirrorNode } from "@tiptap/pm/model"; import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
import { CellSelection, TableMap } from "@tiptap/pm/tables"; import { CellSelection, TableMap } from "@tiptap/pm/tables";
// constants // constants
@ -6,18 +6,18 @@ import { CORE_EXTENSIONS } from "@/constants/extension";
// extensions // extensions
import { isCellEmpty, isCellSelection } from "@/extensions/table/table/utilities/helpers"; import { isCellEmpty, isCellSelection } from "@/extensions/table/table/utilities/helpers";
interface CellCoord { type CellCoord = {
row: number; row: number;
col: number; col: number;
} };
interface TableInfo { type TableInfo = {
node: ProseMirrorNode; node: ProseMirrorNode;
pos: number; pos: number;
map: TableMap; map: TableMap;
totalColumns: number; totalColumns: number;
totalRows: number; totalRows: number;
} };
export const handleDeleteKeyOnTable: KeyboardShortcutCommand = (props) => { export const handleDeleteKeyOnTable: KeyboardShortcutCommand = (props) => {
const { editor } = props; const { editor } = props;

View file

@ -1,6 +1,8 @@
import type { Node as ProseMirrorNode } from "@tiptap/pm/model"; import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
import type { Selection } from "@tiptap/pm/state"; import type { Selection } from "@tiptap/pm/state";
import { CellSelection } from "@tiptap/pm/tables"; import { CellSelection } from "@tiptap/pm/tables";
// constants
import { CORE_EXTENSIONS } from "@/constants/extension";
/** /**
* @description Check if the selection is a cell selection * @description Check if the selection is a cell selection
@ -22,7 +24,7 @@ export const isCellEmpty = (cell: ProseMirrorNode | null): boolean => {
// Check if cell has any non-empty content // Check if cell has any non-empty content
let hasContent = false; let hasContent = false;
cell.content.forEach((node) => { cell.content.forEach((node) => {
if (node.type.name === "paragraph") { if (node.type.name === CORE_EXTENSIONS.PARAGRAPH) {
if (node.content.size > 0) { if (node.content.size > 0) {
hasContent = true; hasContent = true;
} }

View file

@ -1,6 +1,6 @@
import { textInputRule } from "@tiptap/core"; import { textInputRule } from "@tiptap/core";
export interface TypographyOptions { export type TypographyOptions = {
emDash: false | string; emDash: false | string;
ellipsis: false | string; ellipsis: false | string;
leftArrow: false | string; leftArrow: false | string;
@ -20,7 +20,7 @@ export interface TypographyOptions {
oneQuarter: false | string; oneQuarter: false | string;
threeQuarters: false | string; threeQuarters: false | string;
impliesArrowRight: false | string; impliesArrowRight: false | string;
} };
export const emDash = (override?: string) => export const emDash = (override?: string) =>
textInputRule({ textInputRule({

View file

@ -30,13 +30,13 @@ declare module "@tiptap/core" {
} }
} }
export interface UtilityExtensionStorage { export type UtilityExtensionStorage = {
assetsList: TEditorAsset[]; assetsList: TEditorAsset[];
assetsUploadStatus: TFileHandler["assetsUploadStatus"]; assetsUploadStatus: TFileHandler["assetsUploadStatus"];
uploadInProgress: boolean; uploadInProgress: boolean;
activeDropbarExtensions: TActiveDropbarExtensions[]; activeDropbarExtensions: TActiveDropbarExtensions[];
isTouchDevice: boolean; isTouchDevice: boolean;
} };
type Props = Pick<IEditorProps, "disabledExtensions"> & { type Props = Pick<IEditorProps, "disabledExtensions"> & {
fileHandler: TFileHandler; fileHandler: TFileHandler;

View file

@ -1,4 +1,4 @@
import { ReactNodeViewRenderer, NodeViewWrapper } from "@tiptap/react"; import { ReactNodeViewRenderer, NodeViewWrapper, type NodeViewProps } from "@tiptap/react";
// local imports // local imports
import { WorkItemEmbedExtensionConfig } from "./extension-config"; import { WorkItemEmbedExtensionConfig } from "./extension-config";
@ -17,7 +17,7 @@ type Props = {
export const WorkItemEmbedExtension = (props: Props) => export const WorkItemEmbedExtension = (props: Props) =>
WorkItemEmbedExtensionConfig.extend({ WorkItemEmbedExtensionConfig.extend({
addNodeView() { addNodeView() {
return ReactNodeViewRenderer((issueProps: any) => ( return ReactNodeViewRenderer((issueProps: NodeViewProps) => (
<NodeViewWrapper> <NodeViewWrapper>
{props.widgetCallback({ {props.widgetCallback({
issueId: issueProps.node.attrs.entity_identifier, issueId: issueProps.node.attrs.entity_identifier,

View file

@ -5,13 +5,13 @@ import { cn } from "@plane/utils";
// constants // constants
import { CORE_EXTENSIONS } from "@/constants/extension"; import { CORE_EXTENSIONS } from "@/constants/extension";
interface EditorClassNames { type EditorClassNameArgs = {
noBorder?: boolean; noBorder?: boolean;
borderOnFocus?: boolean; borderOnFocus?: boolean;
containerClassName?: string; containerClassName?: string;
} };
export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassName }: EditorClassNames) => export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassName }: EditorClassNameArgs) =>
cn( cn(
"w-full max-w-full sm:rounded-lg focus:outline-none focus:border-0", "w-full max-w-full sm:rounded-lg focus:outline-none focus:border-0",
{ {

View file

@ -1,11 +1,6 @@
import { Editor } from "@tiptap/react"; import type { Editor } from "@tiptap/react";
// types
export interface IMarking { import type { IMarking } from "@/types";
type: "heading";
level: number;
text: string;
sequence: number;
}
function findNthH1(editor: Editor, n: number, level: number): number { function findNthH1(editor: Editor, n: number, level: number): number {
let count = 0; let count = 0;

View file

@ -4,10 +4,9 @@ import type { Selection } from "@tiptap/pm/state";
import type { EditorProps, EditorView } from "@tiptap/pm/view"; import type { EditorProps, EditorView } from "@tiptap/pm/view";
// extension types // extension types
import type { TTextAlign } from "@/extensions"; import type { TTextAlign } from "@/extensions";
// helpers
import type { IMarking } from "@/helpers/scroll-to-node";
// types // types
import type { import type {
IMarking,
TAIHandler, TAIHandler,
TDisplayConfig, TDisplayConfig,
TDocumentEventEmitter, TDocumentEventEmitter,
@ -129,7 +128,7 @@ export type EditorRefApi = {
}; };
// editor props // editor props
export interface IEditorProps { export type IEditorProps = {
autofocus?: boolean; autofocus?: boolean;
bubbleMenuEnabled?: boolean; bubbleMenuEnabled?: boolean;
containerClassName?: string; containerClassName?: string;
@ -155,7 +154,7 @@ export interface IEditorProps {
placeholder?: string | ((isFocused: boolean, value: string) => string); placeholder?: string | ((isFocused: boolean, value: string) => string);
tabIndex?: number; tabIndex?: number;
value?: string | null; value?: string | null;
} };
export type ILiteTextEditorProps = IEditorProps; export type ILiteTextEditorProps = IEditorProps;
@ -163,8 +162,7 @@ export type IRichTextEditorProps = IEditorProps & {
dragDropEnabled?: boolean; dragDropEnabled?: boolean;
}; };
export interface ICollaborativeDocumentEditorProps export type ICollaborativeDocumentEditorProps = Omit<IEditorProps, "initialValue" | "onEnterKeyPress" | "value"> & {
extends Omit<IEditorProps, "initialValue" | "onEnterKeyPress" | "value"> {
aiHandler?: TAIHandler; aiHandler?: TAIHandler;
documentLoaderClassName?: string; documentLoaderClassName?: string;
dragDropEnabled?: boolean; dragDropEnabled?: boolean;
@ -173,16 +171,16 @@ export interface ICollaborativeDocumentEditorProps
realtimeConfig: TRealtimeConfig; realtimeConfig: TRealtimeConfig;
serverHandler?: TServerHandler; serverHandler?: TServerHandler;
user: TUserDetails; user: TUserDetails;
} };
export interface IDocumentEditorProps extends Omit<IEditorProps, "initialValue" | "onEnterKeyPress" | "value"> { export type IDocumentEditorProps = Omit<IEditorProps, "initialValue" | "onEnterKeyPress" | "value"> & {
aiHandler?: TAIHandler; aiHandler?: TAIHandler;
embedHandler: TEmbedConfig; embedHandler: TEmbedConfig;
user?: TUserDetails; user?: TUserDetails;
value: Content; value: Content;
} };
export interface EditorEvents { export type EditorEvents = {
beforeCreate: never; beforeCreate: never;
create: never; create: never;
update: never; update: never;
@ -192,4 +190,4 @@ export interface EditorEvents {
blur: never; blur: never;
destroy: never; destroy: never;
ready: { height: number }; ready: { height: number };
} };