@khanacademy/wonder-blocks-popover 6.0.6 → 6.0.8

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/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var _extends = require('@babel/runtime/helpers/extends');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var ReactDOM = require('react-dom');
8
8
  var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
@@ -35,760 +35,32 @@ function _interopNamespace(e) {
35
35
  return Object.freeze(n);
36
36
  }
37
37
 
38
- var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
39
38
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
40
39
  var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
41
40
  var xIcon__default = /*#__PURE__*/_interopDefaultLegacy(xIcon);
42
41
  var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
43
42
 
44
- const defaultContext = {
45
- close: undefined,
46
- placement: "top"
47
- };
48
- const PopoverContext = React__namespace.createContext(defaultContext);
49
- PopoverContext.displayName = "PopoverContext";
43
+ const defaultContext={close:undefined,placement:"top"};const PopoverContext=React__namespace.createContext(defaultContext);PopoverContext.displayName="PopoverContext";
50
44
 
51
- class PopoverAnchor extends React__namespace.Component {
52
- componentDidMount() {
53
- const anchorNode = ReactDOM__namespace.findDOMNode(this);
54
- if (anchorNode) {
55
- this.props.anchorRef(anchorNode);
56
- }
57
- }
58
- render() {
59
- const {
60
- children,
61
- id,
62
- onClick,
63
- "aria-controls": ariaControls,
64
- "aria-expanded": ariaExpanded
65
- } = this.props;
66
- const sharedProps = {
67
- id: id,
68
- "aria-controls": ariaControls,
69
- "aria-expanded": ariaExpanded
70
- };
71
- if (typeof children === "function") {
72
- const renderedChildren = children({
73
- open: onClick
74
- });
75
- return React__namespace.cloneElement(renderedChildren, sharedProps);
76
- } else {
77
- return React__namespace.cloneElement(children, _extends__default["default"]({}, children.props, sharedProps, {
78
- onClick: children.props.onClick ? e => {
79
- e.stopPropagation();
80
- children.props.onClick();
81
- onClick();
82
- } : onClick
83
- }));
84
- }
85
- }
86
- }
45
+ class PopoverAnchor extends React__namespace.Component{componentDidMount(){const anchorNode=ReactDOM__namespace.findDOMNode(this);if(anchorNode){this.props.anchorRef(anchorNode);}}render(){const{children,id,onClick,"aria-controls":ariaControls,"aria-expanded":ariaExpanded}=this.props;const sharedProps={id:id,"aria-controls":ariaControls,"aria-expanded":ariaExpanded};if(typeof children==="function"){const renderedChildren=children({open:onClick});return React__namespace.cloneElement(renderedChildren,sharedProps)}else {return React__namespace.cloneElement(children,{...children.props,...sharedProps,onClick:children.props.onClick?e=>{e.stopPropagation();children.props.onClick();onClick();}:onClick})}}}
87
46
 
88
- class PopoverDialog extends React__namespace.Component {
89
- componentDidUpdate(prevProps) {
90
- if (prevProps.placement !== this.props.placement) {
91
- this.props.onUpdate(this.props.placement);
92
- }
93
- }
94
- render() {
95
- const {
96
- placement,
97
- children,
98
- id,
99
- isReferenceHidden,
100
- updateBubbleRef,
101
- updateTailRef,
102
- tailOffset,
103
- style,
104
- showTail,
105
- "aria-describedby": ariaDescribedby,
106
- "aria-labelledby": ariaLabelledBy,
107
- "aria-label": ariaLabel
108
- } = this.props;
109
- const contentProps = children.props;
110
- const color = contentProps.color;
111
- return React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement(wonderBlocksCore.View, {
112
- "aria-label": ariaLabel,
113
- "aria-describedby": ariaDescribedby,
114
- "aria-labelledby": ariaLabelledBy,
115
- id: id,
116
- role: "dialog",
117
- ref: updateBubbleRef,
118
- "data-placement": placement,
119
- style: [isReferenceHidden && styles$2.hide, styles$2[`content-${placement}`], style]
120
- }, children, React__namespace.createElement(wonderBlocksTooltip.TooltipTail, {
121
- show: showTail,
122
- color: color,
123
- updateRef: updateTailRef,
124
- placement: placement,
125
- offset: tailOffset
126
- })));
127
- }
128
- }
129
- const styles$2 = aphrodite.StyleSheet.create({
130
- hide: {
131
- pointerEvents: "none",
132
- opacity: 0,
133
- backgroundColor: "transparent",
134
- color: "transparent"
135
- },
136
- "content-top": {
137
- flexDirection: "column"
138
- },
139
- "content-right": {
140
- flexDirection: "row-reverse"
141
- },
142
- "content-bottom": {
143
- flexDirection: "column-reverse"
144
- },
145
- "content-left": {
146
- flexDirection: "row"
147
- }
148
- });
47
+ class PopoverDialog extends React__namespace.Component{componentDidUpdate(prevProps){if(prevProps.placement!==this.props.placement){this.props.onUpdate(this.props.placement);}}render(){const{placement,children,id,isReferenceHidden,updateBubbleRef,updateTailRef,tailOffset,style,showTail,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,"aria-label":ariaLabel}=this.props;const contentProps=children.props;const color=contentProps.color;return jsxRuntime.jsx(React__namespace.Fragment,{children:jsxRuntime.jsxs(wonderBlocksCore.View,{"aria-label":ariaLabel,"aria-describedby":ariaDescribedby,"aria-labelledby":ariaLabelledBy,id:id,role:"dialog",ref:updateBubbleRef,"data-placement":placement,style:[isReferenceHidden&&styles$2.hide,styles$2[`content-${placement}`],style],children:[children,jsxRuntime.jsx(wonderBlocksTooltip.TooltipTail,{show:showTail,color:color,updateRef:updateTailRef,placement:placement,offset:tailOffset})]})})}}const styles$2=aphrodite.StyleSheet.create({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"}});
149
48
 
150
- const FOCUSABLE_ELEMENTS = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
151
- function findFocusableNodes(root) {
152
- return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS));
153
- }
154
- function isFocusable(element) {
155
- return element.matches(FOCUSABLE_ELEMENTS);
156
- }
49
+ const FOCUSABLE_ELEMENTS='button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';function findFocusableNodes(root){return Array.from(root.querySelectorAll(FOCUSABLE_ELEMENTS))}function isFocusable(element){return element.matches(FOCUSABLE_ELEMENTS)}
157
50
 
