mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-11-27 14:59:27 +08:00
fix(react): update typescript types to be backwards-compatible (#5479)
This commit is contained in:
parent
b30462a2c6
commit
a42692e479
5
.changeset/spotty-lobsters-compare.md
Normal file
5
.changeset/spotty-lobsters-compare.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tiptap/react": patch
|
||||
---
|
||||
|
||||
This resolves some typescript errors with the exported React type to remove contentComponent from being exported (it is an implementation detail)
|
@ -1,7 +1,6 @@
|
||||
import { Editor } from '@tiptap/core'
|
||||
import React, { createContext, ReactNode, useContext } from 'react'
|
||||
|
||||
import { Editor as ReactEditor } from './Editor.js'
|
||||
import { EditorContent } from './EditorContent.js'
|
||||
import { useEditor, UseEditorOptions } from './useEditor.js'
|
||||
|
||||
@ -45,7 +44,7 @@ export function EditorProvider({
|
||||
{slotBefore}
|
||||
<EditorConsumer>
|
||||
{({ editor: currentEditor }) => (
|
||||
<EditorContent editor={currentEditor as ReactEditor} />
|
||||
<EditorContent editor={currentEditor} />
|
||||
)}
|
||||
</EditorConsumer>
|
||||
{children}
|
||||
|
@ -1,16 +1,13 @@
|
||||
import { Editor as CoreEditor } from '@tiptap/core'
|
||||
import React from 'react'
|
||||
import { Editor } from '@tiptap/core'
|
||||
import { ReactPortal } from 'react'
|
||||
|
||||
import { ReactRenderer } from './ReactRenderer.js'
|
||||
|
||||
type ContentComponent = {
|
||||
export type EditorWithContentComponent = Editor & { contentComponent: ContentComponent | null }
|
||||
export type ContentComponent = {
|
||||
setRenderer(id: string, renderer: ReactRenderer): void;
|
||||
removeRenderer(id: string): void;
|
||||
subscribe: (callback: () => void) => () => void;
|
||||
getSnapshot: () => Record<string, React.ReactPortal>;
|
||||
getServerSnapshot: () => Record<string, React.ReactPortal>;
|
||||
}
|
||||
|
||||
export class Editor extends CoreEditor {
|
||||
public contentComponent: ContentComponent | null = null
|
||||
getSnapshot: () => Record<string, ReactPortal>;
|
||||
getServerSnapshot: () => Record<string, ReactPortal>;
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { Editor } from '@tiptap/core'
|
||||
import React, {
|
||||
ForwardedRef, forwardRef, HTMLProps, LegacyRef, MutableRefObject,
|
||||
} from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { useSyncExternalStore } from 'use-sync-external-store/shim'
|
||||
|
||||
import { Editor } from './Editor.js'
|
||||
import { ContentComponent, EditorWithContentComponent } from './Editor.js'
|
||||
import { ReactRenderer } from './ReactRenderer.js'
|
||||
|
||||
const mergeRefs = <T extends HTMLDivElement>(
|
||||
@ -24,7 +25,7 @@ const mergeRefs = <T extends HTMLDivElement>(
|
||||
/**
|
||||
* This component renders all of the editor's node views.
|
||||
*/
|
||||
const Portals: React.FC<{ contentComponent: Exclude<Editor['contentComponent'], null> }> = ({
|
||||
const Portals: React.FC<{ contentComponent: ContentComponent }> = ({
|
||||
contentComponent,
|
||||
}) => {
|
||||
// For performance reasons, we render the node view portals on state changes only
|
||||
@ -47,7 +48,7 @@ export interface EditorContentProps extends HTMLProps<HTMLDivElement> {
|
||||
innerRef?: ForwardedRef<HTMLDivElement | null>;
|
||||
}
|
||||
|
||||
function getInstance(): Exclude<Editor['contentComponent'], null> {
|
||||
function getInstance(): ContentComponent {
|
||||
const subscribers = new Set<() => void>()
|
||||
let renderers: Record<string, React.ReactPortal> = {}
|
||||
|
||||
@ -107,7 +108,7 @@ export class PureEditorContent extends React.Component<
|
||||
this.initialized = false
|
||||
|
||||
this.state = {
|
||||
hasContentComponentInitialized: Boolean(props.editor?.contentComponent),
|
||||
hasContentComponentInitialized: Boolean((props.editor as EditorWithContentComponent).contentComponent),
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ export class PureEditorContent extends React.Component<
|
||||
}
|
||||
|
||||
init() {
|
||||
const { editor } = this.props
|
||||
const editor = this.props.editor as EditorWithContentComponent
|
||||
|
||||
if (editor && !editor.isDestroyed && editor.options.element) {
|
||||
if (editor.contentComponent) {
|
||||
@ -164,7 +165,7 @@ export class PureEditorContent extends React.Component<
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { editor } = this.props
|
||||
const editor = this.props.editor as EditorWithContentComponent
|
||||
|
||||
if (!editor) {
|
||||
return
|
||||
@ -215,6 +216,7 @@ const EditorContentWithKey = forwardRef<HTMLDivElement, EditorContentProps>(
|
||||
(props: Omit<EditorContentProps, 'innerRef'>, ref) => {
|
||||
const key = React.useMemo(() => {
|
||||
return Math.floor(Math.random() * 0xffffffff).toString()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [props.editor])
|
||||
|
||||
// Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
|
||||
|
@ -12,6 +12,7 @@ export const NodeViewContent: React.FC<NodeViewContentProps> = props => {
|
||||
const { nodeViewContentRef } = useReactNodeView()
|
||||
|
||||
return (
|
||||
// @ts-ignore
|
||||
<Tag
|
||||
{...props}
|
||||
ref={nodeViewContentRef}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
DecorationWithType,
|
||||
Editor,
|
||||
NodeView,
|
||||
NodeViewProps,
|
||||
NodeViewRenderer,
|
||||
@ -10,7 +11,7 @@ import { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
||||
import { Decoration, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
|
||||
import React from 'react'
|
||||
|
||||
import { Editor } from './Editor.js'
|
||||
import { EditorWithContentComponent } from './Editor.js'
|
||||
import { ReactRenderer } from './ReactRenderer.js'
|
||||
import { ReactNodeViewContext, ReactNodeViewContextProps } from './useReactNodeView.js'
|
||||
|
||||
@ -216,7 +217,7 @@ export function ReactNodeViewRenderer(
|
||||
// try to get the parent component
|
||||
// this is important for vue devtools to show the component hierarchy correctly
|
||||
// maybe it’s `undefined` because <editor-content> isn’t rendered yet
|
||||
if (!(props.editor as Editor).contentComponent) {
|
||||
if (!(props.editor as EditorWithContentComponent).contentComponent) {
|
||||
return {}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { Editor } from '@tiptap/core'
|
||||
import React from 'react'
|
||||
import { flushSync } from 'react-dom'
|
||||
|
||||
import { Editor as ExtendedEditor } from './Editor.js'
|
||||
import { EditorWithContentComponent } from './Editor.js'
|
||||
|
||||
/**
|
||||
* Check if a component is a class component.
|
||||
@ -86,7 +86,7 @@ type ComponentType<R, P> =
|
||||
export class ReactRenderer<R = unknown, P = unknown> {
|
||||
id: string
|
||||
|
||||
editor: ExtendedEditor
|
||||
editor: Editor
|
||||
|
||||
component: any
|
||||
|
||||
@ -107,7 +107,7 @@ export class ReactRenderer<R = unknown, P = unknown> {
|
||||
}: ReactRendererOptions) {
|
||||
this.id = Math.floor(Math.random() * 0xFFFFFFFF).toString()
|
||||
this.component = component
|
||||
this.editor = editor as ExtendedEditor
|
||||
this.editor = editor as EditorWithContentComponent
|
||||
this.props = props
|
||||
this.element = document.createElement(as)
|
||||
this.element.classList.add('react-renderer')
|
||||
@ -136,6 +136,7 @@ export class ReactRenderer<R = unknown, P = unknown> {
|
||||
render(): void {
|
||||
const Component = this.component
|
||||
const props = this.props
|
||||
const editor = this.editor as EditorWithContentComponent
|
||||
|
||||
if (isClassComponent(Component) || isForwardRefComponent(Component)) {
|
||||
props.ref = (ref: R) => {
|
||||
@ -145,7 +146,7 @@ export class ReactRenderer<R = unknown, P = unknown> {
|
||||
|
||||
this.reactElement = React.createElement(Component, props)
|
||||
|
||||
this.editor?.contentComponent?.setRenderer(this.id, this)
|
||||
editor?.contentComponent?.setRenderer(this.id, this)
|
||||
}
|
||||
|
||||
updateProps(props: Record<string, any> = {}): void {
|
||||
@ -158,6 +159,8 @@ export class ReactRenderer<R = unknown, P = unknown> {
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.editor?.contentComponent?.removeRenderer(this.id)
|
||||
const editor = this.editor as EditorWithContentComponent
|
||||
|
||||
editor?.contentComponent?.removeRenderer(this.id)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
export * from './BubbleMenu.js'
|
||||
export * from './Context.js'
|
||||
export { Editor } from './Editor.js'
|
||||
export * from './EditorContent.js'
|
||||
export * from './FloatingMenu.js'
|
||||
export * from './NodeViewContent.js'
|
||||
@ -10,4 +9,5 @@ export * from './ReactRenderer.js'
|
||||
export * from './useEditor.js'
|
||||
export * from './useEditorState.js'
|
||||
export * from './useReactNodeView.js'
|
||||
export { Editor } from '@tiptap/core'
|
||||
export * from '@tiptap/core'
|
||||
|
Loading…
Reference in New Issue
Block a user