@zohodesk/components 1.5.2 → 1.5.4-temp-1

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.
Files changed (63) hide show
  1. package/README.md +21 -0
  2. package/assets/Appearance/dark/mode/Component_DarkMode.module.css +2 -0
  3. package/assets/Appearance/light/mode/Component_LightMode.module.css +2 -0
  4. package/assets/Appearance/pureDark/mode/Component_PureDarkMode.module.css +2 -0
  5. package/es/CheckBox/CheckBox.js +21 -10
  6. package/es/CheckBox/CheckBox.module.css +21 -6
  7. package/es/CheckBox/__tests__/CheckBox.spec.js +9 -0
  8. package/es/CheckBox/__tests__/__snapshots__/CheckBox.spec.js.snap +162 -93
  9. package/es/CheckBox/props/propTypes.js +4 -1
  10. package/es/DropBox/DropBoxElement/DropBoxElement.js +1 -1
  11. package/es/DropBox/utils/isMobilePopover.js +3 -14
  12. package/es/Label/Label.js +19 -1
  13. package/es/Label/__tests__/Label.spec.js +58 -0
  14. package/es/Label/__tests__/__snapshots__/Label.spec.js.snap +66 -0
  15. package/es/Label/props/defaultProps.js +1 -0
  16. package/es/Label/props/propTypes.js +7 -1
  17. package/es/ListItem/__tests__/__snapshots__/ListItemWithCheckBox.spec.js.snap +7 -7
  18. package/es/ListItem/__tests__/__snapshots__/ListItemWithRadio.spec.js.snap +7 -7
  19. package/es/Popup/Popup.js +32 -1045
  20. package/es/Radio/Radio.js +20 -9
  21. package/es/Radio/Radio.module.css +38 -5
  22. package/es/Radio/__tests__/Radio.spec.js +10 -0
  23. package/es/Radio/__tests__/__snapshots__/Radio.spec.js.snap +154 -81
  24. package/es/Radio/props/propTypes.js +4 -1
  25. package/es/Tag/Tag.js +5 -2
  26. package/es/Tag/props/propTypes.js +2 -0
  27. package/es/utils/Common.js +1 -1
  28. package/es/v1/Popup/Popup.js +2 -2
  29. package/lib/CheckBox/CheckBox.js +23 -9
  30. package/lib/CheckBox/CheckBox.module.css +21 -6
  31. package/lib/CheckBox/__tests__/CheckBox.spec.js +21 -12
  32. package/lib/CheckBox/__tests__/__snapshots__/CheckBox.spec.js.snap +162 -93
  33. package/lib/CheckBox/props/propTypes.js +5 -1
  34. package/lib/DropBox/DropBoxElement/DropBoxElement.js +5 -5
  35. package/lib/DropBox/utils/isMobilePopover.js +4 -14
  36. package/lib/Label/Label.js +21 -1
  37. package/lib/Label/__tests__/Label.spec.js +58 -0
  38. package/lib/Label/__tests__/__snapshots__/Label.spec.js.snap +66 -0
  39. package/lib/Label/props/defaultProps.js +1 -0
  40. package/lib/Label/props/propTypes.js +8 -1
  41. package/lib/ListItem/__tests__/__snapshots__/ListItemWithCheckBox.spec.js.snap +7 -7
  42. package/lib/ListItem/__tests__/__snapshots__/ListItemWithRadio.spec.js.snap +7 -7
  43. package/lib/Popup/Popup.js +36 -1149
  44. package/lib/Radio/Radio.js +22 -8
  45. package/lib/Radio/Radio.module.css +38 -5
  46. package/lib/Radio/__tests__/Radio.spec.js +10 -0
  47. package/lib/Radio/__tests__/__snapshots__/Radio.spec.js.snap +154 -81
  48. package/lib/Radio/props/propTypes.js +5 -1
  49. package/lib/Tag/Tag.js +6 -2
  50. package/lib/Tag/props/propTypes.js +2 -0
  51. package/lib/utils/Common.js +1 -1
  52. package/lib/v1/Popup/Popup.js +4 -4
  53. package/package.json +9 -9
  54. package/es/DropBox/DropBoxPositionMapping.js +0 -142
  55. package/es/Popup/PositionMapping.js +0 -72
  56. package/es/Popup/Registry.js +0 -36
  57. package/es/Popup/intersectionObserver.js +0 -49
  58. package/es/Popup/viewPort.js +0 -373
  59. package/lib/DropBox/DropBoxPositionMapping.js +0 -149
  60. package/lib/Popup/PositionMapping.js +0 -81
  61. package/lib/Popup/Registry.js +0 -46
  62. package/lib/Popup/intersectionObserver.js +0 -72
  63. package/lib/Popup/viewPort.js +0 -367
package/es/Popup/Popup.js CHANGED
@@ -1,1053 +1,40 @@
1
- /**** Libraries ****/
2
1
  import React from 'react';