158
- class PopoverEventListener extends React__namespace.Component {
159
- constructor(...args) {
160
- super(...args);
161
- this.state = {
162
- isFirstClick: true
163
- };
164
- this._handleKeyup = e => {
165
- if (e.key === "Escape") {
166
- e.preventDefault();
167
- e.stopPropagation();
168
- this.props.onClose(true);
169
- }
170
- };
171
- this._handleClick = e => {
172
- var _this$props$contentRe;
173
- if (this.state.isFirstClick) {
174
- this.setState({
175
- isFirstClick: false
176
- });
177
- return;
178
- }
179
- const node = ReactDOM__namespace.findDOMNode((_this$props$contentRe = this.props.contentRef) == null ? void 0 : _this$props$contentRe.current);
180
- if (node && !node.contains(e.target)) {
181
- e.preventDefault();
182
- e.stopPropagation();
183
- const shouldReturnFocus = !isFocusable(e.target);
184
- this.props.onClose(shouldReturnFocus);
185
- }
186
- };
187
- }
188
- componentDidMount() {
189
- window.addEventListener("keyup", this._handleKeyup);
190
- window.addEventListener("click", this._handleClick);
191
- }
192
- componentWillUnmount() {
193
- window.removeEventListener("keyup", this._handleKeyup);
194
- window.removeEventListener("click", this._handleClick);
195
- }
196
- render() {
197
- return null;
198
- }
199
- }
51
+ class PopoverEventListener extends React__namespace.Component{componentDidMount(){window.addEventListener("keyup",this._handleKeyup);window.addEventListener("click",this._handleClick);}componentWillUnmount(){window.removeEventListener("keyup",this._handleKeyup);window.removeEventListener("click",this._handleClick);}render(){return null}constructor(...args){super(...args),this.state={isFirstClick:true},this._handleKeyup=e=>{if(e.key==="Escape"){e.preventDefault();e.stopPropagation();this.props.onClose(true);}},this._handleClick=e=>{if(this.state.isFirstClick){this.setState({isFirstClick:false});return}const node=ReactDOM__namespace.findDOMNode(this.props.contentRef?.current);if(node&&!node.contains(e.target)){e.preventDefault();e.stopPropagation();const shouldReturnFocus=!isFocusable(e.target);this.props.onClose(shouldReturnFocus);}};}}
200
52
 
201
- class InitialFocus extends React__namespace.Component {
202
- constructor(...args) {
203
- super(...args);
204
- this.setInitialFocusableElement = node => {
205
- const firstFocusableElement = this.maybeGetInitialFocusElement(node) || this.maybeGetFirstFocusableElement(node) || node;
206
- if (firstFocusableElement === node) {
207
- node.tabIndex = -1;
208
- }
209
- setTimeout(() => {
210
- firstFocusableElement.focus();
211
- }, 0);
212
- };
213
- }
214
- componentDidMount() {
215
- const node = ReactDOM__namespace.findDOMNode(this);
216
- if (!node) {
217
- return;
218
- }
219
- this.setInitialFocusableElement(node);
220
- }
221
- maybeGetInitialFocusElement(node) {
222
- const {
223
- initialFocusId
224
- } = this.props;
225
- if (!initialFocusId) {
226
- return null;
227
- }
228
- return node.querySelector(`#${initialFocusId}`);
229
- }
230
- maybeGetFirstFocusableElement(node) {
231
- const focusableElements = findFocusableNodes(node);
232
- if (!focusableElements.length) {
233
- return null;
234
- }
235
- return focusableElements[0];
236
- }
237
- render() {
238
- return this.props.children;
239
- }
240
- }
53
+ class InitialFocus extends React__namespace.Component{componentDidMount(){const node=ReactDOM__namespace.findDOMNode(this);if(!node){return}this.setInitialFocusableElement(node);}maybeGetInitialFocusElement(node){const{initialFocusId}=this.props;if(!initialFocusId){return null}return node.querySelector(`#${initialFocusId}`)}maybeGetFirstFocusableElement(node){const focusableElements=findFocusableNodes(node);if(!focusableElements.length){return null}return focusableElements[0]}render(){return this.props.children}constructor(...args){super(...args),this.setInitialFocusableElement=node=>{const firstFocusableElement=this.maybeGetInitialFocusElement(node)||this.maybeGetFirstFocusableElement(node)||node;if(firstFocusableElement===node){node.tabIndex=-1;}setTimeout(()=>{firstFocusableElement.focus();},0);};}}
241
54
 
