From 6a2f1c2362211e3572485c11dc67ba806bc5af59 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Thu, 25 Jan 2024 22:56:52 +0800
Subject: [PATCH 01/10] docs: updating the `dropdownRender` description and
 jumps in the FAQ for Select

---
 components/select/index.en-US.md | 2 +-
 components/select/index.zh-CN.md | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md
index b2e25873ec..136217e541 100644
--- a/components/select/index.en-US.md
+++ b/components/select/index.en-US.md
@@ -117,7 +117,7 @@ Select component to select value from options.
 
 ### The dropdown is closed when click `dropdownRender` area?
 
-Dropdown menu will be closed if click `dropdownRender` area, you can prevent it by wrapping `@mousedown.prevent` See the [dropdownRender example](/components/select/#components-select-demo-custom-dropdown).
+Dropdown menu will be closed if click `dropdownRender` area, you can prevent the default behavior of a click event, See the [dropdownRender example](#components-select-demo-custom-dropdown-menu).
 
 ### Why is `placeholder` not displayed?
 
diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md
index d4d49a3806..4de3bf8ae4 100644
--- a/components/select/index.zh-CN.md
+++ b/components/select/index.zh-CN.md
@@ -117,7 +117,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*5oPiTqPxGAUAAA
 
 ### 点击 `dropdownRender` 里的内容浮层关闭怎么办?
 
-自定义内容点击时会关闭浮层,如果不喜欢关闭,可以添加 `@mousedown.prevent` 进行阻止。 看下 [dropdownRender 例子](/components/select-cn/#components-select-demo-custom-dropdown) 里的说明。
+自定义内容点击时会关闭浮层,如果不喜欢关闭,可以通过取消点击事件的默认行为进行阻止。 看下 [dropdownRender 例子](#components-select-demo-custom-dropdown-menu) 里的说明。
 
 ### 为什么 `placeholder` 不显示 ?
 

From 36759431f032e37be11c4a6aa6c35b80ef43a699 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Tue, 26 Mar 2024 13:31:37 +0800
Subject: [PATCH 02/10] wip: add popover-arrow

---
 components/popover/index.tsx               |  8 +++++++-
 components/style/placementArrow.ts         | 16 ++++++++++++----
 components/tooltip/abstractTooltipProps.ts |  5 +++++
 components/vc-tooltip/src/Tooltip.tsx      | 17 +++++++++++++----
 components/vc-trigger/Popup/PopupInner.tsx | 16 +++++++++++++++-
 components/vc-trigger/Popup/context.ts     |  1 +
 6 files changed, 53 insertions(+), 10 deletions(-)
 create mode 100644 components/vc-trigger/Popup/context.ts

diff --git a/components/popover/index.tsx b/components/popover/index.tsx
index a391f152cf..5de2dec657 100644
--- a/components/popover/index.tsx
+++ b/components/popover/index.tsx
@@ -1,5 +1,5 @@
 import type { ExtractPropTypes } from 'vue';
-import { computed, defineComponent, ref } from 'vue';
+import { computed, defineComponent, provide, ref, toRef } from 'vue';
 import Tooltip from '../tooltip';
 import abstractTooltipProps from '../tooltip/abstractTooltipProps';
 import { filterEmpty, initDefaultProps } from '../_util/props-util';
@@ -11,6 +11,7 @@ import { tooltipDefaultProps } from '../tooltip/Tooltip';
 import useStyle from './style';
 import classNames from '../_util/classNames';
 import warning from '../_util/warning';
+import { popupContextKey } from '../vc-trigger/Popup/context';
 
 export const popoverProps = () => ({
   ...abstractTooltipProps(),
@@ -59,6 +60,11 @@ const Popover = defineComponent({
         </>
       );
     };
+
+    provide(popupContextKey, {
+      arrow: toRef(props, 'arrow'),
+    });
+
     return () => {
       const overlayCls = classNames(props.overlayClassName, hashId.value);
       return wrapSSR(
diff --git a/components/style/placementArrow.ts b/components/style/placementArrow.ts
index 5af5bbe78c..152b329f51 100644
--- a/components/style/placementArrow.ts
+++ b/components/style/placementArrow.ts
@@ -209,7 +209,9 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
       // Offset the popover to account for the dropdown arrow
       // >>>>> Top
       [connectArrowCls(
-        [`&-placement-topLeft`, `&-placement-top`, `&-placement-topRight`],
+        [`&-placement-topLeft`, `&-placement-top`, `&-placement-topRight`].map(
+          cls => (cls += ':not(&-arrow-hidden)'),
+        ),
         showArrowCls,
       )]: {
         paddingBottom: dropdownArrowDistance,
@@ -217,7 +219,9 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
 
       // >>>>> Bottom
       [connectArrowCls(
-        [`&-placement-bottomLeft`, `&-placement-bottom`, `&-placement-bottomRight`],
+        [`&-placement-bottomLeft`, `&-placement-bottom`, `&-placement-bottomRight`].map(
+          cls => (cls += ':not(&-arrow-hidden)'),
+        ),
         showArrowCls,
       )]: {
         paddingTop: dropdownArrowDistance,
@@ -225,7 +229,9 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
 
       // >>>>> Left
       [connectArrowCls(
-        [`&-placement-leftTop`, `&-placement-left`, `&-placement-leftBottom`],
+        [`&-placement-leftTop`, `&-placement-left`, `&-placement-leftBottom`].map(
+          cls => (cls += ':not(&-arrow-hidden)'),
+        ),
         showArrowCls,
       )]: {
         paddingRight: {
@@ -236,7 +242,9 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
 
       // >>>>> Right
       [connectArrowCls(
-        [`&-placement-rightTop`, `&-placement-right`, `&-placement-rightBottom`],
+        [`&-placement-rightTop`, `&-placement-right`, `&-placement-rightBottom`].map(
+          cls => (cls += ':not(&-arrow-hidden)'),
+        ),
         showArrowCls,
       )]: {
         paddingLeft: {
diff --git a/components/tooltip/abstractTooltipProps.ts b/components/tooltip/abstractTooltipProps.ts
index 489829de4a..3d90cb1eb5 100644
--- a/components/tooltip/abstractTooltipProps.ts
+++ b/components/tooltip/abstractTooltipProps.ts
@@ -35,7 +35,12 @@ export default () => ({
   mouseEnterDelay: Number,
   mouseLeaveDelay: Number,
   getPopupContainer: Function as PropType<(triggerNode: HTMLElement) => HTMLElement>,
+  /**@deprecated Please use `arrow={{ pointAtCenter: true }}` instead. */
   arrowPointAtCenter: { type: Boolean, default: undefined },
+  arrow: {
+    type: [Boolean, Object] as PropType<boolean | { pointAtCenter?: boolean }>,
+    default: true,
+  },
   autoAdjustOverflow: {
     type: [Boolean, Object] as PropType<boolean | AdjustOverflow>,
     default: undefined as boolean | AdjustOverflow,
diff --git a/components/vc-tooltip/src/Tooltip.tsx b/components/vc-tooltip/src/Tooltip.tsx
index fa4110e91f..bf7eeb49c9 100644
--- a/components/vc-tooltip/src/Tooltip.tsx
+++ b/components/vc-tooltip/src/Tooltip.tsx
@@ -4,7 +4,9 @@ import { placements } from './placements';
 import Content from './Content';
 import { getPropsSlot } from '../../_util/props-util';
 import type { CSSProperties, PropType } from 'vue';
-import { defineComponent, shallowRef, watchEffect } from 'vue';
+import { defineComponent, inject, shallowRef, unref, watchEffect } from 'vue';
+import { popupContextKey } from '../../vc-trigger/Popup/context';
+
 function noop() {}
 export default defineComponent({
   compatConfig: { MODE: 3 },
@@ -42,10 +44,17 @@ export default defineComponent({
 
     const getPopupElement = () => {
       const { prefixCls, tipId, overlayInnerStyle } = props;
+
+      const injectData = inject(popupContextKey, {
+        arrow: true,
+      });
+      const arrow = unref(injectData.arrow);
       return [
-        <div class={`${prefixCls}-arrow`} key="arrow">
-          {getPropsSlot(slots, props, 'arrowContent')}
-        </div>,
+        arrow ? (
+          <div class={`${prefixCls}-arrow`} key="arrow">
+            {getPropsSlot(slots, props, 'arrowContent')}
+          </div>
+        ) : null,
         <Content
           key="content"
           prefixCls={prefixCls}
diff --git a/components/vc-trigger/Popup/PopupInner.tsx b/components/vc-trigger/Popup/PopupInner.tsx
index 5699785f80..54678ea105 100644
--- a/components/vc-trigger/Popup/PopupInner.tsx
+++ b/components/vc-trigger/Popup/PopupInner.tsx
@@ -5,9 +5,11 @@ import type { CSSProperties } from 'vue';
 import {
   computed,
   defineComponent,
+  inject,
   shallowRef,
   toRef,
   Transition,
+  unref,
   watch,
   withModifiers,
 } from 'vue';
@@ -20,6 +22,7 @@ import type { PopupInnerProps } from './interface';
 import { innerProps } from './interface';
 import { getTransitionProps } from '../../_util/transition';
 import supportsPassive from '../../_util/supportsPassive';
+import { popupContextKey } from './context';
 
 export default defineComponent({
   compatConfig: { MODE: 3 },
@@ -171,7 +174,18 @@ export default defineComponent({
       if (childNode.length > 1) {
         childNode = <div class={`${prefixCls}-content`}>{childNode}</div>;
       }
-      const mergedClassName = classNames(prefixCls, attrs.class, alignedClassName.value);
+
+      const injectData = inject(popupContextKey, {
+        arrow: true,
+      });
+
+      const arrow = unref(injectData.arrow);
+      const mergedClassName = classNames(
+        prefixCls,
+        attrs.class,
+        alignedClassName.value,
+        !arrow && `${prefixCls}-arrow-hidden`,
+      );
       const hasAnimate = visible.value || !props.visible;
       const transitionProps = hasAnimate ? getTransitionProps(motion.value.name, motion.value) : {};
 
diff --git a/components/vc-trigger/Popup/context.ts b/components/vc-trigger/Popup/context.ts
new file mode 100644
index 0000000000..15e36857ba
--- /dev/null
+++ b/components/vc-trigger/Popup/context.ts
@@ -0,0 +1 @@
+export const popupContextKey = Symbol('PopupContextKey');

From baf9ccbbb737ac2f4028e4d5e6031f64d9a72bff Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 17:43:38 +0530
Subject: [PATCH 03/10] wip: trigger add arrow attr

---
 components/tooltip/demo/arrow.vue          | 122 +++++++++++++++++++++
 components/tooltip/demo/index.vue          |   3 +
 components/tooltip/index.zh-CN.md          |   1 +
 components/vc-tooltip/src/Tooltip.tsx      |  14 +--
 components/vc-trigger/Popup/PopupInner.tsx |  10 +-
 components/vc-trigger/Popup/interface.ts   |   2 +
 components/vc-trigger/Trigger.tsx          |   2 +
 components/vc-trigger/interface.ts         |   1 +
 8 files changed, 139 insertions(+), 16 deletions(-)
 create mode 100644 components/tooltip/demo/arrow.vue

diff --git a/components/tooltip/demo/arrow.vue b/components/tooltip/demo/arrow.vue
new file mode 100644
index 0000000000..a580602756
--- /dev/null
+++ b/components/tooltip/demo/arrow.vue
@@ -0,0 +1,122 @@
+<docs>
+---
+order: 6
+title:
+  zh-CN: 箭头展示
+  en-US: Arrow show
+---
+
+## zh-CN
+支持显示、隐藏以及将箭头保持居中定位。
+
+## en-US
+
+Support show, hide or keep arrow in the center.
+</docs>
+
+<template>
+  <div id="components-a-tooltip-demo-placement">
+    <div>
+      <a-radio-group v-model:value="mergeArrow" button-style="solid">
+        <a-radio :value="true">show</a-radio>
+        <a-radio :value="false">hidden</a-radio>
+        <a-radio :value="{ pointAtCenter: 'center' }">center</a-radio>
+      </a-radio-group>
+    </div>
+    <div :style="{ marginLeft: `${buttonWidth}px`, whiteSpace: 'nowrap' }">
+      <a-tooltip placement="topLeft" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>TL</a-button>
+      </a-tooltip>
+      <a-tooltip placement="top" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>Top</a-button>
+      </a-tooltip>
+      <a-tooltip placement="topRight" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>TR</a-button>
+      </a-tooltip>
+    </div>
+    <div :style="{ width: `${buttonWidth}px`, float: 'left' }">
+      <a-tooltip placement="leftTop" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>LT</a-button>
+      </a-tooltip>
+      <a-tooltip placement="left" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>Left</a-button>
+      </a-tooltip>
+      <a-tooltip placement="leftBottom" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>LB</a-button>
+      </a-tooltip>
+    </div>
+    <div :style="{ width: `${buttonWidth}px`, marginLeft: `${buttonWidth * 4 + 24}px` }">
+      <a-tooltip placement="rightTop" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>RT</a-button>
+      </a-tooltip>
+      <a-tooltip placement="right" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>Right</a-button>
+      </a-tooltip>
+      <a-tooltip placement="rightBottom" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>RB</a-button>
+      </a-tooltip>
+    </div>
+    <div :style="{ marginLeft: `${buttonWidth}px`, clear: 'both', whiteSpace: 'nowrap' }">
+      <a-tooltip placement="bottomLeft" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>BL</a-button>
+      </a-tooltip>
+      <a-tooltip placement="bottom" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>Bottom</a-button>
+      </a-tooltip>
+      <a-tooltip placement="bottomRight" :arrow="mergeArrow">
+        <template #title>
+          <span>prompt text</span>
+        </template>
+        <a-button>BR</a-button>
+      </a-tooltip>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref } from 'vue';
+const buttonWidth = 70;
+
+const mergeArrow = ref(true);
+</script>
+<style scoped>
+:deep(#components-a-tooltip-demo-placement) .ant-btn {
+  width: 70px;
+  text-align: center;
+  padding: 0;
+  margin-right: 8px;
+  margin-bottom: 8px;
+}
+</style>
diff --git a/components/tooltip/demo/index.vue b/components/tooltip/demo/index.vue
index 60fb98dd32..ac227a9bee 100644
--- a/components/tooltip/demo/index.vue
+++ b/components/tooltip/demo/index.vue
@@ -5,6 +5,7 @@
     <arrow-point-at-center />
     <auto-adjust-overflow />
     <color />
+    <Arrow />
   </demo-sort>
 </template>
 <script lang="ts">
@@ -13,6 +14,7 @@ import Placement from './placement.vue';
 import arrowPointAtCenter from './arrow-point-at-center.vue';
 import AutoAdjustOverflow from './auto-adjust-overflow.vue';
 import Color from './color.vue';
+import Arrow from './arrow.vue';
 import CN from '../index.zh-CN.md';
 import US from '../index.en-US.md';
 import { defineComponent } from 'vue';
@@ -25,6 +27,7 @@ export default defineComponent({
     arrowPointAtCenter,
     AutoAdjustOverflow,
     Color,
+    Arrow,
   },
   setup() {
     return {};
diff --git a/components/tooltip/index.zh-CN.md b/components/tooltip/index.zh-CN.md
index d76be5bbad..1818496f63 100644
--- a/components/tooltip/index.zh-CN.md
+++ b/components/tooltip/index.zh-CN.md
@@ -28,6 +28,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*gwrhTozoTC4AAA
 | --- | --- | --- | --- | --- |
 | align | 该值将合并到 placement 的配置中,设置参考 [dom-align](https://github.com/yiminghe/dom-align) | Object | 无 |  |
 | arrowPointAtCenter | 箭头是否指向目标元素中心 | boolean | `false` |  |
+| arrow | 修改箭头的显示状态以及修改箭头是否指向目标元素中心 | boolean \| { pointAtCenter: boolean} | `true` |  |
 | autoAdjustOverflow | 气泡被遮挡时自动调整位置 | boolean | `true` |  |
 | color | 背景颜色 | string | 无 |  |
 | destroyTooltipOnHide | 隐藏后是否销毁 tooltip | boolean | false |  |
diff --git a/components/vc-tooltip/src/Tooltip.tsx b/components/vc-tooltip/src/Tooltip.tsx
index bf7eeb49c9..1b61931d55 100644
--- a/components/vc-tooltip/src/Tooltip.tsx
+++ b/components/vc-tooltip/src/Tooltip.tsx
@@ -4,8 +4,7 @@ import { placements } from './placements';
 import Content from './Content';
 import { getPropsSlot } from '../../_util/props-util';
 import type { CSSProperties, PropType } from 'vue';
-import { defineComponent, inject, shallowRef, unref, watchEffect } from 'vue';
-import { popupContextKey } from '../../vc-trigger/Popup/context';
+import { defineComponent, shallowRef, watchEffect } from 'vue';
 
 function noop() {}
 export default defineComponent({
@@ -38,6 +37,9 @@ export default defineComponent({
     popupVisible: { type: Boolean, default: undefined },
     onVisibleChange: Function,
     onPopupAlign: Function,
+    arrow: {
+      type: [Boolean, Object] as PropType<boolean | { pointAtCenter: boolean }>,
+    },
   },
   setup(props, { slots, attrs, expose }) {
     const triggerDOM = shallowRef();
@@ -45,12 +47,9 @@ export default defineComponent({
     const getPopupElement = () => {
       const { prefixCls, tipId, overlayInnerStyle } = props;
 
-      const injectData = inject(popupContextKey, {
-        arrow: true,
-      });
-      const arrow = unref(injectData.arrow);
+      const showArrow = !!props.arrow;
       return [
-        arrow ? (
+        showArrow ? (
           <div class={`${prefixCls}-arrow`} key="arrow">
             {getPropsSlot(slots, props, 'arrowContent')}
           </div>
@@ -131,6 +130,7 @@ export default defineComponent({
         onPopupVisibleChange: props.onVisibleChange || (noop as any),
         onPopupAlign: props.onPopupAlign || noop,
         ref: triggerDOM,
+        arrow: !!props.arrow,
         popup: getPopupElement(),
       };
       return <Trigger {...triggerProps} v-slots={{ default: slots.default }}></Trigger>;
diff --git a/components/vc-trigger/Popup/PopupInner.tsx b/components/vc-trigger/Popup/PopupInner.tsx
index 54678ea105..df9b4c26a3 100644
--- a/components/vc-trigger/Popup/PopupInner.tsx
+++ b/components/vc-trigger/Popup/PopupInner.tsx
@@ -5,11 +5,9 @@ import type { CSSProperties } from 'vue';
 import {
   computed,
   defineComponent,
-  inject,
   shallowRef,
   toRef,
   Transition,
-  unref,
   watch,
   withModifiers,
 } from 'vue';
@@ -22,7 +20,6 @@ import type { PopupInnerProps } from './interface';
 import { innerProps } from './interface';
 import { getTransitionProps } from '../../_util/transition';
 import supportsPassive from '../../_util/supportsPassive';
-import { popupContextKey } from './context';
 
 export default defineComponent({
   compatConfig: { MODE: 3 },
@@ -175,16 +172,11 @@ export default defineComponent({
         childNode = <div class={`${prefixCls}-content`}>{childNode}</div>;
       }
 
-      const injectData = inject(popupContextKey, {
-        arrow: true,
-      });
-
-      const arrow = unref(injectData.arrow);
       const mergedClassName = classNames(
         prefixCls,
         attrs.class,
         alignedClassName.value,
-        !arrow && `${prefixCls}-arrow-hidden`,
+        !props.arrow && `${prefixCls}-arrow-hidden`,
       );
       const hasAnimate = visible.value || !props.visible;
       const transitionProps = hasAnimate ? getTransitionProps(motion.value.name, motion.value) : {};
diff --git a/components/vc-trigger/Popup/interface.ts b/components/vc-trigger/Popup/interface.ts
index 9c5a8cf040..3526a10ec5 100644
--- a/components/vc-trigger/Popup/interface.ts
+++ b/components/vc-trigger/Popup/interface.ts
@@ -10,6 +10,8 @@ export const innerProps = {
   destroyPopupOnHide: Boolean,
   forceRender: Boolean,
 
+  arrow: { type: Boolean, default: true },
+
   // Legacy Motion
   animation: [String, Object],
   transitionName: String,
diff --git a/components/vc-trigger/Trigger.tsx b/components/vc-trigger/Trigger.tsx
index 3a65609bf9..57cf605ff1 100644
--- a/components/vc-trigger/Trigger.tsx
+++ b/components/vc-trigger/Trigger.tsx
@@ -414,11 +414,13 @@ export default defineComponent({
         stretch,
         alignPoint,
         mobile,
+        arrow,
         forceRender,
       } = this.$props;
       const { sPopupVisible, point } = this.$data;
       const popupProps = {
         prefixCls,
+        arrow,
         destroyPopupOnHide,
         visible: sPopupVisible,
         point: alignPoint ? point : null,
diff --git a/components/vc-trigger/interface.ts b/components/vc-trigger/interface.ts
index 8ffec35c92..7df564b581 100644
--- a/components/vc-trigger/interface.ts
+++ b/components/vc-trigger/interface.ts
@@ -111,6 +111,7 @@ export const triggerProps = () => ({
   onPopupVisibleChange: Function as PropType<(open: boolean) => void>,
   afterPopupVisibleChange: PropTypes.func.def(noop),
   popup: PropTypes.any,
+  arrow: PropTypes.bool.def(true),
   popupStyle: { type: Object as PropType<CSSProperties>, default: undefined as CSSProperties },
   prefixCls: PropTypes.string.def('rc-trigger-popup'),
   popupClassName: PropTypes.string.def(''),

From dab253a0782cee9ea376e79b2686474f75c9535c Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 17:46:33 +0530
Subject: [PATCH 04/10] fix: remove popupContextKey

---
 components/popover/index.tsx           | 7 +------
 components/vc-trigger/Popup/context.ts | 1 -
 2 files changed, 1 insertion(+), 7 deletions(-)
 delete mode 100644 components/vc-trigger/Popup/context.ts

diff --git a/components/popover/index.tsx b/components/popover/index.tsx
index 5de2dec657..2d21b2ff35 100644
--- a/components/popover/index.tsx
+++ b/components/popover/index.tsx
@@ -1,5 +1,5 @@
 import type { ExtractPropTypes } from 'vue';
-import { computed, defineComponent, provide, ref, toRef } from 'vue';
+import { computed, defineComponent, ref } from 'vue';
 import Tooltip from '../tooltip';
 import abstractTooltipProps from '../tooltip/abstractTooltipProps';
 import { filterEmpty, initDefaultProps } from '../_util/props-util';
@@ -11,7 +11,6 @@ import { tooltipDefaultProps } from '../tooltip/Tooltip';
 import useStyle from './style';
 import classNames from '../_util/classNames';
 import warning from '../_util/warning';
-import { popupContextKey } from '../vc-trigger/Popup/context';
 
 export const popoverProps = () => ({
   ...abstractTooltipProps(),
@@ -61,10 +60,6 @@ const Popover = defineComponent({
       );
     };
 
-    provide(popupContextKey, {
-      arrow: toRef(props, 'arrow'),
-    });
-
     return () => {
       const overlayCls = classNames(props.overlayClassName, hashId.value);
       return wrapSSR(
diff --git a/components/vc-trigger/Popup/context.ts b/components/vc-trigger/Popup/context.ts
deleted file mode 100644
index 15e36857ba..0000000000
--- a/components/vc-trigger/Popup/context.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const popupContextKey = Symbol('PopupContextKey');

From fb02e680d961935e81b1f3acc01bb713ecaf7ca0 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 17:50:33 +0530
Subject: [PATCH 05/10] optimize

---
 components/popover/index.tsx          | 1 -
 components/vc-tooltip/src/Tooltip.tsx | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/components/popover/index.tsx b/components/popover/index.tsx
index 2d21b2ff35..a391f152cf 100644
--- a/components/popover/index.tsx
+++ b/components/popover/index.tsx
@@ -59,7 +59,6 @@ const Popover = defineComponent({
         </>
       );
     };
-
     return () => {
       const overlayCls = classNames(props.overlayClassName, hashId.value);
       return wrapSSR(
diff --git a/components/vc-tooltip/src/Tooltip.tsx b/components/vc-tooltip/src/Tooltip.tsx
index 1b61931d55..4ecd629170 100644
--- a/components/vc-tooltip/src/Tooltip.tsx
+++ b/components/vc-tooltip/src/Tooltip.tsx
@@ -47,9 +47,8 @@ export default defineComponent({
     const getPopupElement = () => {
       const { prefixCls, tipId, overlayInnerStyle } = props;
 
-      const showArrow = !!props.arrow;
       return [
-        showArrow ? (
+        !!props.arrow ? (
           <div class={`${prefixCls}-arrow`} key="arrow">
             {getPropsSlot(slots, props, 'arrowContent')}
           </div>

From 97a2ffd872c898badc65cfcdcec81639e2bb4c75 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 18:20:17 +0530
Subject: [PATCH 06/10] perf: optimize

---
 components/tooltip/Tooltip.tsx             |  9 ++++-
 components/tooltip/abstractTooltipProps.ts |  2 +-
 components/tooltip/demo/arrow.vue          | 45 +++++++++++++---------
 components/vc-tooltip/src/Tooltip.tsx      |  4 +-
 4 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/components/tooltip/Tooltip.tsx b/components/tooltip/Tooltip.tsx
index 0a9902afb2..339a44ef50 100644
--- a/components/tooltip/Tooltip.tsx
+++ b/components/tooltip/Tooltip.tsx
@@ -145,11 +145,16 @@ export default defineComponent({
     });
 
     const tooltipPlacements = computed(() => {
-      const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = props;
+      const { builtinPlacements, autoAdjustOverflow, arrow, arrowPointAtCenter } = props;
+      let mergedArrowPointAtCenter = arrowPointAtCenter;
+
+      if (typeof arrow === 'object') {
+        mergedArrowPointAtCenter = arrow.pointAtCenter ?? arrowPointAtCenter;
+      }
       return (
         builtinPlacements ||
         getPlacements({
-          arrowPointAtCenter,
+          arrowPointAtCenter: mergedArrowPointAtCenter,
           autoAdjustOverflow,
         })
       );
diff --git a/components/tooltip/abstractTooltipProps.ts b/components/tooltip/abstractTooltipProps.ts
index 3d90cb1eb5..a3f142db14 100644
--- a/components/tooltip/abstractTooltipProps.ts
+++ b/components/tooltip/abstractTooltipProps.ts
@@ -39,7 +39,7 @@ export default () => ({
   arrowPointAtCenter: { type: Boolean, default: undefined },
   arrow: {
     type: [Boolean, Object] as PropType<boolean | { pointAtCenter?: boolean }>,
-    default: true,
+    default: true as boolean | { pointAtCenter?: boolean },
   },
   autoAdjustOverflow: {
     type: [Boolean, Object] as PropType<boolean | AdjustOverflow>,
diff --git a/components/tooltip/demo/arrow.vue b/components/tooltip/demo/arrow.vue
index a580602756..6137e52b50 100644
--- a/components/tooltip/demo/arrow.vue
+++ b/components/tooltip/demo/arrow.vue
@@ -16,27 +16,27 @@ Support show, hide or keep arrow in the center.
 
 <template>
   <div id="components-a-tooltip-demo-placement">
-    <div>
-      <a-radio-group v-model:value="mergeArrow" button-style="solid">
-        <a-radio :value="true">show</a-radio>
-        <a-radio :value="false">hidden</a-radio>
-        <a-radio :value="{ pointAtCenter: 'center' }">center</a-radio>
+    <div style="margin-bottom: 24px">
+      <a-radio-group v-model:value="arrow" button-style="solid">
+        <a-radio-button :value="true">show</a-radio-button>
+        <a-radio-button :value="false">hidden</a-radio-button>
+        <a-radio-button :value="'center'">center</a-radio-button>
       </a-radio-group>
     </div>
     <div :style="{ marginLeft: `${buttonWidth}px`, whiteSpace: 'nowrap' }">
-      <a-tooltip placement="topLeft" :arrow="mergeArrow">
+      <a-tooltip placement="topLeft" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>TL</a-button>
       </a-tooltip>
-      <a-tooltip placement="top" :arrow="mergeArrow">
+      <a-tooltip placement="top" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>Top</a-button>
       </a-tooltip>
-      <a-tooltip placement="topRight" :arrow="mergeArrow">
+      <a-tooltip placement="topRight" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
@@ -44,19 +44,19 @@ Support show, hide or keep arrow in the center.
       </a-tooltip>
     </div>
     <div :style="{ width: `${buttonWidth}px`, float: 'left' }">
-      <a-tooltip placement="leftTop" :arrow="mergeArrow">
+      <a-tooltip placement="leftTop" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>LT</a-button>
       </a-tooltip>
-      <a-tooltip placement="left" :arrow="mergeArrow">
+      <a-tooltip placement="left" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>Left</a-button>
       </a-tooltip>
-      <a-tooltip placement="leftBottom" :arrow="mergeArrow">
+      <a-tooltip placement="leftBottom" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
@@ -64,19 +64,19 @@ Support show, hide or keep arrow in the center.
       </a-tooltip>
     </div>
     <div :style="{ width: `${buttonWidth}px`, marginLeft: `${buttonWidth * 4 + 24}px` }">
-      <a-tooltip placement="rightTop" :arrow="mergeArrow">
+      <a-tooltip placement="rightTop" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>RT</a-button>
       </a-tooltip>
-      <a-tooltip placement="right" :arrow="mergeArrow">
+      <a-tooltip placement="right" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>Right</a-button>
       </a-tooltip>
-      <a-tooltip placement="rightBottom" :arrow="mergeArrow">
+      <a-tooltip placement="rightBottom" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
@@ -84,19 +84,19 @@ Support show, hide or keep arrow in the center.
       </a-tooltip>
     </div>
     <div :style="{ marginLeft: `${buttonWidth}px`, clear: 'both', whiteSpace: 'nowrap' }">
-      <a-tooltip placement="bottomLeft" :arrow="mergeArrow">
+      <a-tooltip placement="bottomLeft" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>BL</a-button>
       </a-tooltip>
-      <a-tooltip placement="bottom" :arrow="mergeArrow">
+      <a-tooltip placement="bottom" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
         <a-button>Bottom</a-button>
       </a-tooltip>
-      <a-tooltip placement="bottomRight" :arrow="mergeArrow">
+      <a-tooltip placement="bottomRight" :arrow="mergedArrow">
         <template #title>
           <span>prompt text</span>
         </template>
@@ -106,10 +106,17 @@ Support show, hide or keep arrow in the center.
   </div>
 </template>
 <script lang="ts" setup>
-import { ref } from 'vue';
+import { ref, computed } from 'vue';
 const buttonWidth = 70;
 
-const mergeArrow = ref(true);
+const arrow = ref<{ pointAtCenter: boolean } | boolean>(true);
+
+const mergedArrow = computed(() => {
+  if (typeof arrow.value === 'string') {
+    return { pointAtCenter: true };
+  }
+  return arrow.value;
+});
 </script>
 <style scoped>
 :deep(#components-a-tooltip-demo-placement) .ant-btn {
diff --git a/components/vc-tooltip/src/Tooltip.tsx b/components/vc-tooltip/src/Tooltip.tsx
index 4ecd629170..0689708996 100644
--- a/components/vc-tooltip/src/Tooltip.tsx
+++ b/components/vc-tooltip/src/Tooltip.tsx
@@ -37,9 +37,7 @@ export default defineComponent({
     popupVisible: { type: Boolean, default: undefined },
     onVisibleChange: Function,
     onPopupAlign: Function,
-    arrow: {
-      type: [Boolean, Object] as PropType<boolean | { pointAtCenter: boolean }>,
-    },
+    arrow: { type: Boolean, default: true },
   },
   setup(props, { slots, attrs, expose }) {
     const triggerDOM = shallowRef();

From 6f143ed10c0b5d3e8c67ac7d186f35a90dc87364 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 18:22:35 +0530
Subject: [PATCH 07/10] docs: optimize docs

---
 components/tooltip/demo/arrow.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/tooltip/demo/arrow.vue b/components/tooltip/demo/arrow.vue
index 6137e52b50..9918797d06 100644
--- a/components/tooltip/demo/arrow.vue
+++ b/components/tooltip/demo/arrow.vue
@@ -15,7 +15,7 @@ Support show, hide or keep arrow in the center.
 </docs>
 
 <template>
-  <div id="components-a-tooltip-demo-placement">
+  <div id="components-a-tooltip-demo-arrow">
     <div style="margin-bottom: 24px">
       <a-radio-group v-model:value="arrow" button-style="solid">
         <a-radio-button :value="true">show</a-radio-button>
@@ -119,7 +119,7 @@ const mergedArrow = computed(() => {
 });
 </script>
 <style scoped>
-:deep(#components-a-tooltip-demo-placement) .ant-btn {
+:deep(#components-a-tooltip-demo-arrow) .ant-btn {
   width: 70px;
   text-align: center;
   padding: 0;

From c5fb5614f3d4b942ff5a020b576d44c37e6d0e83 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 18:28:03 +0530
Subject: [PATCH 08/10] docs: add `arrow` attribute in tooltip en-US docs

---
 components/tooltip/index.en-US.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/components/tooltip/index.en-US.md b/components/tooltip/index.en-US.md
index 3eca8e8050..fd984377c6 100644
--- a/components/tooltip/index.en-US.md
+++ b/components/tooltip/index.en-US.md
@@ -27,6 +27,7 @@ The following APIs are shared by Tooltip, Popconfirm, Popover.
 | --- | --- | --- | --- | --- |
 | align | this value will be merged into placement's config, please refer to the settings [dom-align](https://github.com/yiminghe/dom-align) | Object | - |  |
 | arrowPointAtCenter | Whether the arrow is pointed at the center of target | boolean | `false` |  |
+| arrow | Change arrow's visible state and change whether the arrow is pointed at the center of target. | boolean \| { pointAtCenter: boolean} | `true` |  |
 | autoAdjustOverflow | Whether to adjust popup placement automatically when popup is off screen | boolean | `true` |  |
 | color | The background color | string | - |  |
 | destroyTooltipOnHide | Whether to destroy tooltip on hide | boolean | false |  |

From 1a1d8e85899879deeb40107bbecbf2acdd3b6da7 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Wed, 27 Mar 2024 18:54:31 +0530
Subject: [PATCH 09/10] fix: fix bug

---
 components/tooltip/Tooltip.tsx | 1 +
 components/vc-tour/Tour.tsx    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/components/tooltip/Tooltip.tsx b/components/tooltip/Tooltip.tsx
index 339a44ef50..65d6203e4b 100644
--- a/components/tooltip/Tooltip.tsx
+++ b/components/tooltip/Tooltip.tsx
@@ -288,6 +288,7 @@ export default defineComponent({
         ...attrs,
         ...(props as TooltipProps),
         prefixCls: prefixCls.value,
+        arrow: !!props.arrow,
         getPopupContainer: getPopupContainer?.value,
         builtinPlacements: tooltipPlacements.value,
         visible: tempVisible,
diff --git a/components/vc-tour/Tour.tsx b/components/vc-tour/Tour.tsx
index a5ca7851bf..0b6b604620 100644
--- a/components/vc-tour/Tour.tsx
+++ b/components/vc-tour/Tour.tsx
@@ -210,6 +210,7 @@ const Tour = defineComponent({
           />
           <Trigger
             {...restProps}
+            arrow={!!restProps.arrow}
             builtinPlacements={
               !curStep.value.target
                 ? undefined

From c1c4a5fffe71db81faf65f7fec4a83a543980181 Mon Sep 17 00:00:00 2001
From: carl-chen <ccheartszzz@gmail.com>
Date: Tue, 2 Apr 2024 12:18:05 +0800
Subject: [PATCH 10/10] perf[demo]: `radio-group` replace with `segmented`

---
 components/tooltip/demo/arrow.vue | 32 ++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/components/tooltip/demo/arrow.vue b/components/tooltip/demo/arrow.vue
index 9918797d06..3fe3f25d5f 100644
--- a/components/tooltip/demo/arrow.vue
+++ b/components/tooltip/demo/arrow.vue
@@ -17,11 +17,7 @@ Support show, hide or keep arrow in the center.
 <template>
   <div id="components-a-tooltip-demo-arrow">
     <div style="margin-bottom: 24px">
-      <a-radio-group v-model:value="arrow" button-style="solid">
-        <a-radio-button :value="true">show</a-radio-button>
-        <a-radio-button :value="false">hidden</a-radio-button>
-        <a-radio-button :value="'center'">center</a-radio-button>
-      </a-radio-group>
+      <a-segmented v-model:value="arrow" :options="options" />
     </div>
     <div :style="{ marginLeft: `${buttonWidth}px`, whiteSpace: 'nowrap' }">
       <a-tooltip placement="topLeft" :arrow="mergedArrow">
@@ -109,13 +105,31 @@ Support show, hide or keep arrow in the center.
 import { ref, computed } from 'vue';
 const buttonWidth = 70;
 
-const arrow = ref<{ pointAtCenter: boolean } | boolean>(true);
+const arrow = ref<string>('show');
 
+const options = [
+  {
+    label: 'Show',
+    value: 'show',
+  },
+  {
+    label: 'Hide',
+    value: 'hide',
+  },
+  {
+    label: 'Center',
+    value: 'center',
+  },
+];
 const mergedArrow = computed(() => {
-  if (typeof arrow.value === 'string') {
-    return { pointAtCenter: true };
+  switch (arrow.value) {
+    case 'show':
+      return true;
+    case 'hide':
+      return false;
+    case 'center':
+      return { pointAtCenter: true };
   }
-  return arrow.value;
 });
 </script>
 <style scoped>