@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/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 = 100;
48
- const TooltipDisappearanceDelay = 75;
14
+ const TooltipAppearanceDelay=100;const TooltipDisappearanceDelay=75;
49
15
 
50
- const TRACKER = new ActiveTracker();
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&&currentTabIndex){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 };