242
- class FocusManager extends React__namespace.Component {
243
- constructor(...args) {
244
- super(...args);
245
- this.nextElementAfterPopover = void 0;
246
- this.rootNode = void 0;
247
- this.elementsThatCanBeFocusableInsidePopover = [];
248
- this.firstFocusableElementInPopover = null;
249
- this.lastFocusableElementInPopover = null;
250
- this.addEventListeners = () => {
251
- const {
252
- anchorElement
253
- } = this.props;
254
- if (anchorElement) {
255
- anchorElement.addEventListener("keydown", this.handleKeydownPreviousFocusableElement);
256
- }
257
- if (this.rootNode) {
258
- this.elementsThatCanBeFocusableInsidePopover = findFocusableNodes(this.rootNode);
259
- this.firstFocusableElementInPopover = this.elementsThatCanBeFocusableInsidePopover[0];
260
- this.lastFocusableElementInPopover = this.elementsThatCanBeFocusableInsidePopover[this.elementsThatCanBeFocusableInsidePopover.length - 1];
261
- }
262
- this.nextElementAfterPopover = this.getNextFocusableElement();
263
- if (!this.nextElementAfterPopover) {
264
- window.addEventListener("blur", () => {
265
- this.changeFocusabilityInsidePopover(true);
266
- });
267
- }
268
- if (this.firstFocusableElementInPopover) {
269
- this.firstFocusableElementInPopover.addEventListener("keydown", this.handleKeydownFirstFocusableElement);
270
- }
271
- if (this.lastFocusableElementInPopover) {
272
- this.lastFocusableElementInPopover.addEventListener("keydown", this.handleKeydownLastFocusableElement);
273
- }
274
- if (this.nextElementAfterPopover) {
275
- this.nextElementAfterPopover.addEventListener("keydown", this.handleKeydownNextFocusableElement);
276
- }
277
- };
278
- this.handleKeydownFirstFocusableElement = e => {
279
- if (e.key === "Tab" && e.shiftKey) {
280
- var _this$props$anchorEle;
281
- e.preventDefault();
282
- (_this$props$anchorEle = this.props.anchorElement) == null || _this$props$anchorEle.focus();
283
- }
284
- };
285
- this.handleKeydownLastFocusableElement = e => {
286
- if (this.nextElementAfterPopover && e.key === "Tab" && !e.shiftKey) {
287
- var _this$nextElementAfte;
288
- e.preventDefault();
289
- (_this$nextElementAfte = this.nextElementAfterPopover) == null || _this$nextElementAfte.focus();
290
- }
291
- };
292
- this.getNextFocusableElement = () => {
293
- const {
294
- anchorElement
295
- } = this.props;
296
- if (!anchorElement) {
297
- return;
298
- }
299
- const focusableElements = findFocusableNodes(document);
300
- const focusableElementsOutside = focusableElements.filter(element => {
301
- const index = this.elementsThatCanBeFocusableInsidePopover.indexOf(element);
302
- return index < 0;
303
- });
304
- const anchorIndex = focusableElementsOutside.indexOf(anchorElement);
305
- if (anchorIndex >= 0 && anchorIndex !== focusableElementsOutside.length - 1) {
306
- const nextElementIndex = anchorIndex < focusableElementsOutside.length - 1 ? anchorIndex + 1 : 0;
307
- return focusableElementsOutside[nextElementIndex];
308
- }
309
- return;
310
- };
311
- this.getComponentRootNode = node => {
312
- if (!node) {
313
- return;
314
- }
315
- const rootNode = ReactDOM__namespace.findDOMNode(node);
316
- if (!rootNode) {
317
- throw new Error("Assertion error: root node should exist after mount");
318
- }
319
- this.rootNode = rootNode;
320
- };
321
- this.handleFocusPreviousFocusableElement = () => {
322
- if (this.props.anchorElement) {
323
- this.props.anchorElement.focus();
324
- }
325
- };
326
- this.changeFocusabilityInsidePopover = (enabled = true) => {
327
- const tabIndex = enabled ? "0" : "-1";
328
- this.elementsThatCanBeFocusableInsidePopover.forEach(element => {
329
- element.setAttribute("tabIndex", tabIndex);
330
- });
331
- };
332
- this.handleFocusNextFocusableElement = () => {
333
- if (this.nextElementAfterPopover) {
334
- this.nextElementAfterPopover.focus();
335
- }
336
- };
337
- this.handleKeydownPreviousFocusableElement = e => {
338
- if (e.key === "Tab" && !e.shiftKey) {
339
- var _this$firstFocusableE;
340
- e.preventDefault();
341
- (_this$firstFocusableE = this.firstFocusableElementInPopover) == null || _this$firstFocusableE.focus();
342
- }
343
- };
344
- this.handleKeydownNextFocusableElement = e => {
345
- if (e.key === "Tab" && e.shiftKey) {
346
- var _this$lastFocusableEl;
347
- e.preventDefault();
348
- (_this$lastFocusableEl = this.lastFocusableElementInPopover) == null || _this$lastFocusableEl.focus();
349
- }
350
- };
351
- }
352
- componentDidMount() {
353
- this.addEventListeners();
354
- }
355
- componentDidUpdate() {
356
- this.removeEventListeners();
357
- this.addEventListeners();
358
- }
359
- componentWillUnmount() {
360
- this.changeFocusabilityInsidePopover(true);
361
- this.removeEventListeners();
362
- }
363
- removeEventListeners() {
364
- const {
365
- anchorElement
366
- } = this.props;
367
- if (anchorElement) {
368
- anchorElement.removeEventListener("keydown", this.handleKeydownPreviousFocusableElement);
369
- }
370
- if (!this.nextElementAfterPopover) {
371
- window.removeEventListener("blur", () => {
372
- this.changeFocusabilityInsidePopover(true);
373
- });
374
- }
375
- if (this.firstFocusableElementInPopover) {
376
- this.firstFocusableElementInPopover.removeEventListener("keydown", this.handleKeydownFirstFocusableElement);
377
- }
378
- if (this.lastFocusableElementInPopover) {
379
- this.lastFocusableElementInPopover.removeEventListener("keydown", this.handleKeydownLastFocusableElement);
380
- }
381
- if (this.nextElementAfterPopover) {
382
- this.nextElementAfterPopover.removeEventListener("keydown", this.handleKeydownNextFocusableElement);
383
- }
384
- }
385
- render() {
386
- const {
387
- children
388
- } = this.props;
389
- return (React__namespace.createElement("div", {
390
- ref: this.getComponentRootNode,
391
- onClick: () => {
392
- this.changeFocusabilityInsidePopover(true);
393
- },
394
- onFocus: () => {
395
- this.changeFocusabilityInsidePopover(true);
396
- },
397
- onBlur: () => {
398
- this.changeFocusabilityInsidePopover(false);
399
- }
400
- }, React__namespace.createElement(InitialFocus, {
401
- initialFocusId: this.props.initialFocusId
402
- }, children))
403
- );
404
- }
405
- }
55
+ class FocusManager extends React__namespace.Component{componentDidMount(){this.addEventListeners();}componentDidUpdate(){this.removeEventListeners();this.addEventListeners();}componentWillUnmount(){this.changeFocusabilityInsidePopover(true);this.removeEventListeners();}removeEventListeners(){const{anchorElement}=this.props;if(anchorElement){anchorElement.removeEventListener("keydown",this.handleKeydownPreviousFocusableElement);}if(!this.nextElementAfterPopover){window.removeEventListener("blur",()=>{this.changeFocusabilityInsidePopover(true);});}if(this.firstFocusableElementInPopover){this.firstFocusableElementInPopover.removeEventListener("keydown",this.handleKeydownFirstFocusableElement);}if(this.lastFocusableElementInPopover){this.lastFocusableElementInPopover.removeEventListener("keydown",this.handleKeydownLastFocusableElement);}if(this.nextElementAfterPopover){this.nextElementAfterPopover.removeEventListener("keydown",this.handleKeydownNextFocusableElement);}}render(){const{children}=this.props;return jsxRuntime.jsx("div",{ref:this.getComponentRootNode,onClick:()=>{this.changeFocusabilityInsidePopover(true);},onFocus:()=>{this.changeFocusabilityInsidePopover(true);},onBlur:()=>{this.changeFocusabilityInsidePopover(false);},children:jsxRuntime.jsx(InitialFocus,{initialFocusId:this.props.initialFocusId,children:children})})}constructor(...args){super(...args),this.elementsThatCanBeFocusableInsidePopover=[],this.firstFocusableElementInPopover=null,this.lastFocusableElementInPopover=null,this.addEventListeners=()=>{const{anchorElement}=this.props;if(anchorElement){anchorElement.addEventListener("keydown",this.handleKeydownPreviousFocusableElement);}if(this.rootNode){this.elementsThatCanBeFocusableInsidePopover=findFocusableNodes(this.rootNode);this.firstFocusableElementInPopover=this.elementsThatCanBeFocusableInsidePopover[0];this.lastFocusableElementInPopover=this.elementsThatCanBeFocusableInsidePopover[this.elementsThatCanBeFocusableInsidePopover.length-1];}this.nextElementAfterPopover=this.getNextFocusableElement();if(!this.nextElementAfterPopover){window.addEventListener("blur",()=>{this.changeFocusabilityInsidePopover(true);});}if(this.firstFocusableElementInPopover){this.firstFocusableElementInPopover.addEventListener("keydown",this.handleKeydownFirstFocusableElement);}if(this.lastFocusableElementInPopover){this.lastFocusableElementInPopover.addEventListener("keydown",this.handleKeydownLastFocusableElement);}if(this.nextElementAfterPopover){this.nextElementAfterPopover.addEventListener("keydown",this.handleKeydownNextFocusableElement);}},this.handleKeydownFirstFocusableElement=e=>{if(e.key==="Tab"&&e.shiftKey){e.preventDefault();this.props.anchorElement?.focus();}},this.handleKeydownLastFocusableElement=e=>{if(this.nextElementAfterPopover&&e.key==="Tab"&&!e.shiftKey){e.preventDefault();this.nextElementAfterPopover?.focus();}},this.getNextFocusableElement=()=>{const{anchorElement}=this.props;if(!anchorElement){return}const focusableElements=findFocusableNodes(document);const focusableElementsOutside=focusableElements.filter(element=>{const index=this.elementsThatCanBeFocusableInsidePopover.indexOf(element);return index<0});const anchorIndex=focusableElementsOutside.indexOf(anchorElement);if(anchorIndex>=0&&anchorIndex!==focusableElementsOutside.length-1){const nextElementIndex=anchorIndex<focusableElementsOutside.length-1?anchorIndex+1:0;return focusableElementsOutside[nextElementIndex]}return},this.getComponentRootNode=node=>{if(!node){return}const rootNode=ReactDOM__namespace.findDOMNode(node);if(!rootNode){throw new Error("Assertion error: root node should exist after mount")}this.rootNode=rootNode;},this.handleFocusPreviousFocusableElement=()=>{if(this.props.anchorElement){this.props.anchorElement.focus();}},this.changeFocusabilityInsidePopover=(enabled=true)=>{const tabIndex=enabled?"0":"-1";this.elementsThatCanBeFocusableInsidePopover.forEach(element=>{element.setAttribute("tabIndex",tabIndex);});},this.handleFocusNextFocusableElement=()=>{if(this.nextElementAfterPopover){this.nextElementAfterPopover.focus();}},this.handleKeydownPreviousFocusableElement=e=>{if(e.key==="Tab"&&!e.shiftKey){e.preventDefault();this.firstFocusableElementInPopover?.focus();}},this.handleKeydownNextFocusableElement=e=>{if(e.key==="Tab"&&e.shiftKey){e.preventDefault();this.lastFocusableElementInPopover?.focus();}};}}
406
56
 