3
- import hoistStatics from 'hoist-non-react-statics';
4
- import { PopupPropTypes, ContextTypes } from "./props/propTypes";
5
- /**** Methods ****/
6
-
7
- import { debounce, isDescendant, isTextSelected, cancelBubblingEffect, DUMMY_OBJECT } from "../utils/Common.js";
8
- import viewPort from "./viewPort";
9
- import { absolutePositionMapping, rtlAbsolutePositionMapping, rtlFixedPositionMapping } from "./PositionMapping.js";
10
- import ResizeObserver from '@zohodesk/virtualizer/lib/commons/ResizeObserver.js';
11
- import { addIntersectionObserver, removeIntersectionObserver } from "./intersectionObserver";
12
- import { positionMapping } from "../DropBox/DropBoxPositionMapping.js";
13
- import isMobilePopover from "../DropBox/utils/isMobilePopover.js";
14
- import selectn from 'selectn';
15
- import Registry from "./Registry.js";
16
-
17
- global.closeGroupPopups = function (groupName) {
18
- const groupPopups = Registry.popups[groupName] || [];
19
- groupPopups.forEach(popup => {
20
- popup.state.isPopupOpen && popup.setState({
21
- isPopupOpen: false,
22
- isPopupReady: false
23
- });
24
- });
25
- };
26
-
27
- const defaultState = {
28
- position: 'bottomCenter',
29
- height: '0px',
30
- positions: {},
31
- //{bottomCenter: true, bottomLeft: false, ...}
32
- positionsOffset: {},
33
- //{bottomCenter: {left: ‘’,top: ‘’ }, .....}
34
- targetOffset: {},
35
- //{height: ‘’, width: ‘’,}
36
- popupOffset: {},
37
- //{height: ‘’, width: ‘’,}
38
- isAbsolutePositioningNeeded: true
39
- };
40
- const SCROLL_BLOCK_EVENTS = Object.freeze([{
41
- name: 'wheel',
42
- handlerName: 'handleBlockScroll',
43
- options: {
44
- capture: true,
45
- passive: false
46
- }
47
- }, {
48
- name: 'touchmove',
49
- handlerName: 'handleBlockScroll',
50
- options: {
51
- capture: true,
52
- passive: false
53
- }
54
- }, {
55
- name: 'scroll',
56
- handlerName: 'handlePositionChange',
57
- options: {
58
- capture: true,
59
- passive: false
60
- }
61
- }, {
62
- name: 'keydown',
63
- handlerName: 'preventKeyboardScroll',
64
- options: {
65
- capture: true,
66
- passive: false
67
- }
68
- }]);
69
- const IFRAME_SCROLL_BLOCK_EVENTS = Object.freeze(SCROLL_BLOCK_EVENTS.filter(event => event.name !== 'keydown'));
70
- const CLICK_EVENTS = Object.freeze([{
71
- name: 'click',
72
- handlerName: 'documentClickHandler',
73
- options: {
74
- capture: false,
75
- passive: false
76
- }
77
- }, {
78
- name: 'click',
79
- handlerName: 'documentClickHandler1',
80
- options: {
81
- capture: true,
82
- passive: false
83
- }
84
- }]);
85
- /* eslint-disable react/no-deprecated */
86
-
87
- /* eslint-disable react/prop-types */
2
+ import DotkitPopup from '@zohodesk/dotkit/es/react/components/Popup/Popup';
3
+ import { getLibraryConfig } from "../Provider/Config.js";
4
+ import { DUMMY_ARRAY, DUMMY_OBJECT } from "./../utils/Common.js";
5
+ import Registry from '@zohodesk/dotkit/es/react/components/Popup/Registry.js';
6
+ global.closeGroupPopups = Registry.closeAllPopupsInGroup;
88
7
 
