@zohodesk/components 1.2.48 → 1.2.49

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/README.md CHANGED
@@ -32,6 +32,14 @@ In this Package, we Provide Some Basic Components to Build Web App
32
32
  - TextBoxIcon
33
33
  - Tooltip
34
34
 
35
+ # 1.2.49 (Yet To Publish)
36
+
37
+ - **Popup**
38
+ - `isOutsideScrollBlocked` prop supported - Scroll blocking behaviours supported
39
+ - Fixed popup re-positioning on window resize not working properly - Issue fixed
40
+ - **DropBoxElement**
41
+ - The dot-ui-element attribute has been added to facilitate the use of component-level CSS selectors
42
+
35
43
  # 1.2.48
36
44
 
37
45
  - **ResizeObserver**
@@ -104,7 +112,7 @@ In this Package, we Provide Some Basic Components to Build Web App
104
112
 
105
113
  - **LibraryContext** - coloredTagVariant, hasTagColorInheritedToText properties added
106
114
  - **Tag** - customAttributes prop supported
107
- - **TextBoxIcon** - needInputFocusOnParentClick prop supported
115
+ - **TextBoxIcon** - needInputFocusOnWrapperClick prop supported
108
116
 
109
117
  # 1.2.38
110
118
 
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/no-unknown-property */
1
2
  import React from 'react';
2
3
  import useDropboxPosCalc from "./useDropboxPosCalc";
3
4
  import cssJSLogic from "./css/cssJSLogic";