407
- class Popover extends React__namespace.Component {
408
- constructor(...args) {
409
- super(...args);
410
- this.state = {
411
- opened: !!this.props.opened,
412
- placement: this.props.placement
413
- };
414
- this.contentRef = React__namespace.createRef();
415
- this.maybeReturnFocus = () => {
416
- const {
417
- anchorElement
418
- } = this.state;
419
- const {
420
- closedFocusId
421
- } = this.props;
422
- if (closedFocusId) {
423
- const focusElement = ReactDOM__namespace.findDOMNode(document.getElementById(closedFocusId));
424
- focusElement == null || focusElement.focus();
425
- return;
426
- }
427
- if (anchorElement) {
428
- anchorElement.focus();
429
- }
430
- };
431
- this.handleClose = (shouldReturnFocus = true) => {
432
- this.setState({
433
- opened: false
434
- }, () => {
435
- var _this$props$onClose, _this$props;
436
- (_this$props$onClose = (_this$props = this.props).onClose) == null || _this$props$onClose.call(_this$props);
437
- if (shouldReturnFocus) {
438
- this.maybeReturnFocus();
439
- }
440
- });
441
- };
442
- this.handleOpen = () => {
443
- if (this.props.dismissEnabled && this.state.opened) {
444
- this.handleClose(true);
445
- } else {
446
- this.setState({
447
- opened: true
448
- });
449
- }
450
- };
451
- this.updateRef = actualRef => {
452
- if (actualRef && this.state.anchorElement !== actualRef) {
453
- this.setState({
454
- anchorElement: actualRef
455
- });
456
- }
457
- };
458
- }
459
- static getDerivedStateFromProps(props, state) {
460
- return {
461
- opened: typeof props.opened === "boolean" ? props.opened : state.opened
462
- };
463
- }
464
- renderContent(uniqueId) {
465
- const {
466
- content
467
- } = this.props;
468
- const popoverContents = typeof content === "function" ? content({
469
- close: this.handleClose
470
- }) : content;
471
- return React__namespace.cloneElement(popoverContents, {
472
- ref: this.contentRef,
473
- uniqueId
474
- });
475
- }
476
- renderPopper(uniqueId) {
477
- const {
478
- initialFocusId,
479
- placement,
480
- showTail,
481
- portal,
482
- "aria-label": ariaLabel,
483
- "aria-describedby": ariaDescribedBy,
484
- rootBoundary,
485
- viewportPadding
486
- } = this.props;
487
- const {
488
- anchorElement
489
- } = this.state;
490
- const describedBy = ariaDescribedBy || `${uniqueId}-content`;
491
- const ariaLabelledBy = ariaLabel ? undefined : `${uniqueId}-title`;
492
- const popperContent = React__namespace.createElement(wonderBlocksTooltip.TooltipPopper, {
493
- anchorElement: anchorElement,
494
- placement: placement,
495
- rootBoundary: rootBoundary,
496
- viewportPadding: viewportPadding
497
- }, props => React__namespace.createElement(PopoverDialog, _extends__default["default"]({}, props, {
498
- "aria-label": ariaLabel,
499
- "aria-describedby": describedBy,
500
- "aria-labelledby": ariaLabelledBy,
501
- id: uniqueId,
502
- onUpdate: placement => this.setState({
503
- placement
504
- }),
505
- showTail: showTail
506
- }), this.renderContent(uniqueId)));
507
- if (portal) {
508
- return React__namespace.createElement(FocusManager, {
509
- anchorElement: anchorElement,
510
- initialFocusId: initialFocusId
511
- }, popperContent);
512
- } else {
513
- return (React__namespace.createElement(InitialFocus, {
514
- initialFocusId: initialFocusId
515
- }, popperContent)
516
- );
517
- }
518
- }
519
- getHost() {
520
- return wonderBlocksModal.maybeGetPortalMountedModalHostElement(this.state.anchorElement) || document.body;
521
- }
522
- renderPortal(uniqueId, opened) {
523
- if (!opened) {
524
- return null;
525
- }
526
- const {
527
- portal
528
- } = this.props;
529
- const popperHost = this.getHost();
530
- if (portal && popperHost) {
531
- return ReactDOM__namespace.createPortal(this.renderPopper(uniqueId), popperHost);
532
- }
533
- return this.renderPopper(uniqueId);
534
- }
535
- render() {
536
- const {
537
- children,
538
- dismissEnabled,
539
- id
540
- } = this.props;
541
- const {
542
- opened,
543
- placement
544
- } = this.state;
545
- return React__namespace.createElement(PopoverContext.Provider, {
546
- value: {
547
- close: this.handleClose,
548
- placement: placement
549
- }
550
- }, React__namespace.createElement(wonderBlocksCore.Id, {
551
- id: id
552
- }, uniqueId => React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement(PopoverAnchor, {
553
- anchorRef: this.updateRef,
554
- id: `${uniqueId}-anchor`,
555
- "aria-controls": uniqueId,
556
- "aria-expanded": opened ? "true" : "false",
557
- onClick: this.handleOpen
558
- }, children), this.renderPortal(uniqueId, opened))), dismissEnabled && opened && React__namespace.createElement(PopoverEventListener, {
559
- onClose: this.handleClose,
560
- contentRef: this.contentRef
561
- }));
562
- }
563
- }
564
- Popover.defaultProps = {
565
- placement: "top",
566
- showTail: true,
567
- portal: true,
568
- rootBoundary: "viewport"
569
- };
57
+ class Popover extends React__namespace.Component{static getDerivedStateFromProps(props,state){return {opened:typeof props.opened==="boolean"?props.opened:state.opened}}renderContent(uniqueId){const{content}=this.props;const popoverContents=typeof content==="function"?content({close:this.handleClose}):content;return React__namespace.cloneElement(popoverContents,{ref:this.contentRef,uniqueId})}renderPopper(uniqueId){const{initialFocusId,placement,showTail,portal,"aria-label":ariaLabel,"aria-describedby":ariaDescribedBy,rootBoundary,viewportPadding}=this.props;const{anchorElement}=this.state;const describedBy=ariaDescribedBy||`${uniqueId}-content`;const ariaLabelledBy=ariaLabel?undefined:`${uniqueId}-title`;const popperContent=jsxRuntime.jsx(wonderBlocksTooltip.TooltipPopper,{anchorElement:anchorElement,placement:placement,rootBoundary:rootBoundary,viewportPadding:viewportPadding,children:props=>jsxRuntime.jsx(PopoverDialog,{...props,"aria-label":ariaLabel,"aria-describedby":describedBy,"aria-labelledby":ariaLabelledBy,id:uniqueId,onUpdate:placement=>this.setState({placement}),showTail:showTail,children:this.renderContent(uniqueId)})});if(portal){return jsxRuntime.jsx(FocusManager,{anchorElement:anchorElement,initialFocusId:initialFocusId,children:popperContent})}else {return jsxRuntime.jsx(InitialFocus,{initialFocusId:initialFocusId,children:popperContent})}}getHost(){return wonderBlocksModal.maybeGetPortalMountedModalHostElement(this.state.anchorElement)||document.body}renderPortal(uniqueId,opened){if(!opened){return null}const{portal}=this.props;const popperHost=this.getHost();if(portal&&popperHost){return ReactDOM__namespace.createPortal(this.renderPopper(uniqueId),popperHost)}return this.renderPopper(uniqueId)}render(){const{children,dismissEnabled,id}=this.props;const{opened,placement}=this.state;return jsxRuntime.jsxs(PopoverContext.Provider,{value:{close:this.handleClose,placement:placement},children:[jsxRuntime.jsx(wonderBlocksCore.Id,{id:id,children:uniqueId=>jsxRuntime.jsxs(React__namespace.Fragment,{children:[jsxRuntime.jsx(PopoverAnchor,{anchorRef:this.updateRef,id:`${uniqueId}-anchor`,"aria-controls":uniqueId,"aria-expanded":opened?"true":"false",onClick:this.handleOpen,children:children}),this.renderPortal(uniqueId,opened)]})}),dismissEnabled&&opened&&jsxRuntime.jsx(PopoverEventListener,{onClose:this.handleClose,contentRef:this.contentRef})]})}constructor(...args){super(...args),this.state={opened:!!this.props.opened,placement:this.props.placement},this.contentRef=React__namespace.createRef(),this.maybeReturnFocus=()=>{const{anchorElement}=this.state;const{closedFocusId}=this.props;if(closedFocusId){const focusElement=ReactDOM__namespace.findDOMNode(document.getElementById(closedFocusId));focusElement?.focus();return}if(anchorElement){anchorElement.focus();}},this.handleClose=(shouldReturnFocus=true)=>{this.setState({opened:false},()=>{this.props.onClose?.();if(shouldReturnFocus){this.maybeReturnFocus();}});},this.handleOpen=()=>{if(this.props.dismissEnabled&&this.state.opened){this.handleClose(true);}else {this.setState({opened:true});}},this.updateRef=actualRef=>{if(actualRef&&this.state.anchorElement!==actualRef){this.setState({anchorElement:actualRef});}};}}Popover.defaultProps={placement:"top",showTail:true,portal:true,rootBoundary:"viewport"};
570
58
 
