🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@tiptap/react

Package Overview
Dependencies
Maintainers
6
Versions
406
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tiptap/react - npm Package Compare versions

Comparing version
3.27.4
to
3.28.0
+39
src/EditorContent.spec.ts
import React from 'react'
import { describe, expect, it, vi } from 'vitest'
import { createContentComponent } from './EditorContent.js'
import type { ReactRenderer } from './ReactRenderer.js'
const createRenderer = (id: string) =>
({
reactElement: React.createElement('span', null, id),
element: document.createElement('div'),
}) as ReactRenderer
describe('createContentComponent', () => {
it('batches synchronous renderer change notifications', async () => {
const contentComponent = createContentComponent()
const subscriber = vi.fn()
contentComponent.subscribe(subscriber)
contentComponent.setRenderer('first', createRenderer('first'))
contentComponent.setRenderer('second', createRenderer('second'))
expect(Object.keys(contentComponent.getSnapshot())).toEqual(['first', 'second'])
expect(subscriber).not.toHaveBeenCalled()
await Promise.resolve()
expect(subscriber).toHaveBeenCalledTimes(1)
contentComponent.removeRenderer('first')
contentComponent.removeRenderer('second')
expect(Object.keys(contentComponent.getSnapshot())).toEqual([])
await Promise.resolve()
expect(subscriber).toHaveBeenCalledTimes(2)
})
})
+25
-4

@@ -55,2 +55,3 @@ "use strict";

TiptapWrapper: () => TiptapWrapper,
createContentComponent: () => createContentComponent,
useCurrentEditor: () => useCurrentEditor,

