@@ -7,6 +7,7 @@ import type {
7
7
VariantType ,
8
8
WrapperType ,
9
9
DataAttribute ,
10
+ ITooltip ,
10
11
} from 'components/Tooltip/TooltipTypes'
11
12
import { useTooltip } from 'components/TooltipProvider'
12
13
import type { ITooltipController } from './TooltipControllerTypes'
@@ -46,10 +47,11 @@ const TooltipController = ({
46
47
const getDataAttributesFromAnchorElement = ( elementReference : HTMLElement ) => {
47
48
const dataAttributes = elementReference ?. getAttributeNames ( ) . reduce ( ( acc , name ) => {
48
49
if ( name . startsWith ( 'data-tooltip-' ) ) {
49
- acc [ name ] = elementReference ?. getAttribute ( name ) ?? null
50
+ const parsedAttribute = name . replace ( / ^ d a t a - t o o l t i p - / , '' ) as DataAttribute
51
+ acc [ parsedAttribute ] = elementReference ?. getAttribute ( name ) ?? null
50
52
}
51
53
return acc
52
- } , { } as Record < string , string | null > )
54
+ } , { } as Record < DataAttribute , string | null > )
53
55
54
56
return dataAttributes
55
57
}
@@ -63,51 +65,43 @@ const TooltipController = ({
63
65
} ,
64
66
content : ( value ) => {
65
67
setIsHtmlContent ( false )
66
- setTooltipContent ( value ?? '' )
68
+ setTooltipContent ( value ?? content )
67
69
} ,
68
70
html : ( value ) => {
69
71
setIsHtmlContent ( true )
70
- setTooltipContent ( value ?? '' )
72
+ setTooltipContent ( value ?? html )
71
73
} ,
72
74
variant : ( value ) => {
73
75
setTooltipVariant ( ( value as VariantType ) ?? variant )
74
76
} ,
75
77
offset : ( value ) => {
76
- setTooltipOffset ( Number ( value ) ?? offset )
78
+ setTooltipOffset ( value === null ? offset : Number ( value ) )
77
79
} ,
78
80
wrapper : ( value ) => {
79
- setTooltipWrapper ( ( value as WrapperType ) ?? wrapper )
81
+ setTooltipWrapper ( ( value as WrapperType ) ?? 'div' )
80
82
} ,
81
83
events : ( value ) => {
82
- const parsedEvents = value ?. split ( ' ' )
83
- setTooltipEvents ( ( parsedEvents as EventsType [ ] ) ?? events )
84
+ const parsed = value ?. split ( ' ' ) as EventsType [ ]
85
+ setTooltipEvents ( parsed ?? events )
84
86
} ,
85
87
'position-strategy' : ( value ) => {
86
88
setTooltipPositionStrategy ( ( value as PositionStrategy ) ?? positionStrategy )
87
89
} ,
88
90
'delay-show' : ( value ) => {
89
- setTooltipDelayShow ( Number ( value ) ?? delayShow )
91
+ setTooltipDelayShow ( value === null ? delayShow : Number ( value ) )
90
92
} ,
91
93
'delay-hide' : ( value ) => {
92
- setTooltipDelayHide ( Number ( value ) ?? delayHide )
94
+ setTooltipDelayHide ( value === null ? delayHide : Number ( value ) )
93
95
} ,
94
96
}
97
+ // reset unset data attributes to default values
98
+ // without this, data attributes from the last active anchor will still be used
99
+ Object . values ( handleDataAttributes ) . forEach ( ( handler ) => handler ( null ) )
95
100
Object . entries ( dataAttributes ) . forEach ( ( [ key , value ] ) => {
96
- const formattedKey = key . replace ( / ^ d a t a - t o o l t i p - / , '' ) as DataAttribute
97
- handleDataAttributes [ formattedKey ] ?.( value )
101
+ handleDataAttributes [ key as DataAttribute ] ?.( value )
98
102
} )
99
103
}
100
104
101
- const getElementSpecificAttributeKeyAndValueParsed = ( {
102
- element,
103
- attributeName,
104
- } : {
105
- element : HTMLElement
106
- attributeName : string
107
- } ) => {
108
- return { [ attributeName ] : element . getAttribute ( attributeName ) }
109
- }
110
-
111
105
useEffect ( ( ) => {
112
106
if ( content ) {
113
107
setTooltipContent ( content )
@@ -130,42 +124,35 @@ const TooltipController = ({
130
124
return ( ) => { }
131
125
}
132
126
133
- // do not check for subtree and childrens, we only want to know attribute changes
134
- // to stay watching `data-attributes` from anchor element
135
- const observerConfig = { attributes : true , childList : false , subtree : false }
136
-
137
127
const observerCallback : MutationCallback = ( mutationList ) => {
138
128
mutationList . forEach ( ( mutation ) => {
139
- if ( ! activeAnchor . current ) {
140
- return
141
- }
142
- if ( mutation . type !== 'attributes' || ! mutation . attributeName ) {
129
+ if (
130
+ ! activeAnchor . current ||
131
+ mutation . type !== 'attributes' ||
132
+ ! mutation . attributeName ?. startsWith ( 'data-tooltip-' )
133
+ ) {
143
134
return
144
135
}
145
- const attributeKeyAndValue = getElementSpecificAttributeKeyAndValueParsed ( {
146
- element : activeAnchor . current ,
147
- attributeName : mutation . attributeName ,
148
- } )
149
- applyAllDataAttributesFromAnchorElement ( attributeKeyAndValue )
136
+ // make sure to get all set attributes, since all unset attributes are reset
137
+ const dataAttributes = getDataAttributesFromAnchorElement ( activeAnchor . current )
138
+ applyAllDataAttributesFromAnchorElement ( dataAttributes )
150
139
} )
151
140
}
152
141
153
142
// Create an observer instance linked to the callback function
154
143
const observer = new MutationObserver ( observerCallback )
155
144
156
- elementRefs . forEach ( ( ref ) => {
157
- if ( ! ref . current ) {
158
- return
159
- }
160
- // Start observing the target nodes for configured mutations
161
- observer . observe ( ref . current , observerConfig )
162
- } )
145
+ // do not check for subtree and childrens, we only want to know attribute changes
146
+ // to stay watching `data-attributes-*` from anchor element
147
+ const observerConfig = { attributes : true , childList : false , subtree : false }
163
148
164
149
const element = activeAnchor . current ?? anchorById
165
150
166
151
if ( element ) {
167
152
const dataAttributes = getDataAttributesFromAnchorElement ( element )
168
153
applyAllDataAttributesFromAnchorElement ( dataAttributes )
154
+ // Start observing the target node for configured mutations
155
+ observer . observe ( element , observerConfig )
169
156
}
170
157
171
158
return ( ) => {
@@ -174,15 +161,7 @@ const TooltipController = ({
174
161
}
175
162
} , [ anchorRefs , activeAnchor , anchorId ] )
176
163
177
- useEffect ( ( ) => {
178
- if ( ! activeAnchor . current ) {
179
- return
180
- }
181
- const dataAttributes = getDataAttributesFromAnchorElement ( activeAnchor . current )
182
- applyAllDataAttributesFromAnchorElement ( dataAttributes )
183
- } , [ activeAnchor ] )
184
-
185
- const props = {
164
+ const props : ITooltip = {
186
165
id,
187
166
anchorId,
188
167
className,
0 commit comments