@transferwise/components 0.0.0-experimental-9a61b0a → 0.0.0-experimental-73858ea
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/build/index.esm.js +183 -257
- package/build/index.esm.js.map +1 -1
- package/build/index.js +182 -256
- package/build/index.js.map +1 -1
- package/build/types/common/focusBoundary/FocusBoundary.d.ts +2 -2
- package/build/types/common/focusBoundary/FocusBoundary.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/common/bottomSheet/__snapshots__/BottomSheet.spec.tsx.snap +8 -1
- package/src/common/focusBoundary/FocusBoundary.tsx +9 -32
- package/build/types/common/focusBoundary/utils/getFocusableElements.d.ts +0 -2
- package/build/types/common/focusBoundary/utils/getFocusableElements.d.ts.map +0 -1
- package/build/types/common/focusBoundary/utils/index.d.ts +0 -3
- package/build/types/common/focusBoundary/utils/index.d.ts.map +0 -1
- package/build/types/common/focusBoundary/utils/resetFocus.d.ts +0 -2
- package/build/types/common/focusBoundary/utils/resetFocus.d.ts.map +0 -1
- package/src/common/focusBoundary/FocusBoundary.spec.tsx +0 -66
- package/src/common/focusBoundary/__snapshots__/FocusBoundary.spec.tsx.snap +0 -16
- package/src/common/focusBoundary/utils/getFocusableElements.js +0 -25
- package/src/common/focusBoundary/utils/getFocusableElements.spec.js +0 -51
- package/src/common/focusBoundary/utils/index.js +0 -2
- package/src/common/focusBoundary/utils/resetFocus.js +0 -23
- package/src/common/focusBoundary/utils/resetFocus.spec.js +0 -103
package/build/index.js
CHANGED
|
@@ -11,8 +11,9 @@ var formatting = require('@transferwise/formatting');
|
|
|
11
11
|
var throttle = require('lodash.throttle');
|
|
12
12
|
var reactTransitionGroup = require('react-transition-group');
|
|
13
13
|
var reactDom = require('react-dom');
|
|
14
|
-
var
|
|
14
|
+
var focus = require('@react-aria/focus');
|
|
15
15
|
var mergeRefs = require('react-merge-refs');
|
|
16
|
+
var neptuneValidation = require('@transferwise/neptune-validation');
|
|
16
17
|
var reactPopper = require('react-popper');
|
|
17
18
|
var react$1 = require('@headlessui/react');
|
|
18
19
|
var reactId = require('@radix-ui/react-id');
|
|
@@ -1490,268 +1491,23 @@ function getInitials(name) {
|
|
|
1490
1491
|
return allInitials[0] + allInitials.slice(-1);
|
|
1491
1492
|
}
|
|
1492
1493
|
|
|
1493
|
-
const THROTTLE_MS = 100;
|
|
1494
|
-
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
1495
|
-
const useClientWidth = ({
|
|
1496
|
-
ref,
|
|
1497
|
-
throttleMs = THROTTLE_MS
|
|
1498
|
-
}) => {
|
|
1499
|
-
const [clientWidth, setClientWidth] = React.useState(null);
|
|
1500
|
-
useIsomorphicLayoutEffect(() => {
|
|
1501
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
1502
|
-
const updateClientWidth = () => {
|
|
1503
|
-
if (ref) {
|
|
1504
|
-
// when `ref` is a window
|
|
1505
|
-
if ('innerWidth' in ref) {
|
|
1506
|
-
setClientWidth(ref.innerWidth);
|
|
1507
|
-
}
|
|
1508
|
-
// when `ref` is an element
|
|
1509
|
-
else if (ref.current) {
|
|
1510
|
-
setClientWidth(ref.current.clientWidth);
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
|
-
};
|
|
1514
|
-
// This assignment saves a reference to the function so it will be the same passed to both addEventListener removeEventListener.
|
|
1515
|
-
// If throttle gets passed directly to both add and removeEventListenet the results will be that the event
|
|
1516
|
-
// won't get removed even if the component is unmounted.
|
|
1517
|
-
const attachedFunction = throttle__default.default(updateClientWidth, throttleMs);
|
|
1518
|
-
window.addEventListener('resize', attachedFunction, true);
|
|
1519
|
-
// using requestAnimationFrame to perform the calculation before the next repaint
|
|
1520
|
-
// getting width earlier causes issues in animations when used with react-transition-group
|
|
1521
|
-
window.requestAnimationFrame(updateClientWidth);
|
|
1522
|
-
return () => window.removeEventListener('resize', attachedFunction, true);
|
|
1523
|
-
}, []);
|
|
1524
|
-
return [clientWidth];
|
|
1525
|
-
};
|
|
1526
|
-
useClientWidth.THROTTLE_MS = THROTTLE_MS;
|
|
1527
|
-
|
|
1528
|
-
const useConditionalListener = ({
|
|
1529
|
-
attachListener,
|
|
1530
|
-
callback,
|
|
1531
|
-
eventType,
|
|
1532
|
-
parent
|
|
1533
|
-
}) => {
|
|
1534
|
-
React.useEffect(() => {
|
|
1535
|
-
if (attachListener && !neptuneValidation.isUndefined(parent)) {
|
|
1536
|
-
parent.addEventListener(eventType, callback, true);
|
|
1537
|
-
}
|
|
1538
|
-
return () => {
|
|
1539
|
-
if (!neptuneValidation.isUndefined(parent)) {
|
|
1540
|
-
parent.removeEventListener(eventType, callback, true);
|
|
1541
|
-
}
|
|
1542
|
-
};
|
|
1543
|
-
}, [attachListener, callback, eventType, parent]);
|
|
1544
|
-
};
|
|
1545
|
-
|
|
1546
|
-
const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
|
|
1547
|
-
const DirectionProvider = ({
|
|
1548
|
-
direction,
|
|
1549
|
-
children
|
|
1550
|
-
}) => {
|
|
1551
|
-
return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
|
|
1552
|
-
value: direction,
|
|
1553
|
-
children: children
|
|
1554
|
-
});
|
|
1555
|
-
};
|
|
1556
|
-
|
|
1557
|
-
const useDirection = () => {
|
|
1558
|
-
const direction = React.useContext(DirectionContext);
|
|
1559
|
-
return {
|
|
1560
|
-
direction,
|
|
1561
|
-
isRTL: direction === 'rtl'
|
|
1562
|
-
};
|
|
1563
|
-
};
|
|
1564
|
-
|
|
1565
|
-
const ObserverParams = {
|
|
1566
|
-
threshold: 0.1
|
|
1567
|
-
};
|
|
1568
|
-
|
|
1569
|
-
/**
|
|
1570
|
-
* useHasIntersected.
|
|
1571
|
-
* Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
|
|
1572
|
-
* Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
|
|
1573
|
-
*
|
|
1574
|
-
* @param elRef.elRef
|
|
1575
|
-
* @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
|
|
1576
|
-
* @param {strimng} [loading = 'eager'] - string that contains the type of loading.
|
|
1577
|
-
* @param elRef.loading
|
|
1578
|
-
* @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
|
|
1579
|
-
*/
|
|
1580
|
-
const useHasIntersected = ({
|
|
1581
|
-
elRef,
|
|
1582
|
-
loading
|
|
1583
|
-
}) => {
|
|
1584
|
-
const [hasIntersected, setHasIntersected] = React.useState(false);
|
|
1585
|
-
const {
|
|
1586
|
-
current
|
|
1587
|
-
} = elRef || {};
|
|
1588
|
-
const isValidReference = () => {
|
|
1589
|
-
return elRef && current;
|
|
1590
|
-
};
|
|
1591
|
-
const handleOnIntersect = (entries, observer) => {
|
|
1592
|
-
entries.forEach(entry => {
|
|
1593
|
-
if (entry.isIntersecting) {
|
|
1594
|
-
setHasIntersected(true);
|
|
1595
|
-
observer.unobserve(current);
|
|
1596
|
-
}
|
|
1597
|
-
});
|
|
1598
|
-
};
|
|
1599
|
-
React.useEffect(() => {
|
|
1600
|
-
let observer;
|
|
1601
|
-
let didCancel = false;
|
|
1602
|
-
|
|
1603
|
-
// Check if window is define for SSR and Old browsers fallback
|
|
1604
|
-
if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
|
|
1605
|
-
setHasIntersected(true);
|
|
1606
|
-
} else if (!didCancel) {
|
|
1607
|
-
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
1608
|
-
observer.observe(current);
|
|
1609
|
-
}
|
|
1610
|
-
return () => {
|
|
1611
|
-
didCancel = true;
|
|
1612
|
-
if (observer) {
|
|
1613
|
-
observer.unobserve(current);
|
|
1614
|
-
}
|
|
1615
|
-
};
|
|
1616
|
-
}, [elRef]);
|
|
1617
|
-
if (loading === 'eager') {
|
|
1618
|
-
return [false];
|
|
1619
|
-
}
|
|
1620
|
-
return [hasIntersected];
|
|
1621
|
-
};
|
|
1622
|
-
|
|
1623
|
-
const useLayout = () => {
|
|
1624
|
-
const windowReference = typeof window === 'undefined' ? undefined : window;
|
|
1625
|
-
const [breakpoint, setBreakpoint] = React.useState();
|
|
1626
|
-
const [clientWidth] = useClientWidth({
|
|
1627
|
-
ref: windowReference
|
|
1628
|
-
});
|
|
1629
|
-
React.useEffect(() => {
|
|
1630
|
-
if (!clientWidth) {
|
|
1631
|
-
return;
|
|
1632
|
-
}
|
|
1633
|
-
if (clientWidth <= exports.Breakpoint.EXTRA_SMALL) {
|
|
1634
|
-
setBreakpoint(exports.Breakpoint.EXTRA_SMALL);
|
|
1635
|
-
return;
|
|
1636
|
-
}
|
|
1637
|
-
if (exports.Breakpoint.EXTRA_SMALL < clientWidth && clientWidth <= exports.Breakpoint.SMALL) {
|
|
1638
|
-
setBreakpoint(exports.Breakpoint.SMALL);
|
|
1639
|
-
return;
|
|
1640
|
-
}
|
|
1641
|
-
if (exports.Breakpoint.SMALL < clientWidth && clientWidth <= exports.Breakpoint.MEDIUM) {
|
|
1642
|
-
setBreakpoint(exports.Breakpoint.MEDIUM);
|
|
1643
|
-
return;
|
|
1644
|
-
}
|
|
1645
|
-
if (exports.Breakpoint.MEDIUM < clientWidth && clientWidth <= exports.Breakpoint.LARGE) {
|
|
1646
|
-
setBreakpoint(exports.Breakpoint.LARGE);
|
|
1647
|
-
return;
|
|
1648
|
-
}
|
|
1649
|
-
if (exports.Breakpoint.LARGE < clientWidth) {
|
|
1650
|
-
setBreakpoint(exports.Breakpoint.EXTRA_LARGE);
|
|
1651
|
-
}
|
|
1652
|
-
}, [clientWidth]);
|
|
1653
|
-
return {
|
|
1654
|
-
isMobile: !!breakpoint && [exports.Breakpoint.EXTRA_SMALL, exports.Breakpoint.SMALL].includes(breakpoint),
|
|
1655
|
-
isExtraSmall: breakpoint === exports.Breakpoint.EXTRA_SMALL,
|
|
1656
|
-
isSmall: breakpoint === exports.Breakpoint.SMALL,
|
|
1657
|
-
isMedium: breakpoint === exports.Breakpoint.MEDIUM,
|
|
1658
|
-
isLarge: breakpoint === exports.Breakpoint.LARGE,
|
|
1659
|
-
isExtraLarge: breakpoint === exports.Breakpoint.EXTRA_LARGE
|
|
1660
|
-
};
|
|
1661
|
-
};
|
|
1662
|
-
|
|
1663
|
-
/**
|
|
1664
|
-
* This function returns the first and the last focusable elements within a node.
|
|
1665
|
-
*
|
|
1666
|
-
* @param {Node} focusBoundaryContainer - the area that contains focused elements.
|
|
1667
|
-
* @returns {object} focusableEls - which contains the first focusable element and the last focusable element. First and last can be the same element if area contains one or none focusable element.
|
|
1668
|
-
*/
|
|
1669
|
-
|
|
1670
|
-
const getFocusableElements = focusBoundaryContainer => {
|
|
1671
|
-
const focusableEls = {
|
|
1672
|
-
first: focusBoundaryContainer,
|
|
1673
|
-
last: focusBoundaryContainer
|
|
1674
|
-
};
|
|
1675
|
-
if (focusBoundaryContainer?.querySelectorAll) {
|
|
1676
|
-
const allEls = [...focusBoundaryContainer.querySelectorAll('a, button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])')].filter(element => !element.hasAttribute('disabled'));
|
|
1677
|
-
if (allEls.length > 0) {
|
|
1678
|
-
[focusableEls.first] = allEls;
|
|
1679
|
-
focusableEls.last = allEls[allEls.length - 1];
|
|
1680
|
-
}
|
|
1681
|
-
}
|
|
1682
|
-
return focusableEls;
|
|
1683
|
-
};
|
|
1684
|
-
|
|
1685
|
-
/**
|
|
1686
|
-
* This function resets the focus to either last of first focusable elements within a node.
|
|
1687
|
-
*
|
|
1688
|
-
* @param {object} focusableEls - contains the first last of first focusable elements within a node.
|
|
1689
|
-
* @param {object} event - the triggered event
|
|
1690
|
-
*/
|
|
1691
|
-
|
|
1692
|
-
const resetFocus = ({
|
|
1693
|
-
focusableEls: {
|
|
1694
|
-
first,
|
|
1695
|
-
last
|
|
1696
|
-
},
|
|
1697
|
-
event
|
|
1698
|
-
}) => {
|
|
1699
|
-
const {
|
|
1700
|
-
activeElement
|
|
1701
|
-
} = document;
|
|
1702
|
-
if (event.shiftKey && activeElement === first) {
|
|
1703
|
-
if (last) {
|
|
1704
|
-
last.focus();
|
|
1705
|
-
}
|
|
1706
|
-
event.preventDefault();
|
|
1707
|
-
}
|
|
1708
|
-
if (!event.shiftKey && activeElement === last) {
|
|
1709
|
-
if (first) {
|
|
1710
|
-
first.focus();
|
|
1711
|
-
}
|
|
1712
|
-
event.preventDefault();
|
|
1713
|
-
}
|
|
1714
|
-
};
|
|
1715
|
-
|
|
1716
|
-
const {
|
|
1717
|
-
TAB
|
|
1718
|
-
} = Key;
|
|
1719
1494
|
const FocusBoundary = ({
|
|
1720
1495
|
children
|
|
1721
1496
|
}) => {
|
|
1722
|
-
const
|
|
1723
|
-
const parent = neptuneValidation.isUndefined(document) ? undefined : document;
|
|
1724
|
-
const [focusableEls, setFocusableEls] = React.useState({});
|
|
1497
|
+
const wrapperReference = React.useRef(null);
|
|
1725
1498
|
React.useEffect(() => {
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
});
|
|
1730
|
-
setFocusableEls(getFocusableElements(boundaryReference.current));
|
|
1731
|
-
}
|
|
1499
|
+
wrapperReference.current?.focus({
|
|
1500
|
+
preventScroll: true
|
|
1501
|
+
});
|
|
1732
1502
|
}, []);
|
|
1733
|
-
// If event type is Tab the resetFocus will force the focus to either the first focusable or last in boundaryRef .
|
|
1734
|
-
useConditionalListener({
|
|
1735
|
-
eventType: 'keydown',
|
|
1736
|
-
callback: event => {
|
|
1737
|
-
if (neptuneValidation.isKey({
|
|
1738
|
-
keyType: TAB,
|
|
1739
|
-
event
|
|
1740
|
-
})) {
|
|
1741
|
-
resetFocus({
|
|
1742
|
-
event,
|
|
1743
|
-
focusableEls
|
|
1744
|
-
});
|
|
1745
|
-
}
|
|
1746
|
-
},
|
|
1747
|
-
attachListener: true,
|
|
1748
|
-
parent
|
|
1749
|
-
});
|
|
1750
1503
|
return /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
1751
|
-
ref:
|
|
1504
|
+
ref: wrapperReference,
|
|
1752
1505
|
tabIndex: -1,
|
|
1753
|
-
|
|
1754
|
-
|
|
1506
|
+
children: /*#__PURE__*/jsxRuntime.jsx(focus.FocusScope, {
|
|
1507
|
+
contain: true,
|
|
1508
|
+
restoreFocus: true,
|
|
1509
|
+
children: children
|
|
1510
|
+
})
|
|
1755
1511
|
});
|
|
1756
1512
|
};
|
|
1757
1513
|
var FocusBoundary$1 = FocusBoundary;
|
|
@@ -2007,6 +1763,176 @@ SlidingPanel.defaultProps = {
|
|
|
2007
1763
|
};
|
|
2008
1764
|
var SlidingPanel$1 = SlidingPanel;
|
|
2009
1765
|
|
|
1766
|
+
const THROTTLE_MS = 100;
|
|
1767
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
1768
|
+
const useClientWidth = ({
|
|
1769
|
+
ref,
|
|
1770
|
+
throttleMs = THROTTLE_MS
|
|
1771
|
+
}) => {
|
|
1772
|
+
const [clientWidth, setClientWidth] = React.useState(null);
|
|
1773
|
+
useIsomorphicLayoutEffect(() => {
|
|
1774
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
1775
|
+
const updateClientWidth = () => {
|
|
1776
|
+
if (ref) {
|
|
1777
|
+
// when `ref` is a window
|
|
1778
|
+
if ('innerWidth' in ref) {
|
|
1779
|
+
setClientWidth(ref.innerWidth);
|
|
1780
|
+
}
|
|
1781
|
+
// when `ref` is an element
|
|
1782
|
+
else if (ref.current) {
|
|
1783
|
+
setClientWidth(ref.current.clientWidth);
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
// This assignment saves a reference to the function so it will be the same passed to both addEventListener removeEventListener.
|
|
1788
|
+
// If throttle gets passed directly to both add and removeEventListenet the results will be that the event
|
|
1789
|
+
// won't get removed even if the component is unmounted.
|
|
1790
|
+
const attachedFunction = throttle__default.default(updateClientWidth, throttleMs);
|
|
1791
|
+
window.addEventListener('resize', attachedFunction, true);
|
|
1792
|
+
// using requestAnimationFrame to perform the calculation before the next repaint
|
|
1793
|
+
// getting width earlier causes issues in animations when used with react-transition-group
|
|
1794
|
+
window.requestAnimationFrame(updateClientWidth);
|
|
1795
|
+
return () => window.removeEventListener('resize', attachedFunction, true);
|
|
1796
|
+
}, []);
|
|
1797
|
+
return [clientWidth];
|
|
1798
|
+
};
|
|
1799
|
+
useClientWidth.THROTTLE_MS = THROTTLE_MS;
|
|
1800
|
+
|
|
1801
|
+
const useConditionalListener = ({
|
|
1802
|
+
attachListener,
|
|
1803
|
+
callback,
|
|
1804
|
+
eventType,
|
|
1805
|
+
parent
|
|
1806
|
+
}) => {
|
|
1807
|
+
React.useEffect(() => {
|
|
1808
|
+
if (attachListener && !neptuneValidation.isUndefined(parent)) {
|
|
1809
|
+
parent.addEventListener(eventType, callback, true);
|
|
1810
|
+
}
|
|
1811
|
+
return () => {
|
|
1812
|
+
if (!neptuneValidation.isUndefined(parent)) {
|
|
1813
|
+
parent.removeEventListener(eventType, callback, true);
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
}, [attachListener, callback, eventType, parent]);
|
|
1817
|
+
};
|
|
1818
|
+
|
|
1819
|
+
const DirectionContext = /*#__PURE__*/React.createContext(exports.Direction.LTR);
|
|
1820
|
+
const DirectionProvider = ({
|
|
1821
|
+
direction,
|
|
1822
|
+
children
|
|
1823
|
+
}) => {
|
|
1824
|
+
return /*#__PURE__*/jsxRuntime.jsx(DirectionContext.Provider, {
|
|
1825
|
+
value: direction,
|
|
1826
|
+
children: children
|
|
1827
|
+
});
|
|
1828
|
+
};
|
|
1829
|
+
|
|
1830
|
+
const useDirection = () => {
|
|
1831
|
+
const direction = React.useContext(DirectionContext);
|
|
1832
|
+
return {
|
|
1833
|
+
direction,
|
|
1834
|
+
isRTL: direction === 'rtl'
|
|
1835
|
+
};
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1838
|
+
const ObserverParams = {
|
|
1839
|
+
threshold: 0.1
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1842
|
+
/**
|
|
1843
|
+
* useHasIntersected.
|
|
1844
|
+
* Use this custom hook to detect when an element has became visible inside the viewport. This hook checks only if the intersection happend.
|
|
1845
|
+
* Once the intersection has happened the hook will not return false even if the element gets out of the viewport.
|
|
1846
|
+
*
|
|
1847
|
+
* @param elRef.elRef
|
|
1848
|
+
* @param {object} [elRef] - node object that contains a react reference to the element that needs to be observed.
|
|
1849
|
+
* @param {strimng} [loading = 'eager'] - string that contains the type of loading.
|
|
1850
|
+
* @param elRef.loading
|
|
1851
|
+
* @usage `const [hasIntersected] = useHasIntersected({imageRef,loading});`
|
|
1852
|
+
*/
|
|
1853
|
+
const useHasIntersected = ({
|
|
1854
|
+
elRef,
|
|
1855
|
+
loading
|
|
1856
|
+
}) => {
|
|
1857
|
+
const [hasIntersected, setHasIntersected] = React.useState(false);
|
|
1858
|
+
const {
|
|
1859
|
+
current
|
|
1860
|
+
} = elRef || {};
|
|
1861
|
+
const isValidReference = () => {
|
|
1862
|
+
return elRef && current;
|
|
1863
|
+
};
|
|
1864
|
+
const handleOnIntersect = (entries, observer) => {
|
|
1865
|
+
entries.forEach(entry => {
|
|
1866
|
+
if (entry.isIntersecting) {
|
|
1867
|
+
setHasIntersected(true);
|
|
1868
|
+
observer.unobserve(current);
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
};
|
|
1872
|
+
React.useEffect(() => {
|
|
1873
|
+
let observer;
|
|
1874
|
+
let didCancel = false;
|
|
1875
|
+
|
|
1876
|
+
// Check if window is define for SSR and Old browsers fallback
|
|
1877
|
+
if (typeof window === 'undefined' || !window.IntersectionObserver || !isValidReference()) {
|
|
1878
|
+
setHasIntersected(true);
|
|
1879
|
+
} else if (!didCancel) {
|
|
1880
|
+
observer = new IntersectionObserver(handleOnIntersect, ObserverParams);
|
|
1881
|
+
observer.observe(current);
|
|
1882
|
+
}
|
|
1883
|
+
return () => {
|
|
1884
|
+
didCancel = true;
|
|
1885
|
+
if (observer) {
|
|
1886
|
+
observer.unobserve(current);
|
|
1887
|
+
}
|
|
1888
|
+
};
|
|
1889
|
+
}, [elRef]);
|
|
1890
|
+
if (loading === 'eager') {
|
|
1891
|
+
return [false];
|
|
1892
|
+
}
|
|
1893
|
+
return [hasIntersected];
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1896
|
+
const useLayout = () => {
|
|
1897
|
+
const windowReference = typeof window === 'undefined' ? undefined : window;
|
|
1898
|
+
const [breakpoint, setBreakpoint] = React.useState();
|
|
1899
|
+
const [clientWidth] = useClientWidth({
|
|
1900
|
+
ref: windowReference
|
|
1901
|
+
});
|
|
1902
|
+
React.useEffect(() => {
|
|
1903
|
+
if (!clientWidth) {
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (clientWidth <= exports.Breakpoint.EXTRA_SMALL) {
|
|
1907
|
+
setBreakpoint(exports.Breakpoint.EXTRA_SMALL);
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
if (exports.Breakpoint.EXTRA_SMALL < clientWidth && clientWidth <= exports.Breakpoint.SMALL) {
|
|
1911
|
+
setBreakpoint(exports.Breakpoint.SMALL);
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
if (exports.Breakpoint.SMALL < clientWidth && clientWidth <= exports.Breakpoint.MEDIUM) {
|
|
1915
|
+
setBreakpoint(exports.Breakpoint.MEDIUM);
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
if (exports.Breakpoint.MEDIUM < clientWidth && clientWidth <= exports.Breakpoint.LARGE) {
|
|
1919
|
+
setBreakpoint(exports.Breakpoint.LARGE);
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1922
|
+
if (exports.Breakpoint.LARGE < clientWidth) {
|
|
1923
|
+
setBreakpoint(exports.Breakpoint.EXTRA_LARGE);
|
|
1924
|
+
}
|
|
1925
|
+
}, [clientWidth]);
|
|
1926
|
+
return {
|
|
1927
|
+
isMobile: !!breakpoint && [exports.Breakpoint.EXTRA_SMALL, exports.Breakpoint.SMALL].includes(breakpoint),
|
|
1928
|
+
isExtraSmall: breakpoint === exports.Breakpoint.EXTRA_SMALL,
|
|
1929
|
+
isSmall: breakpoint === exports.Breakpoint.SMALL,
|
|
1930
|
+
isMedium: breakpoint === exports.Breakpoint.MEDIUM,
|
|
1931
|
+
isLarge: breakpoint === exports.Breakpoint.LARGE,
|
|
1932
|
+
isExtraLarge: breakpoint === exports.Breakpoint.EXTRA_LARGE
|
|
1933
|
+
};
|
|
1934
|
+
};
|
|
1935
|
+
|
|
2010
1936
|
const INITIAL_Y_POSITION = 0;
|
|
2011
1937
|
const CONTENT_SCROLL_THRESHOLD = 1;
|
|
2012
1938
|
const MOVE_OFFSET_THRESHOLD = 50;
|