vrembem 1.35.2 → 1.38.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.
@@ -58,6 +58,8 @@ const camelCase = str => {
58
58
  });
59
59
  };
60
60
 
61
+ var focusableSelectors = ['a[href]:not([tabindex^="-"])', 'area[href]:not([tabindex^="-"])', 'input:not([type="hidden"]):not([type="radio"]):not([disabled]):not([tabindex^="-"])', 'input[type="radio"]:not([disabled]):not([tabindex^="-"])', 'select:not([disabled]):not([tabindex^="-"])', 'textarea:not([disabled]):not([tabindex^="-"])', 'button:not([disabled]):not([tabindex^="-"])', 'iframe:not([tabindex^="-"])', 'audio[controls]:not([tabindex^="-"])', 'video[controls]:not([tabindex^="-"])', '[contenteditable]:not([tabindex^="-"])', '[tabindex]:not([tabindex^="-"])'];
62
+
61
63
  const focusTarget = (target, settings) => {
62
64
  const innerFocus = target.querySelector(`[data-${settings.dataFocus}]`);
63
65
 
@@ -104,6 +106,28 @@ class FocusTrap {
104
106
  this.target = null;
105
107
  }
106
108
 
109
+ refresh() {
110
+ // Check if a target has been set
111
+ if (!this.target) return; // Remove existing events
112
+
113
+ this.target.removeEventListener('keydown', this.__handlerFocusTrap);
114
+ this.target.removeEventListener('keydown', this.handlerFocusLock); // Get the focusable elements
115
+
116
+ this.focusable = this.getFocusable(); // Setup the focus handlers based on focusable length
117
+
118
+ if (this.focusable.length) {
119
+ // If there are focusable elements, setup focus trap
120
+ this.focusableFirst = this.focusable[0];
121
+ this.focusableLast = this.focusable[this.focusable.length - 1];
122
+ this.target.addEventListener('keydown', this.__handlerFocusTrap);
123
+ } else {
124
+ // If there are no focusable elements, setup focus lock
125
+ this.focusableFirst = null;
126
+ this.focusableLast = null;
127
+ this.target.addEventListener('keydown', this.handlerFocusLock);
128
+ }
129
+ }
130
+
107
131
  handlerFocusTrap(event) {
108
132
  const isTab = event.key === 'Tab' || event.keyCode === 9;
109
133
  if (!isTab) return;
@@ -130,7 +154,7 @@ class FocusTrap {
130
154
  const focusable = [];
131
155
  const initFocus = document.activeElement;
132
156
  const initScrollTop = this.inner ? this.inner.scrollTop : 0;
133
- this.target.querySelectorAll('a[href]:not([disabled]),button:not([disabled]),textarea:not([disabled]),input[type="text"]:not([disabled]),input[type="radio"]:not([disabled]),input[type="checkbox"]:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])').forEach(el => {
157
+ this.target.querySelectorAll(focusableSelectors.join(',')).forEach(el => {
134
158
  el.focus();
135
159
 
136
160
  if (el === document.activeElement) {
@@ -790,6 +814,7 @@ class Drawer {
790
814
 
791
815
  focusTarget(drawer, this.settings);
792
816
  drawer.dispatchEvent(new CustomEvent(this.settings.customEventPrefix + 'opened', {
817
+ detail: this,
793
818
  bubbles: true
794
819
  }));
795
820
  this.working = false;
@@ -817,6 +842,7 @@ class Drawer {
817
842
  focusTrigger(this);
818
843
  this.focusTrap.destroy();
819
844
  drawer.dispatchEvent(new CustomEvent(this.settings.customEventPrefix + 'closed', {
845
+ detail: this,
820
846
  bubbles: true
821
847
  }));
822
848
  this.working = false;
@@ -1010,6 +1036,7 @@ class Modal {
1010
1036
  focusTarget(modal, this.settings);
1011
1037
  setInert(true, this.settings.selectorInert);
1012
1038
  modal.dispatchEvent(new CustomEvent(this.settings.customEventPrefix + 'opened', {
1039
+ detail: this,
1013
1040
  bubbles: true
1014
1041
  }));
1015
1042
  this.working = false;
@@ -1030,6 +1057,7 @@ class Modal {
1030
1057
  if (returnFocus) focusTrigger(this);
1031
1058
  this.focusTrap.destroy();
1032
1059
  modal.dispatchEvent(new CustomEvent(this.settings.customEventPrefix + 'closed', {
1060
+ detail: this,
1033
1061
  bubbles: true
1034
1062
  }));
1035
1063
  this.working = false;
@@ -1436,17 +1464,42 @@ function getBasePlacement(placement) {
1436
1464
  return placement.split('-')[0];
1437
1465
  }
1438
1466
 
1439
- function getBoundingClientRect(element) {
1467
+ var max = Math.max;
1468
+ var min = Math.min;
1469
+ var round = Math.round;
1470
+
1471
+ function getBoundingClientRect(element, includeScale) {
1472
+ if (includeScale === void 0) {
1473
+ includeScale = false;
1474
+ }
1475
+
1440
1476
  var rect = element.getBoundingClientRect();
1477
+ var scaleX = 1;
1478
+ var scaleY = 1;
1479
+
1480
+ if (isHTMLElement(element) && includeScale) {
1481
+ var offsetHeight = element.offsetHeight;
1482
+ var offsetWidth = element.offsetWidth; // Do not attempt to divide by 0, otherwise we get `Infinity` as scale
1483
+ // Fallback to 1 in case both values are `0`
1484
+
1485
+ if (offsetWidth > 0) {
1486
+ scaleX = round(rect.width) / offsetWidth || 1;
1487
+ }
1488
+
1489
+ if (offsetHeight > 0) {
1490
+ scaleY = round(rect.height) / offsetHeight || 1;
1491
+ }
1492
+ }
1493
+
1441
1494
  return {
1442
- width: rect.width,
1443
- height: rect.height,
1444
- top: rect.top,
1445
- right: rect.right,
1446
- bottom: rect.bottom,
1447
- left: rect.left,
1448
- x: rect.left,
1449
- y: rect.top
1495
+ width: rect.width / scaleX,
1496
+ height: rect.height / scaleY,
1497
+ top: rect.top / scaleY,
1498
+ right: rect.right / scaleX,
1499
+ bottom: rect.bottom / scaleY,
1500
+ left: rect.left / scaleX,
1501
+ x: rect.left / scaleX,
1502
+ y: rect.top / scaleY
1450
1503
  };
1451
1504
  }
1452
1505
 
@@ -1591,13 +1644,13 @@ function getMainAxisFromPlacement(placement) {
1591
1644
  return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
1592
1645
  }
1593
1646
 
1594
- var max = Math.max;
1595
- var min = Math.min;
1596
- var round = Math.round;
1597
-
1598
1647
  function within(min$1, value, max$1) {
1599
1648
  return max(min$1, min(value, max$1));
1600
1649
  }
1650
+ function withinMaxClamp(min, value, max) {
1651
+ var v = within(min, value, max);
1652
+ return v > max ? max : v;
1653
+ }
1601
1654
 
1602
1655
  function getFreshSideObject() {
1603
1656
  return {
@@ -1701,6 +1754,10 @@ var arrow$1 = {
1701
1754
  requiresIfExists: ['preventOverflow']
1702
1755
  };
1703
1756
 
1757
+ function getVariation(placement) {
1758
+ return placement.split('-')[1];
1759
+ }
1760
+
1704
1761
  var unsetSides = {
1705
1762
  top: 'auto',
1706
1763
  right: 'auto',
@@ -1716,8 +1773,8 @@ function roundOffsetsByDPR(_ref) {
1716
1773
  var win = window;
1717
1774
  var dpr = win.devicePixelRatio || 1;
1718
1775
  return {
1719
- x: round(round(x * dpr) / dpr) || 0,
1720
- y: round(round(y * dpr) / dpr) || 0
1776
+ x: round(x * dpr) / dpr || 0,
1777
+ y: round(y * dpr) / dpr || 0
1721
1778
  };
1722
1779
  }
1723
1780
 
@@ -1727,18 +1784,28 @@ function mapToStyles(_ref2) {
1727
1784
  var popper = _ref2.popper,
1728
1785
  popperRect = _ref2.popperRect,
1729
1786
  placement = _ref2.placement,
1787
+ variation = _ref2.variation,
1730
1788
  offsets = _ref2.offsets,
1731
1789
  position = _ref2.position,
1732
1790
  gpuAcceleration = _ref2.gpuAcceleration,
1733
1791
  adaptive = _ref2.adaptive,
1734
- roundOffsets = _ref2.roundOffsets;
1735
-
1736
- var _ref3 = roundOffsets === true ? roundOffsetsByDPR(offsets) : typeof roundOffsets === 'function' ? roundOffsets(offsets) : offsets,
1737
- _ref3$x = _ref3.x,
1738
- x = _ref3$x === void 0 ? 0 : _ref3$x,
1739
- _ref3$y = _ref3.y,
1740
- y = _ref3$y === void 0 ? 0 : _ref3$y;
1792
+ roundOffsets = _ref2.roundOffsets,
1793
+ isFixed = _ref2.isFixed;
1794
+ var _offsets$x = offsets.x,
1795
+ x = _offsets$x === void 0 ? 0 : _offsets$x,
1796
+ _offsets$y = offsets.y,
1797
+ y = _offsets$y === void 0 ? 0 : _offsets$y;
1798
+
1799
+ var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
1800
+ x: x,
1801
+ y: y
1802
+ }) : {
1803
+ x: x,
1804
+ y: y
1805
+ };
1741
1806
 
1807
+ x = _ref3.x;
1808
+ y = _ref3.y;
1742
1809
  var hasX = offsets.hasOwnProperty('x');
1743
1810
  var hasY = offsets.hasOwnProperty('y');
1744
1811
  var sideX = left;
@@ -1753,7 +1820,7 @@ function mapToStyles(_ref2) {
1753
1820
  if (offsetParent === getWindow(popper)) {
1754
1821
  offsetParent = getDocumentElement(popper);
1755
1822
 
1756
- if (getComputedStyle$1(offsetParent).position !== 'static') {
1823
+ if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') {
1757
1824
  heightProp = 'scrollHeight';
1758
1825
  widthProp = 'scrollWidth';
1759
1826
  }
@@ -1762,17 +1829,19 @@ function mapToStyles(_ref2) {
1762
1829
 
1763
1830
  offsetParent = offsetParent;
1764
1831
 
1765
- if (placement === top) {
1766
- sideY = bottom; // $FlowFixMe[prop-missing]
1767
-
1768
- y -= offsetParent[heightProp] - popperRect.height;
1832
+ if (placement === top || (placement === left || placement === right) && variation === end) {
1833
+ sideY = bottom;
1834
+ var offsetY = isFixed && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
1835
+ offsetParent[heightProp];
1836
+ y -= offsetY - popperRect.height;
1769
1837
  y *= gpuAcceleration ? 1 : -1;
1770
1838
  }
1771
1839
 
1772
- if (placement === left) {
1773
- sideX = right; // $FlowFixMe[prop-missing]
1774
-
1775
- x -= offsetParent[widthProp] - popperRect.width;
1840
+ if (placement === left || (placement === top || placement === bottom) && variation === end) {
1841
+ sideX = right;
1842
+ var offsetX = isFixed && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
1843
+ offsetParent[widthProp];
1844
+ x -= offsetX - popperRect.width;
1776
1845
  x *= gpuAcceleration ? 1 : -1;
1777
1846
  }
1778
1847
  }
@@ -1781,18 +1850,29 @@ function mapToStyles(_ref2) {
1781
1850
  position: position
1782
1851
  }, adaptive && unsetSides);
1783
1852
 
1853
+ var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
1854
+ x: x,
1855
+ y: y
1856
+ }) : {
1857
+ x: x,
1858
+ y: y
1859
+ };
1860
+
1861
+ x = _ref4.x;
1862
+ y = _ref4.y;
1863
+
1784
1864
  if (gpuAcceleration) {
1785
1865
  var _Object$assign;
1786
1866
 
1787
- return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
1867
+ return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
1788
1868
  }
1789
1869
 
1790
1870
  return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
1791
1871
  }
1792
1872
 
1793
- function computeStyles(_ref4) {
1794
- var state = _ref4.state,
1795
- options = _ref4.options;
1873
+ function computeStyles(_ref5) {
1874
+ var state = _ref5.state,
1875
+ options = _ref5.options;
1796
1876
  var _options$gpuAccelerat = options.gpuAcceleration,
1797
1877
  gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
1798
1878
  _options$adaptive = options.adaptive,
@@ -1802,9 +1882,11 @@ function computeStyles(_ref4) {
1802
1882
 
1803
1883
  var commonStyles = {
1804
1884
  placement: getBasePlacement(state.placement),
1885
+ variation: getVariation(state.placement),
1805
1886
  popper: state.elements.popper,
1806
1887
  popperRect: state.rects.popper,
1807
- gpuAcceleration: gpuAcceleration
1888
+ gpuAcceleration: gpuAcceleration,
1889
+ isFixed: state.options.strategy === 'fixed'
1808
1890
  };
1809
1891
 
1810
1892
  if (state.modifiersData.popperOffsets != null) {
@@ -2062,7 +2144,7 @@ function getInnerBoundingClientRect(element) {
2062
2144
  }
2063
2145
 
2064
2146
  function getClientRectFromMixedType(element, clippingParent) {
2065
- return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
2147
+ return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
2066
2148
  } // A "clipping parent" is an overflowable container with the characteristic of
2067
2149
  // clipping (or hiding) overflowing elements with a position different from
2068
2150
  // `initial`
@@ -2104,10 +2186,6 @@ function getClippingRect(element, boundary, rootBoundary) {
2104
2186
  return clippingRect;
2105
2187
  }
2106
2188
 
2107
- function getVariation(placement) {
2108
- return placement.split('-')[1];
2109
- }
2110
-
2111
2189
  function computeOffsets(_ref) {
2112
2190
  var reference = _ref.reference,
2113
2191
  element = _ref.element,
@@ -2193,11 +2271,10 @@ function detectOverflow(state, options) {
2193
2271
  padding = _options$padding === void 0 ? 0 : _options$padding;
2194
2272
  var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
2195
2273
  var altContext = elementContext === popper ? reference : popper;
2196
- var referenceElement = state.elements.reference;
2197
2274
  var popperRect = state.rects.popper;
2198
2275
  var element = state.elements[altBoundary ? altContext : elementContext];
2199
2276
  var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);
2200
- var referenceClientRect = getBoundingClientRect(referenceElement);
2277
+ var referenceClientRect = getBoundingClientRect(state.elements.reference);
2201
2278
  var popperOffsets = computeOffsets({
2202
2279
  reference: referenceClientRect,
2203
2280
  element: popperRect,
@@ -2580,6 +2657,14 @@ function preventOverflow(_ref) {
2580
2657
  var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
2581
2658
  placement: state.placement
2582
2659
  })) : tetherOffset;
2660
+ var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {
2661
+ mainAxis: tetherOffsetValue,
2662
+ altAxis: tetherOffsetValue
2663
+ } : Object.assign({
2664
+ mainAxis: 0,
2665
+ altAxis: 0
2666
+ }, tetherOffsetValue);
2667
+ var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
2583
2668
  var data = {
2584
2669
  x: 0,
2585
2670
  y: 0
@@ -2589,13 +2674,15 @@ function preventOverflow(_ref) {
2589
2674
  return;
2590
2675
  }
2591
2676
 
2592
- if (checkMainAxis || checkAltAxis) {
2677
+ if (checkMainAxis) {
2678
+ var _offsetModifierState$;
2679
+
2593
2680
  var mainSide = mainAxis === 'y' ? top : left;
2594
2681
  var altSide = mainAxis === 'y' ? bottom : right;
2595
2682
  var len = mainAxis === 'y' ? 'height' : 'width';
2596
2683
  var offset = popperOffsets[mainAxis];
2597
- var min$1 = popperOffsets[mainAxis] + overflow[mainSide];
2598
- var max$1 = popperOffsets[mainAxis] - overflow[altSide];
2684
+ var min$1 = offset + overflow[mainSide];
2685
+ var max$1 = offset - overflow[altSide];
2599
2686
  var additive = tether ? -popperRect[len] / 2 : 0;
2600
2687
  var minLen = variation === start ? referenceRect[len] : popperRect[len];
2601
2688
  var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
@@ -2615,36 +2702,45 @@ function preventOverflow(_ref) {
2615
2702
  // width or height)
2616
2703
 
2617
2704
  var arrowLen = within(0, referenceRect[len], arrowRect[len]);
2618
- var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;
2619
- var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;
2705
+ var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
2706
+ var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
2620
2707
  var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
2621
2708
  var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
2622
- var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0;
2623
- var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset;
2624
- var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;
2709
+ var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
2710
+ var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;
2711
+ var tetherMax = offset + maxOffset - offsetModifierValue;
2712
+ var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
2713
+ popperOffsets[mainAxis] = preventedOffset;
2714
+ data[mainAxis] = preventedOffset - offset;
2715
+ }
2625
2716
 
2626
- if (checkMainAxis) {
2627
- var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
2628
- popperOffsets[mainAxis] = preventedOffset;
2629
- data[mainAxis] = preventedOffset - offset;
2630
- }
2717
+ if (checkAltAxis) {
2718
+ var _offsetModifierState$2;
2631
2719
 
2632
- if (checkAltAxis) {
2633
- var _mainSide = mainAxis === 'x' ? top : left;
2720
+ var _mainSide = mainAxis === 'x' ? top : left;
2634
2721
 
2635
- var _altSide = mainAxis === 'x' ? bottom : right;
2722
+ var _altSide = mainAxis === 'x' ? bottom : right;
2636
2723
 
2637
- var _offset = popperOffsets[altAxis];
2724
+ var _offset = popperOffsets[altAxis];
2638
2725
 
2639
- var _min = _offset + overflow[_mainSide];
2726
+ var _len = altAxis === 'y' ? 'height' : 'width';
2640
2727
 
2641
- var _max = _offset - overflow[_altSide];
2728
+ var _min = _offset + overflow[_mainSide];
2642
2729
 
2643
- var _preventedOffset = within(tether ? min(_min, tetherMin) : _min, _offset, tether ? max(_max, tetherMax) : _max);
2730
+ var _max = _offset - overflow[_altSide];
2644
2731
 
2645
- popperOffsets[altAxis] = _preventedOffset;
2646
- data[altAxis] = _preventedOffset - _offset;
2647
- }
2732
+ var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
2733
+
2734
+ var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
2735
+
2736
+ var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
2737
+
2738
+ var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
2739
+
2740
+ var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
2741
+
2742
+ popperOffsets[altAxis] = _preventedOffset;
2743
+ data[altAxis] = _preventedOffset - _offset;
2648
2744
  }
2649
2745
 
2650
2746
  state.modifiersData[name] = data;
@@ -2674,16 +2770,24 @@ function getNodeScroll(node) {
2674
2770
  }
2675
2771
  }
2676
2772
 
2773
+ function isElementScaled(element) {
2774
+ var rect = element.getBoundingClientRect();
2775
+ var scaleX = round(rect.width) / element.offsetWidth || 1;
2776
+ var scaleY = round(rect.height) / element.offsetHeight || 1;
2777
+ return scaleX !== 1 || scaleY !== 1;
2778
+ } // Returns the composite rect of an element relative to its offsetParent.
2677
2779
  // Composite means it takes into account transforms as well as layout.
2678
2780
 
2781
+
2679
2782
  function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
2680
2783
  if (isFixed === void 0) {
2681
2784
  isFixed = false;
2682
2785
  }
2683
2786
 
2684
- var documentElement = getDocumentElement(offsetParent);
2685
- var rect = getBoundingClientRect(elementOrVirtualElement);
2686
2787
  var isOffsetParentAnElement = isHTMLElement(offsetParent);
2788
+ var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
2789
+ var documentElement = getDocumentElement(offsetParent);
2790
+ var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled);
2687
2791
  var scroll = {
2688
2792
  scrollLeft: 0,
2689
2793
  scrollTop: 0
@@ -2700,7 +2804,7 @@ function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
2700
2804
  }
2701
2805
 
2702
2806
  if (isHTMLElement(offsetParent)) {
2703
- offsets = getBoundingClientRect(offsetParent);
2807
+ offsets = getBoundingClientRect(offsetParent, true);
2704
2808
  offsets.x += offsetParent.clientLeft;
2705
2809
  offsets.y += offsetParent.clientTop;
2706
2810
  } else if (documentElement) {
@@ -2837,7 +2941,8 @@ function popperGenerator(generatorOptions) {
2837
2941
  var isDestroyed = false;
2838
2942
  var instance = {
2839
2943
  state: state,
2840
- setOptions: function setOptions(options) {
2944
+ setOptions: function setOptions(setOptionsAction) {
2945
+ var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
2841
2946
  cleanupModifierEffects();
2842
2947
  state.options = Object.assign({}, defaultOptions, state.options, options);
2843
2948
  state.scrollParents = {