@junbyeol/tiptap-editor 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/dist/index.cjs +215 -0
- package/dist/index.mjs +28278 -0
- package/dist/style.css +1 -0
- package/dist/types/components/custom/color-text-popover.d.ts +11 -0
- package/dist/types/components/custom/table-cell-background-color-popover.d.ts +11 -0
- package/dist/types/components/custom/variables.d.ts +41 -0
- package/dist/types/components/tiptap-icons/align-center-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/align-justify-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/align-left-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/align-right-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/bold-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/chevron-down-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/code2-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-five-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-four-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-one-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-six-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-three-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/heading-two-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/italic-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/list-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/list-ordered-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/list-todo-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/redo2-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/strike-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/subscript-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/superscript-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/underline-icon.d.ts +3 -0
- package/dist/types/components/tiptap-icons/undo2-icon.d.ts +3 -0
- package/dist/types/components/tiptap-ui/heading-button/heading-button.d.ts +23 -0
- package/dist/types/components/tiptap-ui/heading-button/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/heading-button/use-heading.d.ts +108 -0
- package/dist/types/components/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.d.ts +20 -0
- package/dist/types/components/tiptap-ui/heading-dropdown-menu/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/heading-dropdown-menu/use-heading-dropdown-menu.d.ts +73 -0
- package/dist/types/components/tiptap-ui/list-button/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/list-button/list-button.d.ts +23 -0
- package/dist/types/components/tiptap-ui/list-button/use-list.d.ts +97 -0
- package/dist/types/components/tiptap-ui/mark-button/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/mark-button/mark-button.d.ts +23 -0
- package/dist/types/components/tiptap-ui/mark-button/use-mark.d.ts +104 -0
- package/dist/types/components/tiptap-ui/text-align-button/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/text-align-button/text-align-button.d.ts +30 -0
- package/dist/types/components/tiptap-ui/text-align-button/use-text-align.d.ts +101 -0
- package/dist/types/components/tiptap-ui/undo-redo-button/index.d.ts +2 -0
- package/dist/types/components/tiptap-ui/undo-redo-button/undo-redo-button.d.ts +23 -0
- package/dist/types/components/tiptap-ui/undo-redo-button/use-undo-redo.d.ts +90 -0
- package/dist/types/components/tiptap-ui-primitive/badge/badge.d.ts +8 -0
- package/dist/types/components/tiptap-ui-primitive/badge/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/button/button.d.ts +17 -0
- package/dist/types/components/tiptap-ui-primitive/button/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/card/card.d.ts +9 -0
- package/dist/types/components/tiptap-ui-primitive/card/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/dropdown-menu/dropdown-menu.d.ts +16 -0
- package/dist/types/components/tiptap-ui-primitive/dropdown-menu/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/label/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/label/label.d.ts +11 -0
- package/dist/types/components/tiptap-ui-primitive/popover/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/popover/popover.d.ts +5 -0
- package/dist/types/components/tiptap-ui-primitive/separator/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/separator/separator.d.ts +6 -0
- package/dist/types/components/tiptap-ui-primitive/spacer/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/spacer/spacer.d.ts +6 -0
- package/dist/types/components/tiptap-ui-primitive/toolbar/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/toolbar/toolbar.d.ts +8 -0
- package/dist/types/components/tiptap-ui-primitive/tooltip/index.d.ts +1 -0
- package/dist/types/components/tiptap-ui-primitive/tooltip/tooltip.d.ts +28 -0
- package/dist/types/hooks/use-composed-ref.d.ts +3 -0
- package/dist/types/hooks/use-is-breakpoint.d.ts +9 -0
- package/dist/types/hooks/use-menu-navigation.d.ts +52 -0
- package/dist/types/hooks/use-tiptap-editor.d.ts +17 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/index.d.ts +5 -0
- package/dist/types/lib/tiptap-utils.d.ts +168 -0
- package/dist/types/tiptap/extensions/default-file-attachment.d.ts +2 -0
- package/dist/types/tiptap/extensions/file-attachment.d.ts +13 -0
- package/dist/types/tiptap/index.d.ts +29 -0
- package/dist/types/tiptap/menubar.d.ts +4 -0
- package/dist/vite.svg +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { FloatingPortal, Placement } from '@floating-ui/react';
|
|
2
|
+
interface TooltipProviderProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
initialOpen?: boolean;
|
|
5
|
+
placement?: Placement;
|
|
6
|
+
open?: boolean;
|
|
7
|
+
onOpenChange?: (open: boolean) => void;
|
|
8
|
+
delay?: number;
|
|
9
|
+
closeDelay?: number;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
useDelayGroup?: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface TooltipTriggerProps extends Omit<React.HTMLProps<HTMLElement>, "ref"> {
|
|
14
|
+
asChild?: boolean;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
interface TooltipContentProps extends Omit<React.HTMLProps<HTMLDivElement>, "ref"> {
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
portal?: boolean;
|
|
20
|
+
portalProps?: Omit<React.ComponentProps<typeof FloatingPortal>, "children">;
|
|
21
|
+
}
|
|
22
|
+
export declare function Tooltip({ children, ...props }: TooltipProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export declare namespace Tooltip {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const TooltipTrigger: import('react').ForwardRefExoticComponent<TooltipTriggerProps & import('react').RefAttributes<HTMLElement>>;
|
|
27
|
+
export declare const TooltipContent: import('react').ForwardRefExoticComponent<TooltipContentProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
type UserRef<T> = ((instance: T | null) => void) | React.RefObject<T | null> | null | undefined;
|
|
2
|
+
export declare const useComposedRef: <T extends HTMLElement>(libRef: React.RefObject<T | null>, userRef: UserRef<T>) => (instance: T | null) => void;
|
|
3
|
+
export default useComposedRef;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type BreakpointMode = "min" | "max";
|
|
2
|
+
/**
|
|
3
|
+
* Hook to detect whether the current viewport matches a given breakpoint rule.
|
|
4
|
+
* Example:
|
|
5
|
+
* useIsBreakpoint("max", 768) // true when width < 768
|
|
6
|
+
* useIsBreakpoint("min", 1024) // true when width >= 1024
|
|
7
|
+
*/
|
|
8
|
+
export declare function useIsBreakpoint(mode?: BreakpointMode, breakpoint?: number): boolean;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/react';
|
|
2
|
+
type Orientation = "horizontal" | "vertical" | "both";
|
|
3
|
+
interface MenuNavigationOptions<T> {
|
|
4
|
+
/**
|
|
5
|
+
* The Tiptap editor instance, if using with a Tiptap editor.
|
|
6
|
+
*/
|
|
7
|
+
editor?: Editor | null;
|
|
8
|
+
/**
|
|
9
|
+
* Reference to the container element for handling keyboard events.
|
|
10
|
+
*/
|
|
11
|
+
containerRef?: React.RefObject<HTMLElement | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Search query that affects the selected item.
|
|
14
|
+
*/
|
|
15
|
+
query?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Array of items to navigate through.
|
|
18
|
+
*/
|
|
19
|
+
items: T[];
|
|
20
|
+
/**
|
|
21
|
+
* Callback fired when an item is selected.
|
|
22
|
+
*/
|
|
23
|
+
onSelect?: (item: T) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Callback fired when the menu should close.
|
|
26
|
+
*/
|
|
27
|
+
onClose?: () => void;
|
|
28
|
+
/**
|
|
29
|
+
* The navigation orientation of the menu.
|
|
30
|
+
* @default "vertical"
|
|
31
|
+
*/
|
|
32
|
+
orientation?: Orientation;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to automatically select the first item when the menu opens.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
autoSelectFirstItem?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Hook that implements keyboard navigation for dropdown menus and command palettes.
|
|
41
|
+
*
|
|
42
|
+
* Handles arrow keys, tab, home/end, enter for selection, and escape to close.
|
|
43
|
+
* Works with both Tiptap editors and regular DOM elements.
|
|
44
|
+
*
|
|
45
|
+
* @param options - Configuration options for the menu navigation
|
|
46
|
+
* @returns Object containing the selected index and a setter function
|
|
47
|
+
*/
|
|
48
|
+
export declare function useMenuNavigation<T>({ editor, containerRef, query, items, onSelect, onClose, orientation, autoSelectFirstItem, }: MenuNavigationOptions<T>): {
|
|
49
|
+
selectedIndex: number | undefined;
|
|
50
|
+
setSelectedIndex: import('react').Dispatch<import('react').SetStateAction<number>>;
|
|
51
|
+
};
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Editor } from '@tiptap/react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook that provides access to a Tiptap editor instance.
|
|
4
|
+
*
|
|
5
|
+
* Accepts an optional editor instance directly, or falls back to retrieving
|
|
6
|
+
* the editor from the Tiptap context if available. This allows components
|
|
7
|
+
* to work both when given an editor directly and when used within a Tiptap
|
|
8
|
+
* editor context.
|
|
9
|
+
*
|
|
10
|
+
* @param providedEditor - Optional editor instance to use instead of the context editor
|
|
11
|
+
* @returns The provided editor or the editor from context, whichever is available
|
|
12
|
+
*/
|
|
13
|
+
export declare function useTiptapEditor(providedEditor?: Editor | null): {
|
|
14
|
+
editor: Editor | null;
|
|
15
|
+
editorState?: Editor["state"];
|
|
16
|
+
canCommand?: Editor["can"];
|
|
17
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as TiptapEditor } from '../tiptap/index';
|
|
2
|
+
export type { TiptapProps } from '../tiptap/index';
|
|
3
|
+
export type { FileAttachmentAttributes } from '../tiptap/extensions/file-attachment';
|
|
4
|
+
export { createFileAttachmentExtension } from '../tiptap/extensions/file-attachment';
|
|
5
|
+
export { DefaultFileAttachmentComponent } from '../tiptap/extensions/default-file-attachment';
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Node as PMNode } from '@tiptap/pm/model';
|
|
2
|
+
import { Transaction, Selection } from '@tiptap/pm/state';
|
|
3
|
+
import { Editor, NodeWithPos } from '@tiptap/react';
|
|
4
|
+
export declare const MAX_FILE_SIZE: number;
|
|
5
|
+
export declare const MAC_SYMBOLS: Record<string, string>;
|
|
6
|
+
export declare const SR_ONLY: {
|
|
7
|
+
readonly position: "absolute";
|
|
8
|
+
readonly width: "1px";
|
|
9
|
+
readonly height: "1px";
|
|
10
|
+
readonly padding: 0;
|
|
11
|
+
readonly margin: "-1px";
|
|
12
|
+
readonly overflow: "hidden";
|
|
13
|
+
readonly clip: "rect(0, 0, 0, 0)";
|
|
14
|
+
readonly whiteSpace: "nowrap";
|
|
15
|
+
readonly borderWidth: 0;
|
|
16
|
+
};
|
|
17
|
+
export declare function cn(...classes: (string | boolean | undefined | null)[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Determines if the current platform is macOS
|
|
20
|
+
* @returns boolean indicating if the current platform is Mac
|
|
21
|
+
*/
|
|
22
|
+
export declare function isMac(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Formats a shortcut key based on the platform (Mac or non-Mac)
|
|
25
|
+
* @param key - The key to format (e.g., "ctrl", "alt", "shift")
|
|
26
|
+
* @param isMac - Boolean indicating if the platform is Mac
|
|
27
|
+
* @param capitalize - Whether to capitalize the key (default: true)
|
|
28
|
+
* @returns Formatted shortcut key symbol
|
|
29
|
+
*/
|
|
30
|
+
export declare const formatShortcutKey: (key: string, isMac: boolean, capitalize?: boolean) => string;
|
|
31
|
+
/**
|
|
32
|
+
* Parses a shortcut key string into an array of formatted key symbols
|
|
33
|
+
* @param shortcutKeys - The string of shortcut keys (e.g., "ctrl-alt-shift")
|
|
34
|
+
* @param delimiter - The delimiter used to split the keys (default: "-")
|
|
35
|
+
* @param capitalize - Whether to capitalize the keys (default: true)
|
|
36
|
+
* @returns Array of formatted shortcut key symbols
|
|
37
|
+
*/
|
|
38
|
+
export declare const parseShortcutKeys: (props: {
|
|
39
|
+
shortcutKeys: string | undefined;
|
|
40
|
+
delimiter?: string;
|
|
41
|
+
capitalize?: boolean;
|
|
42
|
+
}) => string[];
|
|
43
|
+
/**
|
|
44
|
+
* Checks if a mark exists in the editor schema
|
|
45
|
+
* @param markName - The name of the mark to check
|
|
46
|
+
* @param editor - The editor instance
|
|
47
|
+
* @returns boolean indicating if the mark exists in the schema
|
|
48
|
+
*/
|
|
49
|
+
export declare const isMarkInSchema: (markName: string, editor: Editor | null) => boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Checks if a node exists in the editor schema
|
|
52
|
+
* @param nodeName - The name of the node to check
|
|
53
|
+
* @param editor - The editor instance
|
|
54
|
+
* @returns boolean indicating if the node exists in the schema
|
|
55
|
+
*/
|
|
56
|
+
export declare const isNodeInSchema: (nodeName: string, editor: Editor | null) => boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Moves the focus to the next node in the editor
|
|
59
|
+
* @param editor - The editor instance
|
|
60
|
+
* @returns boolean indicating if the focus was moved
|
|
61
|
+
*/
|
|
62
|
+
export declare function focusNextNode(editor: Editor): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Checks if a value is a valid number (not null, undefined, or NaN)
|
|
65
|
+
* @param value - The value to check
|
|
66
|
+
* @returns boolean indicating if the value is a valid number
|
|
67
|
+
*/
|
|
68
|
+
export declare function isValidPosition(pos: number | null | undefined): pos is number;
|
|
69
|
+
/**
|
|
70
|
+
* Checks if one or more extensions are registered in the Tiptap editor.
|
|
71
|
+
* @param editor - The Tiptap editor instance
|
|
72
|
+
* @param extensionNames - A single extension name or an array of names to check
|
|
73
|
+
* @returns True if at least one of the extensions is available, false otherwise
|
|
74
|
+
*/
|
|
75
|
+
export declare function isExtensionAvailable(editor: Editor | null, extensionNames: string | string[]): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Finds a node at the specified position with error handling
|
|
78
|
+
* @param editor The Tiptap editor instance
|
|
79
|
+
* @param position The position in the document to find the node
|
|
80
|
+
* @returns The node at the specified position, or null if not found
|
|
81
|
+
*/
|
|
82
|
+
export declare function findNodeAtPosition(editor: Editor, position: number): PMNode | null;
|
|
83
|
+
/**
|
|
84
|
+
* Finds the position and instance of a node in the document
|
|
85
|
+
* @param props Object containing editor, node (optional), and nodePos (optional)
|
|
86
|
+
* @param props.editor The Tiptap editor instance
|
|
87
|
+
* @param props.node The node to find (optional if nodePos is provided)
|
|
88
|
+
* @param props.nodePos The position of the node to find (optional if node is provided)
|
|
89
|
+
* @returns An object with the position and node, or null if not found
|
|
90
|
+
*/
|
|
91
|
+
export declare function findNodePosition(props: {
|
|
92
|
+
editor: Editor | null;
|
|
93
|
+
node?: PMNode | null;
|
|
94
|
+
nodePos?: number | null;
|
|
95
|
+
}): {
|
|
96
|
+
pos: number;
|
|
97
|
+
node: PMNode;
|
|
98
|
+
} | null;
|
|
99
|
+
/**
|
|
100
|
+
* Determines whether the current selection contains a node whose type matches
|
|
101
|
+
* any of the provided node type names.
|
|
102
|
+
* @param editor Tiptap editor instance
|
|
103
|
+
* @param nodeTypeNames List of node type names to match against
|
|
104
|
+
* @param checkAncestorNodes Whether to check ancestor node types up the depth chain
|
|
105
|
+
*/
|
|
106
|
+
export declare function isNodeTypeSelected(editor: Editor | null, nodeTypeNames?: string[], checkAncestorNodes?: boolean): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Check whether the current selection is fully within nodes
|
|
109
|
+
* whose type names are in the provided `types` list.
|
|
110
|
+
*
|
|
111
|
+
* - NodeSelection → checks the selected node.
|
|
112
|
+
* - Text/AllSelection → ensures all textblocks within [from, to) are allowed.
|
|
113
|
+
*/
|
|
114
|
+
export declare function selectionWithinConvertibleTypes(editor: Editor, types?: string[]): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Handles image upload with progress tracking and abort capability
|
|
117
|
+
* @param file The file to upload
|
|
118
|
+
* @param onProgress Optional callback for tracking upload progress
|
|
119
|
+
* @param abortSignal Optional AbortSignal for cancelling the upload
|
|
120
|
+
* @returns Promise resolving to the URL of the uploaded image
|
|
121
|
+
*/
|
|
122
|
+
export declare const handleImageUpload: (file: File, onProgress?: (event: {
|
|
123
|
+
progress: number;
|
|
124
|
+
}) => void, abortSignal?: AbortSignal) => Promise<string>;
|
|
125
|
+
type ProtocolOptions = {
|
|
126
|
+
/**
|
|
127
|
+
* The protocol scheme to be registered.
|
|
128
|
+
* @default '''
|
|
129
|
+
* @example 'ftp'
|
|
130
|
+
* @example 'git'
|
|
131
|
+
*/
|
|
132
|
+
scheme: string;
|
|
133
|
+
/**
|
|
134
|
+
* If enabled, it allows optional slashes after the protocol.
|
|
135
|
+
* @default false
|
|
136
|
+
* @example true
|
|
137
|
+
*/
|
|
138
|
+
optionalSlashes?: boolean;
|
|
139
|
+
};
|
|
140
|
+
type ProtocolConfig = Array<ProtocolOptions | string>;
|
|
141
|
+
export declare function isAllowedUri(uri: string | undefined, protocols?: ProtocolConfig): true | RegExpMatchArray | null;
|
|
142
|
+
export declare function sanitizeUrl(inputUrl: string, baseUrl: string, protocols?: ProtocolConfig): string;
|
|
143
|
+
/**
|
|
144
|
+
* Update a single attribute on multiple nodes.
|
|
145
|
+
*
|
|
146
|
+
* @param tr - The transaction to mutate
|
|
147
|
+
* @param targets - Array of { node, pos }
|
|
148
|
+
* @param attrName - Attribute key to update
|
|
149
|
+
* @param next - New value OR updater function receiving previous value
|
|
150
|
+
* Pass `undefined` to remove the attribute.
|
|
151
|
+
* @returns true if at least one node was updated, false otherwise
|
|
152
|
+
*/
|
|
153
|
+
export declare function updateNodesAttr<A extends string = string, V = unknown>(tr: Transaction, targets: readonly NodeWithPos[], attrName: A, next: V | ((prev: V | undefined) => V | undefined)): boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Selects the entire content of the current block node if the selection is empty.
|
|
156
|
+
* If the selection is not empty, it does nothing.
|
|
157
|
+
* @param editor The Tiptap editor instance
|
|
158
|
+
*/
|
|
159
|
+
export declare function selectCurrentBlockContent(editor: Editor): void;
|
|
160
|
+
/**
|
|
161
|
+
* Retrieves all nodes of specified types from the current selection.
|
|
162
|
+
* @param selection The current editor selection
|
|
163
|
+
* @param allowedNodeTypes An array of node type names to look for (e.g., ["image", "table"])
|
|
164
|
+
* @returns An array of objects containing the node and its position
|
|
165
|
+
*/
|
|
166
|
+
export declare function getSelectedNodesOfType(selection: Selection, allowedNodeTypes: string[]): NodeWithPos[];
|
|
167
|
+
export declare function getSelectedBlockNodes(editor: Editor): PMNode[];
|
|
168
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Node } from '@tiptap/core';
|
|
2
|
+
import { ComponentType, RefObject } from 'react';
|
|
3
|
+
export interface FileAttachmentAttributes {
|
|
4
|
+
name: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
url: string;
|
|
7
|
+
size: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* componentRef를 인자로 받아 FileAttachment Node 확장을 생성하는 팩토리 함수.
|
|
11
|
+
* ref 패턴을 사용하므로 컴포넌트가 동적으로 교체되어도 stale 클로저가 발생하지 않는다.
|
|
12
|
+
*/
|
|
13
|
+
export declare const createFileAttachmentExtension: (componentRef: RefObject<ComponentType<FileAttachmentAttributes> | undefined>) => Node<any, any>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { FileAttachmentAttributes } from './extensions/file-attachment';
|
|
3
|
+
export interface TiptapProps {
|
|
4
|
+
/**
|
|
5
|
+
* 제공 시: 파일을 CDN에 업로드하고 URL을 반환.
|
|
6
|
+
* 미제공 시: FileReader로 base64 변환 후 브라우저 메모리에 임시 저장.
|
|
7
|
+
*/
|
|
8
|
+
uploadFile?: (file: File) => Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* 파일이 에디터에 삽입될 때 호출되는 콜백.
|
|
11
|
+
*/
|
|
12
|
+
onFileInsert?: (file: File) => void;
|
|
13
|
+
/**
|
|
14
|
+
* 파일 업로드 오류 시 호출되는 콜백.
|
|
15
|
+
*/
|
|
16
|
+
onFileError?: (error: Error) => void;
|
|
17
|
+
/**
|
|
18
|
+
* true 시 이미지 외 파일(PDF, Word 등)도 허용.
|
|
19
|
+
* FileAttachmentComponent가 함께 제공되어야 에디터에 렌더링됨.
|
|
20
|
+
*/
|
|
21
|
+
allowNonImageFile?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 비이미지 파일을 에디터에 렌더링할 React 컴포넌트.
|
|
24
|
+
* allowNonImageFile이 true일 때 유효하며, name/mimeType/url/size를 props로 받는다.
|
|
25
|
+
*/
|
|
26
|
+
FileAttachmentComponent?: ComponentType<FileAttachmentAttributes>;
|
|
27
|
+
}
|
|
28
|
+
declare const TiptapEditor: ({ uploadFile, onFileInsert, onFileError, allowNonImageFile, FileAttachmentComponent, }: TiptapProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export default TiptapEditor;
|
package/dist/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@junbyeol/tiptap-editor",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/types/index.d.ts",
|
|
16
|
+
"default": "./dist/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./style.css": "./dist/style.css"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"dev": "vite",
|
|
26
|
+
"build": "tsc -b && vite build",
|
|
27
|
+
"build:lib": "vite build --config vite.lib.config.ts",
|
|
28
|
+
"lint": "eslint .",
|
|
29
|
+
"preview": "vite preview",
|
|
30
|
+
"prettier": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md,scss}\"",
|
|
31
|
+
"lint-staged": "lint-staged",
|
|
32
|
+
"prepare": "husky"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": "^19.0.0",
|
|
36
|
+
"react-dom": "^19.0.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@floating-ui/react": "^0.27.19",
|
|
40
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
41
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
42
|
+
"@remixicon/react": "^4.9.0",
|
|
43
|
+
"@tiptap/extension-file-handler": "^3.22.2",
|
|
44
|
+
"@tiptap/extension-image": "^3.22.2",
|
|
45
|
+
"@tiptap/extension-list": "^3.20.1",
|
|
46
|
+
"@tiptap/extension-subscript": "^3.20.1",
|
|
47
|
+
"@tiptap/extension-superscript": "^3.20.1",
|
|
48
|
+
"@tiptap/extension-table": "^3.20.1",
|
|
49
|
+
"@tiptap/extension-text-align": "^3.20.1",
|
|
50
|
+
"@tiptap/extension-text-style": "^3.20.1",
|
|
51
|
+
"@tiptap/extension-underline": "^3.20.1",
|
|
52
|
+
"@tiptap/pm": "^3.20.1",
|
|
53
|
+
"@tiptap/react": "^3.20.1",
|
|
54
|
+
"@tiptap/starter-kit": "^3.20.1",
|
|
55
|
+
"react-hotkeys-hook": "^5.2.4"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/js": "^9.39.1",
|
|
59
|
+
"@types/node": "^25.3.5",
|
|
60
|
+
"@types/react": "^19.2.7",
|
|
61
|
+
"@types/react-dom": "^19.2.3",
|
|
62
|
+
"@vitejs/plugin-react-swc": "^4.2.2",
|
|
63
|
+
"eslint": "^9.39.1",
|
|
64
|
+
"eslint-config-prettier": "^10.1.8",
|
|
65
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
66
|
+
"eslint-plugin-react-refresh": "^0.4.24",
|
|
67
|
+
"globals": "^16.5.0",
|
|
68
|
+
"husky": "^9.1.7",
|
|
69
|
+
"lint-staged": "^16.3.3",
|
|
70
|
+
"prettier": "^3.8.1",
|
|
71
|
+
"react": "^19.2.0",
|
|
72
|
+
"react-dom": "^19.2.0",
|
|
73
|
+
"react-toastify": "^11.0.5",
|
|
74
|
+
"sass-embedded": "^1.97.3",
|
|
75
|
+
"typescript": "~5.9.3",
|
|
76
|
+
"typescript-eslint": "^8.48.0",
|
|
77
|
+
"vite": "^7.3.1",
|
|
78
|
+
"vite-plugin-dts": "^4.5.4"
|
|
79
|
+
},
|
|
80
|
+
"lint-staged": {
|
|
81
|
+
"*.{ts,tsx}": [
|
|
82
|
+
"prettier --write",
|
|
83
|
+
"eslint --no-warn-ignored --max-warnings=0"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|