@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 +177 -5
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/popover/Popover.stories.tsx +60 -44
- package/src/components/popover/Popover.tsx +1 -2
- package/src/components/popover/PositionObserver.ts +155 -0
- package/src/components/popover/usePopoverStyle.tsx +35 -5
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
|
-
|
|
4581
|
-
|
|
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,
|