@@ -93,5 +94,16 @@ useEditor: () => useEditor,

};
function getInstance() {
function createContentComponent() {
const subscribers = /* @__PURE__ */ new Set();
let renderers = {};
let isNotificationQueued = false;
const notifySubscribers = () => {
if (isNotificationQueued || !subscribers.size) {
return;
}
isNotificationQueued = true;
queueMicrotask(() => {
isNotificationQueued = false;
subscribers.forEach((subscriber) => subscriber());
});
};
return {

@@ -121,3 +133,3 @@ /**

};
subscribers.forEach((subscriber) => subscriber());
notifySubscribers();
},

@@ -131,3 +143,3 @@ /**

renderers = nextRenderers;
subscribers.forEach((subscriber) => subscriber());
notifySubscribers();
}

@@ -159,3 +171,3 @@ };

});
editor.contentComponent = getInstance();
editor.contentComponent = createContentComponent();
editor.createNodeViews();

@@ -415,2 +427,10 @@ editor.isEditorContentInitialized = true;

return (_b = (_a = this.options.current).onDelete) == null ? void 0 : _b.call(_a, ...args);
},
onMount: (...args) => {
var _a, _b;
return (_b = (_a = this.options.current).onMount) == null ? void 0 : _b.call(_a, ...args);
},
onUnmount: (...args) => {
var _a, _b;
return (_b = (_a = this.options.current).onUnmount) == null ? void 0 : _b.call(_a, ...args);
}

@@ -1250,2 +1270,3 @@ };

TiptapWrapper,
createContentComponent,
useCurrentEditor,

@@ -1252,0 +1273,0 @@ useEditor,

+43
-42

@@ -5,3 +5,3 @@ import * as react_jsx_runtime from 'react/jsx-runtime';

import * as React from 'react';
import React__default, { DependencyList, ReactNode, HTMLAttributes, HTMLProps, ForwardedRef, ComponentProps, ReactPortal, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ComponentType as ComponentType$1 } from 'react';
import React__default, { DependencyList, ReactNode, HTMLAttributes, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ReactPortal, HTMLProps, ForwardedRef, ComponentProps, ComponentType as ComponentType$1 } from 'react';
import { Node } from '@tiptap/pm/model';

@@ -69,42 +69,2 @@ import { Decoration, DecorationSource } from '@tiptap/pm/view';

interface EditorContentProps extends HTMLProps<HTMLDivElement> {
editor: Editor | null;
innerRef?: ForwardedRef<HTMLDivElement | null>;
}
declare class PureEditorContent extends React__default.Component<EditorContentProps, {
hasContentComponentInitialized: boolean;
}> {
editorContentRef: React__default.RefObject<any>;
constructor(props: EditorContentProps);
componentDidMount(): void;
componentDidUpdate(): void;
init(): void;
componentWillUnmount(): void;
render(): react_jsx_runtime.JSX.Element;
}
declare const EditorContent: React__default.NamedExoticComponent<Omit<EditorContentProps, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
type NodeViewContentProps<T extends keyof React__default.JSX.IntrinsicElements = 'div'> = {
as?: NoInfer<T>;
} & ComponentProps<T>;
declare function NodeViewContent<T extends keyof React__default.JSX.IntrinsicElements = 'div'>({ as: Tag, ...props }: NodeViewContentProps<T>): react_jsx_runtime.JSX.Element;
interface NodeViewWrapperProps {
[key: string]: any;
as?: React__default.ElementType;
}
declare const NodeViewWrapper: React__default.FC<NodeViewWrapperProps>;
type EditorWithContentComponent = Editor & {
contentComponent?: ContentComponent | null;
isEditorContentInitialized?: boolean;
};
type ContentComponent = {
setRenderer(id: string, renderer: ReactRenderer): void;
removeRenderer(id: string): void;
subscribe: (callback: () => void) => () => void;
getSnapshot: () => Record<string, ReactPortal>;
getServerSnapshot: () => Record<string, ReactPortal>;
};
interface ReactRendererOptions {

@@ -184,2 +144,43 @@ /**

type EditorWithContentComponent = Editor & {
contentComponent?: ContentComponent | null;
isEditorContentInitialized?: boolean;
};
type ContentComponent = {
setRenderer(id: string, renderer: ReactRenderer): void;
removeRenderer(id: string): void;
subscribe: (callback: () => void) => () => void;
getSnapshot: () => Record<string, ReactPortal>;
getServerSnapshot: () => Record<string, ReactPortal>;
};
interface EditorContentProps extends HTMLProps<HTMLDivElement> {
editor: Editor | null;
innerRef?: ForwardedRef<HTMLDivElement | null>;
}
declare function createContentComponent(): ContentComponent;
declare class PureEditorContent extends React__default.Component<EditorContentProps, {
hasContentComponentInitialized: boolean;
}> {
editorContentRef: React__default.RefObject<any>;
constructor(props: EditorContentProps);
componentDidMount(): void;
componentDidUpdate(): void;
init(): void;
componentWillUnmount(): void;
render(): react_jsx_runtime.JSX.Element;
}
declare const EditorContent: React__default.NamedExoticComponent<Omit<EditorContentProps, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
type NodeViewContentProps<T extends keyof React__default.JSX.IntrinsicElements = 'div'> = {
as?: NoInfer<T>;
} & ComponentProps<T>;
declare function NodeViewContent<T extends keyof React__default.JSX.IntrinsicElements = 'div'>({ as: Tag, ...props }: NodeViewContentProps<T>): react_jsx_runtime.JSX.Element;
interface NodeViewWrapperProps {
[key: string]: any;
as?: React__default.ElementType;
}
declare const NodeViewWrapper: React__default.FC<NodeViewWrapperProps>;
interface MarkViewContextProps {

@@ -562,2 +563,2 @@ markViewContentRef: (element: HTMLElement | null) => void;

export { EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, Tiptap, TiptapContent, TiptapContext, type TiptapContextType, TiptapWrapper, type TiptapWrapperEditorInstanceProps, type TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };
export { EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, Tiptap, TiptapContent, TiptapContext, type TiptapContextType, TiptapWrapper, type TiptapWrapperEditorInstanceProps, type TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, createContentComponent, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };

@@ -5,3 +5,3 @@ import * as react_jsx_runtime from 'react/jsx-runtime';

import * as React from 'react';
import React__default, { DependencyList, ReactNode, HTMLAttributes, HTMLProps, ForwardedRef, ComponentProps, ReactPortal, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ComponentType as ComponentType$1 } from 'react';
import React__default, { DependencyList, ReactNode, HTMLAttributes, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ReactPortal, HTMLProps, ForwardedRef, ComponentProps, ComponentType as ComponentType$1 } from 'react';
import { Node } from '@tiptap/pm/model';

@@ -69,42 +69,2 @@ import { Decoration, DecorationSource } from '@tiptap/pm/view';

interface EditorContentProps extends HTMLProps<HTMLDivElement> {
editor: Editor | null;
innerRef?: ForwardedRef<HTMLDivElement | null>;
}
declare class PureEditorContent extends React__default.Component<EditorContentProps, {
hasContentComponentInitialized: boolean;
}> {
editorContentRef: React__default.RefObject<any>;
constructor(props: EditorContentProps);
componentDidMount(): void;
componentDidUpdate(): void;
init(): void;
componentWillUnmount(): void;
render(): react_jsx_runtime.JSX.Element;
}
declare const EditorContent: React__default.NamedExoticComponent<Omit<EditorContentProps, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
type NodeViewContentProps<T extends keyof React__default.JSX.IntrinsicElements = 'div'> = {
as?: NoInfer<T>;
} & ComponentProps<T>;
declare function NodeViewContent<T extends keyof React__default.JSX.IntrinsicElements = 'div'>({ as: Tag, ...props }: NodeViewContentProps<T>): react_jsx_runtime.JSX.Element;
interface NodeViewWrapperProps {
[key: string]: any;
as?: React__default.ElementType;
}
declare const NodeViewWrapper: React__default.FC<NodeViewWrapperProps>;
type EditorWithContentComponent = Editor & {
contentComponent?: ContentComponent | null;
isEditorContentInitialized?: boolean;
};
type ContentComponent = {
setRenderer(id: string, renderer: ReactRenderer): void;
removeRenderer(id: string): void;
subscribe: (callback: () => void) => () => void;
getSnapshot: () => Record<string, ReactPortal>;
getServerSnapshot: () => Record<string, ReactPortal>;
};
interface ReactRendererOptions {

@@ -184,2 +144,43 @@ /**

type EditorWithContentComponent = Editor & {
contentComponent?: ContentComponent | null;
isEditorContentInitialized?: boolean;
};
type ContentComponent = {
setRenderer(id: string, renderer: ReactRenderer): void;
removeRenderer(id: string): void;
subscribe: (callback: () => void) => () => void;
getSnapshot: () => Record<string, ReactPortal>;
getServerSnapshot: () => Record<string, ReactPortal>;
};
interface EditorContentProps extends HTMLProps<HTMLDivElement> {
editor: Editor | null;
innerRef?: ForwardedRef<HTMLDivElement | null>;
}
declare function createContentComponent(): ContentComponent;
declare class PureEditorContent extends React__default.Component<EditorContentProps, {
hasContentComponentInitialized: boolean;
}> {
editorContentRef: React__default.RefObject<any>;
constructor(props: EditorContentProps);
componentDidMount(): void;
componentDidUpdate(): void;
init(): void;
componentWillUnmount(): void;
render(): react_jsx_runtime.JSX.Element;
}
declare const EditorContent: React__default.NamedExoticComponent<Omit<EditorContentProps, "ref"> & React__default.RefAttributes<HTMLDivElement>>;
type NodeViewContentProps<T extends keyof React__default.JSX.IntrinsicElements = 'div'> = {
as?: NoInfer<T>;
} & ComponentProps<T>;
declare function NodeViewContent<T extends keyof React__default.JSX.IntrinsicElements = 'div'>({ as: Tag, ...props }: NodeViewContentProps<T>): react_jsx_runtime.JSX.Element;
interface NodeViewWrapperProps {
[key: string]: any;
as?: React__default.ElementType;
}
declare const NodeViewWrapper: React__default.FC<NodeViewWrapperProps>;
interface MarkViewContextProps {

@@ -562,2 +563,2 @@ markViewContentRef: (element: HTMLElement | null) => void;

export { EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, Tiptap, TiptapContent, TiptapContext, type TiptapContextType, TiptapWrapper, type TiptapWrapperEditorInstanceProps, type TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };
export { EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, Tiptap, TiptapContent, TiptapContext, type TiptapContextType, TiptapWrapper, type TiptapWrapperEditorInstanceProps, type TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, createContentComponent, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };

@@ -31,5 +31,16 @@ "use client";

};
function getInstance() {
function createContentComponent() {
const subscribers = /* @__PURE__ */ new Set();
let renderers = {};
let isNotificationQueued = false;
const notifySubscribers = () => {
if (isNotificationQueued || !subscribers.size) {
return;
}
isNotificationQueued = true;
queueMicrotask(() => {
isNotificationQueued = false;
subscribers.forEach((subscriber) => subscriber());
});
};
return {

@@ -59,3 +70,3 @@ /**

};
subscribers.forEach((subscriber) => subscriber());
notifySubscribers();
},

@@ -69,3 +80,3 @@ /**

renderers = nextRenderers;
subscribers.forEach((subscriber) => subscriber());
notifySubscribers();
}

@@ -97,3 +108,3 @@ };

});
editor.contentComponent = getInstance();
editor.contentComponent = createContentComponent();
editor.createNodeViews();

@@ -353,2 +364,10 @@ editor.isEditorContentInitialized = true;

return (_b = (_a = this.options.current).onDelete) == null ? void 0 : _b.call(_a, ...args);
},
onMount: (...args) => {
var _a, _b;
return (_b = (_a = this.options.current).onMount) == null ? void 0 : _b.call(_a, ...args);
},
onUnmount: (...args) => {
var _a, _b;
return (_b = (_a = this.options.current).onUnmount) == null ? void 0 : _b.call(_a, ...args);
}

@@ -1187,2 +1206,3 @@ };

TiptapWrapper,
createContentComponent,
useCurrentEditor,

@@ -1189,0 +1209,0 @@ useEditor,

{
"name": "@tiptap/react",
"version": "3.27.4",
"version": "3.28.0",
"description": "React components for tiptap",

@@ -60,4 +60,4 @@ "keywords": [

"react-dom": "^19.0.0",
"@tiptap/core": "^3.27.4",
"@tiptap/pm": "^3.27.4"
"@tiptap/core": "^3.28.0",
"@tiptap/pm": "^3.28.0"
},

@@ -69,8 +69,8 @@ "peerDependencies": {

"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
"@tiptap/core": "3.27.4",
"@tiptap/pm": "3.27.4"
"@tiptap/core": "3.28.0",
"@tiptap/pm": "3.28.0"
},
"optionalDependencies": {
"@tiptap/extension-bubble-menu": "^3.27.4",
"@tiptap/extension-floating-menu": "^3.27.4"
"@tiptap/extension-bubble-menu": "^3.28.0",
"@tiptap/extension-floating-menu": "^3.28.0"
},

@@ -77,0 +77,0 @@ "scripts": {

@@ -44,6 +44,20 @@ import type { Editor } from '@tiptap/core'

function getInstance(): ContentComponent {
export function createContentComponent(): ContentComponent {
const subscribers = new Set<() => void>()
let renderers: Record<string, React.ReactPortal> = {}
let isNotificationQueued = false
const notifySubscribers = () => {
if (isNotificationQueued || !subscribers.size) {
return
}
isNotificationQueued = true
queueMicrotask(() => {
isNotificationQueued = false
subscribers.forEach(subscriber => subscriber())
})
}
return {

@@ -74,3 +88,3 @@ /**

subscribers.forEach(subscriber => subscriber())
notifySubscribers()
},

@@ -85,3 +99,3 @@ /**

renderers = nextRenderers
subscribers.forEach(subscriber => subscriber())
notifySubscribers()
},

@@ -126,3 +140,3 @@ }

editor.contentComponent = getInstance()
editor.contentComponent = createContentComponent()

@@ -129,0 +143,0 @@ editor.createNodeViews()

@@ -137,2 +137,4 @@ import { type EditorOptions, Editor } from '@tiptap/core'

onDelete: (...args) => this.options.current.onDelete?.(...args),
onMount: (...args) => this.options.current.onMount?.(...args),
onUnmount: (...args) => this.options.current.onUnmount?.(...args),
}

@@ -139,0 +141,0 @@ const editor = new Editor(optionsToApply)

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display