Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Commit

Permalink
refactor(legacy-editor): improve node view portal rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
Darmody committed Jul 22, 2022
1 parent 8a01c97 commit c39fe26
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion packages/editor/src/NodePortal/NodePortalContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const NodePortalContainer: FC<NodePortalContainerProps> = ({ children })
return (
<NodePortalsContext.Provider value={contextValue}>
{children}
{nodePortals.map(({ container, child }) => createPortal(child, container))}
{nodePortals.map(({ container, child, id }) => createPortal(child, container, id))}
</NodePortalsContext.Provider>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('NodePortalContainer', () => {
useEffect(() => {
setNodePortals([
{
id: 'id',
container: portalContainer,
child: <span>{text}</span>
}
Expand Down
4 changes: 4 additions & 0 deletions packages/editor/src/NodePortal/useNodePortals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { createContext, Dispatch, ReactNode, SetStateAction, useContext } from '
* A portal contains dom container and react node.
*/
export interface NodePortal {
/**
* unique id
*/
id: string
/**
* the container mounted the react node.
*/
Expand Down
5 changes: 3 additions & 2 deletions packages/legacy-editor/src/tiptapRefactor/Editor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NodePortal } from '@mashcard/editor'
import { Editor as TiptapEditor } from '@tiptap/core'
import { ReactNode } from 'react'

export interface Editor extends TiptapEditor {
updatePortal?: (container: Element, child: ReactNode) => void
updatePortal?: (nodePortal: NodePortal) => void
removePortal?: (id: string) => void
}
20 changes: 10 additions & 10 deletions packages/legacy-editor/src/tiptapRefactor/EditorContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, HTMLProps, ReactNode, useEffect, useRef, useState } from 'react'
import { FC, HTMLProps, useEffect, useRef, useState } from 'react'
import { createPortal } from 'react-dom'
import { Editor } from '@tiptap/core'
import { NodePortal } from '@mashcard/editor'
Expand All @@ -8,10 +8,10 @@ export interface EditorContentProps extends HTMLProps<HTMLDivElement> {
editor: Editor | null
}

const containerMatcher = (container: Element) => (value: NodePortal) => value.container === container
const portalUpdater = (index: number, container: Element, child: ReactNode) => (portal: NodePortal, i: number) => {
if (i === index) return { container, child }
return portal
const containerMatcher = (id: string) => (value: NodePortal) => value.id === id
const portalUpdater = (index: number, nodePortal: NodePortal) => (value: NodePortal, i: number) => {
if (i === index) return nodePortal
return value
}

export const EditorContent: FC<EditorContentProps> = ({ editor, ...props }) => {
Expand All @@ -36,14 +36,14 @@ export const EditorContent: FC<EditorContentProps> = ({ editor, ...props }) => {
editor.setOptions({
element
})
;(editor as ExtendEditor).updatePortal = (container, child) => {
;(editor as ExtendEditor).updatePortal = nodePortal => {
setNodePortals(nodePortals => {
const index = nodePortals.findIndex(containerMatcher(container))
const index = nodePortals.findIndex(containerMatcher(nodePortal.id))

if (index >= 0) {
return nodePortals.map(portalUpdater(index, container, child))
return nodePortals.map(portalUpdater(index, nodePortal))
} else {
return [...nodePortals, { container, child }]
return [...nodePortals, nodePortal]
}
})
}
Expand Down Expand Up @@ -82,7 +82,7 @@ export const EditorContent: FC<EditorContentProps> = ({ editor, ...props }) => {
return (
<>
<div {...props} ref={editorContentRef} />
{nodePortals.map(({ container, child }) => createPortal(child, container))}
{nodePortals.map(({ container, child, id }) => createPortal(child, container, id))}
</>
)
}
6 changes: 4 additions & 2 deletions packages/legacy-editor/src/tiptapRefactor/ReactRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class ReactRenderer<R = unknown, P = unknown> {

this.reactElement = <Component {...props} />

this.editor?.updatePortal?.(this.element, this.reactElement)
this.editor?.updatePortal?.({ id: this.id, child: this.reactElement, container: this.element })
}

updateProps(props: Record<string, any> = {}): void {
Expand All @@ -82,5 +82,7 @@ export class ReactRenderer<R = unknown, P = unknown> {
this.render()
}

destroy(): void {}
destroy(): void {
this.editor?.removePortal?.(this.id)
}
}

0 comments on commit c39fe26

Please sign in to comment.