@kopexa/tiptap 17.8.5 → 17.9.1
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/dist/index.d.mts +117 -2
- package/dist/index.d.ts +117 -2
- package/dist/index.js +115 -4
- package/dist/index.mjs +113 -4
- package/package.json +26 -25
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tiptap_core from '@tiptap/core';
|
|
2
|
-
import { Node, JSONContent } from '@tiptap/core';
|
|
2
|
+
import { Node, JSONContent, Content as Content$1 } from '@tiptap/core';
|
|
3
3
|
export { Content, JSONContent } from '@tiptap/core';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { HocuspocusProvider } from '@hocuspocus/provider';
|
|
@@ -646,6 +646,121 @@ type BasicEditorProps = GetExtensionsOptions & EditorBasicVariants & {
|
|
|
646
646
|
};
|
|
647
647
|
declare const BasicEditor: ({ variant, bordered, content, variables, variableValues, showToolbar, pagesOptions, ...options }: BasicEditorProps) => react_jsx_runtime.JSX.Element;
|
|
648
648
|
|
|
649
|
+
type EditorViewProps = EditorBasicVariants & Pick<GetExtensionsOptions, "customExtensions" | "disabled"> & {
|
|
650
|
+
/**
|
|
651
|
+
* The TipTap content to render.
|
|
652
|
+
* Accepts JSON, HTML string, Markdown string, or plain text.
|
|
653
|
+
* Internally parsed via `safeParseContent` — same as the `Editor` component.
|
|
654
|
+
*/
|
|
655
|
+
content?: Content$1 | undefined;
|
|
656
|
+
/** Additional CSS class names for the root container. */
|
|
657
|
+
className?: string;
|
|
658
|
+
};
|
|
659
|
+
/**
|
|
660
|
+
* Client-side read-only viewer for TipTap content.
|
|
661
|
+
*
|
|
662
|
+
* Uses a real TipTap editor instance in `editable: false` mode, so all
|
|
663
|
+
* NodeViews (images with file-reference resolution, callouts, code blocks,
|
|
664
|
+
* math, tables, etc.) render exactly as they do in the editor — but
|
|
665
|
+
* without the toolbar, bubble menus, slash commands, or collaboration.
|
|
666
|
+
*
|
|
667
|
+
* **Why not `generateHTML`?** Some node types use React NodeViews that
|
|
668
|
+
* resolve data at render time (e.g., images stored as file references that
|
|
669
|
+
* need a signed URL). `generateHTML` produces static HTML and cannot run
|
|
670
|
+
* these React components, resulting in broken images and missing features.
|
|
671
|
+
*
|
|
672
|
+
* **When to use:**
|
|
673
|
+
* - Detail pages, previews, or anywhere you need to display editor content
|
|
674
|
+
* with full NodeView fidelity (image resolution, interactive blocks).
|
|
675
|
+
* - Must be used inside `EditorFileProvider` if your content contains
|
|
676
|
+
* file-reference images.
|
|
677
|
+
*
|
|
678
|
+
* **For server-side rendering** (RSC, SSR, Node.js) where no React NodeViews
|
|
679
|
+
* are needed, use `EditorStaticView` instead. It uses `@tiptap/html` with
|
|
680
|
+
* a virtual DOM and produces pure HTML — but images must already be resolved.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```tsx
|
|
684
|
+
* import { EditorView } from "@kopexa/tiptap";
|
|
685
|
+
*
|
|
686
|
+
* function DocumentPreview({ content }: { content: JSONContent }) {
|
|
687
|
+
* return <EditorView content={content} variant="document" />;
|
|
688
|
+
* }
|
|
689
|
+
* ```
|
|
690
|
+
*
|
|
691
|
+
* @example With file resolution
|
|
692
|
+
* ```tsx
|
|
693
|
+
* import { EditorFileProvider, EditorView } from "@kopexa/tiptap";
|
|
694
|
+
*
|
|
695
|
+
* function DocumentDetail({ content }: { content: JSONContent }) {
|
|
696
|
+
* return (
|
|
697
|
+
* <EditorFileProvider onUpload={upload} onResolve={resolve}>
|
|
698
|
+
* <EditorView content={content} variant="document" />
|
|
699
|
+
* </EditorFileProvider>
|
|
700
|
+
* );
|
|
701
|
+
* }
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
declare function EditorView({ content, variant, bordered, className, customExtensions, disabled, }: EditorViewProps): react_jsx_runtime.JSX.Element | null;
|
|
705
|
+
|
|
706
|
+
type EditorStaticViewProps = EditorBasicVariants & Pick<GetExtensionsOptions, "customExtensions" | "disabled"> & {
|
|
707
|
+
/**
|
|
708
|
+
* The TipTap content to render.
|
|
709
|
+
* Accepts JSON, HTML string, Markdown string, or plain text.
|
|
710
|
+
* Internally parsed via `safeParseContent` — same as the `Editor` component.
|
|
711
|
+
*/
|
|
712
|
+
content?: Content$1 | undefined;
|
|
713
|
+
/** Additional CSS class names for the root container. */
|
|
714
|
+
className?: string;
|
|
715
|
+
};
|
|
716
|
+
/**
|
|
717
|
+
* Static HTML viewer for TipTap content.
|
|
718
|
+
*
|
|
719
|
+
* Converts TipTap `JSONContent` to HTML using `generateHTML` from `@tiptap/html`
|
|
720
|
+
* (virtual DOM — no browser required) and renders it with the same styling as
|
|
721
|
+
* the `Editor` component. Works in **Server Components (RSC)**, SSR, and
|
|
722
|
+
* Node.js environments.
|
|
723
|
+
*
|
|
724
|
+
* Uses the full set of registered extensions to ensure all node/mark types
|
|
725
|
+
* produce correct HTML (tables, callouts, code blocks, math, etc.).
|
|
726
|
+
*
|
|
727
|
+
* **Limitations:**
|
|
728
|
+
* - React NodeViews are NOT rendered. Node types that rely on React components
|
|
729
|
+
* (e.g., images with file-reference resolution) will output their default
|
|
730
|
+
* HTML representation. Images stored as file references will NOT be resolved —
|
|
731
|
+
* ensure image `src` values are already displayable URLs before passing content.
|
|
732
|
+
* - No interactive features (no selection, no cursor, no scroll-to-hash).
|
|
733
|
+
*
|
|
734
|
+
* **When to use:**
|
|
735
|
+
* - Server-rendered pages, email templates, PDF generation, or static exports
|
|
736
|
+
* where you need a lightweight, non-interactive HTML representation.
|
|
737
|
+
* - When all image URLs in the content are already resolved (not file references).
|
|
738
|
+
*
|
|
739
|
+
* **For client-side rendering** with full NodeView fidelity (image resolution,
|
|
740
|
+
* interactive blocks), use `EditorView` instead.
|
|
741
|
+
*
|
|
742
|
+
* @example Server Component
|
|
743
|
+
* ```tsx
|
|
744
|
+
* // app/documents/[id]/page.tsx (RSC)
|
|
745
|
+
* import { EditorStaticView } from "@kopexa/tiptap";
|
|
746
|
+
*
|
|
747
|
+
* export default async function DocumentPage({ params }) {
|
|
748
|
+
* const doc = await fetchDocument(params.id);
|
|
749
|
+
* return <EditorStaticView content={doc.content} variant="document" />;
|
|
750
|
+
* }
|
|
751
|
+
* ```
|
|
752
|
+
*
|
|
753
|
+
* @example Client Component
|
|
754
|
+
* ```tsx
|
|
755
|
+
* import { EditorStaticView } from "@kopexa/tiptap";
|
|
756
|
+
*
|
|
757
|
+
* function LightweightPreview({ content }: { content: JSONContent }) {
|
|
758
|
+
* return <EditorStaticView content={content} variant="inline" />;
|
|
759
|
+
* }
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
declare function EditorStaticView({ content, variant, bordered, className, customExtensions, disabled, }: EditorStaticViewProps): react_jsx_runtime.JSX.Element | null;
|
|
763
|
+
|
|
649
764
|
/**
|
|
650
765
|
* Handles image upload with progress tracking and abort capability
|
|
651
766
|
* @param file The file to upload
|
|
@@ -689,4 +804,4 @@ declare function sanitizeUrl(inputUrl: string, baseUrl: string, protocols?: Prot
|
|
|
689
804
|
*/
|
|
690
805
|
declare function generateColorFromId(id: string): string;
|
|
691
806
|
|
|
692
|
-
export { CalloutNode, type CalloutNodeAttrs, type CalloutVariant, type CollabUser, CollaborationProvider, type CollaborationProviderProps, type CollaborationState, type CollaborationStatus, BasicEditor as Editor, type EditorFileHandler, EditorFileProvider, type EditorFileProviderProps, type GetExtensionsOptions, ImageNode, ImageUploadNode, InlineMath, type InlineMathAttrs, MathBlock, type MathBlockAttrs, type ResolvedCollabUser, TocNode, type VariableDefinition, VariableFillerDialog, type VariableFillerDialogProps, VariableNode, type VariableNodeAttrs, type VariableOptions, VariableProvider, type VariableProviderProps, VariableSuggestion, type VariableSuggestionProps, convertFileToBase64, extractVariablesFromContent, generateColorFromId, getExtensions, handleImageUpload, isAllowedUri, sanitizeUrl, useCollaboration, useCollaborationRequired, useDocumentVisibility, useEditorFile, useEditorFileRequired, useIdle, useVariables, useVariablesWithFallback };
|
|
807
|
+
export { CalloutNode, type CalloutNodeAttrs, type CalloutVariant, type CollabUser, CollaborationProvider, type CollaborationProviderProps, type CollaborationState, type CollaborationStatus, BasicEditor as Editor, type EditorFileHandler, EditorFileProvider, type EditorFileProviderProps, EditorStaticView, type EditorStaticViewProps, EditorView, type EditorViewProps, type GetExtensionsOptions, ImageNode, ImageUploadNode, InlineMath, type InlineMathAttrs, MathBlock, type MathBlockAttrs, type ResolvedCollabUser, TocNode, type VariableDefinition, VariableFillerDialog, type VariableFillerDialogProps, VariableNode, type VariableNodeAttrs, type VariableOptions, VariableProvider, type VariableProviderProps, VariableSuggestion, type VariableSuggestionProps, convertFileToBase64, extractVariablesFromContent, generateColorFromId, getExtensions, handleImageUpload, isAllowedUri, sanitizeUrl, useCollaboration, useCollaborationRequired, useDocumentVisibility, useEditorFile, useEditorFileRequired, useIdle, useVariables, useVariablesWithFallback };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tiptap_core from '@tiptap/core';
|
|
2
|
-
import { Node, JSONContent } from '@tiptap/core';
|
|
2
|
+
import { Node, JSONContent, Content as Content$1 } from '@tiptap/core';
|
|
3
3
|
export { Content, JSONContent } from '@tiptap/core';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { HocuspocusProvider } from '@hocuspocus/provider';
|
|
@@ -646,6 +646,121 @@ type BasicEditorProps = GetExtensionsOptions & EditorBasicVariants & {
|
|
|
646
646
|
};
|
|
647
647
|
declare const BasicEditor: ({ variant, bordered, content, variables, variableValues, showToolbar, pagesOptions, ...options }: BasicEditorProps) => react_jsx_runtime.JSX.Element;
|
|
648
648
|
|
|
649
|
+
type EditorViewProps = EditorBasicVariants & Pick<GetExtensionsOptions, "customExtensions" | "disabled"> & {
|
|
650
|
+
/**
|
|
651
|
+
* The TipTap content to render.
|
|
652
|
+
* Accepts JSON, HTML string, Markdown string, or plain text.
|
|
653
|
+
* Internally parsed via `safeParseContent` — same as the `Editor` component.
|
|
654
|
+
*/
|
|
655
|
+
content?: Content$1 | undefined;
|
|
656
|
+
/** Additional CSS class names for the root container. */
|
|
657
|
+
className?: string;
|
|
658
|
+
};
|
|
659
|
+
/**
|
|
660
|
+
* Client-side read-only viewer for TipTap content.
|
|
661
|
+
*
|
|
662
|
+
* Uses a real TipTap editor instance in `editable: false` mode, so all
|
|
663
|
+
* NodeViews (images with file-reference resolution, callouts, code blocks,
|
|
664
|
+
* math, tables, etc.) render exactly as they do in the editor — but
|
|
665
|
+
* without the toolbar, bubble menus, slash commands, or collaboration.
|
|
666
|
+
*
|
|
667
|
+
* **Why not `generateHTML`?** Some node types use React NodeViews that
|
|
668
|
+
* resolve data at render time (e.g., images stored as file references that
|
|
669
|
+
* need a signed URL). `generateHTML` produces static HTML and cannot run
|
|
670
|
+
* these React components, resulting in broken images and missing features.
|
|
671
|
+
*
|
|
672
|
+
* **When to use:**
|
|
673
|
+
* - Detail pages, previews, or anywhere you need to display editor content
|
|
674
|
+
* with full NodeView fidelity (image resolution, interactive blocks).
|
|
675
|
+
* - Must be used inside `EditorFileProvider` if your content contains
|
|
676
|
+
* file-reference images.
|
|
677
|
+
*
|
|
678
|
+
* **For server-side rendering** (RSC, SSR, Node.js) where no React NodeViews
|
|
679
|
+
* are needed, use `EditorStaticView` instead. It uses `@tiptap/html` with
|
|
680
|
+
* a virtual DOM and produces pure HTML — but images must already be resolved.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```tsx
|
|
684
|
+
* import { EditorView } from "@kopexa/tiptap";
|
|
685
|
+
*
|
|
686
|
+
* function DocumentPreview({ content }: { content: JSONContent }) {
|
|
687
|
+
* return <EditorView content={content} variant="document" />;
|
|
688
|
+
* }
|
|
689
|
+
* ```
|
|
690
|
+
*
|
|
691
|
+
* @example With file resolution
|
|
692
|
+
* ```tsx
|
|
693
|
+
* import { EditorFileProvider, EditorView } from "@kopexa/tiptap";
|
|
694
|
+
*
|
|
695
|
+
* function DocumentDetail({ content }: { content: JSONContent }) {
|
|
696
|
+
* return (
|
|
697
|
+
* <EditorFileProvider onUpload={upload} onResolve={resolve}>
|
|
698
|
+
* <EditorView content={content} variant="document" />
|
|
699
|
+
* </EditorFileProvider>
|
|
700
|
+
* );
|
|
701
|
+
* }
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
declare function EditorView({ content, variant, bordered, className, customExtensions, disabled, }: EditorViewProps): react_jsx_runtime.JSX.Element | null;
|
|
705
|
+
|
|
706
|
+
type EditorStaticViewProps = EditorBasicVariants & Pick<GetExtensionsOptions, "customExtensions" | "disabled"> & {
|
|
707
|
+
/**
|
|
708
|
+
* The TipTap content to render.
|
|
709
|
+
* Accepts JSON, HTML string, Markdown string, or plain text.
|
|
710
|
+
* Internally parsed via `safeParseContent` — same as the `Editor` component.
|
|
711
|
+
*/
|
|
712
|
+
content?: Content$1 | undefined;
|
|
713
|
+
/** Additional CSS class names for the root container. */
|
|
714
|
+
className?: string;
|
|
715
|
+
};
|
|
716
|
+
/**
|
|
717
|
+
* Static HTML viewer for TipTap content.
|
|
718
|
+
*
|
|
719
|
+
* Converts TipTap `JSONContent` to HTML using `generateHTML` from `@tiptap/html`
|
|
720
|
+
* (virtual DOM — no browser required) and renders it with the same styling as
|
|
721
|
+
* the `Editor` component. Works in **Server Components (RSC)**, SSR, and
|
|
722
|
+
* Node.js environments.
|
|
723
|
+
*
|
|
724
|
+
* Uses the full set of registered extensions to ensure all node/mark types
|
|
725
|
+
* produce correct HTML (tables, callouts, code blocks, math, etc.).
|
|
726
|
+
*
|
|
727
|
+
* **Limitations:**
|
|
728
|
+
* - React NodeViews are NOT rendered. Node types that rely on React components
|
|
729
|
+
* (e.g., images with file-reference resolution) will output their default
|
|
730
|
+
* HTML representation. Images stored as file references will NOT be resolved —
|
|
731
|
+
* ensure image `src` values are already displayable URLs before passing content.
|
|
732
|
+
* - No interactive features (no selection, no cursor, no scroll-to-hash).
|
|
733
|
+
*
|
|
734
|
+
* **When to use:**
|
|
735
|
+
* - Server-rendered pages, email templates, PDF generation, or static exports
|
|
736
|
+
* where you need a lightweight, non-interactive HTML representation.
|
|
737
|
+
* - When all image URLs in the content are already resolved (not file references).
|
|
738
|
+
*
|
|
739
|
+
* **For client-side rendering** with full NodeView fidelity (image resolution,
|
|
740
|
+
* interactive blocks), use `EditorView` instead.
|
|
741
|
+
*
|
|
742
|
+
* @example Server Component
|
|
743
|
+
* ```tsx
|
|
744
|
+
* // app/documents/[id]/page.tsx (RSC)
|
|
745
|
+
* import { EditorStaticView } from "@kopexa/tiptap";
|
|
746
|
+
*
|
|
747
|
+
* export default async function DocumentPage({ params }) {
|
|
748
|
+
* const doc = await fetchDocument(params.id);
|
|
749
|
+
* return <EditorStaticView content={doc.content} variant="document" />;
|
|
750
|
+
* }
|
|
751
|
+
* ```
|
|
752
|
+
*
|
|
753
|
+
* @example Client Component
|
|
754
|
+
* ```tsx
|
|
755
|
+
* import { EditorStaticView } from "@kopexa/tiptap";
|
|
756
|
+
*
|
|
757
|
+
* function LightweightPreview({ content }: { content: JSONContent }) {
|
|
758
|
+
* return <EditorStaticView content={content} variant="inline" />;
|
|
759
|
+
* }
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
declare function EditorStaticView({ content, variant, bordered, className, customExtensions, disabled, }: EditorStaticViewProps): react_jsx_runtime.JSX.Element | null;
|
|
763
|
+
|
|
649
764
|
/**
|
|
650
765
|
* Handles image upload with progress tracking and abort capability
|
|
651
766
|
* @param file The file to upload
|
|
@@ -689,4 +804,4 @@ declare function sanitizeUrl(inputUrl: string, baseUrl: string, protocols?: Prot
|
|
|
689
804
|
*/
|
|
690
805
|
declare function generateColorFromId(id: string): string;
|
|
691
806
|
|
|
692
|
-
export { CalloutNode, type CalloutNodeAttrs, type CalloutVariant, type CollabUser, CollaborationProvider, type CollaborationProviderProps, type CollaborationState, type CollaborationStatus, BasicEditor as Editor, type EditorFileHandler, EditorFileProvider, type EditorFileProviderProps, type GetExtensionsOptions, ImageNode, ImageUploadNode, InlineMath, type InlineMathAttrs, MathBlock, type MathBlockAttrs, type ResolvedCollabUser, TocNode, type VariableDefinition, VariableFillerDialog, type VariableFillerDialogProps, VariableNode, type VariableNodeAttrs, type VariableOptions, VariableProvider, type VariableProviderProps, VariableSuggestion, type VariableSuggestionProps, convertFileToBase64, extractVariablesFromContent, generateColorFromId, getExtensions, handleImageUpload, isAllowedUri, sanitizeUrl, useCollaboration, useCollaborationRequired, useDocumentVisibility, useEditorFile, useEditorFileRequired, useIdle, useVariables, useVariablesWithFallback };
|
|
807
|
+
export { CalloutNode, type CalloutNodeAttrs, type CalloutVariant, type CollabUser, CollaborationProvider, type CollaborationProviderProps, type CollaborationState, type CollaborationStatus, BasicEditor as Editor, type EditorFileHandler, EditorFileProvider, type EditorFileProviderProps, EditorStaticView, type EditorStaticViewProps, EditorView, type EditorViewProps, type GetExtensionsOptions, ImageNode, ImageUploadNode, InlineMath, type InlineMathAttrs, MathBlock, type MathBlockAttrs, type ResolvedCollabUser, TocNode, type VariableDefinition, VariableFillerDialog, type VariableFillerDialogProps, VariableNode, type VariableNodeAttrs, type VariableOptions, VariableProvider, type VariableProviderProps, VariableSuggestion, type VariableSuggestionProps, convertFileToBase64, extractVariablesFromContent, generateColorFromId, getExtensions, handleImageUpload, isAllowedUri, sanitizeUrl, useCollaboration, useCollaborationRequired, useDocumentVisibility, useEditorFile, useEditorFileRequired, useIdle, useVariables, useVariablesWithFallback };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,8 @@ __export(index_exports, {
|
|
|
35
35
|
CollaborationProvider: () => CollaborationProvider,
|
|
36
36
|
Editor: () => BasicEditor,
|
|
37
37
|
EditorFileProvider: () => EditorFileProvider,
|
|
38
|
+
EditorStaticView: () => EditorStaticView,
|
|
39
|
+
EditorView: () => EditorView,
|
|
38
40
|
ImageNode: () => ImageNode,
|
|
39
41
|
ImageUploadNode: () => ImageUploadNode,
|
|
40
42
|
InlineMath: () => InlineMath,
|
|
@@ -4024,6 +4026,7 @@ var useCreateEditor = ({
|
|
|
4024
4026
|
const fileHandlerFromContext = useEditorFile();
|
|
4025
4027
|
const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
|
|
4026
4028
|
const collaboration = useCollaboration();
|
|
4029
|
+
const [collabSyncing, setCollabSyncing] = (0, import_react33.useState)(!!collaboration);
|
|
4027
4030
|
const [extensions] = (0, import_react33.useState)(
|
|
4028
4031
|
() => getExtensions({
|
|
4029
4032
|
editable,
|
|
@@ -4038,6 +4041,7 @@ var useCreateEditor = ({
|
|
|
4038
4041
|
disabled
|
|
4039
4042
|
})
|
|
4040
4043
|
);
|
|
4044
|
+
const { onCreate: userOnCreate, ...restOptions } = options;
|
|
4041
4045
|
const editor = (0, import_react32.useEditor)({
|
|
4042
4046
|
editorProps: {
|
|
4043
4047
|
attributes: {
|
|
@@ -4055,14 +4059,40 @@ var useCreateEditor = ({
|
|
|
4055
4059
|
onChange == null ? void 0 : onChange(editor2.getJSON());
|
|
4056
4060
|
},
|
|
4057
4061
|
content: safeParseContent(content),
|
|
4058
|
-
|
|
4062
|
+
// Seed empty collaborative documents with initial content.
|
|
4063
|
+
// When the Collaboration extension is active, TipTap ignores the `content`
|
|
4064
|
+
// prop entirely — content comes from the Y.Doc. If the Hocuspocus server
|
|
4065
|
+
// delivers an empty doc (e.g. a freshly created version), we populate it
|
|
4066
|
+
// with the `content` prop once after the initial sync.
|
|
4067
|
+
onCreate: (ctx) => {
|
|
4068
|
+
if (collaboration) {
|
|
4069
|
+
const provider = collaboration.provider;
|
|
4070
|
+
if (provider && !provider.isSynced) {
|
|
4071
|
+
provider.on("synced", () => {
|
|
4072
|
+
setTimeout(() => {
|
|
4073
|
+
if (ctx.editor.isEmpty && content) {
|
|
4074
|
+
ctx.editor.commands.setContent(safeParseContent(content));
|
|
4075
|
+
}
|
|
4076
|
+
setCollabSyncing(false);
|
|
4077
|
+
}, 0);
|
|
4078
|
+
});
|
|
4079
|
+
} else {
|
|
4080
|
+
if (ctx.editor.isEmpty && content) {
|
|
4081
|
+
ctx.editor.commands.setContent(safeParseContent(content));
|
|
4082
|
+
}
|
|
4083
|
+
setCollabSyncing(false);
|
|
4084
|
+
}
|
|
4085
|
+
}
|
|
4086
|
+
userOnCreate == null ? void 0 : userOnCreate(ctx);
|
|
4087
|
+
},
|
|
4088
|
+
...restOptions
|
|
4059
4089
|
});
|
|
4060
4090
|
(0, import_react33.useEffect)(() => {
|
|
4061
4091
|
if (editor && editor.isEditable !== editable) {
|
|
4062
4092
|
editor.setEditable(editable);
|
|
4063
4093
|
}
|
|
4064
4094
|
}, [editor, editable]);
|
|
4065
|
-
return editor;
|
|
4095
|
+
return { editor, collabSyncing };
|
|
4066
4096
|
};
|
|
4067
4097
|
function getExtensions({
|
|
4068
4098
|
editable,
|
|
@@ -8190,7 +8220,7 @@ var BasicEditor = ({
|
|
|
8190
8220
|
pagesOptions,
|
|
8191
8221
|
...options
|
|
8192
8222
|
}) => {
|
|
8193
|
-
const editor = useCreateEditor({
|
|
8223
|
+
const { editor, collabSyncing } = useCreateEditor({
|
|
8194
8224
|
content,
|
|
8195
8225
|
enableVariables: !!(variables == null ? void 0 : variables.length),
|
|
8196
8226
|
pagesOptions,
|
|
@@ -8201,7 +8231,7 @@ var BasicEditor = ({
|
|
|
8201
8231
|
(name) => variableValues == null ? void 0 : variableValues[name],
|
|
8202
8232
|
[variableValues]
|
|
8203
8233
|
);
|
|
8204
|
-
if (!editor) {
|
|
8234
|
+
if (!editor || collabSyncing) {
|
|
8205
8235
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(LoadingSpinner, {});
|
|
8206
8236
|
}
|
|
8207
8237
|
const isBottomToolbar = variant === "field";
|
|
@@ -8338,12 +8368,93 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
8338
8368
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: styles.text(), children: text })
|
|
8339
8369
|
] }) });
|
|
8340
8370
|
}
|
|
8371
|
+
|
|
8372
|
+
// src/presets/view/index.tsx
|
|
8373
|
+
var import_theme10 = require("@kopexa/theme");
|
|
8374
|
+
var import_react62 = require("@tiptap/react");
|
|
8375
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
8376
|
+
function EditorView({
|
|
8377
|
+
content,
|
|
8378
|
+
variant,
|
|
8379
|
+
bordered,
|
|
8380
|
+
className,
|
|
8381
|
+
customExtensions,
|
|
8382
|
+
disabled
|
|
8383
|
+
}) {
|
|
8384
|
+
const { editor } = useCreateEditor({
|
|
8385
|
+
content,
|
|
8386
|
+
editable: false,
|
|
8387
|
+
customExtensions,
|
|
8388
|
+
disabled
|
|
8389
|
+
});
|
|
8390
|
+
const styles = (0, import_theme10.editorBasic)({ variant, bordered });
|
|
8391
|
+
if (!editor) {
|
|
8392
|
+
return null;
|
|
8393
|
+
}
|
|
8394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: styles.root({ className }), "data-slot": "editor-view", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react62.EditorContext.Provider, { value: { editor }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: styles.wrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
8395
|
+
import_react62.EditorContent,
|
|
8396
|
+
{
|
|
8397
|
+
editor,
|
|
8398
|
+
role: "presentation",
|
|
8399
|
+
className: styles.content()
|
|
8400
|
+
}
|
|
8401
|
+
) }) }) });
|
|
8402
|
+
}
|
|
8403
|
+
|
|
8404
|
+
// src/presets/view/static.tsx
|
|
8405
|
+
var import_theme11 = require("@kopexa/theme");
|
|
8406
|
+
var import_html = require("@tiptap/html");
|
|
8407
|
+
var import_react63 = require("react");
|
|
8408
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
8409
|
+
function EditorStaticView({
|
|
8410
|
+
content,
|
|
8411
|
+
variant,
|
|
8412
|
+
bordered,
|
|
8413
|
+
className,
|
|
8414
|
+
customExtensions,
|
|
8415
|
+
disabled
|
|
8416
|
+
}) {
|
|
8417
|
+
const extensions = (0, import_react63.useMemo)(
|
|
8418
|
+
() => getExtensions({
|
|
8419
|
+
editable: false,
|
|
8420
|
+
customExtensions,
|
|
8421
|
+
disabled
|
|
8422
|
+
}),
|
|
8423
|
+
[customExtensions, disabled]
|
|
8424
|
+
);
|
|
8425
|
+
const html = (0, import_react63.useMemo)(() => {
|
|
8426
|
+
const parsed = safeParseContent(content);
|
|
8427
|
+
if (!parsed) return "";
|
|
8428
|
+
const json = parsed;
|
|
8429
|
+
if (json.content && Array.isArray(json.content) && json.content.length === 0) {
|
|
8430
|
+
return "";
|
|
8431
|
+
}
|
|
8432
|
+
try {
|
|
8433
|
+
return (0, import_html.generateHTML)(json, extensions);
|
|
8434
|
+
} catch {
|
|
8435
|
+
return "";
|
|
8436
|
+
}
|
|
8437
|
+
}, [content, extensions]);
|
|
8438
|
+
const styles = (0, import_theme11.editorBasic)({ variant, bordered });
|
|
8439
|
+
if (!html) {
|
|
8440
|
+
return null;
|
|
8441
|
+
}
|
|
8442
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: styles.root({ className }), "data-slot": "editor-static-view", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: styles.wrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: styles.content(), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8443
|
+
"div",
|
|
8444
|
+
{
|
|
8445
|
+
className: "tiptap ProseMirror",
|
|
8446
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
8447
|
+
}
|
|
8448
|
+
) }) }) });
|
|
8449
|
+
}
|
|
8341
8450
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8342
8451
|
0 && (module.exports = {
|
|
8343
8452
|
CalloutNode,
|
|
8344
8453
|
CollaborationProvider,
|
|
8345
8454
|
Editor,
|
|
8346
8455
|
EditorFileProvider,
|
|
8456
|
+
EditorStaticView,
|
|
8457
|
+
EditorView,
|
|
8347
8458
|
ImageNode,
|
|
8348
8459
|
ImageUploadNode,
|
|
8349
8460
|
InlineMath,
|
package/dist/index.mjs
CHANGED
|
@@ -4022,6 +4022,7 @@ var useCreateEditor = ({
|
|
|
4022
4022
|
const fileHandlerFromContext = useEditorFile();
|
|
4023
4023
|
const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
|
|
4024
4024
|
const collaboration = useCollaboration();
|
|
4025
|
+
const [collabSyncing, setCollabSyncing] = useState13(!!collaboration);
|
|
4025
4026
|
const [extensions] = useState13(
|
|
4026
4027
|
() => getExtensions({
|
|
4027
4028
|
editable,
|
|
@@ -4036,6 +4037,7 @@ var useCreateEditor = ({
|
|
|
4036
4037
|
disabled
|
|
4037
4038
|
})
|
|
4038
4039
|
);
|
|
4040
|
+
const { onCreate: userOnCreate, ...restOptions } = options;
|
|
4039
4041
|
const editor = useEditor({
|
|
4040
4042
|
editorProps: {
|
|
4041
4043
|
attributes: {
|
|
@@ -4053,14 +4055,40 @@ var useCreateEditor = ({
|
|
|
4053
4055
|
onChange == null ? void 0 : onChange(editor2.getJSON());
|
|
4054
4056
|
},
|
|
4055
4057
|
content: safeParseContent(content),
|
|
4056
|
-
|
|
4058
|
+
// Seed empty collaborative documents with initial content.
|
|
4059
|
+
// When the Collaboration extension is active, TipTap ignores the `content`
|
|
4060
|
+
// prop entirely — content comes from the Y.Doc. If the Hocuspocus server
|
|
4061
|
+
// delivers an empty doc (e.g. a freshly created version), we populate it
|
|
4062
|
+
// with the `content` prop once after the initial sync.
|
|
4063
|
+
onCreate: (ctx) => {
|
|
4064
|
+
if (collaboration) {
|
|
4065
|
+
const provider = collaboration.provider;
|
|
4066
|
+
if (provider && !provider.isSynced) {
|
|
4067
|
+
provider.on("synced", () => {
|
|
4068
|
+
setTimeout(() => {
|
|
4069
|
+
if (ctx.editor.isEmpty && content) {
|
|
4070
|
+
ctx.editor.commands.setContent(safeParseContent(content));
|
|
4071
|
+
}
|
|
4072
|
+
setCollabSyncing(false);
|
|
4073
|
+
}, 0);
|
|
4074
|
+
});
|
|
4075
|
+
} else {
|
|
4076
|
+
if (ctx.editor.isEmpty && content) {
|
|
4077
|
+
ctx.editor.commands.setContent(safeParseContent(content));
|
|
4078
|
+
}
|
|
4079
|
+
setCollabSyncing(false);
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
4082
|
+
userOnCreate == null ? void 0 : userOnCreate(ctx);
|
|
4083
|
+
},
|
|
4084
|
+
...restOptions
|
|
4057
4085
|
});
|
|
4058
4086
|
useEffect14(() => {
|
|
4059
4087
|
if (editor && editor.isEditable !== editable) {
|
|
4060
4088
|
editor.setEditable(editable);
|
|
4061
4089
|
}
|
|
4062
4090
|
}, [editor, editable]);
|
|
4063
|
-
return editor;
|
|
4091
|
+
return { editor, collabSyncing };
|
|
4064
4092
|
};
|
|
4065
4093
|
function getExtensions({
|
|
4066
4094
|
editable,
|
|
@@ -8287,7 +8315,7 @@ var BasicEditor = ({
|
|
|
8287
8315
|
pagesOptions,
|
|
8288
8316
|
...options
|
|
8289
8317
|
}) => {
|
|
8290
|
-
const editor = useCreateEditor({
|
|
8318
|
+
const { editor, collabSyncing } = useCreateEditor({
|
|
8291
8319
|
content,
|
|
8292
8320
|
enableVariables: !!(variables == null ? void 0 : variables.length),
|
|
8293
8321
|
pagesOptions,
|
|
@@ -8298,7 +8326,7 @@ var BasicEditor = ({
|
|
|
8298
8326
|
(name) => variableValues == null ? void 0 : variableValues[name],
|
|
8299
8327
|
[variableValues]
|
|
8300
8328
|
);
|
|
8301
|
-
if (!editor) {
|
|
8329
|
+
if (!editor || collabSyncing) {
|
|
8302
8330
|
return /* @__PURE__ */ jsx34(LoadingSpinner, {});
|
|
8303
8331
|
}
|
|
8304
8332
|
const isBottomToolbar = variant === "field";
|
|
@@ -8435,11 +8463,92 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
8435
8463
|
/* @__PURE__ */ jsx34("div", { className: styles.text(), children: text })
|
|
8436
8464
|
] }) });
|
|
8437
8465
|
}
|
|
8466
|
+
|
|
8467
|
+
// src/presets/view/index.tsx
|
|
8468
|
+
import { editorBasic as editorBasic2 } from "@kopexa/theme";
|
|
8469
|
+
import { EditorContent as EditorContent2, EditorContext as EditorContext2 } from "@tiptap/react";
|
|
8470
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
8471
|
+
function EditorView({
|
|
8472
|
+
content,
|
|
8473
|
+
variant,
|
|
8474
|
+
bordered,
|
|
8475
|
+
className,
|
|
8476
|
+
customExtensions,
|
|
8477
|
+
disabled
|
|
8478
|
+
}) {
|
|
8479
|
+
const { editor } = useCreateEditor({
|
|
8480
|
+
content,
|
|
8481
|
+
editable: false,
|
|
8482
|
+
customExtensions,
|
|
8483
|
+
disabled
|
|
8484
|
+
});
|
|
8485
|
+
const styles = editorBasic2({ variant, bordered });
|
|
8486
|
+
if (!editor) {
|
|
8487
|
+
return null;
|
|
8488
|
+
}
|
|
8489
|
+
return /* @__PURE__ */ jsx35("div", { className: styles.root({ className }), "data-slot": "editor-view", children: /* @__PURE__ */ jsx35(EditorContext2.Provider, { value: { editor }, children: /* @__PURE__ */ jsx35("div", { className: styles.wrapper(), children: /* @__PURE__ */ jsx35(
|
|
8490
|
+
EditorContent2,
|
|
8491
|
+
{
|
|
8492
|
+
editor,
|
|
8493
|
+
role: "presentation",
|
|
8494
|
+
className: styles.content()
|
|
8495
|
+
}
|
|
8496
|
+
) }) }) });
|
|
8497
|
+
}
|
|
8498
|
+
|
|
8499
|
+
// src/presets/view/static.tsx
|
|
8500
|
+
import { editorBasic as editorBasic3 } from "@kopexa/theme";
|
|
8501
|
+
import { generateHTML } from "@tiptap/html";
|
|
8502
|
+
import { useMemo as useMemo20 } from "react";
|
|
8503
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
8504
|
+
function EditorStaticView({
|
|
8505
|
+
content,
|
|
8506
|
+
variant,
|
|
8507
|
+
bordered,
|
|
8508
|
+
className,
|
|
8509
|
+
customExtensions,
|
|
8510
|
+
disabled
|
|
8511
|
+
}) {
|
|
8512
|
+
const extensions = useMemo20(
|
|
8513
|
+
() => getExtensions({
|
|
8514
|
+
editable: false,
|
|
8515
|
+
customExtensions,
|
|
8516
|
+
disabled
|
|
8517
|
+
}),
|
|
8518
|
+
[customExtensions, disabled]
|
|
8519
|
+
);
|
|
8520
|
+
const html = useMemo20(() => {
|
|
8521
|
+
const parsed = safeParseContent(content);
|
|
8522
|
+
if (!parsed) return "";
|
|
8523
|
+
const json = parsed;
|
|
8524
|
+
if (json.content && Array.isArray(json.content) && json.content.length === 0) {
|
|
8525
|
+
return "";
|
|
8526
|
+
}
|
|
8527
|
+
try {
|
|
8528
|
+
return generateHTML(json, extensions);
|
|
8529
|
+
} catch {
|
|
8530
|
+
return "";
|
|
8531
|
+
}
|
|
8532
|
+
}, [content, extensions]);
|
|
8533
|
+
const styles = editorBasic3({ variant, bordered });
|
|
8534
|
+
if (!html) {
|
|
8535
|
+
return null;
|
|
8536
|
+
}
|
|
8537
|
+
return /* @__PURE__ */ jsx36("div", { className: styles.root({ className }), "data-slot": "editor-static-view", children: /* @__PURE__ */ jsx36("div", { className: styles.wrapper(), children: /* @__PURE__ */ jsx36("div", { className: styles.content(), children: /* @__PURE__ */ jsx36(
|
|
8538
|
+
"div",
|
|
8539
|
+
{
|
|
8540
|
+
className: "tiptap ProseMirror",
|
|
8541
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
8542
|
+
}
|
|
8543
|
+
) }) }) });
|
|
8544
|
+
}
|
|
8438
8545
|
export {
|
|
8439
8546
|
CalloutNode,
|
|
8440
8547
|
CollaborationProvider,
|
|
8441
8548
|
BasicEditor as Editor,
|
|
8442
8549
|
EditorFileProvider,
|
|
8550
|
+
EditorStaticView,
|
|
8551
|
+
EditorView,
|
|
8443
8552
|
ImageNode,
|
|
8444
8553
|
ImageUploadNode,
|
|
8445
8554
|
InlineMath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kopexa/tiptap",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.9.1",
|
|
4
4
|
"description": "our tiptap components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tiptap"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"motion": ">=12.23.6",
|
|
29
29
|
"react": ">=19.0.0-rc.0",
|
|
30
30
|
"react-dom": ">=19.0.0-rc.0",
|
|
31
|
-
"@kopexa/theme": "17.24.
|
|
31
|
+
"@kopexa/theme": "17.24.5"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@floating-ui/dom": "^1.7.4",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@tiptap/extension-typography": "^3.20.0",
|
|
55
55
|
"@tiptap/extension-unique-id": "^3.20.0",
|
|
56
56
|
"@tiptap/extensions": "^3.20.0",
|
|
57
|
+
"@tiptap/html": "^3.20.0",
|
|
57
58
|
"@tiptap/pm": "^3.20.0",
|
|
58
59
|
"@tiptap/react": "^3.20.0",
|
|
59
60
|
"@tiptap/starter-kit": "^3.20.0",
|
|
@@ -61,34 +62,34 @@
|
|
|
61
62
|
"dompurify": "^3.3.1",
|
|
62
63
|
"katex": "^0.16.33",
|
|
63
64
|
"jsx-dom-cjs": "^8.1.6",
|
|
64
|
-
"markdown-it": "^14.1.
|
|
65
|
+
"markdown-it": "^14.1.1",
|
|
65
66
|
"react-hotkeys-hook": "^5.2.4",
|
|
66
67
|
"react-intl": "^7.1.14",
|
|
67
68
|
"y-indexeddb": "^9.0.12",
|
|
68
69
|
"yjs": "^13.6.0",
|
|
69
|
-
"@kopexa/button": "17.0.
|
|
70
|
-
"@kopexa/callout": "17.0.
|
|
71
|
-
"@kopexa/
|
|
72
|
-
"@kopexa/
|
|
73
|
-
"@kopexa/editor-utils": "17.1.5",
|
|
74
|
-
"@kopexa/chip": "17.1.51",
|
|
70
|
+
"@kopexa/button": "17.0.57",
|
|
71
|
+
"@kopexa/callout": "17.0.57",
|
|
72
|
+
"@kopexa/chip": "17.1.54",
|
|
73
|
+
"@kopexa/dialog": "17.2.22",
|
|
75
74
|
"@kopexa/extension-pages": "17.0.45",
|
|
76
|
-
"@kopexa/
|
|
77
|
-
"@kopexa/
|
|
78
|
-
"@kopexa/extension-
|
|
79
|
-
"@kopexa/
|
|
80
|
-
"@kopexa/
|
|
81
|
-
"@kopexa/
|
|
82
|
-
"@kopexa/
|
|
83
|
-
"@kopexa/icons": "17.7.
|
|
84
|
-
"@kopexa/
|
|
85
|
-
"@kopexa/
|
|
86
|
-
"@kopexa/separator": "17.0.
|
|
87
|
-
"@kopexa/shared-utils": "17.0.
|
|
88
|
-
"@kopexa/
|
|
89
|
-
"@kopexa/use-
|
|
90
|
-
"@kopexa/use-
|
|
91
|
-
"@kopexa/
|
|
75
|
+
"@kopexa/editor-utils": "17.1.8",
|
|
76
|
+
"@kopexa/dropdown-menu": "17.0.57",
|
|
77
|
+
"@kopexa/extension-code": "17.0.57",
|
|
78
|
+
"@kopexa/extension-controlref": "17.1.39",
|
|
79
|
+
"@kopexa/extension-table": "17.1.9",
|
|
80
|
+
"@kopexa/input": "17.0.57",
|
|
81
|
+
"@kopexa/label": "17.0.57",
|
|
82
|
+
"@kopexa/icons": "17.7.22",
|
|
83
|
+
"@kopexa/popover": "17.2.22",
|
|
84
|
+
"@kopexa/select": "17.2.22",
|
|
85
|
+
"@kopexa/separator": "17.0.57",
|
|
86
|
+
"@kopexa/shared-utils": "17.0.57",
|
|
87
|
+
"@kopexa/switch": "17.2.22",
|
|
88
|
+
"@kopexa/use-is-mobile": "17.0.57",
|
|
89
|
+
"@kopexa/use-composed-ref": "17.0.57",
|
|
90
|
+
"@kopexa/toolbar": "17.2.22",
|
|
91
|
+
"@kopexa/react-utils": "17.0.57",
|
|
92
|
+
"@kopexa/tabs": "17.0.57"
|
|
92
93
|
},
|
|
93
94
|
"clean-package": "../../../clean-package.config.json",
|
|
94
95
|
"module": "dist/index.mjs",
|