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;