diff --git a/components/popper/__tests__/__snapshots__/index.test.tsx.snap b/components/popper/__tests__/__snapshots__/index.test.tsx.snap
index 9c1c1690..5c674087 100644
--- a/components/popper/__tests__/__snapshots__/index.test.tsx.snap
+++ b/components/popper/__tests__/__snapshots__/index.test.tsx.snap
@@ -12,7 +12,7 @@ exports[`Popper API test getTriggerElement is useful 1`] = `
tip="tips text"
>
text
@@ -23,7 +23,7 @@ exports[`Popper API test getTriggerElement is useful 1`] = `
test
text
diff --git a/components/popper/index.tsx b/components/popper/index.tsx
index b9ea8ebe..f37860ab 100644
--- a/components/popper/index.tsx
+++ b/components/popper/index.tsx
@@ -10,6 +10,7 @@ import React, {
MutableRefObject,
} from 'react'
import { createPopper, Instance, Modifier, OptionsGeneric, Placement, VirtualElement } from '@popperjs/core'
+import ResizeObserver from 'resize-observer-polyfill'
import { tuple } from '../_utils/type'
import classnames from 'classnames'
import debounce from 'lodash/debounce'
@@ -40,7 +41,18 @@ export const Triggers = tuple('hover', 'focus', 'click', 'contextMenu')
export type TriggerType = typeof Triggers[number]
-export type Reason = TriggerType | 'scroll' | 'clickOutside' | 'clickToClose' | 'parentHidden' | 'unknown'
+export type Reason =
+ | TriggerType
+ | 'scroll'
+ | 'clickOutside'
+ | 'clickToClose'
+ | 'parentHidden'
+ | 'unknown'
+ | 'selectPopperItem'
+ | 'pressEnter'
+ | 'escEnter'
+ | 'delEnter'
+ | 'otherEnter'
export type RenderFunction = () => React.ReactNode
@@ -329,13 +341,17 @@ export const Popper = forwardRef((props, ref) => {
triggerOpen(nextOpen, triggerType, delay)
}
- const onClick = () => {
- if (!visibleInner) {
- onTriggerInner(true, 'click')
- } else if (clickToClose) {
- onTriggerInner(false, 'clickToClose')
- }
- }
+ const onClick = debounce(
+ () => {
+ if (!visibleInner) {
+ onTriggerInner(true, 'click')
+ } else if (clickToClose) {
+ onTriggerInner(false, 'clickToClose')
+ }
+ },
+ 10,
+ { leading: true },
+ )
const onFocus = () => {
onTriggerInner(true, 'focus')
@@ -407,6 +423,14 @@ export const Popper = forwardRef((props, ref) => {
}
}
+ const registerSubPopup = () => {
+ setTimeout(() => {
+ if (popperRef?.current) {
+ parentContext?.registerSubPopup(id, popperRef?.current)
+ }
+ }, 10)
+ }
+
useEffect(() => {
onVisibleChangeRef.current = onVisibleChange
}, [onVisibleChange])
@@ -587,17 +611,42 @@ export const Popper = forwardRef((props, ref) => {
}))
popperInstance.current?.forceUpdate()
}
- setTimeout(() => {
- if (popperRef) {
- if (popperRef?.current) {
- parentContext?.registerSubPopup(id, popperRef?.current)
- }
- }
- }, 10)
+ registerSubPopup()
}
}
}, [visibleInner, placementInner, arrow])
+ useEffect(() => {
+ if (!popperRefDom.current) return
+
+ const lastSize = {
+ width: popperRefDom.current.offsetWidth,
+ height: popperRefDom.current.offsetHeight,
+ }
+
+ const dimensionToObserve =
+ placementInner.startsWith('top') || placementInner.startsWith('bottom') ? 'height' : 'width'
+
+ const resizeObserver = new ResizeObserver((entries) => {
+ entries.forEach((entry) => {
+ const { width, height } = entry.contentRect
+ if (dimensionToObserve === 'height' && height !== lastSize.height) {
+ lastSize.height = height
+ popperInstance.current?.update()
+ } else if (dimensionToObserve === 'width' && width !== lastSize.width) {
+ lastSize.width = width
+ popperInstance.current?.update()
+ }
+ })
+ })
+
+ resizeObserver.observe(popperRefDom.current)
+
+ return () => {
+ resizeObserver?.disconnect()
+ }
+ }, [exist, placementInner])
+
useEnhancedEffect(() => {
if (!exist) {
return undefined
@@ -613,11 +662,7 @@ export const Popper = forwardRef((props, ref) => {
popperRefDom.current as HTMLElement,
popperOptionsInner,
)
- setTimeout(() => {
- if (popperRef?.current) {
- parentContext?.registerSubPopup(id, popperRef?.current)
- }
- }, 10)
+ registerSubPopup()
}
return () => {
@@ -659,7 +704,7 @@ export const Popper = forwardRef((props, ref) => {
const referenceProps = {
ref: referenceRef,
- className: classnames(referenceElement?.props?.className, referencePrefixCls),
+ className: classnames(referencePrefixCls, referenceElement?.props?.className),
}
return (
diff --git a/components/tooltip/index.md b/components/tooltip/index.md
index 6e031e05..eed3c515 100644
--- a/components/tooltip/index.md
+++ b/components/tooltip/index.md
@@ -48,11 +48,32 @@ subtitle: 文字提示
| clickToClose | 点击浮层是否可关闭 | boolean | true | 1.0.0 |
| trigger | 触发行为,有 `hover` \| `focus` \| `click` \| `contextMenu` 四个行为可选,可使用数组设置多个触发行为 | string \| string\[] | `hover` | 1.0.0 |
| visible | 手动控制浮层显隐 | boolean | false | 1.0.0 |
-| onVisibleChange | 显示隐藏的回调 | (visible) => void | - | 1.0.0 |
+| onVisibleChange | 显示隐藏的回调 | (visible, reason:IReason) => void | - | 1.8.29 |
| autoPlacement | 溢出边界时改变 placement,默认镜向翻动 | boolean | true | 1.8.10 |
-| autoPlacementList | 溢出边界时,placement 备选展示位置 [参考 popper](https://popper.js.org/docs/v2/modifiers/flip/) | placement\[] | - | 1.8.10 |
+| autoPlacementList | 溢出边界时,placement 备选展示位置参考 placement | placement\[] | - | 1.8.10 |
| customerModifiers | 自定义修饰符 [参考 popper](https://popper.js.org/docs/v2/modifiers/) | (modifiers: Partial>\[]) => Partial>\[] | - | 1.8.10 |
+# Tooltip.onVisibleChange.IReason
+
+其它组件:(如 `Dropdown` / `Select` / `DatePicker` / `ColorPicker` / `CityPicker` / `Cascader`)使用时也会触发 IReason,下列简称`其它组件`
+
+| 参数 | 说明 | 版本 |
+| ---------------- | -------------------------------------------------------- | ------ |
+| click | 点击,仅在 placement 为 click 时出现 | 1.8.29 |
+| hover | 悬停,仅在 placement 为 hover 时出现 | 1.8.29 |
+| focus | 聚集,仅在 placement 为 focus 时出现 | 1.8.29 |
+| contextMenu | 点击右键,仅在 placement 为 contextMenu 时出现 | 1.8.29 |
+| clickToClose | 再次次点击触发元素关闭,仅在 clickToClose 为 true 时出现 | 1.8.29 |
+| clickOutside | 点击外部关闭 | 1.8.29 |
+| parentHidden | 嵌套 tooltip 中,父级关闭 | 1.8.29 |
+| scroll | 滚动导致的关闭,仅在 scrollHidden 为 true 时出现 | 1.8.29 |
+| selectPopperItem | `其它组件` 选中弹窗选项触发关闭 | 1.8.29 |
+| pressEnter | `其它组件` 回车选中后触发关闭 | 1.8.29 |
+| escEnter | `其它组件` 点击 ESC 触发关闭 | 1.8.29 |
+| delEnter | `其它组件` 点击回退删除触发关闭 | 1.8.29 |
+| otherEnter | `其它组件` 点击其它键时触发关闭 | 1.8.29 |
+| unknown | 受控或其它情况值的改变 | 1.8.29 |
+
## Design Token
| 分类 | 组件 token | 全局 token | 默认值 |