diff --git a/.changeset/thin-pears-judge.md b/.changeset/thin-pears-judge.md new file mode 100644 index 0000000000..fb86f0f4bf --- /dev/null +++ b/.changeset/thin-pears-judge.md @@ -0,0 +1,8 @@ +--- +'@udecode/plate-indent-list': patch +'@udecode/plate-toggle': patch +'@udecode/plate-core': patch +'@udecode/plate-ai': patch +--- + +Update types and docs of `aboveNodes` and `belowNodes` diff --git a/apps/www/content/docs/cn/api/core/plate-plugin.mdx b/apps/www/content/docs/cn/api/core/plate-plugin.mdx index e74d751ea6..973a968a86 100644 --- a/apps/www/content/docs/cn/api/core/plate-plugin.mdx +++ b/apps/www/content/docs/cn/api/core/plate-plugin.mdx @@ -171,8 +171,8 @@ HTML React 序列化器配置。 在 `Editable` 组件上方但在 `Slate` 包装器内渲染组件。 - -在所有其他插件的 `node` 组件上方渲染组件。 + +创建一个函数,该函数为所有其他插件的 `node` React节点生成父节点。 在 `Slate` 包装器上方渲染组件。 @@ -183,8 +183,8 @@ HTML React 序列化器配置。 在 `Editable` 组件前渲染组件。 - -在所有其他插件的 `node` 组件下方但在其 `children` 上方渲染组件。 + +创建一个函数,该函数为所有其他插件的 `node` React节点和其`children`React节点之间生成一个React节点。 渲染节点组件。 diff --git a/apps/www/content/docs/en/api/core/plate-plugin.mdx b/apps/www/content/docs/en/api/core/plate-plugin.mdx index ce63a2b15b..cc7c234c34 100644 --- a/apps/www/content/docs/en/api/core/plate-plugin.mdx +++ b/apps/www/content/docs/en/api/core/plate-plugin.mdx @@ -150,8 +150,8 @@ Defines how the plugin renders components. Component rendered above the Editable component but inside the Slate wrapper. - -Component rendered above all other plugins' node components. + +Create a function that generates a parent React node for all other plugins' node components. Component rendered above the Slate wrapper. @@ -162,8 +162,8 @@ Renders a component after the Editable component. Renders a component before the Editable component. - -Renders a component below all other plugins' node components, but above their children. + +Create a function that generates a React node below all other plugins' node React node, but above their children. Renders the node component. diff --git a/apps/www/src/registry/default/plate-ui/draggable.tsx b/apps/www/src/registry/default/plate-ui/draggable.tsx index 4705971cca..6093d19d3b 100644 --- a/apps/www/src/registry/default/plate-ui/draggable.tsx +++ b/apps/www/src/registry/default/plate-ui/draggable.tsx @@ -6,8 +6,8 @@ import React, { useMemo } from 'react'; import { cn, withRef } from '@udecode/cn'; import { isType } from '@udecode/plate'; import { - type NodeWrapperComponent, type PlateRenderElementProps, + type RenderNodeWrapper, MemoizedChildren, ParagraphPlugin, useEditorPlugin, @@ -46,7 +46,7 @@ const UNDRAGGABLE_KEYS = [ TableCellPlugin.key, ]; -export const DraggableAboveNodes: NodeWrapperComponent = (props) => { +export const DraggableAboveNodes: RenderNodeWrapper = (props) => { const { editor, element, path } = props; const readOnly = useReadOnly(); diff --git a/packages/ai/src/react/copilot/renderCopilotBelowNodes.tsx b/packages/ai/src/react/copilot/renderCopilotBelowNodes.tsx index afd9db3fa3..905769301c 100644 --- a/packages/ai/src/react/copilot/renderCopilotBelowNodes.tsx +++ b/packages/ai/src/react/copilot/renderCopilotBelowNodes.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { - type NodeWrapperComponentProps, + type RenderNodeWrapperProps, getEditorPlugin, } from '@udecode/plate/react'; @@ -11,7 +11,7 @@ import type { CopilotPluginConfig } from './CopilotPlugin'; export const renderCopilotBelowNodes = ({ editor, -}: NodeWrapperComponentProps) => { +}: RenderNodeWrapperProps) => { const copilot = getEditorPlugin(editor, { key: 'copilot', }); @@ -20,7 +20,7 @@ export const renderCopilotBelowNodes = ({ if (!GhostText) return; - return function Component({ children }: { children: React.ReactNode }) { + return ({ children }: { children: React.ReactNode }) => { return ( {children} diff --git a/packages/core/src/lib/plugin/SlatePlugin.ts b/packages/core/src/lib/plugin/SlatePlugin.ts index b4c42b8ff8..4bbb261d49 100644 --- a/packages/core/src/lib/plugin/SlatePlugin.ts +++ b/packages/core/src/lib/plugin/SlatePlugin.ts @@ -70,10 +70,15 @@ export type SlatePlugin = }; render: Nullable<{ /** - * Renders a component above all other plugins' `node` components. - * Useful for wrapping or decorating nodes with additional UI elements. + * When other plugins' `node` components are rendered, this function can + * return an optional wrapper function that turns a `node`'s props to a + * wrapper React node as its parent. Useful for wrapping or decorating + * nodes with additional UI elements. + * + * NOTE: The function can run React hooks. NOTE: Do not run React hooks + * in the wrapper function. It is not equivalent to a React component. */ - aboveNodes?: NodeStaticWrapperComponent>; + aboveNodes?: RenderStaticNodeWrapper>; /** * Renders a component after the `Editable` component. This is the last @@ -85,11 +90,16 @@ export type SlatePlugin = beforeEditable?: () => React.ReactElement | null; /** - * Renders a component below all other plugins' `node` components, but - * above their `children`. This allows for injecting content or UI - * elements within nodes but before their child content. + * When other plugins' `node` components are rendered, this function can + * return an optional wrapper function that turns a `node`'s props to a + * wrapper React node. The wrapper node is the `node`'s child and its + * original children's parent. Useful for wrapping or decorating nodes + * with additional UI elements. + * + * NOTE: The function can run React hooks. NOTE: Do not run React hooks + * in the wrapper function. It is not equivalent to a React component. */ - belowNodes?: NodeStaticWrapperComponent>; + belowNodes?: RenderStaticNodeWrapper>; node?: React.FC; }>; @@ -514,16 +524,32 @@ export type NodeStaticProps = ) => AnyObject | undefined) | AnyObject; +export type RenderStaticNodeWrapper = + (props: RenderStaticNodeWrapperProps) => RenderStaticNodeWrapperFunction; + +export type RenderStaticNodeWrapperFunction = + | ((hocProps: SlateRenderElementProps) => React.ReactNode) + | undefined; + +export interface RenderStaticNodeWrapperProps< + C extends AnyPluginConfig = PluginConfig, +> extends SlateRenderElementProps { + key: string; +} + +/** @deprecated Use {@link RenderStaticNodeWrapper} instead. */ export type NodeStaticWrapperComponent< C extends AnyPluginConfig = PluginConfig, > = ( props: NodeStaticWrapperComponentProps ) => NodeStaticWrapperComponentReturnType; +/** @deprecated Use {@link RenderStaticNodeWrapperFunction} instead. */ export type NodeStaticWrapperComponentReturnType< C extends AnyPluginConfig = PluginConfig, > = React.FC> | undefined; +/** @deprecated Use {@link RenderStaticNodeWrapperProps} instead. */ export interface NodeStaticWrapperComponentProps< C extends AnyPluginConfig = PluginConfig, > extends SlateRenderElementProps { diff --git a/packages/core/src/react/plugin/PlatePlugin.ts b/packages/core/src/react/plugin/PlatePlugin.ts index 685192e6fb..eb230eb1fd 100644 --- a/packages/core/src/react/plugin/PlatePlugin.ts +++ b/packages/core/src/react/plugin/PlatePlugin.ts @@ -127,10 +127,15 @@ export type PlatePlugin = render: Nullable<{ /** - * Renders a component above all other plugins' `node` components. - * Useful for wrapping or decorating nodes with additional UI elements. + * When other plugins' `node` components are rendered, this function can + * return an optional wrapper function that turns a `node`'s props to a + * wrapper React node as its parent. Useful for wrapping or decorating + * nodes with additional UI elements. + * + * NOTE: The function can run React hooks. NOTE: Do not run React hooks + * in the wrapper function. It is not equivalent to a React component. */ - aboveNodes?: NodeWrapperComponent>; + aboveNodes?: RenderNodeWrapper>; /** * Renders a component after the `Editable` component. This is the last @@ -142,11 +147,16 @@ export type PlatePlugin = beforeEditable?: EditableSiblingComponent; /** - * Renders a component below all other plugins' `node` components, but - * above their `children`. This allows for injecting content or UI - * elements within nodes but before their child content. + * When other plugins' `node` components are rendered, this function can + * return an optional wrapper function that turns a `node`'s props to a + * wrapper React node. The wrapper node is the `node`'s child and its + * original children's parent. Useful for wrapping or decorating nodes + * with additional UI elements. + * + * NOTE: The function can run React hooks. NOTE: Do not run React hooks + * in the wrapper function. It is not equivalent to a React component. */ - belowNodes?: NodeWrapperComponent>; + belowNodes?: RenderNodeWrapper>; /** @see {@link NodeComponent} */ node?: NodeComponent; @@ -727,19 +737,36 @@ export type EditableSiblingComponent = ( editableProps: EditableProps ) => React.ReactElement | null; -export interface NodeWrapperComponentProps< +export interface RenderNodeWrapperProps< C extends AnyPluginConfig = PluginConfig, > extends PlateRenderElementProps { key: string; } -export type NodeWrapperComponentReturnType = - | React.FC +export type RenderNodeWrapperFunction = + | ((elementProps: PlateRenderElementProps) => React.ReactNode) | undefined; +export type RenderNodeWrapper = ( + props: RenderNodeWrapperProps +) => RenderNodeWrapperFunction; + +/** @deprecated Use {@link RenderNodeWrapperProps} instead. */ +export interface NodeWrapperComponentProps< + C extends AnyPluginConfig = PluginConfig, +> extends PlateRenderElementProps { + key: string; +} + +/** @deprecated Use {@link RenderNodeWrapperFunction} instead. */ +export type NodeWrapperComponentReturnType< + C extends AnyPluginConfig = PluginConfig, +> = React.FC> | undefined; + +/** @deprecated Use {@link RenderNodeWrapper} instead. */ export type NodeWrapperComponent = ( props: NodeWrapperComponentProps -) => NodeWrapperComponentReturnType; +) => NodeWrapperComponentReturnType; /** * Function called whenever a change occurs in the editor. Return `false` to diff --git a/packages/indent-list/src/lib/renderIndentListBelowNodes.tsx b/packages/indent-list/src/lib/renderIndentListBelowNodes.tsx index 1ac429cf95..c6ed53d202 100644 --- a/packages/indent-list/src/lib/renderIndentListBelowNodes.tsx +++ b/packages/indent-list/src/lib/renderIndentListBelowNodes.tsx @@ -1,9 +1,9 @@ import React from 'react'; import type { - NodeStaticWrapperComponent, - NodeStaticWrapperComponentProps, - NodeStaticWrapperComponentReturnType, + RenderStaticNodeWrapper, + RenderStaticNodeWrapperFunction, + RenderStaticNodeWrapperProps, } from '@udecode/plate'; import { clsx } from 'clsx'; @@ -15,9 +15,9 @@ import { } from '../lib'; import { ULIST_STYLE_TYPES } from '../lib/types'; -export const renderIndentListBelowNodes: NodeStaticWrapperComponent = ( - injectProps: NodeStaticWrapperComponentProps -): NodeStaticWrapperComponentReturnType => { +export const renderIndentListBelowNodes: RenderStaticNodeWrapper = ( + injectProps: RenderStaticNodeWrapperProps +): RenderStaticNodeWrapperFunction => { const { element } = injectProps; const listStyleType = element[BaseIndentListPlugin.key] as string; @@ -32,7 +32,7 @@ export const renderIndentListBelowNodes: NodeStaticWrapperComponent = ( position: 'relative', }; - return function Component({ children, ...props }) { + return ({ children, ...props }) => { const { editor } = props; const { listStyleTypes = {} } = editor.getOptions(BaseIndentListPlugin); diff --git a/packages/toggle/src/react/renderToggleAboveNodes.tsx b/packages/toggle/src/react/renderToggleAboveNodes.tsx index f107efabf0..48e4cde35e 100644 --- a/packages/toggle/src/react/renderToggleAboveNodes.tsx +++ b/packages/toggle/src/react/renderToggleAboveNodes.tsx @@ -1,19 +1,15 @@ import React from 'react'; import type { - NodeWrapperComponent, - NodeWrapperComponentReturnType, + RenderNodeWrapper, + RenderNodeWrapperFunction, } from '@udecode/plate/react'; import { useIsVisible } from './toggleIndexAtom'; -export const renderToggleAboveNodes: NodeWrapperComponent = () => - ToggleAboveNodes; +export const renderToggleAboveNodes: RenderNodeWrapper = () => ToggleAboveNodes; -const ToggleAboveNodes: NodeWrapperComponentReturnType = ({ - children, - element, -}) => { +const ToggleAboveNodes: RenderNodeWrapperFunction = ({ children, element }) => { const isVisible = useIsVisible(element.id as string); if (isVisible) return children;