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>