@khanacademy/wonder-blocks-tooltip 4.1.11 → 4.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/components/tooltip-anchor.d.ts +5 -4
- package/dist/components/tooltip.d.ts +1 -1
- package/dist/es/index.js +10 -856
- package/dist/index.js +10 -859
- package/package.json +6 -7
package/dist/es/index.js
CHANGED
|
@@ -1,878 +1,32 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
1
2
|
import * as React from 'react';
|
|
2
3
|
import * as ReactDOM from 'react-dom';
|
|
3
4
|
import { Text as Text$1, View, Id } from '@khanacademy/wonder-blocks-core';
|
|
4
5
|
import { maybeGetPortalMountedModalHostElement } from '@khanacademy/wonder-blocks-modal';
|
|
5
6
|
import { StyleSheet, css } from 'aphrodite';
|
|
6
7
|
import { spacing, color, border, semanticColor } from '@khanacademy/wonder-blocks-tokens';
|
|
7
|
-
import _extends from '@babel/runtime/helpers/extends';
|
|
8
8
|
import { Strut } from '@khanacademy/wonder-blocks-layout';
|
|
9
9
|
import { HeadingSmall, LabelMedium } from '@khanacademy/wonder-blocks-typography';
|
|
10
10
|
import { Popper } from 'react-popper';
|
|
11
11
|
|
|
12
|
-
class ActiveTracker {
|
|
13
|
-
constructor() {
|
|
14
|
-
this._subscribers = [];
|
|
15
|
-
this._active = false;
|
|
16
|
-
}
|
|
17
|
-
_getIndex(who) {
|
|
18
|
-
return this._subscribers.findIndex(v => v === who);
|
|
19
|
-
}
|
|
20
|
-
steal(who) {
|
|
21
|
-
const wasActive = !!this._active;
|
|
22
|
-
this._active = true;
|
|
23
|
-
for (const anchor of this._subscribers) {
|
|
24
|
-
if (anchor === who) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
anchor.activeStateStolen();
|
|
28
|
-
}
|
|
29
|
-
return wasActive;
|
|
30
|
-
}
|
|
31
|
-
giveup() {
|
|
32
|
-
this._active = false;
|
|
33
|
-
}
|
|
34
|
-
subscribe(who) {
|
|
35
|
-
if (this._getIndex(who) >= 0) {
|
|
36
|
-
throw new Error("Already subscribed.");
|
|
37
|
-
}
|
|
38
|
-
this._subscribers.push(who);
|
|
39
|
-
const unsubscribe = () => {
|
|
40
|
-
const index = this._getIndex(who);
|
|
41
|
-
this._subscribers.splice(index, 1);
|
|
42
|
-
};
|
|
43
|
-
return unsubscribe;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
12
|
+
class ActiveTracker{_getIndex(who){return this._subscribers.findIndex(v=>v===who)}steal(who){const wasActive=!!this._active;this._active=true;for(const anchor of this._subscribers){if(anchor===who){continue}anchor.activeStateStolen();}return wasActive}giveup(){this._active=false;}subscribe(who){if(this._getIndex(who)>=0){throw new Error("Already subscribed.")}this._subscribers.push(who);const unsubscribe=()=>{const index=this._getIndex(who);this._subscribers.splice(index,1);};return unsubscribe}constructor(){this._subscribers=[];this._active=false;}}
|
|
46
13
|
|
|
47
|
-
const TooltipAppearanceDelay
|
|
48
|
-
const TooltipDisappearanceDelay = 75;
|
|
14
|
+
const TooltipAppearanceDelay=100;const TooltipDisappearanceDelay=75;
|
|
49
15
|
|
|
50
|
-
const TRACKER = new
|
|
51
|
-
class TooltipAnchor extends React.Component {
|
|
52
|
-
constructor(props) {
|
|
53
|
-
super(props);
|
|
54
|
-
this._weSetFocusivity = void 0;
|
|
55
|
-
this._anchorNode = void 0;
|
|
56
|
-
this._focused = void 0;
|
|
57
|
-
this._hovered = void 0;
|
|
58
|
-
this._stolenFromUs = void 0;
|
|
59
|
-
this._unsubscribeFromTracker = void 0;
|
|
60
|
-
this._timeoutID = void 0;
|
|
61
|
-
this.activeStateStolen = () => {
|
|
62
|
-
this._stolenFromUs = this.state.active || !!this._timeoutID;
|
|
63
|
-
this._focused = false;
|
|
64
|
-
this._setActiveState(false, true);
|
|
65
|
-
};
|
|
66
|
-
this._handleFocusIn = () => {
|
|
67
|
-
this._updateActiveState(this._hovered, true);
|
|
68
|
-
};
|
|
69
|
-
this._handleFocusOut = () => {
|
|
70
|
-
this._updateActiveState(this._hovered, false);
|
|
71
|
-
};
|
|
72
|
-
this._handleMouseEnter = () => {
|
|
73
|
-
this._updateActiveState(true, this._focused);
|
|
74
|
-
};
|
|
75
|
-
this._handleMouseLeave = () => {
|
|
76
|
-
this._updateActiveState(false, this._focused);
|
|
77
|
-
};
|
|
78
|
-
this._handleKeyUp = e => {
|
|
79
|
-
if (e.key === "Escape" && this.state.active) {
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
e.stopPropagation();
|
|
82
|
-
this._updateActiveState(false, false);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
this._focused = false;
|
|
86
|
-
this._hovered = false;
|
|
87
|
-
this.state = {
|
|
88
|
-
active: false
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
componentDidMount() {
|
|
92
|
-
const anchorNode = ReactDOM.findDOMNode(this);
|
|
93
|
-
if (anchorNode instanceof Text) {
|
|
94
|
-
throw new Error("TooltipAnchor must be applied to an Element. Text content is not supported.");
|
|
95
|
-
}
|
|
96
|
-
this._unsubscribeFromTracker = TRACKER.subscribe(this);
|
|
97
|
-
this._anchorNode = anchorNode;
|
|
98
|
-
this._updateFocusivity();
|
|
99
|
-
if (anchorNode) {
|
|
100
|
-
anchorNode.addEventListener("focusin", this._handleFocusIn);
|
|
101
|
-
anchorNode.addEventListener("focusout", this._handleFocusOut);
|
|
102
|
-
anchorNode.addEventListener("mouseenter", this._handleMouseEnter);
|
|
103
|
-
anchorNode.addEventListener("mouseleave", this._handleMouseLeave);
|
|
104
|
-
this.props.anchorRef(this._anchorNode);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
componentDidUpdate(prevProps) {
|
|
108
|
-
if (prevProps.forceAnchorFocusivity !== this.props.forceAnchorFocusivity || prevProps.children !== this.props.children) {
|
|
109
|
-
this._updateFocusivity();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
componentWillUnmount() {
|
|
113
|
-
if (this._unsubscribeFromTracker) {
|
|
114
|
-
this._unsubscribeFromTracker();
|
|
115
|
-
}
|
|
116
|
-
this._clearPendingAction();
|
|
117
|
-
const anchorNode = this._anchorNode;
|
|
118
|
-
if (anchorNode) {
|
|
119
|
-
anchorNode.removeEventListener("focusin", this._handleFocusIn);
|
|
120
|
-
anchorNode.removeEventListener("focusout", this._handleFocusOut);
|
|
121
|
-
anchorNode.removeEventListener("mouseenter", this._handleMouseEnter);
|
|
122
|
-
anchorNode.removeEventListener("mouseleave", this._handleMouseLeave);
|
|
123
|
-
}
|
|
124
|
-
if (this.state.active) {
|
|
125
|
-
document.removeEventListener("keyup", this._handleKeyUp);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
_updateFocusivity() {
|
|
129
|
-
const anchorNode = this._anchorNode;
|
|
130
|
-
if (!anchorNode) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const {
|
|
134
|
-
forceAnchorFocusivity
|
|
135
|
-
} = this.props;
|
|
136
|
-
const currentTabIndex = anchorNode.getAttribute("tabindex");
|
|
137
|
-
if (forceAnchorFocusivity && !currentTabIndex) {
|
|
138
|
-
anchorNode.setAttribute("tabindex", "0");
|
|
139
|
-
this._weSetFocusivity = true;
|
|
140
|
-
} else if (!forceAnchorFocusivity && currentTabIndex) {
|
|
141
|
-
if (this._weSetFocusivity) {
|
|
142
|
-
anchorNode.removeAttribute("tabindex");
|
|
143
|
-
this._weSetFocusivity = false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
_updateActiveState(hovered, focused) {
|
|
148
|
-
this._hovered = hovered;
|
|
149
|
-
this._focused = focused;
|
|
150
|
-
this._setActiveState(hovered || focused);
|
|
151
|
-
}
|
|
152
|
-
_clearPendingAction() {
|
|
153
|
-
if (this._timeoutID) {
|
|
154
|
-
clearTimeout(this._timeoutID);
|
|
155
|
-
this._timeoutID = null;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
_setActiveState(active, instant) {
|
|
159
|
-
if (this._stolenFromUs || active !== this.state.active || !this.state.active && this._timeoutID) {
|
|
160
|
-
this._clearPendingAction();
|
|
161
|
-
} else if (active === this.state.active) {
|
|
162
|
-
if (this._timeoutID) {
|
|
163
|
-
this._clearPendingAction();
|
|
164
|
-
}
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
instant = instant || active && TRACKER.steal(this);
|
|
168
|
-
if (instant) {
|
|
169
|
-
if (active) {
|
|
170
|
-
document.addEventListener("keyup", this._handleKeyUp);
|
|
171
|
-
} else {
|
|
172
|
-
document.removeEventListener("keyup", this._handleKeyUp);
|
|
173
|
-
}
|
|
174
|
-
this.setState({
|
|
175
|
-
active
|
|
176
|
-
});
|
|
177
|
-
this.props.onActiveChanged(active);
|
|
178
|
-
if (!this._stolenFromUs && !active) {
|
|
179
|
-
TRACKER.giveup();
|
|
180
|
-
}
|
|
181
|
-
this._stolenFromUs = false;
|
|
182
|
-
} else {
|
|
183
|
-
const delay = active ? TooltipAppearanceDelay : TooltipDisappearanceDelay;
|
|
184
|
-
this._timeoutID = setTimeout(() => {
|
|
185
|
-
this._timeoutID = null;
|
|
186
|
-
this._setActiveState(active, true);
|
|
187
|
-
}, delay);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
_renderAnchorableChildren() {
|
|
191
|
-
const {
|
|
192
|
-
children
|
|
193
|
-
} = this.props;
|
|
194
|
-
return typeof children === "string" ? React.createElement(Text$1, null, children) : children;
|
|
195
|
-
}
|
|
196
|
-
_renderAccessibleChildren(uniqueId) {
|
|
197
|
-
const anchorableChildren = this._renderAnchorableChildren();
|
|
198
|
-
return React.cloneElement(anchorableChildren, {
|
|
199
|
-
"aria-describedby": `${uniqueId}-${TooltipAnchor.ariaContentId}`
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
render() {
|
|
203
|
-
if (this.props.id) {
|
|
204
|
-
return this._renderAccessibleChildren(this.props.id);
|
|
205
|
-
}
|
|
206
|
-
return this._renderAnchorableChildren();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
TooltipAnchor.defaultProps = {
|
|
210
|
-
forceAnchorFocusivity: true
|
|
211
|
-
};
|
|
212
|
-
TooltipAnchor.ariaContentId = "aria-content";
|
|
16
|
+
const TRACKER=new ActiveTracker;class TooltipAnchor extends React.Component{componentDidMount(){const anchorNode=ReactDOM.findDOMNode(this);if(anchorNode instanceof Text){throw new Error("TooltipAnchor must be applied to an Element. Text content is not supported.")}this._unsubscribeFromTracker=TRACKER.subscribe(this);this._anchorNode=anchorNode;this._updateFocusivity();if(anchorNode){anchorNode.addEventListener("focusin",this._handleFocusIn);anchorNode.addEventListener("focusout",this._handleFocusOut);anchorNode.addEventListener("mouseenter",this._handleMouseEnter);anchorNode.addEventListener("mouseleave",this._handleMouseLeave);this.props.anchorRef(this._anchorNode);}}componentDidUpdate(prevProps){if(prevProps.forceAnchorFocusivity!==this.props.forceAnchorFocusivity||prevProps.children!==this.props.children){this._updateFocusivity();}}componentWillUnmount(){if(this._unsubscribeFromTracker){this._unsubscribeFromTracker();}this._clearPendingAction();const anchorNode=this._anchorNode;if(anchorNode){anchorNode.removeEventListener("focusin",this._handleFocusIn);anchorNode.removeEventListener("focusout",this._handleFocusOut);anchorNode.removeEventListener("mouseenter",this._handleMouseEnter);anchorNode.removeEventListener("mouseleave",this._handleMouseLeave);}if(this.state.active){document.removeEventListener("keyup",this._handleKeyUp);}}_updateFocusivity(){const anchorNode=this._anchorNode;if(!anchorNode){return}const{forceAnchorFocusivity}=this.props;const currentTabIndex=anchorNode.getAttribute("tabindex");if(forceAnchorFocusivity&&!currentTabIndex){anchorNode.setAttribute("tabindex","0");this._weSetFocusivity=true;}else if(!forceAnchorFocusivity&¤tTabIndex){if(this._weSetFocusivity){anchorNode.removeAttribute("tabindex");this._weSetFocusivity=false;}}}_updateActiveState(hovered,focused){this._hovered=hovered;this._focused=focused;this._setActiveState(hovered||focused);}_clearPendingAction(){if(this._timeoutID){clearTimeout(this._timeoutID);this._timeoutID=null;}}_setActiveState(active,instant){if(this._stolenFromUs||active!==this.state.active||!this.state.active&&this._timeoutID){this._clearPendingAction();}else if(active===this.state.active){if(this._timeoutID){this._clearPendingAction();}return}instant=instant||active&&TRACKER.steal(this);if(instant){if(active){document.addEventListener("keyup",this._handleKeyUp);}else {document.removeEventListener("keyup",this._handleKeyUp);}this.setState({active});this.props.onActiveChanged(active);if(!this._stolenFromUs&&!active){TRACKER.giveup();}this._stolenFromUs=false;}else {const delay=active?TooltipAppearanceDelay:TooltipDisappearanceDelay;this._timeoutID=setTimeout(()=>{this._timeoutID=null;this._setActiveState(active,true);},delay);}}_renderAnchorableChildren(){const{children}=this.props;return typeof children==="string"?jsx(Text$1,{children:children}):children}render(){const{"aria-describedby":ariaDescribedBy}=this.props;const anchorableChildren=this._renderAnchorableChildren();return React.cloneElement(anchorableChildren,{"aria-describedby":ariaDescribedBy})}constructor(props){super(props),this.activeStateStolen=()=>{this._stolenFromUs=this.state.active||!!this._timeoutID;this._focused=false;this._setActiveState(false,true);},this._handleFocusIn=()=>{this._updateActiveState(this._hovered,true);},this._handleFocusOut=()=>{this._updateActiveState(this._hovered,false);},this._handleMouseEnter=()=>{this._updateActiveState(true,this._focused);},this._handleMouseLeave=()=>{this._updateActiveState(false,this._focused);},this._handleKeyUp=e=>{if(e.key==="Escape"&&this.state.active){e.preventDefault();e.stopPropagation();this._updateActiveState(false,false);}};this._focused=false;this._hovered=false;this.state={active:false};}}TooltipAnchor.defaultProps={forceAnchorFocusivity:true};
|
|
213
17
|
|
|
214
|
-
let tempIdCounter = 0;
|
|
215
|
-
class TooltipTail extends React.Component {
|
|
216
|
-
_calculateDimensionsFromPlacement() {
|
|
217
|
-
const {
|
|
218
|
-
placement
|
|
219
|
-
} = this.props;
|
|
220
|
-
const trimlineOffset = 0.5;
|
|
221
|
-
switch (placement) {
|
|
222
|
-
case "top":
|
|
223
|
-
return {
|
|
224
|
-
trimlinePoints: [`0,-${trimlineOffset}`, `${ARROW_WIDTH},-${trimlineOffset}`],
|
|
225
|
-
points: ["0,0", `${ARROW_WIDTH / 2},${ARROW_HEIGHT}`, `${ARROW_WIDTH},0`],
|
|
226
|
-
height: ARROW_HEIGHT,
|
|
227
|
-
width: ARROW_WIDTH
|
|
228
|
-
};
|
|
229
|
-
case "right":
|
|
230
|
-
return {
|
|
231
|
-
trimlinePoints: [`${ARROW_HEIGHT + trimlineOffset},0`, `${ARROW_HEIGHT + trimlineOffset},${ARROW_WIDTH}`],
|
|
232
|
-
points: [`${ARROW_HEIGHT},0`, `0,${ARROW_WIDTH / 2}`, `${ARROW_HEIGHT},${ARROW_WIDTH}`],
|
|
233
|
-
width: ARROW_HEIGHT,
|
|
234
|
-
height: ARROW_WIDTH
|
|
235
|
-
};
|
|
236
|
-
case "bottom":
|
|
237
|
-
return {
|
|
238
|
-
trimlinePoints: [`0, ${ARROW_HEIGHT + trimlineOffset}`, `${ARROW_WIDTH},${ARROW_HEIGHT + trimlineOffset}`],
|
|
239
|
-
points: [`0, ${ARROW_HEIGHT}`, `${ARROW_WIDTH / 2},0`, `${ARROW_WIDTH},${ARROW_HEIGHT}`],
|
|
240
|
-
width: ARROW_WIDTH,
|
|
241
|
-
height: ARROW_HEIGHT
|
|
242
|
-
};
|
|
243
|
-
case "left":
|
|
244
|
-
return {
|
|
245
|
-
trimlinePoints: [`-${trimlineOffset},0`, `-${trimlineOffset},${ARROW_WIDTH}`],
|
|
246
|
-
points: [`0,0`, `${ARROW_HEIGHT},${ARROW_WIDTH / 2}`, `0,${ARROW_WIDTH}`],
|
|
247
|
-
width: ARROW_HEIGHT,
|
|
248
|
-
height: ARROW_WIDTH
|
|
249
|
-
};
|
|
250
|
-
default:
|
|
251
|
-
throw new Error(`Unknown placement: ${placement}`);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
_getFilterPositioning() {
|
|
255
|
-
const {
|
|
256
|
-
placement
|
|
257
|
-
} = this.props;
|
|
258
|
-
switch (placement) {
|
|
259
|
-
case "top":
|
|
260
|
-
return {
|
|
261
|
-
y: "-50%",
|
|
262
|
-
x: "-50%",
|
|
263
|
-
offsetShadowX: 0
|
|
264
|
-
};
|
|
265
|
-
case "bottom":
|
|
266
|
-
return null;
|
|
267
|
-
case "left":
|
|
268
|
-
return {
|
|
269
|
-
y: "-50%",
|
|
270
|
-
x: "0%",
|
|
271
|
-
offsetShadowX: 1
|
|
272
|
-
};
|
|
273
|
-
case "right":
|
|
274
|
-
return {
|
|
275
|
-
y: "-50%",
|
|
276
|
-
x: "-100%",
|
|
277
|
-
offsetShadowX: -1
|
|
278
|
-
};
|
|
279
|
-
default:
|
|
280
|
-
throw new Error(`Unknown placement: ${placement}`);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
_maybeRenderDropshadow(points) {
|
|
284
|
-
const position = this._getFilterPositioning();
|
|
285
|
-
if (!position) {
|
|
286
|
-
return null;
|
|
287
|
-
}
|
|
288
|
-
const {
|
|
289
|
-
placement
|
|
290
|
-
} = this.props;
|
|
291
|
-
const {
|
|
292
|
-
y,
|
|
293
|
-
x,
|
|
294
|
-
offsetShadowX
|
|
295
|
-
} = position;
|
|
296
|
-
const dropShadowFilterId = `tooltip-dropshadow-${placement}-${tempIdCounter++}`;
|
|
297
|
-
return [React.createElement("filter", {
|
|
298
|
-
key: "filter",
|
|
299
|
-
id: dropShadowFilterId,
|
|
300
|
-
width: "200%",
|
|
301
|
-
height: "200%",
|
|
302
|
-
x: x,
|
|
303
|
-
y: y
|
|
304
|
-
}, React.createElement("feGaussianBlur", {
|
|
305
|
-
in: "SourceAlpha",
|
|
306
|
-
stdDeviation: spacing.xxSmall_6 / 2
|
|
307
|
-
}), React.createElement("feComponentTransfer", null, React.createElement("feFuncA", {
|
|
308
|
-
type: "linear",
|
|
309
|
-
slope: "0.3"
|
|
310
|
-
}))), React.createElement("g", {
|
|
311
|
-
key: "dropshadow",
|
|
312
|
-
transform: `translate(${offsetShadowX},5.5)`
|
|
313
|
-
}, React.createElement("polyline", {
|
|
314
|
-
fill: color.offBlack16,
|
|
315
|
-
points: points.join(" "),
|
|
316
|
-
stroke: color.offBlack32,
|
|
317
|
-
filter: `url(#${dropShadowFilterId})`
|
|
318
|
-
}))];
|
|
319
|
-
}
|
|
320
|
-
_getFullTailWidth() {
|
|
321
|
-
return ARROW_WIDTH + 2 * MIN_DISTANCE_FROM_CORNERS;
|
|
322
|
-
}
|
|
323
|
-
_getFullTailHeight() {
|
|
324
|
-
return ARROW_HEIGHT + DISTANCE_FROM_ANCHOR;
|
|
325
|
-
}
|
|
326
|
-
_getContainerStyle() {
|
|
327
|
-
const {
|
|
328
|
-
placement
|
|
329
|
-
} = this.props;
|
|
330
|
-
const fullTailWidth = this._getFullTailWidth();
|
|
331
|
-
const fullTailHeight = this._getFullTailHeight();
|
|
332
|
-
switch (placement) {
|
|
333
|
-
case "top":
|
|
334
|
-
return {
|
|
335
|
-
top: -1,
|
|
336
|
-
width: fullTailWidth,
|
|
337
|
-
height: fullTailHeight
|
|
338
|
-
};
|
|
339
|
-
case "right":
|
|
340
|
-
return {
|
|
341
|
-
left: 1,
|
|
342
|
-
width: fullTailHeight,
|
|
343
|
-
height: fullTailWidth
|
|
344
|
-
};
|
|
345
|
-
case "bottom":
|
|
346
|
-
return {
|
|
347
|
-
top: 1,
|
|
348
|
-
width: fullTailWidth,
|
|
349
|
-
height: fullTailHeight
|
|
350
|
-
};
|
|
351
|
-
case "left":
|
|
352
|
-
return {
|
|
353
|
-
left: -1,
|
|
354
|
-
width: fullTailHeight,
|
|
355
|
-
height: fullTailWidth
|
|
356
|
-
};
|
|
357
|
-
default:
|
|
358
|
-
throw new Error(`Unknown placement: ${placement}`);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
_getArrowStyle() {
|
|
362
|
-
const {
|
|
363
|
-
placement
|
|
364
|
-
} = this.props;
|
|
365
|
-
switch (placement) {
|
|
366
|
-
case "top":
|
|
367
|
-
return {
|
|
368
|
-
marginLeft: MIN_DISTANCE_FROM_CORNERS,
|
|
369
|
-
marginRight: MIN_DISTANCE_FROM_CORNERS,
|
|
370
|
-
paddingBottom: DISTANCE_FROM_ANCHOR
|
|
371
|
-
};
|
|
372
|
-
case "right":
|
|
373
|
-
return {
|
|
374
|
-
marginTop: MIN_DISTANCE_FROM_CORNERS,
|
|
375
|
-
marginBottom: MIN_DISTANCE_FROM_CORNERS,
|
|
376
|
-
paddingLeft: DISTANCE_FROM_ANCHOR
|
|
377
|
-
};
|
|
378
|
-
case "bottom":
|
|
379
|
-
return {
|
|
380
|
-
marginLeft: MIN_DISTANCE_FROM_CORNERS,
|
|
381
|
-
marginRight: MIN_DISTANCE_FROM_CORNERS,
|
|
382
|
-
paddingTop: DISTANCE_FROM_ANCHOR
|
|
383
|
-
};
|
|
384
|
-
case "left":
|
|
385
|
-
return {
|
|
386
|
-
marginTop: MIN_DISTANCE_FROM_CORNERS,
|
|
387
|
-
marginBottom: MIN_DISTANCE_FROM_CORNERS,
|
|
388
|
-
paddingRight: DISTANCE_FROM_ANCHOR
|
|
389
|
-
};
|
|
390
|
-
default:
|
|
391
|
-
throw new Error(`Unknown placement: ${placement}`);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
_renderArrow() {
|
|
395
|
-
const {
|
|
396
|
-
trimlinePoints,
|
|
397
|
-
points,
|
|
398
|
-
height,
|
|
399
|
-
width
|
|
400
|
-
} = this._calculateDimensionsFromPlacement();
|
|
401
|
-
const {
|
|
402
|
-
color: arrowColor,
|
|
403
|
-
show
|
|
404
|
-
} = this.props;
|
|
405
|
-
if (!show) {
|
|
406
|
-
return React.createElement(Strut, {
|
|
407
|
-
size: height
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
return React.createElement("svg", {
|
|
411
|
-
className: css(styles$2.arrow),
|
|
412
|
-
style: this._getArrowStyle(),
|
|
413
|
-
width: width,
|
|
414
|
-
height: height,
|
|
415
|
-
"aria-hidden": true
|
|
416
|
-
}, this._maybeRenderDropshadow(points), React.createElement("polyline", {
|
|
417
|
-
fill: color[arrowColor],
|
|
418
|
-
stroke: color[arrowColor],
|
|
419
|
-
points: points.join(" ")
|
|
420
|
-
}), React.createElement("polyline", {
|
|
421
|
-
fill: color[arrowColor],
|
|
422
|
-
points: points.join(" "),
|
|
423
|
-
stroke: color.offBlack16
|
|
424
|
-
}), React.createElement("polyline", {
|
|
425
|
-
stroke: color[arrowColor],
|
|
426
|
-
points: trimlinePoints.join(" ")
|
|
427
|
-
}));
|
|
428
|
-
}
|
|
429
|
-
render() {
|
|
430
|
-
const {
|
|
431
|
-
offset,
|
|
432
|
-
placement,
|
|
433
|
-
updateRef
|
|
434
|
-
} = this.props;
|
|
435
|
-
return React.createElement(View, {
|
|
436
|
-
style: [styles$2.tailContainer, _extends({}, offset), this._getContainerStyle()],
|
|
437
|
-
"data-placement": placement,
|
|
438
|
-
ref: updateRef
|
|
439
|
-
}, this._renderArrow());
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
TooltipTail.defaultProps = {
|
|
443
|
-
color: "white",
|
|
444
|
-
show: true
|
|
445
|
-
};
|
|
446
|
-
const DISTANCE_FROM_ANCHOR = spacing.xSmall_8;
|
|
447
|
-
const MIN_DISTANCE_FROM_CORNERS = spacing.xSmall_8;
|
|
448
|
-
const ARROW_WIDTH = spacing.large_24;
|
|
449
|
-
const ARROW_HEIGHT = spacing.small_12;
|
|
450
|
-
const styles$2 = StyleSheet.create({
|
|
451
|
-
tailContainer: {
|
|
452
|
-
position: "relative",
|
|
453
|
-
pointerEvents: "none"
|
|
454
|
-
},
|
|
455
|
-
arrow: {
|
|
456
|
-
overflow: "visible"
|
|
457
|
-
}
|
|
458
|
-
});
|
|
18
|
+
let tempIdCounter=0;class TooltipTail extends React.Component{_calculateDimensionsFromPlacement(){const{placement}=this.props;const trimlineOffset=.5;switch(placement){case"top":return {trimlinePoints:[`0,-${trimlineOffset}`,`${ARROW_WIDTH},-${trimlineOffset}`],points:["0,0",`${ARROW_WIDTH/2},${ARROW_HEIGHT}`,`${ARROW_WIDTH},0`],height:ARROW_HEIGHT,width:ARROW_WIDTH};case"right":return {trimlinePoints:[`${ARROW_HEIGHT+trimlineOffset},0`,`${ARROW_HEIGHT+trimlineOffset},${ARROW_WIDTH}`],points:[`${ARROW_HEIGHT},0`,`0,${ARROW_WIDTH/2}`,`${ARROW_HEIGHT},${ARROW_WIDTH}`],width:ARROW_HEIGHT,height:ARROW_WIDTH};case"bottom":return {trimlinePoints:[`0, ${ARROW_HEIGHT+trimlineOffset}`,`${ARROW_WIDTH},${ARROW_HEIGHT+trimlineOffset}`],points:[`0, ${ARROW_HEIGHT}`,`${ARROW_WIDTH/2},0`,`${ARROW_WIDTH},${ARROW_HEIGHT}`],width:ARROW_WIDTH,height:ARROW_HEIGHT};case"left":return {trimlinePoints:[`-${trimlineOffset},0`,`-${trimlineOffset},${ARROW_WIDTH}`],points:[`0,0`,`${ARROW_HEIGHT},${ARROW_WIDTH/2}`,`0,${ARROW_WIDTH}`],width:ARROW_HEIGHT,height:ARROW_WIDTH};default:throw new Error(`Unknown placement: ${placement}`)}}_getFilterPositioning(){const{placement}=this.props;switch(placement){case"top":return {y:"-50%",x:"-50%",offsetShadowX:0};case"bottom":return null;case"left":return {y:"-50%",x:"0%",offsetShadowX:1};case"right":return {y:"-50%",x:"-100%",offsetShadowX:-1};default:throw new Error(`Unknown placement: ${placement}`)}}_maybeRenderDropshadow(points){const position=this._getFilterPositioning();if(!position){return null}const{placement}=this.props;const{y,x,offsetShadowX}=position;const dropShadowFilterId=`tooltip-dropshadow-${placement}-${tempIdCounter++}`;return [jsxs("filter",{id:dropShadowFilterId,width:"200%",height:"200%",x:x,y:y,children:[jsx("feGaussianBlur",{in:"SourceAlpha",stdDeviation:spacing.xxSmall_6/2}),jsx("feComponentTransfer",{children:jsx("feFuncA",{type:"linear",slope:"0.3"})})]},"filter"),jsx("g",{transform:`translate(${offsetShadowX},5.5)`,children:jsx("polyline",{fill:color.offBlack16,points:points.join(" "),stroke:color.offBlack32,filter:`url(#${dropShadowFilterId})`})},"dropshadow")]}_getFullTailWidth(){return ARROW_WIDTH+2*MIN_DISTANCE_FROM_CORNERS}_getFullTailHeight(){return ARROW_HEIGHT+DISTANCE_FROM_ANCHOR}_getContainerStyle(){const{placement}=this.props;const fullTailWidth=this._getFullTailWidth();const fullTailHeight=this._getFullTailHeight();switch(placement){case"top":return {top:-1,width:fullTailWidth,height:fullTailHeight};case"right":return {left:1,width:fullTailHeight,height:fullTailWidth};case"bottom":return {top:1,width:fullTailWidth,height:fullTailHeight};case"left":return {left:-1,width:fullTailHeight,height:fullTailWidth};default:throw new Error(`Unknown placement: ${placement}`)}}_getArrowStyle(){const{placement}=this.props;switch(placement){case"top":return {marginLeft:MIN_DISTANCE_FROM_CORNERS,marginRight:MIN_DISTANCE_FROM_CORNERS,paddingBottom:DISTANCE_FROM_ANCHOR};case"right":return {marginTop:MIN_DISTANCE_FROM_CORNERS,marginBottom:MIN_DISTANCE_FROM_CORNERS,paddingLeft:DISTANCE_FROM_ANCHOR};case"bottom":return {marginLeft:MIN_DISTANCE_FROM_CORNERS,marginRight:MIN_DISTANCE_FROM_CORNERS,paddingTop:DISTANCE_FROM_ANCHOR};case"left":return {marginTop:MIN_DISTANCE_FROM_CORNERS,marginBottom:MIN_DISTANCE_FROM_CORNERS,paddingRight:DISTANCE_FROM_ANCHOR};default:throw new Error(`Unknown placement: ${placement}`)}}_renderArrow(){const{trimlinePoints,points,height,width}=this._calculateDimensionsFromPlacement();const{color:arrowColor,show}=this.props;if(!show){return jsx(Strut,{size:height})}return jsxs("svg",{className:css(styles$2.arrow),style:this._getArrowStyle(),width:width,height:height,"aria-hidden":true,children:[this._maybeRenderDropshadow(points),jsx("polyline",{fill:color[arrowColor],stroke:color[arrowColor],points:points.join(" ")}),jsx("polyline",{fill:color[arrowColor],points:points.join(" "),stroke:color.offBlack16}),jsx("polyline",{stroke:color[arrowColor],points:trimlinePoints.join(" ")})]})}render(){const{offset,placement,updateRef}=this.props;return jsx(View,{style:[styles$2.tailContainer,{...offset},this._getContainerStyle()],"data-placement":placement,ref:updateRef,children:this._renderArrow()})}}TooltipTail.defaultProps={color:"white",show:true};const DISTANCE_FROM_ANCHOR=spacing.xSmall_8;const MIN_DISTANCE_FROM_CORNERS=spacing.xSmall_8;const ARROW_WIDTH=spacing.large_24;const ARROW_HEIGHT=spacing.small_12;const styles$2=StyleSheet.create({tailContainer:{position:"relative",pointerEvents:"none"},arrow:{overflow:"visible"}});
|
|
459
19
|
|
|
460
|
-
class TooltipBubble extends React.Component {
|
|
461
|
-
constructor(...args) {
|
|
462
|
-
super(...args);
|
|
463
|
-
this.state = {
|
|
464
|
-
active: false
|
|
465
|
-
};
|
|
466
|
-
this.handleMouseEnter = () => {
|
|
467
|
-
this._setActiveState(true);
|
|
468
|
-
};
|
|
469
|
-
this.handleMouseLeave = () => {
|
|
470
|
-
this.props.onActiveChanged(false);
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
_setActiveState(active) {
|
|
474
|
-
this.setState({
|
|
475
|
-
active
|
|
476
|
-
});
|
|
477
|
-
this.props.onActiveChanged(active);
|
|
478
|
-
}
|
|
479
|
-
render() {
|
|
480
|
-
const {
|
|
481
|
-
id,
|
|
482
|
-
children,
|
|
483
|
-
updateBubbleRef,
|
|
484
|
-
placement,
|
|
485
|
-
isReferenceHidden,
|
|
486
|
-
style,
|
|
487
|
-
updateTailRef,
|
|
488
|
-
tailOffset,
|
|
489
|
-
backgroundColor
|
|
490
|
-
} = this.props;
|
|
491
|
-
return React.createElement(View, {
|
|
492
|
-
id: id,
|
|
493
|
-
role: "tooltip",
|
|
494
|
-
"data-placement": placement,
|
|
495
|
-
onMouseEnter: this.handleMouseEnter,
|
|
496
|
-
onMouseLeave: this.handleMouseLeave,
|
|
497
|
-
ref: updateBubbleRef,
|
|
498
|
-
style: [isReferenceHidden && styles$1.hide, styles$1.bubble, styles$1[`content-${placement}`], style]
|
|
499
|
-
}, React.createElement(View, {
|
|
500
|
-
style: [styles$1.content, backgroundColor && {
|
|
501
|
-
backgroundColor: color[backgroundColor]
|
|
502
|
-
}]
|
|
503
|
-
}, children), React.createElement(TooltipTail, {
|
|
504
|
-
updateRef: updateTailRef,
|
|
505
|
-
placement: placement,
|
|
506
|
-
offset: tailOffset,
|
|
507
|
-
color: backgroundColor
|
|
508
|
-
}));
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
const styles$1 = StyleSheet.create({
|
|
512
|
-
bubble: {
|
|
513
|
-
position: "absolute"
|
|
514
|
-
},
|
|
515
|
-
hide: {
|
|
516
|
-
pointerEvents: "none",
|
|
517
|
-
opacity: 0,
|
|
518
|
-
backgroundColor: "transparent",
|
|
519
|
-
color: "transparent"
|
|
520
|
-
},
|
|
521
|
-
"content-top": {
|
|
522
|
-
flexDirection: "column"
|
|
523
|
-
},
|
|
524
|
-
"content-right": {
|
|
525
|
-
flexDirection: "row-reverse"
|
|
526
|
-
},
|
|
527
|
-
"content-bottom": {
|
|
528
|
-
flexDirection: "column-reverse"
|
|
529
|
-
},
|
|
530
|
-
"content-left": {
|
|
531
|
-
flexDirection: "row"
|
|
532
|
-
},
|
|
533
|
-
content: {
|
|
534
|
-
maxWidth: 472,
|
|
535
|
-
borderRadius: border.radius.radius_040,
|
|
536
|
-
border: `solid 1px ${semanticColor.border.primary}`,
|
|
537
|
-
backgroundColor: semanticColor.surface.primary,
|
|
538
|
-
boxShadow: `0 ${spacing.xSmall_8}px ${spacing.xSmall_8}px 0 ${color.offBlack8}`,
|
|
539
|
-
justifyContent: "center"
|
|
540
|
-
}
|
|
541
|
-
});
|
|
20
|
+
class TooltipBubble extends React.Component{_setActiveState(active){this.setState({active});this.props.onActiveChanged(active);}render(){const{id,children,updateBubbleRef,placement,isReferenceHidden,style,updateTailRef,tailOffset,backgroundColor}=this.props;return jsxs(View,{id:id,role:"tooltip","data-placement":placement,onMouseEnter:this.handleMouseEnter,onMouseLeave:this.handleMouseLeave,ref:updateBubbleRef,style:[isReferenceHidden&&styles$1.hide,styles$1.bubble,styles$1[`content-${placement}`],style],children:[jsx(View,{style:[styles$1.content,backgroundColor&&{backgroundColor:color[backgroundColor]}],children:children}),jsx(TooltipTail,{updateRef:updateTailRef,placement:placement,offset:tailOffset,color:backgroundColor})]})}constructor(...args){super(...args),this.state={active:false},this.handleMouseEnter=()=>{this._setActiveState(true);},this.handleMouseLeave=()=>{this.props.onActiveChanged(false);};}}const styles$1=StyleSheet.create({bubble:{position:"absolute"},hide:{pointerEvents:"none",opacity:0,backgroundColor:"transparent",color:"transparent"},"content-top":{flexDirection:"column"},"content-right":{flexDirection:"row-reverse"},"content-bottom":{flexDirection:"column-reverse"},"content-left":{flexDirection:"row"},content:{maxWidth:472,borderRadius:border.radius.radius_040,border:`solid 1px ${semanticColor.border.primary}`,backgroundColor:semanticColor.surface.primary,boxShadow:`0 ${spacing.xSmall_8}px ${spacing.xSmall_8}px 0 ${color.offBlack8}`,justifyContent:"center"}});
|
|
542
21
|
|
|
543
|
-
class TooltipContent extends React.Component {
|
|
544
|
-
_renderTitle() {
|
|
545
|
-
const {
|
|
546
|
-
title
|
|
547
|
-
} = this.props;
|
|
548
|
-
if (title) {
|
|
549
|
-
if (typeof title === "string") {
|
|
550
|
-
return React.createElement(HeadingSmall, null, title);
|
|
551
|
-
} else {
|
|
552
|
-
return title;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
return null;
|
|
556
|
-
}
|
|
557
|
-
_renderChildren() {
|
|
558
|
-
const {
|
|
559
|
-
children
|
|
560
|
-
} = this.props;
|
|
561
|
-
if (typeof children === "string") {
|
|
562
|
-
return React.createElement(LabelMedium, null, children);
|
|
563
|
-
} else {
|
|
564
|
-
return children;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
render() {
|
|
568
|
-
const title = this._renderTitle();
|
|
569
|
-
const children = this._renderChildren();
|
|
570
|
-
const containerStyle = title ? styles.withTitle : styles.withoutTitle;
|
|
571
|
-
return React.createElement(View, {
|
|
572
|
-
style: [containerStyle, this.props.contentStyle],
|
|
573
|
-
testId: this.props.testId
|
|
574
|
-
}, title, title && children && React.createElement(Strut, {
|
|
575
|
-
size: spacing.xxxSmall_4
|
|
576
|
-
}), children);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
const styles = StyleSheet.create({
|
|
580
|
-
withoutTitle: {
|
|
581
|
-
padding: `10px ${spacing.medium_16}px`
|
|
582
|
-
},
|
|
583
|
-
withTitle: {
|
|
584
|
-
padding: spacing.medium_16
|
|
585
|
-
}
|
|
586
|
-
});
|
|
22
|
+
class TooltipContent extends React.Component{_renderTitle(){const{title}=this.props;if(title){if(typeof title==="string"){return jsx(HeadingSmall,{children:title})}else {return title}}return null}_renderChildren(){const{children}=this.props;if(typeof children==="string"){return jsx(LabelMedium,{children:children})}else {return children}}render(){const title=this._renderTitle();const children=this._renderChildren();const containerStyle=title?styles.withTitle:styles.withoutTitle;return jsxs(View,{style:[containerStyle,this.props.contentStyle],testId:this.props.testId,children:[title,title&&children&&jsx(Strut,{size:spacing.xxxSmall_4}),children]})}}const styles=StyleSheet.create({withoutTitle:{padding:`10px ${spacing.medium_16}px`},withTitle:{padding:spacing.medium_16}});
|
|
587
23
|
|
|
588
24
|
var t=e=>null==e||"object"!=typeof e?e:Array.isArray(e)?e.map(t):Object.keys(e).reduce(((n,r)=>(n[r]=t(e[r]),n)),{}),n=Object.freeze({Unknown:"Unknown",Internal:"Internal",InvalidInput:"InvalidInput",InvalidUse:"InvalidUse",NotFound:"NotFound",NotAllowed:"NotAllowed",Unauthorized:"Unauthorized",NotImplemented:"NotImplemented"});function r(t,e,n){return (e=function(t){var e=function(t,e){if("object"!=typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0!==n){var r=n.call(t,e||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return ("string"===e?String:Number)(t)}(t,"string");return "symbol"==typeof e?e:String(e)}(e))in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}class s{constructor(t,e,n){r(this,"_name",void 0),r(this,"_message",void 0),r(this,"_stackFrames",void 0),this._name=t,this._message=e,this._stackFrames=[...n];}get message(){return this._message}get name(){return this._name}get messageWithName(){return "".concat(this.name,": ").concat(this.message)}get stack(){return [...this._stackFrames]}get standardizedStack(){return "".concat(this.messageWithName,"\n").concat(this._stackFrames.join("\n"))}static fromConsequenceAndCause(t,e){var n;if("production"!==process.env.NODE_ENV){if(!(t instanceof s))throw new Error("consequence must be an instance of ErrorInfo");if(!(e instanceof s))throw new Error("cause must be an instance of ErrorInfo");if(e===t)throw new Error("cause and consequence must be different")}for(var r=[],i=e.stack,a=null!==(n=null==t?void 0:t.stack)&&void 0!==n?n:[],o=i.length-1,c=a.length-1;o>=0&&c>=0&&i[o]===a[c];)r.unshift(i[o]),o--,c--;for(;o>=0;o--)r.unshift(i[o]);for(;c>=0;c--)r.unshift(a[c]);return new s(t.name,((t,e)=>{var n=t=>(null==t?void 0:t.trim())||"(empty message)",r=n(t);return null==e?r:"".concat(r,"\n\tcaused by\n\t\t").concat(n(e))})(t.message,e.messageWithName),r)}static normalize(t){var e,n,r,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;if("production"!==process.env.NODE_ENV){if(!(t instanceof Error))throw new Error("Error must be an instance of Error");if(i<0)throw new Error("stripFrames must be >= 0");if(a<0)throw new Error("minimumFrameCount must be >= 0")}var o=null!==(e=t.message.toString().split("\n").find((t=>t.trim().length)))&&void 0!==e?e:"(empty message)",c=t.toString(),u=(null!==(n=t.stack)&&void 0!==n&&n.startsWith(c)&&t.stack!==c?t.stack.substring(c.length):null!==(r=t.stack)&&void 0!==r?r:"").split("\n").filter((t=>t.trim().length)),l=u.length>=i+a?i:0;return new s(t.name,o,u.slice(l))}static from(t){var e,n;if("production"!==process.env.NODE_ENV&&!(t instanceof Error))throw new Error("Error must be an instance of Error");var r=t.toString(),i=(null!==(e=t.stack)&&void 0!==e&&e.startsWith(r)&&t.stack!==r?t.stack.substring(r.length):null!==(n=t.stack)&&void 0!==n?n:"").split("\n").filter((t=>t.trim().length));return new s(t.name,t.message,i)}}class i extends Error{constructor(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.Unknown,{cause:a,prefix:o,name:c,metadata:u,stripStackFrames:l,minimumFrameCount:m,compositeStack:d}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Object.freeze({});if("production"!==process.env.NODE_ENV){if(a&&!(a instanceof Error))throw new Error("cause must be an instance of Error");if(null!=c&&/\s/g.test(c))throw new Error("name must not contain whitespace");if(/\s/g.test(i))throw new Error("kind must not contain whitespace");if(null!=o&&/\s/g.test(o))throw new Error("prefix must not contain whitespace");if(null!=l&&l<0)throw new Error("stripStackFrames must be >= 0");if(null!=m&&m<0)throw new Error("minimumFrameCount must be >= 0")}super(e),r(this,"kind",void 0),r(this,"originalMessage",void 0),r(this,"originalStack",void 0),r(this,"metadata",void 0),r(this,"cause",void 0),this.originalMessage=e,this.metadata=(e=>{if(null==e)return e;var n=t(e);return Object.freeze(n)})(u),this.name="".concat(null!=o?o:"").concat(i).concat(null!=c?c:"","Error"),this.kind=i,this.originalStack=this.stack,this.cause=a;var f=s.normalize(this,null!=l?l:0,null!=m?m:1);if(delete this.stack,this.stack=f.standardizedStack,null!=a){var h=s.from(a),v=s.fromConsequenceAndCause(f,h);this.message=v.message,!0===d&&(this.stack=v.standardizedStack);}}}Object.freeze({ConsequenceFirst:"consequence-first",CauseFirst:"cause-first"});class w extends i{constructor(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:n.InvalidInput,r=arguments.length>2?arguments[2]:void 0;super("Unhandled case for '".concat(t,"'"),e,r);}}
|
|
589
25
|
|
|
590
|
-
class RefTracker {
|
|
591
|
-
constructor() {
|
|
592
|
-
this._lastRef = void 0;
|
|
593
|
-
this._targetFn = void 0;
|
|
594
|
-
this.updateRef = ref => {
|
|
595
|
-
if (ref) {
|
|
596
|
-
const domNode = ReactDOM.findDOMNode(ref);
|
|
597
|
-
if (domNode instanceof HTMLElement && domNode !== this._lastRef) {
|
|
598
|
-
var _this$_targetFn;
|
|
599
|
-
this._lastRef = domNode;
|
|
600
|
-
(_this$_targetFn = this._targetFn) == null || _this$_targetFn.call(this, domNode);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
this.setCallback = targetFn => {
|
|
605
|
-
if (this._targetFn !== targetFn) {
|
|
606
|
-
if (targetFn && typeof targetFn !== "function") {
|
|
607
|
-
throw new Error("targetFn must be a function");
|
|
608
|
-
}
|
|
609
|
-
this._targetFn = targetFn || undefined;
|
|
610
|
-
if (this._lastRef && this._targetFn) {
|
|
611
|
-
this._targetFn(this._lastRef);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
}
|
|
616
|
-
}
|
|
26
|
+
class RefTracker{constructor(){this.updateRef=ref=>{if(ref){const domNode=ReactDOM.findDOMNode(ref);if(domNode instanceof HTMLElement&&domNode!==this._lastRef){this._lastRef=domNode;this._targetFn?.(domNode);}}};this.setCallback=targetFn=>{if(this._targetFn!==targetFn){if(targetFn&&typeof targetFn!=="function"){throw new Error("targetFn must be a function")}this._targetFn=targetFn||undefined;if(this._lastRef&&this._targetFn){this._targetFn(this._lastRef);}}};}}
|
|
617
27
|
|
|
618
|
-
const filterPopperPlacement = placement => {
|
|
619
|
-
switch (placement) {
|
|
620
|
-
case "auto":
|
|
621
|
-
case "auto-start":
|
|
622
|
-
case "auto-end":
|
|
623
|
-
case "top":
|
|
624
|
-
case "top-start":
|
|
625
|
-
case "top-end":
|
|
626
|
-
return "top";
|
|
627
|
-
case "bottom":
|
|
628
|
-
case "bottom-start":
|
|
629
|
-
case "bottom-end":
|
|
630
|
-
return "bottom";
|
|
631
|
-
case "right":
|
|
632
|
-
case "right-start":
|
|
633
|
-
case "right-end":
|
|
634
|
-
return "right";
|
|
635
|
-
case "left":
|
|
636
|
-
case "left-start":
|
|
637
|
-
case "left-end":
|
|
638
|
-
return "left";
|
|
639
|
-
default:
|
|
640
|
-
throw new w(placement);
|
|
641
|
-
}
|
|
642
|
-
};
|
|
643
|
-
function _modifyPosition({
|
|
644
|
-
state
|
|
645
|
-
}) {
|
|
646
|
-
const popperHeight = state.rects.popper.height + state.rects.reference.height;
|
|
647
|
-
const minHeight = document.documentElement.clientHeight;
|
|
648
|
-
if (minHeight < popperHeight && state.modifiersData.hide) {
|
|
649
|
-
state.modifiersData.hide = _extends({}, state.modifiersData.hide, {
|
|
650
|
-
isReferenceHidden: false
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
const smallViewportModifier = {
|
|
655
|
-
name: "smallViewport",
|
|
656
|
-
enabled: true,
|
|
657
|
-
phase: "main",
|
|
658
|
-
fn: _modifyPosition
|
|
659
|
-
};
|
|
660
|
-
class TooltipPopper extends React.Component {
|
|
661
|
-
constructor(props) {
|
|
662
|
-
super(props);
|
|
663
|
-
this._bubbleRefTracker = new RefTracker();
|
|
664
|
-
this._tailRefTracker = new RefTracker();
|
|
665
|
-
this._observer = null;
|
|
666
|
-
this._popperUpdate = null;
|
|
667
|
-
this.handleFirstUpdate = () => {
|
|
668
|
-
this.setState({
|
|
669
|
-
isReady: true
|
|
670
|
-
});
|
|
671
|
-
};
|
|
672
|
-
this.state = {
|
|
673
|
-
isReady: false
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
componentDidMount() {
|
|
677
|
-
const {
|
|
678
|
-
anchorElement,
|
|
679
|
-
autoUpdate
|
|
680
|
-
} = this.props;
|
|
681
|
-
if (!anchorElement || !autoUpdate) {
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
this._observer = new MutationObserver(() => {
|
|
685
|
-
var _this$_popperUpdate;
|
|
686
|
-
(_this$_popperUpdate = this._popperUpdate) == null || _this$_popperUpdate.call(this);
|
|
687
|
-
});
|
|
688
|
-
this._observer.observe(anchorElement, {
|
|
689
|
-
attributes: true,
|
|
690
|
-
childList: true,
|
|
691
|
-
subtree: true
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
componentWillUnmount() {
|
|
695
|
-
var _this$_observer;
|
|
696
|
-
(_this$_observer = this._observer) == null || _this$_observer.disconnect();
|
|
697
|
-
}
|
|
698
|
-
_renderPositionedContent(popperProps) {
|
|
699
|
-
const {
|
|
700
|
-
children
|
|
701
|
-
} = this.props;
|
|
702
|
-
const {
|
|
703
|
-
isReady
|
|
704
|
-
} = this.state;
|
|
705
|
-
const placement = filterPopperPlacement(popperProps.placement) || this.props.placement;
|
|
706
|
-
this._bubbleRefTracker.setCallback(popperProps.ref);
|
|
707
|
-
this._tailRefTracker.setCallback(popperProps.arrowProps.ref);
|
|
708
|
-
this._popperUpdate = popperProps.update;
|
|
709
|
-
const bubbleProps = {
|
|
710
|
-
placement,
|
|
711
|
-
style: {
|
|
712
|
-
top: popperProps.style.top,
|
|
713
|
-
left: popperProps.style.left,
|
|
714
|
-
bottom: popperProps.style.bottom,
|
|
715
|
-
right: popperProps.style.right,
|
|
716
|
-
position: popperProps.style.position,
|
|
717
|
-
transform: popperProps.style.transform,
|
|
718
|
-
visibility: !isReady ? "hidden" : undefined
|
|
719
|
-
},
|
|
720
|
-
updateBubbleRef: this._bubbleRefTracker.updateRef,
|
|
721
|
-
tailOffset: {
|
|
722
|
-
bottom: popperProps.arrowProps.style.bottom,
|
|
723
|
-
right: popperProps.arrowProps.style.right,
|
|
724
|
-
top: popperProps.arrowProps.style.top,
|
|
725
|
-
left: popperProps.arrowProps.style.left,
|
|
726
|
-
transform: popperProps.arrowProps.style.transform
|
|
727
|
-
},
|
|
728
|
-
updateTailRef: this._tailRefTracker.updateRef,
|
|
729
|
-
isReferenceHidden: popperProps.isReferenceHidden
|
|
730
|
-
};
|
|
731
|
-
return children(bubbleProps);
|
|
732
|
-
}
|
|
733
|
-
render() {
|
|
734
|
-
const {
|
|
735
|
-
anchorElement,
|
|
736
|
-
placement,
|
|
737
|
-
rootBoundary,
|
|
738
|
-
viewportPadding
|
|
739
|
-
} = this.props;
|
|
740
|
-
const modifiers = [smallViewportModifier];
|
|
741
|
-
if (rootBoundary === "viewport") {
|
|
742
|
-
modifiers.push({
|
|
743
|
-
name: "preventOverflow",
|
|
744
|
-
options: {
|
|
745
|
-
rootBoundary: "viewport",
|
|
746
|
-
padding: viewportPadding
|
|
747
|
-
}
|
|
748
|
-
});
|
|
749
|
-
} else {
|
|
750
|
-
modifiers.push({
|
|
751
|
-
name: "flip",
|
|
752
|
-
options: {
|
|
753
|
-
rootBoundary: "document"
|
|
754
|
-
}
|
|
755
|
-
});
|
|
756
|
-
}
|
|
757
|
-
return React.createElement(Popper, {
|
|
758
|
-
referenceElement: anchorElement,
|
|
759
|
-
strategy: "fixed",
|
|
760
|
-
placement: placement,
|
|
761
|
-
modifiers: modifiers,
|
|
762
|
-
onFirstUpdate: this.handleFirstUpdate
|
|
763
|
-
}, props => this._renderPositionedContent(props));
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
TooltipPopper.defaultProps = {
|
|
767
|
-
rootBoundary: "viewport",
|
|
768
|
-
viewportPadding: spacing.small_12
|
|
769
|
-
};
|
|
28
|
+
const filterPopperPlacement=placement=>{switch(placement){case"auto":case"auto-start":case"auto-end":case"top":case"top-start":case"top-end":return "top";case"bottom":case"bottom-start":case"bottom-end":return "bottom";case"right":case"right-start":case"right-end":return "right";case"left":case"left-start":case"left-end":return "left";default:throw new w(placement)}};function _modifyPosition({state}){const popperHeight=state.rects.popper.height+state.rects.reference.height;const minHeight=document.documentElement.clientHeight;if(minHeight<popperHeight&&state.modifiersData.hide){state.modifiersData.hide={...state.modifiersData.hide,isReferenceHidden:false};}}const smallViewportModifier={name:"smallViewport",enabled:true,phase:"main",fn:_modifyPosition};class TooltipPopper extends React.Component{componentDidMount(){const{anchorElement,autoUpdate}=this.props;if(!anchorElement||!autoUpdate){return}this._observer=new MutationObserver(()=>{this._popperUpdate?.();});this._observer.observe(anchorElement,{attributes:true,childList:true,subtree:true});}componentWillUnmount(){this._observer?.disconnect();}_renderPositionedContent(popperProps){const{children}=this.props;const{isReady}=this.state;const placement=filterPopperPlacement(popperProps.placement)||this.props.placement;this._bubbleRefTracker.setCallback(popperProps.ref);this._tailRefTracker.setCallback(popperProps.arrowProps.ref);this._popperUpdate=popperProps.update;const bubbleProps={placement,style:{top:popperProps.style.top,left:popperProps.style.left,bottom:popperProps.style.bottom,right:popperProps.style.right,position:popperProps.style.position,transform:popperProps.style.transform,visibility:!isReady?"hidden":undefined},updateBubbleRef:this._bubbleRefTracker.updateRef,tailOffset:{bottom:popperProps.arrowProps.style.bottom,right:popperProps.arrowProps.style.right,top:popperProps.arrowProps.style.top,left:popperProps.arrowProps.style.left,transform:popperProps.arrowProps.style.transform},updateTailRef:this._tailRefTracker.updateRef,isReferenceHidden:popperProps.isReferenceHidden};return children(bubbleProps)}render(){const{anchorElement,placement,rootBoundary,viewportPadding}=this.props;const modifiers=[smallViewportModifier];if(rootBoundary==="viewport"){modifiers.push({name:"preventOverflow",options:{rootBoundary:"viewport",padding:viewportPadding}});}else {modifiers.push({name:"flip",options:{rootBoundary:"document"}});}return jsx(Popper,{referenceElement:anchorElement,strategy:"fixed",placement:placement,modifiers:modifiers,onFirstUpdate:this.handleFirstUpdate,children:props=>this._renderPositionedContent(props)})}constructor(props){super(props),this._bubbleRefTracker=new RefTracker,this._tailRefTracker=new RefTracker,this._observer=null,this._popperUpdate=null,this.handleFirstUpdate=()=>{this.setState({isReady:true});};this.state={isReady:false};}}TooltipPopper.defaultProps={rootBoundary:"viewport",viewportPadding:spacing.small_12};
|
|
770
29
|
|
|
771
|
-
class Tooltip extends React.Component {
|
|
772
|
-
constructor(...args) {
|
|
773
|
-
super(...args);
|
|
774
|
-
this.state = {
|
|
775
|
-
active: false,
|
|
776
|
-
activeBubble: false
|
|
777
|
-
};
|
|
778
|
-
}
|
|
779
|
-
static getDerivedStateFromProps(props, state) {
|
|
780
|
-
return {
|
|
781
|
-
active: typeof props.opened === "boolean" ? props.opened : state.active
|
|
782
|
-
};
|
|
783
|
-
}
|
|
784
|
-
_updateAnchorElement(ref) {
|
|
785
|
-
if (ref && ref !== this.state.anchorElement) {
|
|
786
|
-
this.setState({
|
|
787
|
-
anchorElement: ref
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
_renderBubbleContent() {
|
|
792
|
-
const {
|
|
793
|
-
title,
|
|
794
|
-
content,
|
|
795
|
-
contentStyle,
|
|
796
|
-
testId
|
|
797
|
-
} = this.props;
|
|
798
|
-
if (typeof content === "string") {
|
|
799
|
-
return React.createElement(TooltipContent, {
|
|
800
|
-
title: title,
|
|
801
|
-
contentStyle: contentStyle,
|
|
802
|
-
testId: testId ? `${testId}-content` : undefined
|
|
803
|
-
}, content);
|
|
804
|
-
} else if (title) {
|
|
805
|
-
return React.cloneElement(content, {
|
|
806
|
-
title
|
|
807
|
-
});
|
|
808
|
-
} else {
|
|
809
|
-
return content;
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
_renderPopper(bubbleId) {
|
|
813
|
-
const {
|
|
814
|
-
backgroundColor,
|
|
815
|
-
placement
|
|
816
|
-
} = this.props;
|
|
817
|
-
return React.createElement(TooltipPopper, {
|
|
818
|
-
anchorElement: this.state.anchorElement,
|
|
819
|
-
placement: placement,
|
|
820
|
-
autoUpdate: this.props.autoUpdate,
|
|
821
|
-
viewportPadding: this.props.viewportPadding
|
|
822
|
-
}, props => React.createElement(TooltipBubble, {
|
|
823
|
-
id: bubbleId,
|
|
824
|
-
style: props.style,
|
|
825
|
-
backgroundColor: backgroundColor,
|
|
826
|
-
tailOffset: props.tailOffset,
|
|
827
|
-
isReferenceHidden: props.isReferenceHidden,
|
|
828
|
-
placement: props.placement,
|
|
829
|
-
updateTailRef: props.updateTailRef,
|
|
830
|
-
updateBubbleRef: props.updateBubbleRef,
|
|
831
|
-
onActiveChanged: active => this.setState({
|
|
832
|
-
activeBubble: active
|
|
833
|
-
})
|
|
834
|
-
}, this._renderBubbleContent()));
|
|
835
|
-
}
|
|
836
|
-
_getHost() {
|
|
837
|
-
const {
|
|
838
|
-
anchorElement
|
|
839
|
-
} = this.state;
|
|
840
|
-
return maybeGetPortalMountedModalHostElement(anchorElement) || document.body;
|
|
841
|
-
}
|
|
842
|
-
_renderTooltipAnchor(uniqueId) {
|
|
843
|
-
const {
|
|
844
|
-
autoUpdate,
|
|
845
|
-
children,
|
|
846
|
-
forceAnchorFocusivity
|
|
847
|
-
} = this.props;
|
|
848
|
-
const {
|
|
849
|
-
active,
|
|
850
|
-
activeBubble
|
|
851
|
-
} = this.state;
|
|
852
|
-
const popperHost = this._getHost();
|
|
853
|
-
const shouldAnchorExist = autoUpdate ? this.state.anchorElement : true;
|
|
854
|
-
const shouldBeVisible = popperHost && (active || activeBubble) && shouldAnchorExist;
|
|
855
|
-
return React.createElement(React.Fragment, null, React.createElement(TooltipAnchor, {
|
|
856
|
-
forceAnchorFocusivity: forceAnchorFocusivity,
|
|
857
|
-
anchorRef: r => this._updateAnchorElement(r),
|
|
858
|
-
onActiveChanged: active => this.setState({
|
|
859
|
-
active
|
|
860
|
-
}),
|
|
861
|
-
id: `${uniqueId}-anchor`
|
|
862
|
-
}, children), shouldBeVisible && ReactDOM.createPortal(this._renderPopper(uniqueId), popperHost));
|
|
863
|
-
}
|
|
864
|
-
render() {
|
|
865
|
-
const {
|
|
866
|
-
id
|
|
867
|
-
} = this.props;
|
|
868
|
-
return React.createElement(Id, {
|
|
869
|
-
id: id
|
|
870
|
-
}, uniqueId => this._renderTooltipAnchor(uniqueId));
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
Tooltip.defaultProps = {
|
|
874
|
-
forceAnchorFocusivity: true,
|
|
875
|
-
placement: "top"
|
|
876
|
-
};
|
|
30
|
+
class Tooltip extends React.Component{static getDerivedStateFromProps(props,state){return {active:typeof props.opened==="boolean"?props.opened:state.active}}_updateAnchorElement(ref){if(ref&&ref!==this.state.anchorElement){this.setState({anchorElement:ref});}}_renderBubbleContent(){const{title,content,contentStyle,testId}=this.props;if(typeof content==="string"){return jsx(TooltipContent,{title:title,contentStyle:contentStyle,testId:testId?`${testId}-content`:undefined,children:content})}else if(title){return React.cloneElement(content,{title})}else {return content}}_renderPopper(ariaContentId){const{backgroundColor,placement}=this.props;return jsx(TooltipPopper,{anchorElement:this.state.anchorElement,placement:placement,autoUpdate:this.props.autoUpdate,viewportPadding:this.props.viewportPadding,children:props=>jsx(TooltipBubble,{id:ariaContentId,style:props.style,backgroundColor:backgroundColor,tailOffset:props.tailOffset,isReferenceHidden:props.isReferenceHidden,placement:props.placement,updateTailRef:props.updateTailRef,updateBubbleRef:props.updateBubbleRef,onActiveChanged:active=>this.setState({activeBubble:active}),children:this._renderBubbleContent()})})}_getHost(){const{anchorElement}=this.state;return maybeGetPortalMountedModalHostElement(anchorElement)||document.body}_renderTooltipAnchor(uniqueId){const{autoUpdate,children,forceAnchorFocusivity}=this.props;const{active,activeBubble}=this.state;const popperHost=this._getHost();const shouldAnchorExist=autoUpdate?this.state.anchorElement:true;const shouldBeVisible=popperHost&&(active||activeBubble)&&shouldAnchorExist;const ariaContentId=`${uniqueId}-aria-content`;return jsxs(React.Fragment,{children:[jsx(TooltipAnchor,{forceAnchorFocusivity:forceAnchorFocusivity,anchorRef:r=>this._updateAnchorElement(r),onActiveChanged:active=>this.setState({active}),"aria-describedby":shouldBeVisible?ariaContentId:undefined,children:children}),shouldBeVisible&&ReactDOM.createPortal(this._renderPopper(ariaContentId),popperHost)]})}render(){const{id}=this.props;return jsx(Id,{id:id,children:uniqueId=>this._renderTooltipAnchor(uniqueId)})}constructor(...args){super(...args),this.state={active:false,activeBubble:false};}}Tooltip.defaultProps={forceAnchorFocusivity:true,placement:"top"};
|
|
877
31
|
|
|
878
32
|
export { TooltipContent, TooltipPopper, TooltipTail, Tooltip as default };
|