diff --git a/packages/core/src/event/bus/action.ts b/packages/core/src/event/bus/action.ts index 6c60d08..7bbcf22 100644 --- a/packages/core/src/event/bus/action.ts +++ b/packages/core/src/event/bus/action.ts @@ -37,6 +37,8 @@ export type Handler = { priority: number; listener: Listener; }; -export type WithStop = T & { stop: () => void; prevent: () => void; _raw: T; _key: string }; export type Listener = (value: WithStop) => void; export type Listeners = { [T in EventType]?: Handler[] }; +export type WithStop = T extends Object.Any + ? T & { stop: () => void; prevent: () => void; _raw: T; _key: string } + : T; diff --git a/packages/core/src/event/bus/index.ts b/packages/core/src/event/bus/index.ts index 16a0c16..407dbd7 100644 --- a/packages/core/src/event/bus/index.ts +++ b/packages/core/src/event/bus/index.ts @@ -8,7 +8,7 @@ export class EventBus { /** * @param key * @param listener - * @param priority + * @param priority 默认 100 */ public on(key: T, listener: Listener, priority = DEFAULT_PRIORITY) { this.addEventListener(key, listener, priority, false); @@ -17,7 +17,7 @@ export class EventBus { /** * @param key * @param listener - * @param priority + * @param priority 默认 100 */ public once(key: T, listener: Listener, priority = DEFAULT_PRIORITY) { this.addEventListener(key, listener, priority, true); diff --git a/packages/core/src/preset/editable.tsx b/packages/core/src/preset/editable.tsx index ecea7ba..1226ddb 100644 --- a/packages/core/src/preset/editable.tsx +++ b/packages/core/src/preset/editable.tsx @@ -7,6 +7,7 @@ import { INIT_NODE } from "../editor/constant"; import { EDITOR_EVENT } from "../event/bus/action"; import type { ApplyPlugins } from "../plugin/types/apply"; import { EDITOR_STATE } from "../state/types"; +import { WithContext } from "./with-context"; type EditableProps = { readonly?: boolean; @@ -86,22 +87,24 @@ export class Editable extends React.PureComponent value={this.props.init || this.props.editor.options.init || INIT_NODE} onChange={this.props.onChange} > - + + + ); } diff --git a/packages/core/src/preset/with-context.tsx b/packages/core/src/preset/with-context.tsx new file mode 100644 index 0000000..96e937a --- /dev/null +++ b/packages/core/src/preset/with-context.tsx @@ -0,0 +1,35 @@ +import { useSlate } from "doc-editor-delta"; +import type { FC } from "react"; +import { useEffect, useRef } from "react"; + +import type { EditorKit } from "../editor"; +import { EDITOR_EVENT } from "../event/bus/action"; + +export const WithContext: FC<{ editor: EditorKit }> = props => { + const { editor, children } = props; + const isNeedPaint = useRef(true); + // 保证每次触发 Apply 时都会重新渲染 + // https://github.com/ianstormtaylor/slate/blob/25be3b/packages/slate-react/src/components/slate.tsx#L29 + useSlate(); + + useEffect(() => { + const onContentChange = () => { + isNeedPaint.current = true; + }; + editor.event.on(EDITOR_EVENT.CONTENT_CHANGE, onContentChange, 1); + return () => { + editor.event.off(EDITOR_EVENT.CONTENT_CHANGE, onContentChange); + }; + }, [editor]); + + useEffect(() => { + if (isNeedPaint.current) { + Promise.resolve().then(() => { + editor.event.trigger(EDITOR_EVENT.PAINT, {}); + }); + } + isNeedPaint.current = false; + }); + + return children as JSX.Element; +};