@lumx/react 3.11.0 → 3.11.1-alpha.0

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/index.js CHANGED
@@ -4434,6 +4434,147 @@ const ARROW_SIZE$1 = 14;
4434
4434
  */
4435
4435
  const POPOVER_ZINDEX = 9999;
4436
4436
 
4437
+ const errorString = 'PositionObserver Error';
4438
+ const ROOT = DOCUMENT === null || DOCUMENT === void 0 ? void 0 : DOCUMENT.documentElement;
4439
+
4440
+ /**
4441
+ * The PositionObserver class is a utility class that observes the position
4442
+ * of DOM elements and triggers a callback when their position changes.
4443
+ */
4444
+ class PositionObserver {
4445
+ /**
4446
+ * The constructor takes two arguments, a `callback`, which is called
4447
+ * whenever the position of an observed element changes and an `options` object.
4448
+ * The callback function should take an array of `PositionObserverEntry` objects
4449
+ * as its only argument, but it's not required.
4450
+ *
4451
+ * @param callback the callback that applies to all targets of this observer
4452
+ */
4453
+ constructor(callback) {
4454
+ _defineProperty(this, "entries", void 0);
4455
+ _defineProperty(this, "_tick", void 0);
4456
+ _defineProperty(this, "_callback", void 0);
4457
+ /**
4458
+ * Start observing the position of the specified element.
4459
+ * If the element is not currently attached to the DOM,
4460
+ * it will NOT be added to the entries.
4461
+ *
4462
+ * @param target an `Element` target
4463
+ */
4464
+ _defineProperty(this, "observe", target => {
4465
+ if (!(target instanceof Element)) {
4466
+ throw new Error(`${errorString}: ${target} is not an instance of Element.`);
4467
+ }
4468
+ if (!(ROOT !== null && ROOT !== void 0 && ROOT.contains(target))) return;
4469
+ this._new(target).then(_ref => {
4470
+ let {
4471
+ boundingClientRect
4472
+ } = _ref;
4473
+ if (ROOT && boundingClientRect && !this.entries.has(target)) {
4474
+ const {
4475
+ clientWidth,
4476
+ clientHeight
4477
+ } = ROOT;
4478
+ this.entries.set(target, {
4479
+ target,
4480
+ boundingClientRect,
4481
+ clientWidth,
4482
+ clientHeight
4483
+ });
4484
+ }
4485
+ if (!this._tick) this._tick = requestAnimationFrame(this._runCallback);
4486
+ });
4487
+ });
4488
+ /**
4489
+ * Private method responsible for all the heavy duty,
4490
+ * the observer's runtime.
4491
+ */
4492
+ _defineProperty(this, "_runCallback", () => {
4493
+ /* istanbul ignore if @preserve - a guard must be set */
4494
+ if (!ROOT || !this.entries.size) return;
4495
+ const {
4496
+ clientWidth,
4497
+ clientHeight
4498
+ } = ROOT;
4499
+ const queue = new Promise(resolve => {
4500
+ const updates = [];
4501
+ this.entries.forEach(_ref2 => {
4502
+ let {
4503
+ target,
4504
+ boundingClientRect: oldBoundingBox,
4505
+ clientWidth: oldWidth,
4506
+ clientHeight: oldHeight
4507
+ } = _ref2;
4508
+ /* istanbul ignore if @preserve - a guard must be set when target has been removed */
4509
+ if (!ROOT.contains(target)) return;
4510
+ this._new(target).then(_ref3 => {
4511
+ let {
4512
+ boundingClientRect,
4513
+ isIntersecting
4514
+ } = _ref3;
4515
+ /* istanbul ignore if @preserve - make sure to only count visible entries */
4516
+ if (!isIntersecting) return;
4517
+ const {
4518
+ left,
4519
+ top
4520
+ } = boundingClientRect;
4521
+
4522
+ /* istanbul ignore else @preserve - only schedule entries that changed position */
4523
+ if (oldBoundingBox.top !== top || oldBoundingBox.left !== left || oldWidth !== clientWidth || oldHeight !== clientHeight) {
4524
+ const newEntry = {
4525
+ target,
4526
+ boundingClientRect,
4527
+ clientHeight,
4528
+ clientWidth
4529
+ };
4530
+ this.entries.set(target, newEntry);
4531
+ updates.push(newEntry);
4532
+ }
4533
+ });
4534
+ });
4535
+ resolve(updates);
4536
+ });
4537
+ this._tick = requestAnimationFrame(async () => {
4538
+ // execute the queue
4539
+ const updates = await queue;
4540
+
4541
+ // only execute the callback if position actually changed
4542
+ /* istanbul ignore else @preserve */
4543
+ if (updates.length) this._callback(updates, this);
4544
+ this._runCallback();
4545
+ });
4546
+ });
4547
+ /**
4548
+ * Check intersection status and resolve it
4549
+ * right away.
4550
+ *
4551
+ * @param target an `Element` target
4552
+ */
4553
+ _defineProperty(this, "_new", target => {
4554
+ return new Promise(resolve => {
4555
+ if (!(WINDOW !== null && WINDOW !== void 0 && WINDOW.IntersectionObserver)) return;
4556
+ const intersectionObserver = new IntersectionObserver((_ref4, ob) => {
4557
+ let [entry] = _ref4;
4558
+ ob.disconnect();
4559
+ resolve(entry);
4560
+ });
4561
+ intersectionObserver.observe(target);
4562
+ });
4563
+ });
4564
+ /**
4565
+ * Immediately stop observing all elements.
4566
+ */
4567
+ _defineProperty(this, "disconnect", () => {
4568
+ cancelAnimationFrame(this._tick);
4569
+ this.entries.clear();
4570
+ this._tick = 0;
4571
+ });
4572
+ this.entries = new Map();
4573
+ this._callback = callback;
4574
+ this._tick = 0;
4575
+ }
4576
+ }
4577
+
4437
4578
  /**
4438
4579
  * Popper js modifier to fit popover min width to the anchor width.
4439
4580
  */
