1
- import { defineComponent , ExtractPropTypes , inject , CSSProperties } from 'vue' ;
1
+ import { defineComponent , ExtractPropTypes , CSSProperties , onMounted , ref } from 'vue' ;
2
2
import VcTooltip from '../vc-tooltip' ;
3
3
import classNames from '../_util/classNames' ;
4
4
import getPlacements from './placements' ;
5
5
import PropTypes from '../_util/vue-types' ;
6
6
import { PresetColorTypes } from '../_util/colors' ;
7
- import {
8
- hasProp ,
9
- getComponent ,
10
- getStyle ,
11
- filterEmpty ,
12
- getSlot ,
13
- isValidElement ,
14
- } from '../_util/props-util' ;
7
+ import warning from '../_util/warning' ;
8
+ import { getPropsSlot , getStyle , filterEmpty , isValidElement } from '../_util/props-util' ;
15
9
import { cloneElement } from '../_util/vnode' ;
16
- import { defaultConfigProvider } from '../config-provider ' ;
17
- import abstractTooltipProps from './abstractTooltipProps ' ;
10
+ import abstractTooltipProps , { triggerTypes , placementTypes } from './abstractTooltipProps ' ;
11
+ import useConfigInject from '../_util/hooks/useConfigInject ' ;
18
12
19
13
const splitObject = ( obj : any , keys : string [ ] ) => {
20
14
const picked = { } ;
21
15
const omitted = { ...obj } ;
22
- keys . forEach ( key => {
16
+ keys . forEach ( ( key ) => {
23
17
if ( obj && key in obj ) {
24
18
picked [ key ] = obj [ key ] ;
25
19
delete omitted [ key ] ;
@@ -36,59 +30,67 @@ const tooltipProps = {
36
30
title : PropTypes . VNodeChild ,
37
31
} ;
38
32
33
+ export type TriggerTypes = typeof triggerTypes [ number ] ;
34
+
35
+ export type PlacementTypes = typeof placementTypes [ number ] ;
36
+
39
37
export type TooltipProps = Partial < ExtractPropTypes < typeof tooltipProps > > ;
40
38
41
39
export default defineComponent ( {
42
40
name : 'ATooltip' ,
43
41
inheritAttrs : false ,
44
42
props : tooltipProps ,
45
43
emits : [ 'update:visible' , 'visibleChange' ] ,
46
- setup ( ) {
47
- return {
48
- configProvider : inject ( 'configProvider' , defaultConfigProvider ) ,
44
+ setup ( props , { slots, emit, attrs, expose } ) {
45
+ const { prefixCls, getTargetContainer } = useConfigInject ( 'tooltip' , props ) ;
46
+
47
+ const visible = ref ( props . visible ) ;
48
+
49
+ const tooltip = ref ( ) ;
50
+
51
+ onMounted ( ( ) => {
52
+ warning (
53
+ ! ( 'default-visible' in attrs ) || ! ( 'defaultVisible' in attrs ) ,
54
+ 'Tooltip' ,
55
+ `'defaultVisible' is deprecated, please use 'v-model:visible'` ,
56
+ ) ;
57
+ } ) ;
58
+
59
+ const handleVisibleChange = ( bool : boolean ) => {
60
+ visible . value = isNoTitle ( ) ? false : bool ;
61
+ if ( ! isNoTitle ( ) ) {
62
+ emit ( 'update:visible' , bool ) ;
63
+ emit ( 'visibleChange' , bool ) ;
64
+ }
49
65
} ;
50
- } ,
51
- data ( ) {
52
- return {
53
- sVisible : ! ! this . $props . visible || ! ! this . $props . defaultVisible ,
66
+
67
+ const isNoTitle = ( ) => {
68
+ const title = getPropsSlot ( slots , props , 'title' ) ;
69
+ return ! title && title !== 0 ;
70
+ } ;
71
+
72
+ const getPopupDomNode = ( ) => {
73
+ return tooltip . value . getPopupDomNode ( ) ;
74
+ } ;
75
+
76
+ const getVisible = ( ) => {
77
+ return ! ! visible . value ;
54
78
} ;
55
- } ,
56
- watch : {
57
- visible ( val ) {
58
- this . sVisible = val ;
59
- } ,
60
- } ,
61
- methods : {
62
- handleVisibleChange ( visible : boolean ) {
63
- if ( ! hasProp ( this , 'visible' ) ) {
64
- this . sVisible = this . isNoTitle ( ) ? false : visible ;
65
- }
66
- if ( ! this . isNoTitle ( ) ) {
67
- this . $emit ( 'update:visible' , visible ) ;
68
- this . $emit ( 'visibleChange' , visible ) ;
69
- }
70
- } ,
71
79
72
- getPopupDomNode ( ) {
73
- return ( this . $refs . tooltip as any ) . getPopupDomNode ( ) ;
74
- } ,
80
+ expose ( { getPopupDomNode, getVisible } ) ;
75
81
76
- getPlacements ( ) {
77
- const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = this . $ props;
82
+ const getTooltipPlacements = ( ) => {
83
+ const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = props ;
78
84
return (
79
85
builtinPlacements ||
80
86
getPlacements ( {
81
87
arrowPointAtCenter,
82
- verticalArrowShift : 8 ,
83
88
autoAdjustOverflow,
84
89
} )
85
90
) ;
86
- } ,
91
+ } ;
87
92
88
- // Fix Tooltip won't hide at disabled button
89
- // mouse events don't trigger at disabled button in Chrome
90
- // https://github.com/react-component/tooltip/issues/18
91
- getDisabledCompatibleChildren ( ele : any ) {
93
+ const getDisabledCompatibleChildren = ( ele : any ) => {
92
94
if (
93
95
( ( typeof ele . type === 'object' &&
94
96
( ele . type . __ANT_BUTTON === true ||
@@ -130,27 +132,21 @@ export default defineComponent({
130
132
return < span style = { spanStyle } > { child } </ span > ;
131
133
}
132
134
return ele ;
133
- } ,
134
-
135
- isNoTitle ( ) {
136
- const title = getComponent ( this , 'title' ) ;
137
- return ! title && title !== 0 ;
138
- } ,
135
+ } ;
139
136
140
- getOverlay ( ) {
141
- const title = getComponent ( this , 'title' ) ;
137
+ const getOverlay = ( ) => {
138
+ const title = getPropsSlot ( slots , props , 'title' ) ;
142
139
if ( title === 0 ) {
143
140
return title ;
144
141
}
145
142
return title || '' ;
146
- } ,
143
+ } ;
147
144
148
- // 动态设置动画点
149
- onPopupAlign ( domNode : HTMLElement , align : any ) {
150
- const placements = this . getPlacements ( ) ;
145
+ const onPopupAlign = ( domNode : HTMLElement , align : any ) => {
146
+ const placements = getTooltipPlacements ( ) ;
151
147
// 当前返回的位置
152
148
const placement = Object . keys ( placements ) . filter (
153
- key =>
149
+ ( key ) =>
154
150
placements [ key ] . points [ 0 ] === align . points [ 0 ] &&
155
151
placements [ key ] . points [ 1 ] === align . points [ 1 ] ,
156
152
) [ 0 ] ;
@@ -174,67 +170,58 @@ export default defineComponent({
174
170
transformOrigin . left = `${ - align . offset [ 0 ] } px` ;
175
171
}
176
172
domNode . style . transformOrigin = `${ transformOrigin . left } ${ transformOrigin . top } ` ;
177
- } ,
178
- } ,
173
+ } ;
179
174
180
- render ( ) {
181
- const { $props, $data, $attrs } = this ;
182
- const {
183
- prefixCls : customizePrefixCls ,
184
- openClassName,
185
- getPopupContainer,
186
- color,
187
- overlayClassName,
188
- } = $props ;
189
- const { getPopupContainer : getContextPopupContainer } = this . configProvider ;
190
- const getPrefixCls = this . configProvider . getPrefixCls ;
191
- const prefixCls = getPrefixCls ( 'tooltip' , customizePrefixCls ) ;
192
- let children = this . children || filterEmpty ( getSlot ( this ) ) ;
193
- children = children . length === 1 ? children [ 0 ] : children ;
194
- let sVisible = $data . sVisible ;
195
- // Hide tooltip when there is no title
196
- if ( ! hasProp ( this , 'visible' ) && this . isNoTitle ( ) ) {
197
- sVisible = false ;
198
- }
199
- if ( ! children ) {
200
- return null ;
201
- }
202
- const child = this . getDisabledCompatibleChildren (
203
- isValidElement ( children ) ? children : < span > { children } </ span > ,
204
- ) ;
205
- const childCls = classNames ( {
206
- [ openClassName || `${ prefixCls } -open` ] : sVisible ,
207
- [ child . props && child . props . class ] : child . props && child . props . class ,
208
- } ) ;
209
- const customOverlayClassName = classNames ( overlayClassName , {
210
- [ `${ prefixCls } -${ color } ` ] : color && PresetColorRegex . test ( color ) ,
211
- } ) ;
212
- let formattedOverlayInnerStyle : CSSProperties ;
213
- let arrowContentStyle : CSSProperties ;
214
- if ( color && ! PresetColorRegex . test ( color ) ) {
215
- formattedOverlayInnerStyle = { backgroundColor : color } ;
216
- arrowContentStyle = { backgroundColor : color } ;
217
- }
175
+ return ( ) => {
176
+ const { openClassName, getPopupContainer, color, overlayClassName } = props ;
177
+ let children = filterEmpty ( slots . default ?.( ) ) ?? null ;
178
+ children = children . length === 1 ? children [ 0 ] : children ;
179
+ // Hide tooltip when there is no title
180
+ if ( ! ( 'visible' in props ) && isNoTitle ( ) ) {
181
+ visible . value = false ;
182
+ }
183
+ if ( ! children ) {
184
+ return null ;
185
+ }
186
+ const child = getDisabledCompatibleChildren (
187
+ isValidElement ( children ) ? children : < span > { children } </ span > ,
188
+ ) ;
189
+ const childCls = classNames ( {
190
+ [ openClassName || `${ prefixCls . value } -open` ] : visible . value ,
191
+ [ child . props && child . props . class ] : child . props && child . props . class ,
192
+ } ) ;
193
+ const customOverlayClassName = classNames ( overlayClassName , {
194
+ [ `${ prefixCls . value } -${ color } ` ] : color && PresetColorRegex . test ( color ) ,
195
+ } ) ;
196
+ let formattedOverlayInnerStyle : CSSProperties ;
197
+ let arrowContentStyle : CSSProperties ;
198
+ if ( color && ! PresetColorRegex . test ( color ) ) {
199
+ formattedOverlayInnerStyle = { backgroundColor : color } ;
200
+ arrowContentStyle = { backgroundColor : color } ;
201
+ }
218
202
219
- const vcTooltipProps = {
220
- ...$attrs ,
221
- ...$props ,
222
- prefixCls,
223
- getTooltipContainer : getPopupContainer || getContextPopupContainer ,
224
- builtinPlacements : this . getPlacements ( ) ,
225
- overlay : this . getOverlay ( ) ,
226
- visible : sVisible ,
227
- ref : 'tooltip' ,
228
- overlayClassName : customOverlayClassName ,
229
- overlayInnerStyle : formattedOverlayInnerStyle ,
230
- arrowContent : < span class = { `${ prefixCls } -arrow-content` } style = { arrowContentStyle } > </ span > ,
231
- onVisibleChange : this . handleVisibleChange ,
232
- onPopupAlign : this . onPopupAlign ,
203
+ const vcTooltipProps = {
204
+ ...attrs ,
205
+ ...props ,
206
+ prefixCls : prefixCls . value ,
207
+ getTooltipContainer : getPopupContainer || getTargetContainer . value ,
208
+ builtinPlacements : getTooltipPlacements ( ) ,
209
+ overlay : getOverlay ( ) ,
210
+ visible : visible . value ,
211
+ ref : tooltip ,
212
+ overlayClassName : customOverlayClassName ,
213
+ overlayInnerStyle : formattedOverlayInnerStyle ,
214
+ arrowContent : (
215
+ < span class = { `${ prefixCls . value } -arrow-content` } style = { arrowContentStyle } > </ span >
216
+ ) ,
217
+ onVisibleChange : handleVisibleChange ,
218
+ onPopupAlign,
219
+ } ;
220
+ return (
221
+ < VcTooltip { ...vcTooltipProps } >
222
+ { visible . value ? cloneElement ( child , { class : childCls } ) : child }
223
+ </ VcTooltip >
224
+ ) ;
233
225
} ;
234
- return (
235
- < VcTooltip { ...vcTooltipProps } >
236
- { sVisible ? cloneElement ( child , { class : childCls } ) : child }
237
- </ VcTooltip >
238
- ) ;
239
226
} ,
240
227
} ) ;
0 commit comments