@tiptap/react 3.17.1 → 3.19.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/dist/index.cjs +79 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -1
- package/dist/index.d.ts +178 -1
- package/dist/index.js +73 -4
- package/dist/index.js.map +1 -1
- package/dist/menus/index.cjs +72 -17
- package/dist/menus/index.cjs.map +1 -1
- package/dist/menus/index.js +74 -19
- package/dist/menus/index.js.map +1 -1
- package/package.json +7 -7
- package/src/ReactNodeViewRenderer.tsx +29 -3
- package/src/Tiptap.tsx +224 -0
- package/src/index.ts +1 -0
- package/src/menus/BubbleMenu.tsx +49 -1
- package/src/menus/FloatingMenu.tsx +76 -20
package/dist/index.d.cts
CHANGED
|
@@ -244,6 +244,13 @@ declare class ReactNodeView<T = HTMLElement, Component extends ComponentType$1<R
|
|
|
244
244
|
*/
|
|
245
245
|
selectionRafId: number | null;
|
|
246
246
|
constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>);
|
|
247
|
+
private cachedExtensionWithSyncedStorage;
|
|
248
|
+
/**
|
|
249
|
+
* Returns a proxy of the extension that redirects storage access to the editor's mutable storage.
|
|
250
|
+
* This preserves the original prototype chain (instanceof checks, methods like configure/extend work).
|
|
251
|
+
* Cached to avoid proxy creation on every update.
|
|
252
|
+
*/
|
|
253
|
+
get extensionWithSyncedStorage(): NodeViewRendererProps['extension'];
|
|
247
254
|
/**
|
|
248
255
|
* Setup the React component.
|
|
249
256
|
* Called on initialization.
|
|
@@ -294,6 +301,176 @@ declare class ReactNodeView<T = HTMLElement, Component extends ComponentType$1<R
|
|
|
294
301
|
*/
|
|
295
302
|
declare function ReactNodeViewRenderer<T = HTMLElement>(component: ComponentType$1<ReactNodeViewProps<T>>, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer;
|
|
296
303
|
|
|
304
|
+
/**
|
|
305
|
+
* The shape of the React context used by the `<Tiptap />` components.
|
|
306
|
+
*
|
|
307
|
+
* The editor instance is always available when using the default `useEditor`
|
|
308
|
+
* configuration. For SSR scenarios where `immediatelyRender: false` is used,
|
|
309
|
+
* consider using the legacy `EditorProvider` pattern instead.
|
|
310
|
+
*/
|
|
311
|
+
type TiptapContextType = {
|
|
312
|
+
/** The Tiptap editor instance. */
|
|
313
|
+
editor: Editor;
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* React context that stores the current editor instance.
|
|
317
|
+
*
|
|
318
|
+
* Use `useTiptap()` to read from this context in child components.
|
|
319
|
+
*/
|
|
320
|
+
declare const TiptapContext: React.Context<TiptapContextType>;
|
|
321
|
+
/**
|
|
322
|
+
* Hook to read the Tiptap context and access the editor instance.
|
|
323
|
+
*
|
|
324
|
+
* This is a small convenience wrapper around `useContext(TiptapContext)`.
|
|
325
|
+
* The editor is always available when used within a `<Tiptap>` provider.
|
|
326
|
+
*
|
|
327
|
+
* @returns The current `TiptapContextType` value from the provider.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```tsx
|
|
331
|
+
* import { useTiptap } from '@tiptap/react'
|
|
332
|
+
*
|
|
333
|
+
* function Toolbar() {
|
|
334
|
+
* const { editor } = useTiptap()
|
|
335
|
+
*
|
|
336
|
+
* return (
|
|
337
|
+
* <button onClick={() => editor.chain().focus().toggleBold().run()}>
|
|
338
|
+
* Bold
|
|
339
|
+
* </button>
|
|
340
|
+
* )
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare const useTiptap: () => TiptapContextType;
|
|
345
|
+
/**
|
|
346
|
+
* Select a slice of the editor state using the context-provided editor.
|
|
347
|
+
*
|
|
348
|
+
* This is a thin wrapper around `useEditorState` that reads the `editor`
|
|
349
|
+
* instance from `useTiptap()` so callers don't have to pass it manually.
|
|
350
|
+
*
|
|
351
|
+
* @typeParam TSelectorResult - The type returned by the selector.
|
|
352
|
+
* @param selector - Function that receives the editor state snapshot and
|
|
353
|
+
* returns the piece of state you want to subscribe to.
|
|
354
|
+
* @param equalityFn - Optional function to compare previous/next selected
|
|
355
|
+
* values and avoid unnecessary updates.
|
|
356
|
+
* @returns The selected slice of the editor state.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```tsx
|
|
360
|
+
* function WordCount() {
|
|
361
|
+
* const wordCount = useTiptapState(state => {
|
|
362
|
+
* const text = state.editor.state.doc.textContent
|
|
363
|
+
* return text.split(/\s+/).filter(Boolean).length
|
|
364
|
+
* })
|
|
365
|
+
*
|
|
366
|
+
* return <span>{wordCount} words</span>
|
|
367
|
+
* }
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
declare function useTiptapState<TSelectorResult>(selector: (context: EditorStateSnapshot<Editor>) => TSelectorResult, equalityFn?: (a: TSelectorResult, b: TSelectorResult | null) => boolean): TSelectorResult;
|
|
371
|
+
/**
|
|
372
|
+
* Props for the `Tiptap` root/provider component.
|
|
373
|
+
*/
|
|
374
|
+
type TiptapWrapperProps = {
|
|
375
|
+
/**
|
|
376
|
+
* The editor instance to provide to child components.
|
|
377
|
+
* Use `useEditor()` to create this instance.
|
|
378
|
+
*/
|
|
379
|
+
editor?: Editor;
|
|
380
|
+
/**
|
|
381
|
+
* @deprecated Use `editor` instead. Will be removed in the next major version.
|
|
382
|
+
*/
|
|
383
|
+
instance?: Editor;
|
|
384
|
+
children: ReactNode;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Top-level provider component that makes the editor instance available via
|
|
388
|
+
* React context to all child components.
|
|
389
|
+
*
|
|
390
|
+
* This component also provides backwards compatibility with the legacy
|
|
391
|
+
* `EditorContext`, so components using `useCurrentEditor()` will work
|
|
392
|
+
* inside a `<Tiptap>` provider.
|
|
393
|
+
*
|
|
394
|
+
* @param props - Component props.
|
|
395
|
+
* @returns A context provider element wrapping `children`.
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```tsx
|
|
399
|
+
* import { Tiptap, useEditor } from '@tiptap/react'
|
|
400
|
+
*
|
|
401
|
+
* function App() {
|
|
402
|
+
* const editor = useEditor({ extensions: [...] })
|
|
403
|
+
*
|
|
404
|
+
* return (
|
|
405
|
+
* <Tiptap editor={editor}>
|
|
406
|
+
* <Toolbar />
|
|
407
|
+
* <Tiptap.Content />
|
|
408
|
+
* </Tiptap>
|
|
409
|
+
* )
|
|
410
|
+
* }
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
declare function TiptapWrapper({ editor, instance, children }: TiptapWrapperProps): react_jsx_runtime.JSX.Element;
|
|
414
|
+
declare namespace TiptapWrapper {
|
|
415
|
+
var displayName: string;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Convenience component that renders `EditorContent` using the context-provided
|
|
419
|
+
* editor instance. Use this instead of manually passing the `editor` prop.
|
|
420
|
+
*
|
|
421
|
+
* @param props - All `EditorContent` props except `editor` and `ref`.
|
|
422
|
+
* @returns An `EditorContent` element bound to the context editor.
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```tsx
|
|
426
|
+
* // inside a Tiptap provider
|
|
427
|
+
* <Tiptap.Content className="editor" />
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
declare function TiptapContent({ ...rest }: Omit<EditorContentProps, 'editor' | 'ref'>): react_jsx_runtime.JSX.Element;
|
|
431
|
+
declare namespace TiptapContent {
|
|
432
|
+
var displayName: string;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Root `Tiptap` component. Use it as the provider for all child components.
|
|
436
|
+
*
|
|
437
|
+
* The exported object includes the `Content` subcomponent for rendering the
|
|
438
|
+
* editor content area.
|
|
439
|
+
*
|
|
440
|
+
* This component provides both the new `TiptapContext` (accessed via `useTiptap()`)
|
|
441
|
+
* and the legacy `EditorContext` (accessed via `useCurrentEditor()`) for
|
|
442
|
+
* backwards compatibility.
|
|
443
|
+
*
|
|
444
|
+
* For bubble menus and floating menus, import them separately from
|
|
445
|
+
* `@tiptap/react/menus` to keep floating-ui as an optional dependency.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```tsx
|
|
449
|
+
* import { Tiptap, useEditor } from '@tiptap/react'
|
|
450
|
+
* import { BubbleMenu } from '@tiptap/react/menus'
|
|
451
|
+
*
|
|
452
|
+
* function App() {
|
|
453
|
+
* const editor = useEditor({ extensions: [...] })
|
|
454
|
+
*
|
|
455
|
+
* return (
|
|
456
|
+
* <Tiptap editor={editor}>
|
|
457
|
+
* <Tiptap.Content />
|
|
458
|
+
* <BubbleMenu>
|
|
459
|
+
* <button onClick={() => editor.chain().focus().toggleBold().run()}>Bold</button>
|
|
460
|
+
* </BubbleMenu>
|
|
461
|
+
* </Tiptap>
|
|
462
|
+
* )
|
|
463
|
+
* }
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
declare const Tiptap: typeof TiptapWrapper & {
|
|
467
|
+
/**
|
|
468
|
+
* The Tiptap Content component that renders the EditorContent with the editor instance from the context.
|
|
469
|
+
* @see TiptapContent
|
|
470
|
+
*/
|
|
471
|
+
Content: typeof TiptapContent;
|
|
472
|
+
};
|
|
473
|
+
|
|
297
474
|
type EditorStateSnapshot<TEditor extends Editor | null = Editor | null> = {
|
|
298
475
|
editor: TEditor;
|
|
299
476
|
transactionNumber: number;
|
|
@@ -354,4 +531,4 @@ declare const ReactNodeViewContentProvider: ({ children, content }: {
|
|
|
354
531
|
}) => React.FunctionComponentElement<React.ProviderProps<ReactNodeViewContextProps>>;
|
|
355
532
|
declare const useReactNodeView: () => ReactNodeViewContextProps;
|
|
356
533
|
|
|
357
|
-
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, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView };
|
|
534
|
+
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 TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };
|
package/dist/index.d.ts
CHANGED
|
@@ -244,6 +244,13 @@ declare class ReactNodeView<T = HTMLElement, Component extends ComponentType$1<R
|
|
|
244
244
|
*/
|
|
245
245
|
selectionRafId: number | null;
|
|
246
246
|
constructor(component: Component, props: NodeViewRendererProps, options?: Partial<Options>);
|
|
247
|
+
private cachedExtensionWithSyncedStorage;
|
|
248
|
+
/**
|
|
249
|
+
* Returns a proxy of the extension that redirects storage access to the editor's mutable storage.
|
|
250
|
+
* This preserves the original prototype chain (instanceof checks, methods like configure/extend work).
|
|
251
|
+
* Cached to avoid proxy creation on every update.
|
|
252
|
+
*/
|
|
253
|
+
get extensionWithSyncedStorage(): NodeViewRendererProps['extension'];
|
|
247
254
|
/**
|
|
248
255
|
* Setup the React component.
|
|
249
256
|
* Called on initialization.
|
|
@@ -294,6 +301,176 @@ declare class ReactNodeView<T = HTMLElement, Component extends ComponentType$1<R
|
|
|
294
301
|
*/
|
|
295
302
|
declare function ReactNodeViewRenderer<T = HTMLElement>(component: ComponentType$1<ReactNodeViewProps<T>>, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer;
|
|
296
303
|
|
|
304
|
+
/**
|
|
305
|
+
* The shape of the React context used by the `<Tiptap />` components.
|
|
306
|
+
*
|
|
307
|
+
* The editor instance is always available when using the default `useEditor`
|
|
308
|
+
* configuration. For SSR scenarios where `immediatelyRender: false` is used,
|
|
309
|
+
* consider using the legacy `EditorProvider` pattern instead.
|
|
310
|
+
*/
|
|
311
|
+
type TiptapContextType = {
|
|
312
|
+
/** The Tiptap editor instance. */
|
|
313
|
+
editor: Editor;
|
|
314
|
+
};
|
|
315
|
+
/**
|
|
316
|
+
* React context that stores the current editor instance.
|
|
317
|
+
*
|
|
318
|
+
* Use `useTiptap()` to read from this context in child components.
|
|
319
|
+
*/
|
|
320
|
+
declare const TiptapContext: React.Context<TiptapContextType>;
|
|
321
|
+
/**
|
|
322
|
+
* Hook to read the Tiptap context and access the editor instance.
|
|
323
|
+
*
|
|
324
|
+
* This is a small convenience wrapper around `useContext(TiptapContext)`.
|
|
325
|
+
* The editor is always available when used within a `<Tiptap>` provider.
|
|
326
|
+
*
|
|
327
|
+
* @returns The current `TiptapContextType` value from the provider.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```tsx
|
|
331
|
+
* import { useTiptap } from '@tiptap/react'
|
|
332
|
+
*
|
|
333
|
+
* function Toolbar() {
|
|
334
|
+
* const { editor } = useTiptap()
|
|
335
|
+
*
|
|
336
|
+
* return (
|
|
337
|
+
* <button onClick={() => editor.chain().focus().toggleBold().run()}>
|
|
338
|
+
* Bold
|
|
339
|
+
* </button>
|
|
340
|
+
* )
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
declare const useTiptap: () => TiptapContextType;
|
|
345
|
+
/**
|
|
346
|
+
* Select a slice of the editor state using the context-provided editor.
|
|
347
|
+
*
|
|
348
|
+
* This is a thin wrapper around `useEditorState` that reads the `editor`
|
|
349
|
+
* instance from `useTiptap()` so callers don't have to pass it manually.
|
|
350
|
+
*
|
|
351
|
+
* @typeParam TSelectorResult - The type returned by the selector.
|
|
352
|
+
* @param selector - Function that receives the editor state snapshot and
|
|
353
|
+
* returns the piece of state you want to subscribe to.
|
|
354
|
+
* @param equalityFn - Optional function to compare previous/next selected
|
|
355
|
+
* values and avoid unnecessary updates.
|
|
356
|
+
* @returns The selected slice of the editor state.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```tsx
|
|
360
|
+
* function WordCount() {
|
|
361
|
+
* const wordCount = useTiptapState(state => {
|
|
362
|
+
* const text = state.editor.state.doc.textContent
|
|
363
|
+
* return text.split(/\s+/).filter(Boolean).length
|
|
364
|
+
* })
|
|
365
|
+
*
|
|
366
|
+
* return <span>{wordCount} words</span>
|
|
367
|
+
* }
|
|
368
|
+
* ```
|
|
369
|
+
*/
|
|
370
|
+
declare function useTiptapState<TSelectorResult>(selector: (context: EditorStateSnapshot<Editor>) => TSelectorResult, equalityFn?: (a: TSelectorResult, b: TSelectorResult | null) => boolean): TSelectorResult;
|
|
371
|
+
/**
|
|
372
|
+
* Props for the `Tiptap` root/provider component.
|
|
373
|
+
*/
|
|
374
|
+
type TiptapWrapperProps = {
|
|
375
|
+
/**
|
|
376
|
+
* The editor instance to provide to child components.
|
|
377
|
+
* Use `useEditor()` to create this instance.
|
|
378
|
+
*/
|
|
379
|
+
editor?: Editor;
|
|
380
|
+
/**
|
|
381
|
+
* @deprecated Use `editor` instead. Will be removed in the next major version.
|
|
382
|
+
*/
|
|
383
|
+
instance?: Editor;
|
|
384
|
+
children: ReactNode;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Top-level provider component that makes the editor instance available via
|
|
388
|
+
* React context to all child components.
|
|
389
|
+
*
|
|
390
|
+
* This component also provides backwards compatibility with the legacy
|
|
391
|
+
* `EditorContext`, so components using `useCurrentEditor()` will work
|
|
392
|
+
* inside a `<Tiptap>` provider.
|
|
393
|
+
*
|
|
394
|
+
* @param props - Component props.
|
|
395
|
+
* @returns A context provider element wrapping `children`.
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```tsx
|
|
399
|
+
* import { Tiptap, useEditor } from '@tiptap/react'
|
|
400
|
+
*
|
|
401
|
+
* function App() {
|
|
402
|
+
* const editor = useEditor({ extensions: [...] })
|
|
403
|
+
*
|
|
404
|
+
* return (
|
|
405
|
+
* <Tiptap editor={editor}>
|
|
406
|
+
* <Toolbar />
|
|
407
|
+
* <Tiptap.Content />
|
|
408
|
+
* </Tiptap>
|
|
409
|
+
* )
|
|
410
|
+
* }
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
declare function TiptapWrapper({ editor, instance, children }: TiptapWrapperProps): react_jsx_runtime.JSX.Element;
|
|
414
|
+
declare namespace TiptapWrapper {
|
|
415
|
+
var displayName: string;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Convenience component that renders `EditorContent` using the context-provided
|
|
419
|
+
* editor instance. Use this instead of manually passing the `editor` prop.
|
|
420
|
+
*
|
|
421
|
+
* @param props - All `EditorContent` props except `editor` and `ref`.
|
|
422
|
+
* @returns An `EditorContent` element bound to the context editor.
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```tsx
|
|
426
|
+
* // inside a Tiptap provider
|
|
427
|
+
* <Tiptap.Content className="editor" />
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
declare function TiptapContent({ ...rest }: Omit<EditorContentProps, 'editor' | 'ref'>): react_jsx_runtime.JSX.Element;
|
|
431
|
+
declare namespace TiptapContent {
|
|
432
|
+
var displayName: string;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Root `Tiptap` component. Use it as the provider for all child components.
|
|
436
|
+
*
|
|
437
|
+
* The exported object includes the `Content` subcomponent for rendering the
|
|
438
|
+
* editor content area.
|
|
439
|
+
*
|
|
440
|
+
* This component provides both the new `TiptapContext` (accessed via `useTiptap()`)
|
|
441
|
+
* and the legacy `EditorContext` (accessed via `useCurrentEditor()`) for
|
|
442
|
+
* backwards compatibility.
|
|
443
|
+
*
|
|
444
|
+
* For bubble menus and floating menus, import them separately from
|
|
445
|
+
* `@tiptap/react/menus` to keep floating-ui as an optional dependency.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```tsx
|
|
449
|
+
* import { Tiptap, useEditor } from '@tiptap/react'
|
|
450
|
+
* import { BubbleMenu } from '@tiptap/react/menus'
|
|
451
|
+
*
|
|
452
|
+
* function App() {
|
|
453
|
+
* const editor = useEditor({ extensions: [...] })
|
|
454
|
+
*
|
|
455
|
+
* return (
|
|
456
|
+
* <Tiptap editor={editor}>
|
|
457
|
+
* <Tiptap.Content />
|
|
458
|
+
* <BubbleMenu>
|
|
459
|
+
* <button onClick={() => editor.chain().focus().toggleBold().run()}>Bold</button>
|
|
460
|
+
* </BubbleMenu>
|
|
461
|
+
* </Tiptap>
|
|
462
|
+
* )
|
|
463
|
+
* }
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
declare const Tiptap: typeof TiptapWrapper & {
|
|
467
|
+
/**
|
|
468
|
+
* The Tiptap Content component that renders the EditorContent with the editor instance from the context.
|
|
469
|
+
* @see TiptapContent
|
|
470
|
+
*/
|
|
471
|
+
Content: typeof TiptapContent;
|
|
472
|
+
};
|
|
473
|
+
|
|
297
474
|
type EditorStateSnapshot<TEditor extends Editor | null = Editor | null> = {
|
|
298
475
|
editor: TEditor;
|
|
299
476
|
transactionNumber: number;
|
|
@@ -354,4 +531,4 @@ declare const ReactNodeViewContentProvider: ({ children, content }: {
|
|
|
354
531
|
}) => React.FunctionComponentElement<React.ProviderProps<ReactNodeViewContextProps>>;
|
|
355
532
|
declare const useReactNodeView: () => ReactNodeViewContextProps;
|
|
356
533
|
|
|
357
|
-
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, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView };
|
|
534
|
+
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 TiptapWrapperProps, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useTiptap, useTiptapState };
|
package/dist/index.js
CHANGED
|
@@ -815,6 +815,7 @@ var ReactNodeView = class extends NodeView {
|
|
|
815
815
|
* The requestAnimationFrame ID used for selection updates.
|
|
816
816
|
*/
|
|
817
817
|
this.selectionRafId = null;
|
|
818
|
+
this.cachedExtensionWithSyncedStorage = null;
|
|
818
819
|
if (!this.node.isLeaf) {
|
|
819
820
|
if (this.options.contentDOMElementTag) {
|
|
820
821
|
this.contentDOMElement = document.createElement(this.options.contentDOMElementTag);
|
|
@@ -831,6 +832,27 @@ var ReactNodeView = class extends NodeView {
|
|
|
831
832
|
contentTarget.appendChild(this.contentDOMElement);
|
|
832
833
|
}
|
|
833
834
|
}
|
|
835
|
+
/**
|
|
836
|
+
* Returns a proxy of the extension that redirects storage access to the editor's mutable storage.
|
|
837
|
+
* This preserves the original prototype chain (instanceof checks, methods like configure/extend work).
|
|
838
|
+
* Cached to avoid proxy creation on every update.
|
|
839
|
+
*/
|
|
840
|
+
get extensionWithSyncedStorage() {
|
|
841
|
+
if (!this.cachedExtensionWithSyncedStorage) {
|
|
842
|
+
const editor = this.editor;
|
|
843
|
+
const extension = this.extension;
|
|
844
|
+
this.cachedExtensionWithSyncedStorage = new Proxy(extension, {
|
|
845
|
+
get(target, prop, receiver) {
|
|
846
|
+
var _a;
|
|
847
|
+
if (prop === "storage") {
|
|
848
|
+
return (_a = editor.storage[extension.name]) != null ? _a : {};
|
|
849
|
+
}
|
|
850
|
+
return Reflect.get(target, prop, receiver);
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
return this.cachedExtensionWithSyncedStorage;
|
|
855
|
+
}
|
|
834
856
|
/**
|
|
835
857
|
* Setup the React component.
|
|
836
858
|
* Called on initialization.
|
|
@@ -843,7 +865,7 @@ var ReactNodeView = class extends NodeView {
|
|
|
843
865
|
innerDecorations: this.innerDecorations,
|
|
844
866
|
view: this.view,
|
|
845
867
|
selected: false,
|
|
846
|
-
extension: this.
|
|
868
|
+
extension: this.extensionWithSyncedStorage,
|
|
847
869
|
HTMLAttributes: this.HTMLAttributes,
|
|
848
870
|
getPos: () => this.getPos(),
|
|
849
871
|
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
|
|
@@ -964,7 +986,7 @@ var ReactNodeView = class extends NodeView {
|
|
|
964
986
|
newDecorations: decorations,
|
|
965
987
|
oldInnerDecorations,
|
|
966
988
|
innerDecorations,
|
|
967
|
-
updateProps: () => rerenderComponent({ node, decorations, innerDecorations })
|
|
989
|
+
updateProps: () => rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage })
|
|
968
990
|
});
|
|
969
991
|
}
|
|
970
992
|
if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
|
|
@@ -973,7 +995,7 @@ var ReactNodeView = class extends NodeView {
|
|
|
973
995
|
this.node = node;
|
|
974
996
|
this.decorations = decorations;
|
|
975
997
|
this.innerDecorations = innerDecorations;
|
|
976
|
-
rerenderComponent({ node, decorations, innerDecorations });
|
|
998
|
+
rerenderComponent({ node, decorations, innerDecorations, extension: this.extensionWithSyncedStorage });
|
|
977
999
|
return true;
|
|
978
1000
|
}
|
|
979
1001
|
/**
|
|
@@ -1035,6 +1057,47 @@ function ReactNodeViewRenderer(component, options) {
|
|
|
1035
1057
|
};
|
|
1036
1058
|
}
|
|
1037
1059
|
|
|
1060
|
+
// src/Tiptap.tsx
|
|
1061
|
+
import { createContext as createContext3, useContext as useContext3, useMemo as useMemo2 } from "react";
|
|
1062
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1063
|
+
var TiptapContext = createContext3({
|
|
1064
|
+
get editor() {
|
|
1065
|
+
throw new Error("useTiptap must be used within a <Tiptap> provider");
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
TiptapContext.displayName = "TiptapContext";
|
|
1069
|
+
var useTiptap = () => useContext3(TiptapContext);
|
|
1070
|
+
function useTiptapState(selector, equalityFn) {
|
|
1071
|
+
const { editor } = useTiptap();
|
|
1072
|
+
return useEditorState({
|
|
1073
|
+
editor,
|
|
1074
|
+
selector,
|
|
1075
|
+
equalityFn
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
function TiptapWrapper({ editor, instance, children }) {
|
|
1079
|
+
const resolvedEditor = editor != null ? editor : instance;
|
|
1080
|
+
if (!resolvedEditor) {
|
|
1081
|
+
throw new Error("Tiptap: An editor instance is required. Pass a non-null `editor` prop.");
|
|
1082
|
+
}
|
|
1083
|
+
const tiptapContextValue = useMemo2(() => ({ editor: resolvedEditor }), [resolvedEditor]);
|
|
1084
|
+
const legacyContextValue = useMemo2(() => ({ editor: resolvedEditor }), [resolvedEditor]);
|
|
1085
|
+
return /* @__PURE__ */ jsx8(EditorContext.Provider, { value: legacyContextValue, children: /* @__PURE__ */ jsx8(TiptapContext.Provider, { value: tiptapContextValue, children }) });
|
|
1086
|
+
}
|
|
1087
|
+
TiptapWrapper.displayName = "Tiptap";
|
|
1088
|
+
function TiptapContent({ ...rest }) {
|
|
1089
|
+
const { editor } = useTiptap();
|
|
1090
|
+
return /* @__PURE__ */ jsx8(EditorContent, { editor, ...rest });
|
|
1091
|
+
}
|
|
1092
|
+
TiptapContent.displayName = "Tiptap.Content";
|
|
1093
|
+
var Tiptap = Object.assign(TiptapWrapper, {
|
|
1094
|
+
/**
|
|
1095
|
+
* The Tiptap Content component that renders the EditorContent with the editor instance from the context.
|
|
1096
|
+
* @see TiptapContent
|
|
1097
|
+
*/
|
|
1098
|
+
Content: TiptapContent
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1038
1101
|
// src/index.ts
|
|
1039
1102
|
export * from "@tiptap/core";
|
|
1040
1103
|
export {
|
|
@@ -1054,9 +1117,15 @@ export {
|
|
|
1054
1117
|
ReactNodeViewContext,
|
|
1055
1118
|
ReactNodeViewRenderer,
|
|
1056
1119
|
ReactRenderer,
|
|
1120
|
+
Tiptap,
|
|
1121
|
+
TiptapContent,
|
|
1122
|
+
TiptapContext,
|
|
1123
|
+
TiptapWrapper,
|
|
1057
1124
|
useCurrentEditor,
|
|
1058
1125
|
useEditor,
|
|
1059
1126
|
useEditorState,
|
|
1060
|
-
useReactNodeView
|
|
1127
|
+
useReactNodeView,
|
|
1128
|
+
useTiptap,
|
|
1129
|
+
useTiptapState
|
|
1061
1130
|
};
|
|
1062
1131
|
//# sourceMappingURL=index.js.map
|