@@ -4520,7 +4661,6 @@ function usePopoverStyle(_ref5) {
4520
4661
  fitWithinViewportHeight,
4521
4662
  boundaryRef,
4522
4663
  anchorRef,
4523
- children,
4524
4664
  placement,
4525
4665
  style,
4526
4666
  zIndex
@@ -4576,9 +4716,39 @@ function usePopoverStyle(_ref5) {
4576
4716
  placement,
4577
4717
  modifiers
4578
4718
  });
4719
+
4720
+ // Auto update popover
4579
4721
  useEffect(() => {
4580
- update === null || update === void 0 ? void 0 : update();
4581
- }, [children, update]);
4722
+ const {
4723
+ current: anchorElement
4724
+ } = anchorRef;
4725
+ if (!update || !popperElement || !anchorElement || !(WINDOW !== null && WINDOW !== void 0 && WINDOW.ResizeObserver)) {
4726
+ return undefined;
4727
+ }
4728
+
4729
+ // Only update once per frame
4730
+ let frame;
4731
+ function limitedUpdate() {
4732
+ if (frame) return;
4733
+ frame = requestAnimationFrame(() => {
4734
+ update === null || update === void 0 ? void 0 : update();
4735
+ frame = undefined;
4736
+ });
4737
+ }
4738
+
4739
+ // On anchor move
4740
+ const positionObserver = new PositionObserver(limitedUpdate);
4741
+ positionObserver.observe(anchorElement);
4742
+
4743
+ // On anchor or popover resize
4744
+ const resizeObserver = new ResizeObserver(limitedUpdate);
4745
+ resizeObserver.observe(anchorElement);
4746
+ resizeObserver.observe(popperElement);
4747
+ return () => {
4748
+ resizeObserver.disconnect();
4749
+ positionObserver.disconnect();
4750
+ };
4751
+ }, [anchorRef, popperElement, update]);
4582
4752
  const position = (_state$placement = state === null || state === void 0 ? void 0 : state.placement) !== null && _state$placement !== void 0 ? _state$placement : placement;
4583
4753
  const popoverStyle = useMemo(() => {
4584
4754
  const newStyles = _objectSpread2(_objectSpread2(_objectSpread2({}, style), styles.popper), {}, {
@@ -4587,6 +4757,9 @@ function usePopoverStyle(_ref5) {
4587
4757
  if (fitWithinViewportHeight && !newStyles.maxHeight) {
4588
4758
  newStyles.maxHeight = (WINDOW === null || WINDOW === void 0 ? void 0 : WINDOW.innerHeight) || (DOCUMENT === null || DOCUMENT === void 0 ? void 0 : DOCUMENT.documentElement.clientHeight);
4589
4759
  }
4760
+
4761
+ // Do not show the popover while it's not properly placed
4762
+ if (!newStyles.transform) newStyles.visibility = 'hidden';
4590
4763
  return newStyles;
4591
4764
  }, [style, styles.popper, zIndex, fitWithinViewportHeight]);
4592
4765
  return {
@@ -4680,7 +4853,6 @@ const _InnerPopover = forwardRef((props, ref) => {
4680
4853
  fitWithinViewportHeight,
4681
4854
  boundaryRef,
4682
4855
  anchorRef,
4683
- children,
4684
4856
  placement,
4685
4857
  style,
4686
4858
  zIndex
@@ -4698,7 +4870,7 @@ const _InnerPopover = forwardRef((props, ref) => {
4698
4870
  useFocusTrap(withFocusTrap && isOpen && focusZoneElement, focusElement === null || focusElement === void 0 ? void 0 : focusElement.current);
4699
4871
  const clickAwayRefs = useRef([popoverRef, anchorRef]);
4700
4872
  const mergedRefs = useMergeRefs(setPopperElement, ref, popoverRef);
4701
- return isOpen ? renderPopover( /*#__PURE__*/React__default.createElement(Component, _extends({}, forwardedProps, {
4873
+ return isOpen && styles.popover ? renderPopover( /*#__PURE__*/React__default.createElement(Component, _extends({}, forwardedProps, {
4702
4874
  ref: mergedRefs,
4703
4875
  className: classNames(className, handleBasicClasses({
4704
4876
  prefix: CLASSNAME$1d,