571
- class CloseButton extends React__namespace.Component {
572
- render() {
573
- const {
574
- "aria-label": ariaLabel,
575
- style,
576
- testId
577
- } = this.props;
578
- return React__namespace.createElement(PopoverContext.Consumer, null, ({
579
- close
580
- }) => {
581
- return React__namespace.createElement(IconButton__default["default"], {
582
- icon: xIcon__default["default"],
583
- "aria-label": ariaLabel,
584
- onClick: close,
585
- kind: "tertiary",
586
- actionType: "neutral",
587
- style: style,
588
- testId: testId
589
- });
590
- });
591
- }
592
- }
593
- CloseButton.defaultProps = {
594
- "aria-label": "Close Popover"
595
- };
59
+ class CloseButton extends React__namespace.Component{render(){const{"aria-label":ariaLabel,style,testId}=this.props;return jsxRuntime.jsx(PopoverContext.Consumer,{children:({close})=>{return jsxRuntime.jsx(IconButton__default["default"],{icon:xIcon__default["default"],"aria-label":ariaLabel,onClick:close,kind:"tertiary",actionType:"neutral",style:style,testId:testId})}})}}CloseButton.defaultProps={"aria-label":"Close Popover"};
596
60
 
597
- class PopoverContentCore extends React__namespace.Component {
598
- render() {
599
- const {
600
- "aria-label": ariaLabel,
601
- children,
602
- closeButtonLight,
603
- closeButtonLabel,
604
- closeButtonVisible,
605
- style,
606
- testId
607
- } = this.props;
608
- return React__namespace.createElement(wonderBlocksCore.View, {
609
- testId: testId,
610
- style: [styles$1.content, style],
611
- "aria-label": ariaLabel
612
- }, closeButtonVisible && React__namespace.createElement(CloseButton, {
613
- "aria-label": closeButtonLabel,
614
- style: [styles$1.closeButton, closeButtonLight && wonderBlocksStyles.actionStyles.inverse],
615
- testId: `${testId || "popover"}-close-btn`
616
- }), children);
617
- }
618
- }
619
- PopoverContentCore.defaultProps = {
620
- closeButtonLight: false,
621
- closeButtonVisible: false
622
- };
623
- const styles$1 = aphrodite.StyleSheet.create({
624
- content: {
625
- borderRadius: wonderBlocksTokens.border.radius.radius_040,
626
- border: `solid 1px ${wonderBlocksTokens.semanticColor.border.primary}`,
627
- backgroundColor: wonderBlocksTokens.semanticColor.surface.primary,
628
- boxShadow: `0 ${wonderBlocksTokens.spacing.xSmall_8}px ${wonderBlocksTokens.spacing.xSmall_8}px 0 ${wonderBlocksTokens.color.offBlack8}`,
629
- margin: 0,
630
- maxWidth: wonderBlocksTokens.spacing.medium_16 * 18,
631
- padding: wonderBlocksTokens.spacing.large_24,
632
- overflow: "hidden",
633
- justifyContent: "center"
634
- },
635
- closeButton: {
636
- margin: 0,
637
- position: "absolute",
638
- right: wonderBlocksTokens.spacing.xxxSmall_4,
639
- top: wonderBlocksTokens.spacing.xxxSmall_4,
640
- zIndex: 1
641
- }
642
- });
61
+ class PopoverContentCore extends React__namespace.Component{render(){const{"aria-label":ariaLabel,children,closeButtonLight,closeButtonLabel,closeButtonVisible,style,testId}=this.props;return jsxRuntime.jsxs(wonderBlocksCore.View,{testId:testId,style:[styles$1.content,style],"aria-label":ariaLabel,children:[closeButtonVisible&&jsxRuntime.jsx(CloseButton,{"aria-label":closeButtonLabel,style:[styles$1.closeButton,closeButtonLight&&wonderBlocksStyles.actionStyles.inverse],testId:`${testId||"popover"}-close-btn`}),children]})}}PopoverContentCore.defaultProps={closeButtonLight:false,closeButtonVisible:false};const styles$1=aphrodite.StyleSheet.create({content:{borderRadius:wonderBlocksTokens.border.radius.radius_040,border:`solid 1px ${wonderBlocksTokens.semanticColor.border.primary}`,backgroundColor:wonderBlocksTokens.semanticColor.surface.primary,boxShadow:`0 ${wonderBlocksTokens.spacing.xSmall_8}px ${wonderBlocksTokens.spacing.xSmall_8}px 0 ${wonderBlocksTokens.color.offBlack8}`,margin:0,maxWidth:wonderBlocksTokens.spacing.medium_16*18,padding:wonderBlocksTokens.spacing.large_24,overflow:"hidden",justifyContent:"center"},closeButton:{margin:0,position:"absolute",right:wonderBlocksTokens.spacing.xxxSmall_4,top:wonderBlocksTokens.spacing.xxxSmall_4,zIndex:1}});
643
62
 