89
8
  const Popup = function (Component) {
90
9
  let group = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'global';
91
10
  let needResizeHandling = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
92
- let {
93
- isAbsolutePositioningNeeded: isAbsolutePopup = true,
94
- isArrow: needPopupArrow = false,
95
- customOrder: customPositionOrder = [],
96
- scrollDebounceTime: popupScrollDebounceTime = 0,
97
- closeOnScroll: closeOnScrollPopup = false,
98
- isOutsideScrollBlocked: isOutsideScrollBlock = false
99
- } = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
100
-
101
- class Popup extends React.Component {
102
- constructor(props) {
103
- super(props);
104
- this.state = {
105
- isPopupOpen: props.isPopupOpen || false,
106
- position: 'bottomCenter',
107
- height: '0px',
108
- isPopupReady: props.isPopupOpen || false,
109
- positions: {},
110
- //{bottomCenter: true, bottomLeft: false, ...}
111
- positionsOffset: {},
112
- //{bottomCenter: {left: ‘’,top: ‘’ }, .....}
113
- targetOffset: {},
114
- //{height: ‘’, width: ‘’,}
115
- popupOffset: {},
116
- //{height: ‘’, width: ‘’,}
117
- isAbsolutePositioningNeeded: true,
118
- isMobile: false
119
- };
120
- this.togglePopup = this.togglePopup.bind(this);
121
- this.documentClickHandler = this.documentClickHandler.bind(this);
122
- this.documentClickHandler1 = this.documentClickHandler1.bind(this);
123
- this.removeClose = this.removeClose.bind(this);
124
- this.documentKeyupHandler = this.documentKeyupHandler.bind(this);
125
- this.openPopupOnly = this.openPopupOnly.bind(this);
126
- this.closePopupOnly = this.closePopupOnly.bind(this);
127
- this.getTargetRef = this.getTargetRef.bind(this);
128
- this.getContainerRef = this.getContainerRef.bind(this);
129
- this.handlePopupPosition = this.handlePopupPosition.bind(this);
130
- this.handleResize = debounce(this.handleResize.bind(this), 300);
131
- this.handlePopupResize = this.handlePopupResize.bind(this);
132
- this.getIsAbsolutePopup = this.getIsAbsolutePopup.bind(this);
133
- this.getIsOutsideScrollBlocked = this.getIsOutsideScrollBlocked.bind(this);
134
- this.getNeedArrow = this.getNeedArrow.bind(this);
135
- this.getCustomPositionOrder = this.getCustomPositionOrder.bind(this);
136
- this.handleOpenPopupPositionChange = this.handleOpenPopupPositionChange.bind(this);
137
- this.getScrollDebounceTime = this.getScrollDebounceTime.bind(this);
138
- this.getCloseOnScrollPopup = this.getCloseOnScrollPopup.bind(this);
139
- this.handleCloseLastOpenedGroup = this.handleCloseLastOpenedGroup.bind(this);
140
- this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
141
- this.handleDocumentFocus = this.handleDocumentFocus.bind(this);
142
- this.handleGetNeedPrevent = this.handleGetNeedPrevent.bind(this);
143
- this.handleBlockScroll = this.handleBlockScroll.bind(this);
144
- this.handlePositionChange = this.handlePositionChange.bind(this);
145
- this.preventKeyboardScroll = this.preventKeyboardScroll.bind(this);
146
- this.updateListeners = this.updateListeners.bind(this);
147
- this.addScrollBlockListeners = this.addScrollBlockListeners.bind(this);
148
- this.removeScrollBlockListeners = this.removeScrollBlockListeners.bind(this);
149
- this.addScrollToUpdateListeners = this.addScrollToUpdateListeners.bind(this);
150
- this.removeScrollToUpdateListeners = this.removeScrollToUpdateListeners.bind(this);
151
- this.handleAddingScrollBlock = this.handleAddingScrollBlock.bind(this);
152
- this.handleRemovingScrollBlock = this.handleRemovingScrollBlock.bind(this);
153
- this.handleIntersectionObserver = this.handleIntersectionObserver.bind(this);
154
- this.updateVisibilityOnIntersection = this.updateVisibilityOnIntersection.bind(this);
155
- this.handleAddingScrollToUpdatePosition = this.handleAddingScrollToUpdatePosition.bind(this);
156
- this.handleRemovingScrollToUpdatePosition = this.handleRemovingScrollToUpdatePosition.bind(this);
157
- this.setContainerDynamicPositioning = this.setContainerDynamicPositioning.bind(this);
158
- this.updatePopupState = this.updatePopupState.bind(this);
159
- this.handleScrollAndBlockEvents = this.handleScrollAndBlockEvents.bind(this);
160
- this.handleIframeEventListeners = this.handleIframeEventListeners.bind(this);
161
- this.handleDropElementStyleUpdate = this.handleDropElementStyleUpdate.bind(this);
162
- this.setPosition = this.setPosition.bind(this);
163
- this.positionRef = /*#__PURE__*/React.createRef();
164
- this.rootElement = Registry.getRootElement();
165
- this.popupObserver = new ResizeObserver(this.handlePopupResize);
166
- this.cancelRaf = this.cancelRaf.bind(this);
167
- this.cancelPendingAnimationFrames = this.cancelPendingAnimationFrames.bind(this);
168
- this.setPositionRafId = null;
169
- this.resizePositionRafId = null; //dropBoxSize
170
-
171
- this.size = null;
172
- this.isTargetElementVisible = false;
173
- this.isAbsolutePopup = isAbsolutePopup;
174
- this.needPopupArrow = needPopupArrow;
175
- this.customPositionOrder = customPositionOrder;
176
- this.scrollDebounceTime = popupScrollDebounceTime;
177
- this.closeOnScroll = closeOnScrollPopup;
178
- this.isOutsideScrollBlock = isOutsideScrollBlock;
179
- const scrollDebounceTime = this.getScrollDebounceTime(this);
180
- this.updatePositionOnScroll = scrollDebounceTime > 0 ? debounce(this.updatePositionOnScroll.bind(this), scrollDebounceTime) : this.updatePositionOnScroll.bind(this); // this.handleScroll = debounce(this.handleScroll.bind(this), scrollDebounceTime);
181
- }
182
-
183
- componentDidMount() {
184
- const group = this.getGroup();
185
- const groupPopups = Registry.popups[group] || [];
186
- groupPopups.push(this);
187
- Registry.popups[group] = groupPopups;
188
-
189
- if (Object.keys(Registry.popups).length === 1 && groupPopups.length === 1 && Registry.listenerPopupRef === undefined) {
190
- Registry.listenerPopupRef = this;
191
- Registry.listenerPopupRef.updateListeners(true, CLICK_EVENTS, document);
192
- document.addEventListener('keyup', Registry.listenerPopupRef.documentKeyupHandler, false); // document.addEventListener('scroll', Registry.listenerPopupRef.handleScroll, true);
193
-
194
- window.addEventListener('resize', Registry.listenerPopupRef.handleResize);
195
- document.addEventListener('mousedown', Registry.listenerPopupRef.handleDocumentMouseDown, true);
196
- document.addEventListener('focus', Registry.listenerPopupRef.handleDocumentFocus, true);
197
- }
198
- }
199
-
200
- UNSAFE_componentWillReceiveProps(nextProps) {
201
- const {
202
- isPopupOpen
203
- } = this.state;
204
-
205
- if (typeof nextProps.isPopupOpen !== 'undefined' && nextProps.isPopupOpen !== isPopupOpen) {
206
- this.setState({
207
- isPopupOpen: nextProps.isPopupOpen,
208
- isPopupReady: nextProps.isPopupOpen
209
- });
210
- }
211
- }
212
-
213
- handleScrollAndBlockEvents(shouldAdd) {
214
- if (shouldAdd) {
215
- this.handleAddingScrollBlock();
216
- this.handleAddingScrollToUpdatePosition();
217
- } else {
218
- this.handleRemovingScrollBlock();
219
- this.handleRemovingScrollToUpdatePosition();
220
- }
221
- }
222
-
223
- handleIframeEventListeners(shouldAdd, eventList) {
224
- this.rootElement.querySelectorAll('iframe').forEach(frame => {
225
- const frameDocument = frame.contentDocument;
226
-
227
- if (frameDocument) {
228
- this.updateListeners(shouldAdd, eventList, frameDocument);
229
- }
230
- });
231
- }
232
-
233
- componentDidUpdate(prevProps, prevState) {
234
- const {
235
- isPopupReady,
236
- isMobile
237
- } = this.state;
238
- const {
239
- isPopupReady: oldStateOpen = false,
240
- isMobile: oldIsMobileState
241
- } = prevState || {};
242
- const {
243
- dropElement
244
- } = this;
245
- const {
246
- needResizeHandling: propResizeHandling
247
- } = this.props;
248
-
249
- if (oldStateOpen !== isPopupReady) {
250
- if (isPopupReady && dropElement && (propResizeHandling !== undefined ? propResizeHandling : needResizeHandling)) {
251
- this.popupObserver.replaceObservationElement(dropElement);
252
- } else if (!isPopupReady) {
253
- this.size = null;
254
- this.popupObserver.disconnect();
255
- }
256
- }
257
-
258
- if (oldStateOpen !== isPopupReady && !isMobile || oldIsMobileState !== isMobile) {
259
- const shouldAdd = isPopupReady && !isMobile;
260
- this.handleScrollAndBlockEvents(shouldAdd);
261
- this.handleIframeEventListeners(shouldAdd, CLICK_EVENTS);
262
- }
263
- }
264
-
265
- cancelRaf(refName) {
266
- const id = this[refName];
267
-
268
- if (id) {
269
- cancelAnimationFrame(id);
270
- this[refName] = null;
271
- }
272
- }
273
-
274
- cancelPendingAnimationFrames() {
275
- this.cancelRaf('setPositionRafId');
276
- this.cancelRaf('resizePositionRafId');
277
- }
278
-
279
- componentWillUnmount() {
280
- const group = this.getGroup();
281
- Registry.popups = Object.keys(Registry.popups).reduce((res, groupName) => {
282
- if (groupName === group) {
283
- const groupPopups = Registry.popups[group];
284
- const newGroupPopups = groupPopups.filter(popup => popup !== this);
285
- newGroupPopups.length === 0 && Registry.lastOpenedGroup.indexOf(group) >= 0 && Registry.lastOpenedGroup.splice(Registry.lastOpenedGroup.indexOf(group), 1);
286
- res[group] = newGroupPopups;
287
- }
288
-
289
- return res;
290
- }, Registry.popups);
291
- this.handleRemovingScrollBlock();
292
- this.handleRemovingScrollToUpdatePosition();
293
- this.handleIframeEventListeners(false, CLICK_EVENTS);
294
- let noPopups = true;
295
-
296
- for (const i in Registry.popups) {
297
- if (Registry.popups[i].length >= 1) {
298
- noPopups = false;
299
- break;
300
- }
301
- }
302
-
303
- if (this.popupObserver) {
304
- this.popupObserver.disconnect();
305
- }
306
-
307
- if (noPopups && Registry.listenerPopupRef !== undefined) {
308
- Registry.listenerPopupRef.updateListeners(false, CLICK_EVENTS, document);
309
- document.removeEventListener('keyup', Registry.listenerPopupRef.documentKeyupHandler); // document.removeEventListener('scroll', Registry.listenerPopupRef.handleScroll);
310
-
311
- window.removeEventListener('resize', Registry.listenerPopupRef.handleResize);
312
- document.removeEventListener('mousedown', Registry.listenerPopupRef.handleDocumentMouseDown, true);
313
- document.removeEventListener('focus', Registry.listenerPopupRef.handleDocumentFocus, true);
314
- Registry.listenerPopupRef = undefined;
315
- }
316
-
317
- this.cancelPendingAnimationFrames();
318
- }
319
-
320
- handleAddingScrollBlock() {
321
- const isAbsolutePositioningNeeded = this.getIsAbsolutePopup(this);
322
- const isOutsideScrollBlocked = this.getIsOutsideScrollBlocked(this);
323
-
324
- if (isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
325
- addIntersectionObserver(this.placeHolderElement, this.handleIntersectionObserver);
326
- this.addScrollBlockListeners();
327
- }
328
- }
329
-
330
- handleRemovingScrollBlock() {
331
- const isAbsolutePositioningNeeded = this.getIsAbsolutePopup(this);
332
- const isOutsideScrollBlocked = this.getIsOutsideScrollBlocked(this);
333
-
334
- if (isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
335
- removeIntersectionObserver(this.placeHolderElement, this.handleIntersectionObserver);
336
- this.removeScrollBlockListeners();
337
- }
338
- }
339
-
340
- handleAddingScrollToUpdatePosition() {
341
- const isAbsolutePositioningNeeded = this.getIsAbsolutePopup(this);
342
- const isOutsideScrollBlocked = this.getIsOutsideScrollBlocked(this);
343
-
344
- if (!isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
345
- addIntersectionObserver(this.placeHolderElement, this.updateVisibilityOnIntersection);
346
- const shouldAddScrollToUpdatePositionListeners = Registry.getOpenedScrollableFixedPopups().length === 1 && Registry.scrollableListenerPopupRef === undefined;
347
-
348
- if (shouldAddScrollToUpdatePositionListeners) {
349
- Registry.scrollableListenerPopupRef = this;
350
- Registry.scrollableListenerPopupRef.addScrollToUpdateListeners();
351
- }
352
- }
353
- }
354
-
355
- handleRemovingScrollToUpdatePosition() {
356
- const isAbsolutePositioningNeeded = this.getIsAbsolutePopup(this);
357
- const isOutsideScrollBlocked = this.getIsOutsideScrollBlocked(this);
358
-
359
- if (!isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
360
- removeIntersectionObserver(this.placeHolderElement, this.updateVisibilityOnIntersection);
361
- const shouldRemoveScrollToUpdatePositionListeners = Registry.getOpenedScrollableFixedPopups().length === 0 && Registry.scrollableListenerPopupRef !== undefined;
362
-
363
- if (shouldRemoveScrollToUpdatePositionListeners) {
364
- Registry.scrollableListenerPopupRef.removeScrollToUpdateListeners();
365
- Registry.scrollableListenerPopupRef = undefined;
366
- }
367
- }
368
- }
369
-
370
- handleDropElementStyleUpdate(_ref) {
371
- let {
372
- top = '',
373
- left = '',
374
- bottom = '',
375
- right = ''
376
- } = _ref;
377
- const {
378
- dropElement
379
- } = this;
380
- Object.assign(dropElement.style, {
381
- top: top ? `${top}px` : '',
382
- left: left ? `${left}px` : '',
383
- right: right ? `${right}px` : '',
384
- bottom: bottom ? `${bottom}px` : ''
385
- });
386
- }
387
-
388
- setContainerDynamicPositioning(betterPosition, needArrow) {
389
- const {
390
- dropElement
391
- } = this;
392
- const {
393
- isMobile
394
- } = this.state;
395
-
396
- if (dropElement) {
397
- const {
398
- view,
399
- viewsOffset
400
- } = betterPosition || DUMMY_OBJECT;
401
- const styleToApply = selectn(`${view}`, viewsOffset);
402
-
403
- if (isMobile) {
404
- this.handleDropElementStyleUpdate({
405
- top: '',
406
- left: '',
407
- right: '',
408
- bottom: ''
409
- });
410
- } else {
411
- this.handleDropElementStyleUpdate(styleToApply);
412
-
413
- if (this.positionRef.current !== view) {
414
- dropElement.setAttribute('data-position', `${view}`);
415
- dropElement.setAttribute('data-box-direction', selectn(`${view}.direction`, positionMapping));
416
-
417
- if (needArrow) {
418
- dropElement.setAttribute('data-arrow-position', selectn(`${view}.arrowPosition`, positionMapping));
419
- }
420
-
421
- this.positionRef.current = view;
422
- }
423
- }
424
- }
425
- }
426
-
427
- updatePositionOnScroll(e) {
428
- const scrollablePopups = Registry.getOpenedScrollableFixedPopups(); // Check if the event target is outside all dropElements
429
-
430
- scrollablePopups.forEach(_ref2 => {
431
- let {
432
- placeHolderElement,
433
- defaultPosition,
434
- isTargetElementVisible,
435
- handlePopupPosition
436
- } = _ref2;
437
-
438
- if (e.target.contains(placeHolderElement) && isTargetElementVisible) {
439
- handlePopupPosition(defaultPosition, true);
440
- }
441
- });
442
- }
443
-
444
- updateListeners() {
445
- let add = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
446
- let eventList = arguments.length > 1 ? arguments[1] : undefined;
447
- let element = arguments.length > 2 ? arguments[2] : undefined;
448
- const method = add ? 'addEventListener' : 'removeEventListener';
449
- eventList.forEach(_ref3 => {
450
- let {
451
- name,
452
- handlerName,
453
- options
454
- } = _ref3;
455
- const handler = this[handlerName];
456
-
457
- if (handler) {
458
- element[method](name, handler, options);
459
- }
460
- });
461
- }
462
-
463
- addScrollBlockListeners() {
464
- // Only add scroll block listeners if at least one open popup needs outside scroll blocked
465
- const shouldAddScrollBlockListeners = Registry.getOpenedScrollBlockedFixedPopups().length === 1 && Registry.scrollBlockedListenerPopupRef === undefined;
466
-
467
- if (shouldAddScrollBlockListeners) {
468
- Registry.scrollBlockedListenerPopupRef = this; // Main document
469
-
470
- Registry.scrollBlockedListenerPopupRef.updateListeners(true, SCROLL_BLOCK_EVENTS, document); // Attach event listeners to all iframes within rootElement
471
-
472
- Registry.scrollBlockedListenerPopupRef.handleIframeEventListeners(true, IFRAME_SCROLL_BLOCK_EVENTS);
473
- }
474
- }
475
-
476
- removeScrollBlockListeners() {
477
- // Only remove scroll block listeners if at least one open popup needs outside scroll blocked
478
- const shouldRemoveScrollBlockListeners = Registry.getOpenedScrollBlockedFixedPopups().length === 0 && Registry.scrollBlockedListenerPopupRef !== undefined;
479
-
480
- if (shouldRemoveScrollBlockListeners) {
481
- Registry.scrollBlockedListenerPopupRef.updateListeners(false, SCROLL_BLOCK_EVENTS, document);
482
- Registry.scrollBlockedListenerPopupRef.handleIframeEventListeners(false, IFRAME_SCROLL_BLOCK_EVENTS);
483
- Registry.scrollBlockedListenerPopupRef = undefined;
484
- }
485
- }
486
-
487
- addScrollToUpdateListeners() {
488
- document.addEventListener('scroll', this.updatePositionOnScroll, {
489
- capture: true,
490
- passive: false
491
- });
492
- }
493
-
494
- removeScrollToUpdateListeners() {
495
- document.removeEventListener('scroll', this.updatePositionOnScroll, {
496
- capture: true,
497
- passive: false
498
- });
499
- }
500
-
501
- handleBlockScroll(event) {
502
- const scrollBlockedPopups = Registry.getOpenedScrollBlockedFixedPopups(); // Check if the event target is outside all dropElements
503
-
504
- const isOutsideAllDropElements = scrollBlockedPopups.every(_ref4 => {
505
- let {
506
- dropElement
507
- } = _ref4;
508
- return dropElement && dropElement !== event.target && !dropElement.contains(event.target);
509
- });
510
-
511
- if (isOutsideAllDropElements) {
512
- event.preventDefault();
513
- }
514
- }
515
-
516
- handlePositionChange(event) {
517
- const scrollBlockedPopups = Registry.getOpenedScrollBlockedFixedPopups();
518
- scrollBlockedPopups.forEach(_ref5 => {
519
- let {
520
- placeHolderElement,
521
- dropElement,
522
- handlePopupPosition,
523
- state
524
- } = _ref5;
525
-
526
- if (dropElement && dropElement !== event.target && !dropElement.contains(event.target) && placeHolderElement && placeHolderElement !== event.target && !placeHolderElement.contains(event.target) && event.target.contains(placeHolderElement)) {
527
- handlePopupPosition(state.position, true);
528
- }
529
- });
530
- }
531
-
532
- preventKeyboardScroll(event) {
533
- const keys = [32, 37, 38, 39, 40]; // Space, Arrow keys
534
-
535
- const scrollBlockedPopups = Registry.getOpenedScrollBlockedFixedPopups(); // Check if the event target is outside all dropElements
536
-
537
- const isOutsideAllDropElements = scrollBlockedPopups.every(_ref6 => {
538
- let {
539
- dropElement
540
- } = _ref6;
541
- return dropElement && dropElement !== event.target && !dropElement.contains(event.target) && keys.includes(event.keyCode);
542
- });
543
-
544
- if (isOutsideAllDropElements) {
545
- event.preventDefault();
546
- }
547
- }
548
-
549
- handleIntersectionObserver(entry) {
550
- if (entry.intersectionRatio === 0 && entry.isIntersecting === false) {
551
- this.closePopupOnly();
552
- }
553
- }
554
-
555
- updateVisibilityOnIntersection(entry) {
556
- const {
557
- dropElement
558
- } = this;
559
- if (!dropElement) return;
560
-
561
- if (entry.isIntersecting === true) {
562
- this.isTargetElementVisible = true;
563
- dropElement.setAttribute('data-visible', 'visible');
564
- } else if (entry.intersectionRatio === 0 && entry.isIntersecting === false) {
565
- this.isTargetElementVisible = false;
566
- dropElement.setAttribute('data-visible', 'hidden');
567
- }
568
- }
569
-
570
- getGroup() {
571
- const {
572
- popupGroup
573
- } = this.props;
574
- return popupGroup || group;
575
- }
576
-
577
- getNeedArrow(popup) {
578
- const {
579
- isArrow
580
- } = popup.props;
581
- const {
582
- needPopupArrow
583
- } = popup;
584
- return isArrow !== undefined ? isArrow : needPopupArrow;
585
- }
586
-
587
- getScrollDebounceTime(popup) {
588
- const {
589
- scrollDebounceTime
590
- } = popup.props;
591
- const {
592
- scrollDebounceTime: popupScrollDebounceTime
593
- } = popup;
594
- return scrollDebounceTime !== undefined ? scrollDebounceTime : popupScrollDebounceTime;
595
- }
596
-
597
- getCloseOnScrollPopup(popup) {
598
- const {
599
- closeOnScroll
600
- } = popup.props;
601
- const {
602
- closeOnScroll: closeOnScrollPopup
603
- } = popup;
604
- return closeOnScroll !== undefined ? closeOnScroll : closeOnScrollPopup;
605
- }
606
-
607
- getIsAbsolutePopup(popup) {
608
- const {
609
- isAbsolutePositioningNeeded
610
- } = popup.props;
611
- const {
612
- isAbsolutePopup
613
- } = popup;
614
- return isAbsolutePositioningNeeded !== undefined ? isAbsolutePositioningNeeded : isAbsolutePopup;
615
- }
616
-
617
- getIsOutsideScrollBlocked(popup) {
618
- const {
619
- isOutsideScrollBlocked
620
- } = popup.props;
621
- const {
622
- isOutsideScrollBlock
623
- } = popup;
624
- return isOutsideScrollBlocked !== undefined ? isOutsideScrollBlocked : isOutsideScrollBlock;
625
- }
626
-
627
- getCustomPositionOrder(popup) {
628
- const {
629
- customOrder = []
630
- } = popup.props;
631
- const {
632
- customPositionOrder
633
- } = popup;
634
- return customOrder.length !== 0 ? customOrder : customPositionOrder;
635
- }
636
-
637
- togglePopup(e, defaultPosition) {
638
- const group = this.getGroup();
639
- this.removeClose(e);
640
- const {
641
- isPopupOpen
642
- } = this.state;
643
- const groupPopups = Registry.popups[group] || [];
644
- Registry.lastOpenedGroup = !isPopupOpen && Registry.lastOpenedGroup.indexOf(group) === -1 ? [group, ...Registry.lastOpenedGroup] : Registry.lastOpenedGroup;
645
- isPopupOpen && Registry.lastOpenedGroup.splice(0, 1);
646
- groupPopups.forEach(popup => {
647
- if (popup !== this && popup.state.isPopupOpen) {
648
- popup.setState({
649
- isPopupOpen: false,
650
- isPopupReady: false
651
- });
652
- }
653
- });
654
-
655
- if (isPopupOpen) {
656
- this.setState({
657
- isPopupOpen: false,
658
- isPopupReady: false
659
- });
660
- } else {
661
- this.handlePopupPosition(defaultPosition);
662
- }
663
- }
664
-
665
- openPopupOnly(e, defaultPosition) {
666
- const group = this.getGroup();
667
- this.removeClose(e);
668
- Registry.lastOpenedGroup = Registry.lastOpenedGroup.indexOf(group) === -1 ? [group, ...Registry.lastOpenedGroup] : Registry.lastOpenedGroup;
669
- this.handlePopupPosition(defaultPosition);
670
- }
671
-
672
- closePopupOnly(e) {
673
- this.removeClose(e);
674
- const {
675
- isPopupOpen
676
- } = this.state;
677
-
678
- if (isPopupOpen) {
679
- Registry.lastOpenedGroup.splice(0, 1);
680
- this.setState({
681
- isPopupOpen: false,
682
- isPopupReady: false
683
- });
684
- }
685
- }
686
-
687
- handleCloseLastOpenedGroup() {
688
- const groupPopups = Registry.lastOpenedGroup.length ? Registry.popups[Registry.lastOpenedGroup[0]] || [] : [];
689
- Registry.lastOpenedGroup.splice(0, 1);
690
- groupPopups.forEach(popup => {
691
- popup.state.isPopupOpen && popup.setState({
692
- isPopupOpen: false,
693
- isPopupReady: false
694
- });
695
- });
696
- }
697
-
698
- handleDocumentMouseDown(e) {
699
- const needPrevent = this.handleGetNeedPrevent(e);
700
-
701
- if (needPrevent) {
702
- this.removeClose(e);
703
- }
704
- }
705
-
706
- handleDocumentFocus(e) {
707
- const needPrevent = this.handleGetNeedPrevent(e);
708
-
709
- if (needPrevent) {
710
- this.removeClose(e);
711
- }
712
- }
713
-
714
- handleGetNeedPrevent(e) {
715
- let needPrevent = false;
716
-
717
- if (Registry.lastOpenedGroup.length > 1) {
718
- const {
719
- target
720
- } = e;
721
- const groupPopups = Registry.lastOpenedGroup.length ? Registry.popups[Registry.lastOpenedGroup[0]] : [];
722
- let openedPopup = null; // eslint-disable-next-line guard-for-in
723
-
724
- for (const i in groupPopups) {
725
- const {
726
- isPopupOpen
727
- } = groupPopups[i].state;
728
-
729
- if (isPopupOpen) {
730
- openedPopup = groupPopups[i];
731
- break;
732
- }
733
- }
734
-
735
- if (openedPopup) {
736
- const {
737
- dropElement,
738
- placeHolderElement
739
- } = openedPopup;
740
- const isDropBoxChild = isDescendant(dropElement, target);
741
- const isTargetChild = isDescendant(placeHolderElement, target); // const isPopupMassUpdateChild = isDescendant(
742
- // massUpdateParent,
743
- // dropElement
744
- // );
745
-
746
- if (!isDropBoxChild && !isTargetChild // && isPopupMassUpdateChild
747
- ) {
748
- needPrevent = true;
749
- }
750
- }
751
- }
752
-
753
- return needPrevent;
754
- }
755
-
756
- documentClickHandler1(e) {
757
- const needPrevent = this.handleGetNeedPrevent(e);
758
-
759
- if (needPrevent) {
760
- this.removeClose(e);
761
- this.handleCloseLastOpenedGroup();
762
- }
763
- }
764
-
765
- documentClickHandler() {
766
- try {
767
- Object.keys(Registry.popups).forEach(groupName => {
768
- const groupPopups = Registry.popups[groupName] || [];
769
- groupPopups.forEach(popup => {
770
- popup.state.isPopupOpen && (!popup.props.checkBeforeClose || popup.props.checkBeforeClose && popup.props.checkBeforeClose()) && !isTextSelected() && popup.setState({
771
- isPopupOpen: false,
772
- isPopupReady: false
773
- });
774
- });
775
- });
776
- Registry.lastOpenedGroup = [];
777
- } catch (e) {// eslint-disable-next-line no-console
778
- //console.error('popup component not unmounted properly', e);
779
- }
780
- }
781
-
782
- documentKeyupHandler(e) {
783
- try {
784
- if (e.keyCode === 27) {
785
- this.handleCloseLastOpenedGroup();
786
- }
787
- } catch (e) {// eslint-disable-next-line no-console
788
- //console.log('error', e);
789
- }
790
- }
791
-
792
- removeClose(e) {
793
- // e && e.preventDefault && e.preventDefault();
794
- cancelBubblingEffect(e);
795
- }
796
-
797
- updatePopupState(view, views, viewsOffset, targetOffset, popupOffset, isAbsolute) {
798
- const isMobile = isMobilePopover(true);
799
- this.setState({
800
- isPopupReady: true,
801
- position: view,
802
- positions: views,
803
- positionsOffset: viewsOffset,
804
- targetOffset,
805
- popupOffset,
806
- isAbsolutePositioningNeeded: isAbsolute,
807
- isMobile: isMobile
808
- });
809
- }
810
-
811
- setPosition() {
812
- this.cancelRaf('setPositionRafId');
813
- const needArrow = this.getNeedArrow(this);
814
- const isAbsolute = this.getIsAbsolutePopup(this);
815
- const customOrder = this.getCustomPositionOrder(this);
816
- this.setPositionRafId = requestAnimationFrame(() => {
817
- const {
818
- placeHolderElement,
819
- dropElement,
820
- defaultPosition
821
- } = this;
822
- const {
823
- position,
824
- isPopupReady
825
- } = this.state;
826
- const scrollContainer = placeHolderElement ? placeHolderElement.closest('[data-scroll=true]') || document.body : document.body;
827
- const betterPosition = viewPort.betterView(dropElement, placeHolderElement, defaultPosition, scrollContainer, {
828
- needArrow,
829
- isAbsolute,
830
- customOrder
831
- });
832
- const {
833
- view,
834
- views,
835
- viewsOffset,
836
- targetOffset,
837
- popupOffset
838
- } = betterPosition || DUMMY_OBJECT;
839
-
840
- if (!isAbsolute) {
841
- if (!isPopupReady) {
842
- this.updatePopupState(view, views, viewsOffset, targetOffset, popupOffset, isAbsolute);
843
- }
844
-
845
- this.setContainerDynamicPositioning(betterPosition, needArrow);
846
- } else {
847
- if (position !== view || !isPopupReady) {
848
- this.updatePopupState(view, views, viewsOffset, targetOffset, popupOffset, isAbsolute);
849
- }
850
- }
851
-
852
- this.setPositionRafId = null;
853
- });
854
- }
855
-
856
- handlePopupPosition() {
857
- let defaultPosition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'bottomCenter';
858
- let isUpdatePosition = arguments.length > 1 ? arguments[1] : undefined;
859
- // isUpdatePosition --->>> Window resize and dropBox resize and to update the position
860
- const {
861
- direction
862
- } = this.context || {};
863
- const {
864
- placeHolderElement,
865
- dropElement
866
- } = this;
867
- const isAbsolute = this.getIsAbsolutePopup(this);
868
-
869
- if (direction === 'rtl') {
870
- defaultPosition = isAbsolute ? rtlAbsolutePositionMapping[defaultPosition] : rtlFixedPositionMapping[defaultPosition];
871
- } else {
872
- defaultPosition = isAbsolute ? absolutePositionMapping[defaultPosition] : defaultPosition;
873
- }
874
-
875
- this.defaultPosition = defaultPosition;
876
-
877
- if (!placeHolderElement && !dropElement) {
878
- const isMobile = isMobilePopover(true);
879
- this.setState({
880
- isPopupOpen: true,
881
- isPopupReady: true,
882
- isMobile: isMobile
883
- });
884
- return;
885
- }
886
-
887
- if (isUpdatePosition) {
888
- this.setPosition();
889
- } else {
890
- this.setState({
891
- isPopupOpen: true,
892
- isPopupReady: false
893
- }, this.setPosition);
894
- }
895
- }
896
-
897
- handleOpenPopupPositionChange() {
898
- Object.keys(Registry.popups).forEach(groupName => {
899
- const groupPopups = Registry.popups[groupName] || [];
900
- groupPopups.forEach(popup => {
901
- if (popup.state.isPopupOpen) {
902
- const {
903
- placeHolderElement,
904
- dropElement,
905
- defaultPosition
906
- } = popup;
907
- const {
908
- position,
909
- positionsOffset = {}
910
- } = popup.state;
911
-
912
- if (placeHolderElement && dropElement) {
913
- const scrollContainer = placeHolderElement.closest('[data-scroll=true]') || document.body;
914
- this.cancelRaf('resizePositionRafId');
915
- this.resizePositionRafId = requestAnimationFrame(() => {
916
- const needArrow = this.getNeedArrow(popup);
917
- const isAbsolute = this.getIsAbsolutePopup(popup);
918
- const customOrder = this.getCustomPositionOrder(popup);
919
- const isMobile = isMobilePopover(true);
920
- const betterPosition = viewPort.betterView(dropElement, placeHolderElement, defaultPosition, scrollContainer, {
921
- needArrow,
922
- isAbsolute,
923
- customOrder
924
- });
925
- const {
926
- view,
927
- views,
928
- viewsOffset = {},
929
- targetOffset,
930
- popupOffset
931
- } = betterPosition || {};
932
- const {
933
- left: oldLeft = '',
934
- top: oldTop = '',
935
- bottom: oldBottom = '',
936
- right: oldRight = ''
937
- } = positionsOffset[position] || {};
938
- const {
939
- left = '',
940
- top = '',
941
- bottom = '',
942
- right = ''
943
- } = viewsOffset[view] || {};
944
- const changeState = isAbsolute ? position !== view : oldLeft !== left || oldTop !== top || oldBottom !== bottom || oldRight !== right; // let isInViewPort = viewPort.isInViewPort(
945
- // placeHolderElement,
946
- // scrollContainer
947
- // );
948
-
949
- if (changeState) {
950
- popup.setState({
951
- position: view,
952
- positions: views,
953
- positionsOffset: viewsOffset,
954
- targetOffset,
955
- popupOffset,
956
- isAbsolutePositioningNeeded: isAbsolute,
957
- isMobile: isMobile
958
- });
959
- } // if (!isInViewPort && !isAbsolute) {
960
- // popup.setState({ isPopupOpen: false, isPopupReady: false });
961
- // } else if (view && changeState) {
962
- // popup.setState({
963
- // position: view,
964
- // positions: views,
965
- // positionsOffset: viewsOffset,
966
- // targetOffset,
967
- // popupOffset,
968
- // isAbsolutePositioningNeeded: isAbsolute
969
- // });
970
- // }
971
-
972
-
973
- this.resizePositionRafId = null;
974
- });
975
- }
976
- }
977
- });
978
- });
979
- }
980
-
981
- handleResize() {
982
- this.handleOpenPopupPositionChange();
983
- } // handleScroll(e) {
984
- // // this.handleOpenPopupPositionChange();
985
- // const { closeOnScroll } = this.getCloseOnScrollPopup(this);
986
- // const { isPopupReady } = this.state;
987
- // if (isPopupReady) {
988
- // console.log('onscrollPopupREady');
989
- // }
990
- // if (isPopupReady && closeOnScroll) {
991
- // console.log(this, 'handle Scroll');
992
- // this.togglePopup(e);
993
- // }
994
- // }
995
-
996
-
997
- handlePopupResize(popupSize) {
998
- const {
999
- height,
1000
- width
1001
- } = popupSize;
1002
- const {
1003
- height: oldHeight = 0,
1004
- width: oldWidth = 0
1005
- } = this.size || {};
1006
- const {
1007
- isPopupReady,
1008
- position
1009
- } = this.state;
1010
-
1011
- if (isPopupReady && this.size && (oldHeight !== height || width !== oldWidth)) {
1012
- this.handlePopupPosition(position, true);
1013
- }
1014
-
1015
- this.size = popupSize;
1016
- }
1017
-
1018
- getTargetRef(el) {
1019
- this.placeHolderElement = el;
1020
- }
1021
-
1022
- getContainerRef(el) {
1023
- this.dropElement = el;
1024
- }
1025
-
1026
- render() {
1027
- // const { isPopupReady, isPopupOpen } = this.state;
1028
- const {
1029
- isMobile,
1030
- ...restState
1031
- } = this.state; // const localState = isPopupReady ? this.state : {};
1032
-
1033
- return /*#__PURE__*/React.createElement(Component, { ...this.props,
1034
- ...restState,
1035
- openPopupOnly: this.openPopupOnly,
1036
- closePopupOnly: this.closePopupOnly,
1037
- togglePopup: this.togglePopup,
1038
- recomputePosition: this.setPosition,
1039
- removeClose: this.removeClose,
1040
- getTargetRef: this.getTargetRef,
1041
- getContainerRef: this.getContainerRef
1042
- });
1043
- }
1044
-
1045
- }
1046
-
1047
- Popup.displayName = Component.displayName || Component.name || Popup.name;
1048
- Popup.contextTypes = ContextTypes;
1049
- Popup.propTypes = PopupPropTypes;
1050
- return hoistStatics(Popup, Component);
11
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DUMMY_OBJECT;
12
+ const {
13
+ isAbsolutePositioningNeeded = true,
14
+ isArrow = false,
15
+ customOrder = DUMMY_ARRAY,
16
+ scrollDebounceTime = 0,
17
+ closeOnScroll = false,
18
+ isOutsideScrollBlocked = false
19
+ } = options;
20
+ const getRootElement = getLibraryConfig('getRootElement');
21
+ const mobileWidth = getLibraryConfig('mobileWidth');
22
+ const middleware = {
23
+ useAbsolutePositioning: isAbsolutePositioningNeeded,
24
+ positionOrder: customOrder,
25
+ isArrow,
26
+ scrollDebounceTime,
27
+ closeOnScroll,
28
+ isOutsideScrollBlocked,
29
+ enableResizeHandling: needResizeHandling
30
+ };
31
+ const popupConfig = {
32
+ group,
33
+ mobileWidth,
34
+ rootElementCallback: getRootElement,
35
+ middleware
36
+ };
37
+ return DotkitPopup(Component, popupConfig);
1051
38
  };
1052
39
 
1053
40
  export default Popup;