@@ -108,7 +109,8 @@ export default function DropBoxElement(props) {
108
109
  "aria-labelledby": ariaLabelledby,
109
110
  tabIndex: tabIndex,
110
111
  onAnimationEnd: isAnimate && FireOnAnimationEnd,
111
- "data-a11y-focus-main-area": true
112
+ "data-a11y-focus-main-area": true,
113
+ "dot-ui-element": "dropbox"
112
114
  }, /*#__PURE__*/React.createElement("div", {
113
115
  tabIndex: "-1",
114
116
  className: `${subContainerClass} ${style[`${palette}Palette`]}`,
@@ -9,6 +9,7 @@ exports[`DropBoxElement rendering the defult props 1`] = `
9
9
  data-position="bottomStart"
10
10
  data-selector-id="dropBox"
11
11
  data-test-id="dropBox"
12
+ dot-ui-element="dropbox"
12
13
  >
13
14
  <div
14
15
  class="subContainer bottom_shadow radius defaultPalette"
@@ -9,6 +9,7 @@ exports[`DropBox rendering the defult props 1`] = `
9
9
  data-position="bottomStart"
10
10
  data-selector-id="dropBox"
11
11
  data-test-id="dropBox"
12
+ dot-ui-element="dropbox"
12
13
  >
13
14
  <div
14
15
  class="subContainer bottom_shadow radius defaultPalette"
@@ -19,6 +19,7 @@ exports[`DropDown rendering the defult props 1`] = `
19
19
  data-position="bottomMid"
20
20
  data-selector-id="dropBox"
21
21
  data-test-id="dropBox"
22
+ dot-ui-element="dropbox"
22
23
  >
23
24
  <div
24
25
  class="subContainer bottom_shadow radius defaultPalette"
package/es/Popup/Popup.js CHANGED
@@ -1,13 +1,14 @@
1
1
  /**** Libraries ****/
2
2
  import React from 'react';
3
- import PropTypes from 'prop-types';
4
3
  import hoistStatics from 'hoist-non-react-statics';
4
+ import { PopupPropTypes, ContextTypes } from "./props/propTypes";
5
5
  /**** Methods ****/
6
6
 
7
7
  import { debounce, isDescendant, isTextSelected, cancelBubblingEffect } from "../utils/Common.js";
8
8
  import viewPort from "./viewPort";
9
9
  import { absolutePositionMapping, rtlAbsolutePositionMapping, rtlFixedPositionMapping } from "./PositionMapping.js";
10
10
  import ResizeObserver from '@zohodesk/virtualizer/lib/commons/ResizeObserver.js';
11
+ import { addIntersectionObserver, removeIntersectionObserver } from "./intersectionObserver";
11
12
  let lastOpenedGroup = [];
12
13
  let popups = {};
13
14
 
@@ -89,6 +90,12 @@ const Popup = function (Component) {
89
90
  this.handleDocumentMouseDown = this.handleDocumentMouseDown.bind(this);
90
91
  this.handleDocumentFocus = this.handleDocumentFocus.bind(this);
91
92
  this.handleGetNeedPrevent = this.handleGetNeedPrevent.bind(this);
93
+ this.handleBlockScroll = this.handleBlockScroll.bind(this);
94
+ this.handlePositionChange = this.handlePositionChange.bind(this);
95
+ this.preventKeyboardScroll = this.preventKeyboardScroll.bind(this);
96
+ this.addScrollBlockListeners = this.addScrollBlockListeners.bind(this);
97
+ this.removeScrollBlockListeners = this.removeScrollBlockListeners.bind(this);
98
+ this.handleIntersectionObserver = this.handleIntersectionObserver.bind(this);
92
99
  this.popupObserver = new ResizeObserver(this.handlePopupResize); //dropBoxSize
93
100
 
94
101
  this.size = null;
@@ -101,6 +108,7 @@ const Popup = function (Component) {
101
108
  scrollDebounceTime
102
109
  } = this.getScrollDebounceTime(this);
103
110
  this.handleScroll = debounce(this.handleScroll.bind(this), scrollDebounceTime);
111
+ this.handleDebouncedPositionChange = debounce(this.handlePositionChange.bind(this), 100);
104
112
  }
105
113
 
106
114
  componentDidMount() {
@@ -144,7 +152,9 @@ const Popup = function (Component) {
144
152
  dropElement
145
153
  } = this;
146
154
  const {
147
- needResizeHandling: propResizeHandling
155
+ needResizeHandling: propResizeHandling,
156
+ isAbsolutePositioningNeeded,
157
+ isOutsideScrollBlocked
148
158
  } = this.props;
149
159
 
150
160
  if (oldStateOpen !== isPopupReady) {
@@ -154,6 +164,16 @@ const Popup = function (Component) {
154
164
  this.size = null;
155
165
  this.popupObserver.disconnect();
156
166
  }
167
+
168
+ if (isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
169
+ if (isPopupReady) {
170
+ addIntersectionObserver(this.placeHolderElement, this.handleIntersectionObserver);
171
+ this.addScrollBlockListeners();
172
+ } else {
173
+ removeIntersectionObserver(this.placeHolderElement, this.handleIntersectionObserver);
174
+ this.removeScrollBlockListeners();
175
+ }
176
+ }
157
177
  }
158
178
  }
159
179
 
@@ -169,6 +189,8 @@ const Popup = function (Component) {
169
189
 
170
190
  return res;
171
191
  }, popups);
192
+ removeIntersectionObserver(this.placeHolderElement, this.handleIntersectionObserver);
193
+ this.removeScrollBlockListeners();
172
194
  let noPopups = true;
173
195
 
174
196
  for (const i in popups) {
@@ -193,6 +215,82 @@ const Popup = function (Component) {
193
215
  }
194
216
  }
195
217
 
218
+ addScrollBlockListeners() {
219
+ document.addEventListener('wheel', this.handleBlockScroll, {
220
+ capture: true,
221
+ passive: false
222
+ });
223
+ document.addEventListener('touchmove', this.handleBlockScroll, {
224
+ capture: true,
225
+ passive: false
226
+ });
227
+ document.addEventListener('scroll', this.handleDebouncedPositionChange, {
228
+ capture: true,
229
+ passive: false
230
+ });
231
+ document.addEventListener('keydown', this.preventKeyboardScroll, {
232
+ capture: true,
233
+ passive: false
234
+ });
235
+ }
236
+
237
+ removeScrollBlockListeners() {
238
+ document.removeEventListener('wheel', this.handleBlockScroll, {
239
+ capture: true,
240
+ passive: false
241
+ });
242
+ document.removeEventListener('touchmove', this.handleBlockScroll, {
243
+ capture: true,
244
+ passive: false
245
+ });
246
+ document.removeEventListener('scroll', this.handleDebouncedPositionChange, {
247
+ capture: true,
248
+ passive: false
249
+ });
250
+ document.removeEventListener('keydown', this.preventKeyboardScroll, {
251
+ capture: true,
252
+ passive: false
253
+ });
254
+ }
255
+
256
+ handleBlockScroll(event) {
257
+ // const targetElement = this.placeHolderElement;
258
+ const containerElement = this.dropElement;
259
+
260
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target)) {
261
+ // --- Scroll exclude Target & Container elements --- For reference. Will adopt in future
262
+ // if(
263
+ // (containerElement && (containerElement !== event.target && !containerElement.contains(event.target)))
264
+ // && (targetElement && (targetElement !== event.target && !targetElement.contains(event.target)))
265
+ // ) {
266
+ event.preventDefault();
267
+ }
268
+ }
269
+
270
+ handlePositionChange(event) {
271
+ const targetElement = this.placeHolderElement;
272
+ const containerElement = this.dropElement;
273
+
274
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target) && targetElement && targetElement !== event.target && !targetElement.contains(event.target) && event.target.contains(targetElement)) {
275
+ this.handlePopupPosition(this.state.position); // this.closePopupOnly(event);
276
+ }
277
+ }
278
+
279
+ preventKeyboardScroll(event) {
280
+ const containerElement = this.dropElement;
281
+ const keys = [32, 37, 38, 39, 40]; // Space, Arrow keys
282
+
283
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target) && keys.includes(event.keyCode)) {
284
+ event.preventDefault();
285
+ }
286
+ }
287
+
288
+ handleIntersectionObserver(entry) {
289
+ if (entry.intersectionRatio === 0) {
290
+ this.closePopupOnly();
291
+ }
292
+ }
293
+
196
294
  getGroup() {
197
295
  const {
198
296
  popupGroup
@@ -523,13 +621,15 @@ const Popup = function (Component) {
523
621
  } = betterPosition || {};
524
622
  const {
525
623
  left: oldLeft = '',
526
- top: oldTop = ''
624
+ top: oldTop = '',
625
+ bottom: oldBottom = ''
527
626
  } = positionsOffset[position] || {};
528
627
  const {
529
628
  left = '',
530
- top = ''
629
+ top = '',
630
+ bottom = ''
531
631
  } = viewsOffset[view] || {};
532
- const changeState = isAbsolute ? position !== view : oldLeft !== left || oldTop !== top; // let isInViewPort = viewPort.isInViewPort(
632
+ const changeState = isAbsolute ? position !== view : oldLeft !== left || oldTop !== top || oldBottom !== bottom; // let isInViewPort = viewPort.isInViewPort(
533
633
  // placeHolderElement,
534
634
  // scrollContainer
535
635
  // );
@@ -635,9 +735,8 @@ const Popup = function (Component) {
635
735
  }
636
736
 
637
737
  Popup.displayName = Component.displayName || Component.name || Popup.name;
638
- Popup.contextTypes = {
639
- direction: PropTypes.string
640
- };
738
+ Popup.contextTypes = ContextTypes;
739
+ Popup.propTypes = PopupPropTypes;
641
740
  return hoistStatics(Popup, Component);
642
741
  };
643
742
 
@@ -0,0 +1,39 @@
1
+ let observerCallbacks = null;
2
+ let intersectionObserver = null;
3
+
4
+ function handleObserverCallbacks(entries) {
5
+ entries.map((entry, i) => {
6
+ let oldCallbacks = observerCallbacks.get(entry.target);
7
+ oldCallbacks.length && oldCallbacks.forEach(callback => {
8
+ callback && callback(entry);
9
+ });
10
+ });
11
+ }
12
+
13
+ export function addIntersectionObserver(element, callback, options) {
14
+ if (intersectionObserver === null && observerCallbacks === null) {
15
+ intersectionObserver = new IntersectionObserver(entries => {
16
+ handleObserverCallbacks(entries);
17
+ }, options);
18
+ observerCallbacks = new Map();
19
+ }
20
+
21
+ intersectionObserver.observe(element);
22
+ let oldCallbacks = observerCallbacks.get(element) || [];
23
+ observerCallbacks.set(element, [...oldCallbacks, callback]);
24
+ }
25
+ export function removeIntersectionObserver(element, callback) {
26
+ let oldCallbacks = observerCallbacks ? observerCallbacks.get(element) : [];
27
+ oldCallbacks = oldCallbacks.filter(handler => handler !== callback);
28
+
29
+ if (intersectionObserver && oldCallbacks.length === 0) {
30
+ observerCallbacks.delete(element);
31
+ intersectionObserver.unobserve(element);
32
+ }
33
+
34
+ if (intersectionObserver && observerCallbacks && observerCallbacks.size === 0) {
35
+ intersectionObserver.disconnect();
36
+ intersectionObserver = null;
37
+ observerCallbacks = null;
38
+ }
39
+ }
@@ -0,0 +1,30 @@
1
+ import PropTypes from 'prop-types';
2
+ export const ContextTypes = {
3
+ direction: PropTypes.string
4
+ };
5
+ export const PopupPropTypes = {
6
+ popupGroup: PropTypes.string,
7
+ isArrow: PropTypes.bool,
8
+ isPopupOpen: PropTypes.bool,
9
+ closeOnScroll: PropTypes.bool,
10
+ isOutsideScrollBlocked: PropTypes.bool,
11
+ needResizeHandling: PropTypes.bool,
12
+ isAbsolutePositioningNeeded: PropTypes.bool,
13
+ scrollDebounceTime: PropTypes.number,
14
+ customOrder: PropTypes.arrayOf(PropTypes.string),
15
+ checkBeforeClose: PropTypes.func
16
+ };
17
+ export const PopupWrappersPropTypes = {
18
+ openPopupOnly: PropTypes.func,
19
+ closePopupOnly: PropTypes.func,
20
+ togglePopup: PropTypes.func,
21
+ removeClose: PropTypes.func,
22
+ isPopupReady: PropTypes.bool,
23
+ position: PropTypes.oneOf(['bottomRight', 'bottomLeft', 'bottomCenter', 'topRight', 'topLeft', 'topCenter', 'rightTop', 'rightBottom', 'rightCenter', 'leftTop', 'leftBottom', 'leftCenter']),
24
+ getTargetRef: PropTypes.func,
25
+ getContainerRef: PropTypes.func,
26
+ ...PopupPropTypes,
27
+ isRestrictScroll: PropTypes.bool,
28
+ positionsOffset: PropTypes.object,
29
+ targetOffset: PropTypes.object
30
+ };
@@ -9,6 +9,7 @@ exports[`ResponsiveDropBox rendering the defult props 1`] = `
9
9
  data-position="bottomStart"
10
10
  data-selector-id="dropBox"
11
11
  data-test-id="dropBox"
12
+ dot-ui-element="dropbox"
12
13
  >
13
14
  <div
14
15
  class="subContainer bottom_shadow radius defaultPalette"
@@ -169,7 +169,7 @@ export default class TextBox extends React.PureComponent {
169
169
  ref: this.inputRef,
170
170
  type: type,
171
171
  value: value,
172
- onScroll: isScrollPrevent ? this.handlePreventTextBoxScroll : '',
172
+ onScroll: isScrollPrevent ? this.handlePreventTextBoxScroll : null,
173
173
  onKeyPress: onKeyPress,
174
174
  onMouseDown: onMouseDown,
175
175
  ...options,
@@ -23,6 +23,7 @@ var _DropBoxElementModule = _interopRequireDefault(require("./css/DropBoxElement
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
25
25
 
26
+ /* eslint-disable react/no-unknown-property */
26
27
  function DropBoxElement(props) {
27
28
  var children = props.children,
28
29
  isAnimate = props.isAnimate,
@@ -120,7 +121,8 @@ function DropBoxElement(props) {
120
121
  "aria-labelledby": ariaLabelledby,
121
122
  tabIndex: tabIndex,
122
123
  onAnimationEnd: isAnimate && FireOnAnimationEnd,
123
- "data-a11y-focus-main-area": true
124
+ "data-a11y-focus-main-area": true,
125
+ "dot-ui-element": "dropbox"
124
126
  }, /*#__PURE__*/_react["default"].createElement("div", {
125
127
  tabIndex: "-1",
126
128
  className: "".concat(subContainerClass, " ").concat(_DropBoxElementModule["default"]["".concat(palette, "Palette")]),
@@ -9,6 +9,7 @@ exports[`DropBoxElement rendering the defult props 1`] = `
9
9
  data-position="bottomStart"
10
10
  data-selector-id="dropBox"
11
11
  data-test-id="dropBox"
12
+ dot-ui-element="dropbox"
12
13
  >
13
14
  <div
14
15
  class="subContainer bottom_shadow radius defaultPalette"
@@ -9,6 +9,7 @@ exports[`DropBox rendering the defult props 1`] = `
9
9
  data-position="bottomStart"
10
10
  data-selector-id="dropBox"
11
11
  data-test-id="dropBox"
12
+ dot-ui-element="dropbox"
12
13
  >
13
14
  <div
14
15
  class="subContainer bottom_shadow radius defaultPalette"
@@ -19,6 +19,7 @@ exports[`DropDown rendering the defult props 1`] = `
19
19
  data-position="bottomMid"
20
20
  data-selector-id="dropBox"
21
21
  data-test-id="dropBox"
22
+ dot-ui-element="dropbox"
22
23
  >
23
24
  <div
24
25
  class="subContainer bottom_shadow radius defaultPalette"
@@ -9,10 +9,10 @@ exports["default"] = void 0;
9
9
 
10
10
  var _react = _interopRequireDefault(require("react"));
11
11
 
12
- var _propTypes = _interopRequireDefault(require("prop-types"));
13
-
14
12
  var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
15
13
 
14
+ var _propTypes = require("./props/propTypes");
15
+
16
16
  var _Common = require("../utils/Common.js");
17
17
 
18
18
  var _viewPort = _interopRequireDefault(require("./viewPort"));
@@ -21,6 +21,8 @@ var _PositionMapping = require("./PositionMapping.js");
21
21
 
22
22
  var _ResizeObserver = _interopRequireDefault(require("@zohodesk/virtualizer/lib/commons/ResizeObserver.js"));
23
23
 
24
+ var _intersectionObserver = require("./intersectionObserver");
25
+
24
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
25
27
 
26
28
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@@ -151,6 +153,12 @@ var Popup = function Popup(Component) {
151
153
  _this.handleDocumentMouseDown = _this.handleDocumentMouseDown.bind(_assertThisInitialized(_this));
152
154
  _this.handleDocumentFocus = _this.handleDocumentFocus.bind(_assertThisInitialized(_this));
153
155
  _this.handleGetNeedPrevent = _this.handleGetNeedPrevent.bind(_assertThisInitialized(_this));
156
+ _this.handleBlockScroll = _this.handleBlockScroll.bind(_assertThisInitialized(_this));
157
+ _this.handlePositionChange = _this.handlePositionChange.bind(_assertThisInitialized(_this));
158
+ _this.preventKeyboardScroll = _this.preventKeyboardScroll.bind(_assertThisInitialized(_this));
159
+ _this.addScrollBlockListeners = _this.addScrollBlockListeners.bind(_assertThisInitialized(_this));
160
+ _this.removeScrollBlockListeners = _this.removeScrollBlockListeners.bind(_assertThisInitialized(_this));
161
+ _this.handleIntersectionObserver = _this.handleIntersectionObserver.bind(_assertThisInitialized(_this));
154
162
  _this.popupObserver = new _ResizeObserver["default"](_this.handlePopupResize); //dropBoxSize
155
163
 
156
164
  _this.size = null;
@@ -164,6 +172,7 @@ var Popup = function Popup(Component) {
164
172
  scrollDebounceTime = _this$getScrollDeboun.scrollDebounceTime;
165
173
 
166
174
  _this.handleScroll = (0, _Common.debounce)(_this.handleScroll.bind(_assertThisInitialized(_this)), scrollDebounceTime);
175
+ _this.handleDebouncedPositionChange = (0, _Common.debounce)(_this.handlePositionChange.bind(_assertThisInitialized(_this)), 100);
167
176
  return _this;
168
177
  }
169
178
 
@@ -207,7 +216,10 @@ var Popup = function Popup(Component) {
207
216
  oldStateOpen = _ref2$isPopupReady === void 0 ? false : _ref2$isPopupReady;
208
217
 
209
218
  var dropElement = this.dropElement;
210
- var propResizeHandling = this.props.needResizeHandling;
219
+ var _this$props = this.props,
220
+ propResizeHandling = _this$props.needResizeHandling,
221
+ isAbsolutePositioningNeeded = _this$props.isAbsolutePositioningNeeded,
222
+ isOutsideScrollBlocked = _this$props.isOutsideScrollBlocked;
211
223
 
212
224
  if (oldStateOpen !== isPopupReady) {
213
225
  if (isPopupReady && dropElement && (propResizeHandling !== undefined ? propResizeHandling : needResizeHandling)) {
@@ -216,6 +228,16 @@ var Popup = function Popup(Component) {
216
228
  this.size = null;
217
229
  this.popupObserver.disconnect();
218
230
  }
231
+
232
+ if (isOutsideScrollBlocked && !isAbsolutePositioningNeeded) {
233
+ if (isPopupReady) {
234
+ (0, _intersectionObserver.addIntersectionObserver)(this.placeHolderElement, this.handleIntersectionObserver);
235
+ this.addScrollBlockListeners();
236
+ } else {
237
+ (0, _intersectionObserver.removeIntersectionObserver)(this.placeHolderElement, this.handleIntersectionObserver);
238
+ this.removeScrollBlockListeners();
239
+ }
240
+ }
219
241
  }
220
242
  }
221
243
  }, {
@@ -236,6 +258,8 @@ var Popup = function Popup(Component) {
236
258
 
237
259
  return res;
238
260
  }, popups);
261
+ (0, _intersectionObserver.removeIntersectionObserver)(this.placeHolderElement, this.handleIntersectionObserver);
262
+ this.removeScrollBlockListeners();
239
263
  var noPopups = true;
240
264
 
241
265
  for (var i in popups) {
@@ -259,6 +283,88 @@ var Popup = function Popup(Component) {
259
283
  document.removeEventListener('focus', this.handleDocumentFocus, true);
260
284
  }
261
285
  }
286
+ }, {
287
+ key: "addScrollBlockListeners",
288
+ value: function addScrollBlockListeners() {
289
+ document.addEventListener('wheel', this.handleBlockScroll, {
290
+ capture: true,
291
+ passive: false
292
+ });
293
+ document.addEventListener('touchmove', this.handleBlockScroll, {
294
+ capture: true,
295
+ passive: false
296
+ });
297
+ document.addEventListener('scroll', this.handleDebouncedPositionChange, {
298
+ capture: true,
299
+ passive: false
300
+ });
301
+ document.addEventListener('keydown', this.preventKeyboardScroll, {
302
+ capture: true,
303
+ passive: false
304
+ });
305
+ }
306
+ }, {
307
+ key: "removeScrollBlockListeners",
308
+ value: function removeScrollBlockListeners() {
309
+ document.removeEventListener('wheel', this.handleBlockScroll, {
310
+ capture: true,
311
+ passive: false
312
+ });
313
+ document.removeEventListener('touchmove', this.handleBlockScroll, {
314
+ capture: true,
315
+ passive: false
316
+ });
317
+ document.removeEventListener('scroll', this.handleDebouncedPositionChange, {
318
+ capture: true,
319
+ passive: false
320
+ });
321
+ document.removeEventListener('keydown', this.preventKeyboardScroll, {
322
+ capture: true,
323
+ passive: false
324
+ });
325
+ }
326
+ }, {
327
+ key: "handleBlockScroll",
328
+ value: function handleBlockScroll(event) {
329
+ // const targetElement = this.placeHolderElement;
330
+ var containerElement = this.dropElement;
331
+
332
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target)) {
333
+ // --- Scroll exclude Target & Container elements --- For reference. Will adopt in future
334
+ // if(
335
+ // (containerElement && (containerElement !== event.target && !containerElement.contains(event.target)))
336
+ // && (targetElement && (targetElement !== event.target && !targetElement.contains(event.target)))
337
+ // ) {
338
+ event.preventDefault();
339
+ }
340
+ }
341
+ }, {
342
+ key: "handlePositionChange",
343
+ value: function handlePositionChange(event) {
344
+ var targetElement = this.placeHolderElement;
345
+ var containerElement = this.dropElement;
346
+
347
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target) && targetElement && targetElement !== event.target && !targetElement.contains(event.target) && event.target.contains(targetElement)) {
348
+ this.handlePopupPosition(this.state.position); // this.closePopupOnly(event);
349
+ }
350
+ }
351
+ }, {
352
+ key: "preventKeyboardScroll",
353
+ value: function preventKeyboardScroll(event) {
354
+ var containerElement = this.dropElement;
355
+ var keys = [32, 37, 38, 39, 40]; // Space, Arrow keys
356
+
357
+ if (containerElement && containerElement !== event.target && !containerElement.contains(event.target) && keys.includes(event.keyCode)) {
358
+ event.preventDefault();
359
+ }
360
+ }
361
+ }, {
362
+ key: "handleIntersectionObserver",
363
+ value: function handleIntersectionObserver(entry) {
364
+ if (entry.intersectionRatio === 0) {
365
+ this.closePopupOnly();
366
+ }
367
+ }
262
368
  }, {
263
369
  key: "getGroup",
264
370
  value: function getGroup() {
@@ -587,15 +693,19 @@ var Popup = function Popup(Component) {
587
693
  _ref6$left = _ref6.left,
588
694
  oldLeft = _ref6$left === void 0 ? '' : _ref6$left,
589
695
  _ref6$top = _ref6.top,
590
- oldTop = _ref6$top === void 0 ? '' : _ref6$top;
696
+ oldTop = _ref6$top === void 0 ? '' : _ref6$top,
697
+ _ref6$bottom = _ref6.bottom,
698
+ oldBottom = _ref6$bottom === void 0 ? '' : _ref6$bottom;
591
699
 
592
700
  var _ref7 = viewsOffset[view] || {},
593
701
  _ref7$left = _ref7.left,
594
702
  left = _ref7$left === void 0 ? '' : _ref7$left,
595
703
  _ref7$top = _ref7.top,
596
- top = _ref7$top === void 0 ? '' : _ref7$top;
704
+ top = _ref7$top === void 0 ? '' : _ref7$top,
705
+ _ref7$bottom = _ref7.bottom,
706
+ bottom = _ref7$bottom === void 0 ? '' : _ref7$bottom;
597
707
 
598
- var changeState = isAbsolute ? position !== view : oldLeft !== left || oldTop !== top; // let isInViewPort = viewPort.isInViewPort(
708
+ var changeState = isAbsolute ? position !== view : oldLeft !== left || oldTop !== top || oldBottom !== bottom; // let isInViewPort = viewPort.isInViewPort(
599
709
  // placeHolderElement,
600
710
  // scrollContainer
601
711
  // );
@@ -705,9 +815,8 @@ var Popup = function Popup(Component) {
705
815
  }(_react["default"].Component);
706
816
 
707
817
  Popup.displayName = Component.displayName || Component.name || Popup.name;
708
- Popup.contextTypes = {
709
- direction: _propTypes["default"].string
710
- };
818
+ Popup.contextTypes = _propTypes.ContextTypes;
819
+ Popup.propTypes = _propTypes.PopupPropTypes;
711
820
  return (0, _hoistNonReactStatics["default"])(Popup, Component);
712
821
  };
713
822
 
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.addIntersectionObserver = addIntersectionObserver;
7
+ exports.removeIntersectionObserver = removeIntersectionObserver;
8
+
9
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
10
+
11
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12
+
13
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
14
+
15
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
16
+
17
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
18
+
19
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
20
+
21
+ var observerCallbacks = null;
22
+ var intersectionObserver = null;
23
+
24
+ function handleObserverCallbacks(entries) {
25
+ entries.map(function (entry, i) {
26
+ var oldCallbacks = observerCallbacks.get(entry.target);
27
+ oldCallbacks.length && oldCallbacks.forEach(function (callback) {
28
+ callback && callback(entry);
29
+ });
30
+ });
31
+ }
32
+
33
+ function addIntersectionObserver(element, callback, options) {
34
+ if (intersectionObserver === null && observerCallbacks === null) {
35
+ intersectionObserver = new IntersectionObserver(function (entries) {
36
+ handleObserverCallbacks(entries);
37
+ }, options);
38
+ observerCallbacks = new Map();
39
+ }
40
+
41
+ intersectionObserver.observe(element);
42
+ var oldCallbacks = observerCallbacks.get(element) || [];
43
+ observerCallbacks.set(element, [].concat(_toConsumableArray(oldCallbacks), [callback]));
44
+ }
45
+
46
+ function removeIntersectionObserver(element, callback) {
47
+ var oldCallbacks = observerCallbacks ? observerCallbacks.get(element) : [];
48
+ oldCallbacks = oldCallbacks.filter(function (handler) {
49
+ return handler !== callback;
50
+ });
51
+
52
+ if (intersectionObserver && oldCallbacks.length === 0) {
53
+ observerCallbacks["delete"](element);
54
+ intersectionObserver.unobserve(element);
55
+ }
56
+
57
+ if (intersectionObserver && observerCallbacks && observerCallbacks.size === 0) {
58
+ intersectionObserver.disconnect();
59
+ intersectionObserver = null;
60
+ observerCallbacks = null;
61
+ }
62
+ }