644
- const StyledImg = wonderBlocksCore.addStyle("img");
645
- class PopoverContent extends React__namespace.Component {
646
- constructor(...args) {
647
- super(...args);
648
- this.maybeRenderImage = ({
649
- placement
650
- }) => {
651
- const {
652
- image
653
- } = this.props;
654
- if (!image) {
655
- return null;
656
- }
657
- return React__namespace.createElement(wonderBlocksCore.View, {
658
- style: [styles.image, placement === "bottom" && styles.imageToBottom]
659
- }, image);
660
- };
661
- this.maybeRenderIcon = () => {
662
- const {
663
- icon,
664
- iconAlt
665
- } = this.props;
666
- if (!icon) {
667
- return null;
668
- }
669
- return React__namespace.createElement(wonderBlocksCore.View, {
670
- style: styles.iconContainer
671
- }, typeof icon !== "string" ? icon : React__namespace.createElement(StyledImg, {
672
- src: icon,
673
- style: styles.icon,
674
- alt: iconAlt || ""
675
- }));
676
- };
677
- this.maybeRenderActions = close => {
678
- const {
679
- actions
680
- } = this.props;
681
- if (!actions) {
682
- return null;
683
- }
684
- return React__namespace.createElement(wonderBlocksCore.View, {
685
- style: styles.actions
686
- }, typeof actions === "function" ? actions({
687
- close: close
688
- }) : actions);
689
- };
690
- }
691
- componentDidMount() {
692
- const {
693
- icon,
694
- image
695
- } = this.props;
696
- if (image && icon) {
697
- throw new Error("'image' and 'icon' cannot be used at the same time. You can fix this by either removing 'image' or 'icon' from your instance.");
698
- }
699
- }
700
- validateProps({
701
- placement
702
- }) {
703
- if (this.props.image && (placement === "left" || placement === "right")) {
704
- throw new Error("'image' can only be vertically placed. You can fix this by either changing `placement` to `top` or `bottom` or removing the `image` prop inside `content`.");
705
- }
706
- }
707
- render() {
708
- const {
709
- closeButtonLabel,
710
- closeButtonVisible,
711
- content,
712
- icon,
713
- image,
714
- style,
715
- title,
716
- testId,
717
- uniqueId
718
- } = this.props;
719
- return React__namespace.createElement(PopoverContext.Consumer, null, ({
720
- close,
721
- placement
722
- }) => {
723
- this.validateProps({
724
- close,
725
- placement
726
- });
727
- return React__namespace.createElement(PopoverContentCore, {
728
- closeButtonLight: image && placement === "top",
729
- closeButtonLabel: closeButtonLabel,
730
- closeButtonVisible: closeButtonVisible,
731
- style: style,
732
- testId: testId
733
- }, React__namespace.createElement(wonderBlocksCore.View, {
734
- style: !!icon && styles.withIcon
735
- }, this.maybeRenderImage({
736
- placement
737
- }), this.maybeRenderIcon(), React__namespace.createElement(wonderBlocksCore.View, {
738
- style: styles.text
739
- }, React__namespace.createElement(wonderBlocksTypography.HeadingSmall, {
740
- id: `${uniqueId}-title`,
741
- style: styles.title
742
- }, title), React__namespace.createElement(wonderBlocksTypography.Body, {
743
- id: `${uniqueId}-content`
744
- }, content))), this.maybeRenderActions(close));
745
- });
746
- }
747
- }
748
- PopoverContent.defaultProps = {
749
- closeButtonVisible: false
750
- };
751
- const styles = aphrodite.StyleSheet.create({
752
- actions: {
753
- marginTop: wonderBlocksTokens.spacing.large_24,
754
- flexDirection: "row",
755
- alignItems: "center",
756
- justifyContent: "flex-end"
757
- },
758
- text: {
759
- justifyContent: "center"
760
- },
761
- title: {
762
- marginBottom: wonderBlocksTokens.spacing.xSmall_8
763
- },
764
- iconContainer: {
765
- alignItems: "center",
766
- justifyContent: "center",
767
- height: wonderBlocksTokens.spacing.xxxLarge_64,
768
- width: wonderBlocksTokens.spacing.xxxLarge_64,
769
- minWidth: wonderBlocksTokens.spacing.xxxLarge_64,
770
- marginRight: wonderBlocksTokens.spacing.medium_16,
771
- overflow: "hidden"
772
- },
773
- icon: {
774
- width: "100%"
775
- },
776
- withIcon: {
777
- flexDirection: "row"
778
- },
779
- image: {
780
- marginBottom: wonderBlocksTokens.spacing.large_24,
781
- marginLeft: -wonderBlocksTokens.spacing.large_24,
782
- marginRight: -wonderBlocksTokens.spacing.large_24,
783
- marginTop: -wonderBlocksTokens.spacing.large_24,
784
- width: `calc(100% + ${wonderBlocksTokens.spacing.large_24 * 2}px)`
785
- },
786
- imageToBottom: {
787
- marginBottom: -wonderBlocksTokens.spacing.large_24,
788
- marginTop: wonderBlocksTokens.spacing.large_24,
789
- order: 1
790
- }
791
- });
63
+ const StyledImg=wonderBlocksCore.addStyle("img");class PopoverContent extends React__namespace.Component{componentDidMount(){const{icon,image}=this.props;if(image&&icon){throw new Error("'image' and 'icon' cannot be used at the same time. You can fix this by either removing 'image' or 'icon' from your instance.")}}validateProps({placement}){if(this.props.image&&(placement==="left"||placement==="right")){throw new Error("'image' can only be vertically placed. You can fix this by either changing `placement` to `top` or `bottom` or removing the `image` prop inside `content`.")}}render(){const{closeButtonLabel,closeButtonVisible,content,icon,image,style,title,testId,uniqueId}=this.props;return jsxRuntime.jsx(PopoverContext.Consumer,{children:({close,placement})=>{this.validateProps({close,placement});return jsxRuntime.jsxs(PopoverContentCore,{closeButtonLight:image&&placement==="top",closeButtonLabel:closeButtonLabel,closeButtonVisible:closeButtonVisible,style:style,testId:testId,children:[jsxRuntime.jsxs(wonderBlocksCore.View,{style:!!icon&&styles.withIcon,children:[this.maybeRenderImage({placement}),this.maybeRenderIcon(),jsxRuntime.jsxs(wonderBlocksCore.View,{style:styles.text,children:[jsxRuntime.jsx(wonderBlocksTypography.HeadingSmall,{id:`${uniqueId}-title`,style:styles.title,children:title}),jsxRuntime.jsx(wonderBlocksTypography.Body,{id:`${uniqueId}-content`,children:content})]})]}),this.maybeRenderActions(close)]})}})}constructor(...args){super(...args),this.maybeRenderImage=({placement})=>{const{image}=this.props;if(!image){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:[styles.image,placement==="bottom"&&styles.imageToBottom],children:image})},this.maybeRenderIcon=()=>{const{icon,iconAlt}=this.props;if(!icon){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.iconContainer,children:typeof icon!=="string"?icon:jsxRuntime.jsx(StyledImg,{src:icon,style:styles.icon,alt:iconAlt||""})})},this.maybeRenderActions=close=>{const{actions}=this.props;if(!actions){return null}return jsxRuntime.jsx(wonderBlocksCore.View,{style:styles.actions,children:typeof actions==="function"?actions({close:close}):actions})};}}PopoverContent.defaultProps={closeButtonVisible:false};const styles=aphrodite.StyleSheet.create({actions:{marginTop:wonderBlocksTokens.spacing.large_24,flexDirection:"row",alignItems:"center",justifyContent:"flex-end"},text:{justifyContent:"center"},title:{marginBottom:wonderBlocksTokens.spacing.xSmall_8},iconContainer:{alignItems:"center",justifyContent:"center",height:wonderBlocksTokens.spacing.xxxLarge_64,width:wonderBlocksTokens.spacing.xxxLarge_64,minWidth:wonderBlocksTokens.spacing.xxxLarge_64,marginRight:wonderBlocksTokens.spacing.medium_16,overflow:"hidden"},icon:{width:"100%"},withIcon:{flexDirection:"row"},image:{marginBottom:wonderBlocksTokens.spacing.large_24,marginLeft:-wonderBlocksTokens.spacing.large_24,marginRight:-wonderBlocksTokens.spacing.large_24,marginTop:-wonderBlocksTokens.spacing.large_24,width:`calc(100% + ${wonderBlocksTokens.spacing.large_24*2}px)`},imageToBottom:{marginBottom:-wonderBlocksTokens.spacing.large_24,marginTop:wonderBlocksTokens.spacing.large_24,order:1}});
792
64
 
793
65
  exports.Popover = Popover;
794
66
  exports.PopoverContent = PopoverContent;