diff --git a/components/tour/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/tour/__tests__/__snapshots__/demo-extend.test.ts.snap
index 82b5b9f9bb..09def5aa87 100644
--- a/components/tour/__tests__/__snapshots__/demo-extend.test.ts.snap
+++ b/components/tour/__tests__/__snapshots__/demo-extend.test.ts.snap
@@ -1,5 +1,178 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`renders components/tour/demo/actions-render.tsx extend context correctly 1`] = `
+Array [
+ ,
+
,
+
+
+
+
+
+
+
+
+
,
+
+
+
+
+
+
+
+ Put your files here.
+
+
+
+
+
,
+]
+`;
+
+exports[`renders components/tour/demo/actions-render.tsx extend context correctly 2`] = `[]`;
+
exports[`renders components/tour/demo/basic.tsx extend context correctly 1`] = `
Array [
@@ -726,7 +899,7 @@ Array [
type="button"
>
- Upload
+ Upload
@@ -899,7 +1072,7 @@ Array [
type="button"
>
- Upload
+ Upload
diff --git a/components/tour/__tests__/__snapshots__/demo.test.tsx.snap b/components/tour/__tests__/__snapshots__/demo.test.tsx.snap
index 61e98c3002..b47819fba1 100644
--- a/components/tour/__tests__/__snapshots__/demo.test.tsx.snap
+++ b/components/tour/__tests__/__snapshots__/demo.test.tsx.snap
@@ -25,7 +25,84 @@ Array [
type="button"
>
- Upload
+ Upload
+
+
+
+
+
+
+
+ ,
+]
+`;
+
+exports[`renders components/tour/demo/actions-render.tsx correctly 1`] = `
+Array [
+ ,
+ ,
+
+
+
@@ -385,7 +462,7 @@ Array [
type="button"
>
- Upload
+ Upload
@@ -462,7 +539,7 @@ Array [
type="button"
>
- Upload
+ Upload
diff --git a/components/tour/demo/actions-render.md b/components/tour/demo/actions-render.md
new file mode 100644
index 0000000000..b90719b3d1
--- /dev/null
+++ b/components/tour/demo/actions-render.md
@@ -0,0 +1,7 @@
+## zh-CN
+
+自定义操作按钮。
+
+## en-US
+
+Custom action.
diff --git a/components/tour/demo/actions-render.tsx b/components/tour/demo/actions-render.tsx
new file mode 100644
index 0000000000..755602998c
--- /dev/null
+++ b/components/tour/demo/actions-render.tsx
@@ -0,0 +1,68 @@
+import React, { useRef, useState } from 'react';
+import { EllipsisOutlined } from '@ant-design/icons';
+import type { GetRef, TourProps } from 'antd';
+import { Button, Divider, Space, Tour } from 'antd';
+
+const App: React.FC = () => {
+ const ref1 = useRef>(null);
+ const ref2 = useRef>(null);
+ const ref3 = useRef>(null);
+
+ const [open, setOpen] = useState(false);
+
+ const steps: TourProps['steps'] = [
+ {
+ title: 'Upload File',
+ description: 'Put your files here.',
+ target: () => ref1.current!,
+ },
+ {
+ title: 'Save',
+ description: 'Save your changes.',
+ target: () => ref2.current!,
+ },
+ {
+ title: 'Other Actions',
+ description: 'Click to see other actions.',
+ target: () => ref3.current!,
+ },
+ ];
+
+ return (
+ <>
+
+
+
+
+
+ } />
+
+ setOpen(false)}
+ steps={steps}
+ actionsRender={(originNode, { current, total }) => (
+ <>
+ {current !== total - 1 && (
+
+ )}
+ {originNode}
+ >
+ )}
+ />
+ >
+ );
+};
+
+export default App;
diff --git a/components/tour/demo/basic.tsx b/components/tour/demo/basic.tsx
index 340130c6a0..16d7c8d1f8 100644
--- a/components/tour/demo/basic.tsx
+++ b/components/tour/demo/basic.tsx
@@ -40,7 +40,7 @@ const App: React.FC = () => {
-
+
diff --git a/components/tour/demo/mask.tsx b/components/tour/demo/mask.tsx
index de08788c3d..d6906756e1 100644
--- a/components/tour/demo/mask.tsx
+++ b/components/tour/demo/mask.tsx
@@ -50,7 +50,7 @@ const App: React.FC = () => {
-
+
diff --git a/components/tour/demo/non-modal.tsx b/components/tour/demo/non-modal.tsx
index 29ab480f2d..331fa0d796 100644
--- a/components/tour/demo/non-modal.tsx
+++ b/components/tour/demo/non-modal.tsx
@@ -43,7 +43,7 @@ const App: React.FC = () => {
-
+
diff --git a/components/tour/index.en-US.md b/components/tour/index.en-US.md
index 763fd58f1e..4112881767 100644
--- a/components/tour/index.en-US.md
+++ b/components/tour/index.en-US.md
@@ -22,6 +22,7 @@ Use when you want to guide users through a product.
Placement
Custom mask style
Custom indicator
+Custom action
Custom highlighted area style
\_InternalPanelDoNotUseOrYouWillBeFired
@@ -46,6 +47,7 @@ Common props ref:[Common props](/docs/react/common-props)
| current | What is the current step | `number` | - | |
| scrollIntoViewOptions | support pass custom scrollIntoView options | `boolean \| ScrollIntoViewOptions` | `true` | 5.2.0 |
| indicatorsRender | custom indicator | `(current: number, total: number) => ReactNode` | - | 5.2.0 |
+| actionsRender | custom action | `(originNode: ReactNode, info: { current: number, total: number }) => ReactNode` | - | 5.25.0 |
| zIndex | Tour's zIndex | number | 1001 | 5.3.0 |
| getPopupContainer | Set the rendering node of Tour floating layer | `(node: HTMLElement) => HTMLElement` | body | 5.12.0 |
diff --git a/components/tour/index.tsx b/components/tour/index.tsx
index 8b16000f47..c56fbf1fe2 100644
--- a/components/tour/index.tsx
+++ b/components/tour/index.tsx
@@ -22,6 +22,7 @@ const Tour: React.FC & { _InternalPanelDoNotUseOrYouWillBeFired: type
type,
rootClassName,
indicatorsRender,
+ actionsRender,
steps,
closeIcon,
...restProps
@@ -66,6 +67,7 @@ const Tour: React.FC & { _InternalPanelDoNotUseOrYouWillBeFired: type
stepProps={stepProps}
current={stepCurrent}
indicatorsRender={indicatorsRender}
+ actionsRender={actionsRender}
/>
);
diff --git a/components/tour/index.zh-CN.md b/components/tour/index.zh-CN.md
index 8c0d3c91af..e2d5b5d78d 100644
--- a/components/tour/index.zh-CN.md
+++ b/components/tour/index.zh-CN.md
@@ -23,6 +23,7 @@ tag: 5.0.0
位置
自定义遮罩样式
自定义指示器
+自定义操作按钮
自定义高亮区域的样式
\_InternalPanelDoNotUseOrYouWillBeFired
@@ -48,6 +49,7 @@ tag: 5.0.0
| current | 当前处于哪一步 | `number` | - | |
| scrollIntoViewOptions | 是否支持当前元素滚动到视窗内,也可传入配置指定滚动视窗的相关参数 | `boolean \| ScrollIntoViewOptions` | `true` | 5.2.0 |
| indicatorsRender | 自定义指示器 | `(current: number, total: number) => ReactNode` | - | 5.2.0 |
+| actionsRender | 自定义操作按钮 | `(originNode: ReactNode, info: { current: number, total: number }) => ReactNode` | - | 5.25.0 |
| zIndex | Tour 的层级 | number | 1001 | 5.3.0 |
| getPopupContainer | 设置 Tour 浮层的渲染节点,默认是 body | `(node: HTMLElement) => HTMLElement` | body | 5.12.0 |
diff --git a/components/tour/interface.ts b/components/tour/interface.ts
index 83a1d0b14c..5155ad5d4f 100644
--- a/components/tour/interface.ts
+++ b/components/tour/interface.ts
@@ -9,6 +9,7 @@ export interface TourProps extends Omit {
prefixCls?: string;
current?: number;
indicatorsRender?: (current: number, total: number) => ReactNode;
+ actionsRender?: TourStepProps['actionsRender'];
type?: 'default' | 'primary'; // default type, affects the background color and text color
}
@@ -27,6 +28,7 @@ export interface TourStepProps extends RCTourStepProps {
style?: React.CSSProperties;
};
indicatorsRender?: (current: number, total: number) => ReactNode;
+ actionsRender?: (originNode: ReactNode, info: { current: number; total: number }) => ReactNode;
type?: 'default' | 'primary'; // default type, affects the background color and text color
}
diff --git a/components/tour/panelRender.tsx b/components/tour/panelRender.tsx
index 20fb9bd568..d39df1da73 100644
--- a/components/tour/panelRender.tsx
+++ b/components/tour/panelRender.tsx
@@ -21,12 +21,13 @@ interface TourPanelProps {
current: number;
type: TourStepProps['type'];
indicatorsRender?: TourStepProps['indicatorsRender'];
+ actionsRender?: TourStepProps['actionsRender'];
}
// Due to the independent design of Panel, it will be too coupled to put in rc-tour,
// so a set of Panel logic is implemented separately in antd.
const TourPanel: React.FC = (props) => {
- const { stepProps, current, type, indicatorsRender } = props;
+ const { stepProps, current, type, indicatorsRender, actionsRender } = props;
const {
prefixCls,
total = 1,
@@ -115,6 +116,32 @@ const TourPanel: React.FC = (props) => {
ghost: mergedType === 'primary',
};
+ const defaultActionsNode = (
+ <>
+ {current !== 0 ? (
+
+ ) : null}
+
+ >
+ );
+
return (
@@ -125,27 +152,9 @@ const TourPanel: React.FC
= (props) => {
{total > 1 &&
{mergedIndicatorNode}
}
- {current !== 0 ? (
-
- ) : null}
-
+ {actionsRender
+ ? actionsRender(defaultActionsNode, { current, total })
+ : defaultActionsNode}