@samline/drawer 2.0.4 → 2.0.6
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 +1 -0
- package/dist/{svelte/components-client-DXeaMmfk.js → browser/components-client-CJuQ5vtW.js} +172 -31
- package/dist/browser/{components-client-CZSt5H60.mjs → components-client-tfLTRxPH.mjs} +173 -32
- package/dist/browser/index.cjs +192 -34
- package/dist/browser/index.js +192 -34
- package/dist/browser/index.mjs +192 -34
- package/dist/{browser/components-client-DXeaMmfk.js → components-client-CJuQ5vtW.js} +172 -31
- package/dist/{svelte/components-client-CZSt5H60.mjs → components-client-tfLTRxPH.mjs} +173 -32
- package/dist/index.js +192 -34
- package/dist/index.mjs +192 -34
- package/dist/react/index.js +193 -31
- package/dist/react/index.mjs +194 -32
- package/dist/{vue/components-client-DXeaMmfk.js → svelte/components-client-CJuQ5vtW.js} +172 -31
- package/dist/{components-client-CZSt5H60.mjs → svelte/components-client-tfLTRxPH.mjs} +173 -32
- package/dist/svelte/index.js +192 -34
- package/dist/svelte/index.mjs +192 -34
- package/dist/{components-client-DXeaMmfk.js → vue/components-client-CJuQ5vtW.js} +172 -31
- package/dist/vue/{components-client-DZfql3-W.mjs → components-client-DSM2G8ef.mjs} +173 -32
- package/dist/vue/index.js +192 -34
- package/dist/vue/index.mjs +192 -34
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -215,30 +215,38 @@ const nonTextInputTypes = new Set([
|
|
|
215
215
|
'submit',
|
|
216
216
|
'reset'
|
|
217
217
|
]);
|
|
218
|
-
|
|
219
|
-
let
|
|
220
|
-
|
|
218
|
+
const activePreventScrollLocks = new Set();
|
|
219
|
+
let activePreventScrollRestore = null;
|
|
220
|
+
function acquirePreventScrollLock(lockId) {
|
|
221
|
+
activePreventScrollLocks.add(lockId);
|
|
222
|
+
if (activePreventScrollLocks.size === 1 && isIOS()) {
|
|
223
|
+
activePreventScrollRestore = preventScrollMobileSafari();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function releasePreventScrollLock(lockId) {
|
|
227
|
+
activePreventScrollLocks.delete(lockId);
|
|
228
|
+
if (activePreventScrollLocks.size === 0) {
|
|
229
|
+
activePreventScrollRestore == null ? void 0 : activePreventScrollRestore();
|
|
230
|
+
activePreventScrollRestore = null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
221
233
|
/**
|
|
222
234
|
* Prevents scrolling on the document body on mount, and
|
|
223
235
|
* restores it on unmount. Also ensures that content does not
|
|
224
236
|
* shift due to the scrollbars disappearing.
|
|
225
237
|
*/ function usePreventScroll(options = {}) {
|
|
226
238
|
let { isDisabled } = options;
|
|
239
|
+
const lockIdRef = React.useRef();
|
|
240
|
+
if (!lockIdRef.current) {
|
|
241
|
+
lockIdRef.current = Symbol('drawer-prevent-scroll-lock');
|
|
242
|
+
}
|
|
227
243
|
useIsomorphicLayoutEffect(()=>{
|
|
228
244
|
if (isDisabled) {
|
|
229
245
|
return;
|
|
230
246
|
}
|
|
231
|
-
|
|
232
|
-
if (preventScrollCount === 1) {
|
|
233
|
-
if (isIOS()) {
|
|
234
|
-
restore = preventScrollMobileSafari();
|
|
235
|
-
}
|
|
236
|
-
}
|
|
247
|
+
acquirePreventScrollLock(lockIdRef.current);
|
|
237
248
|
return ()=>{
|
|
238
|
-
|
|
239
|
-
if (preventScrollCount === 0) {
|
|
240
|
-
restore == null ? void 0 : restore();
|
|
241
|
-
}
|
|
249
|
+
releasePreventScrollLock(lockIdRef.current);
|
|
242
250
|
};
|
|
243
251
|
}, [
|
|
244
252
|
isDisabled
|
|
@@ -973,12 +981,23 @@ function useScaleBackground() {
|
|
|
973
981
|
const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext();
|
|
974
982
|
const timeoutIdRef = React__namespace.default.useRef(null);
|
|
975
983
|
const initialBackgroundColor = React.useMemo(()=>document.body.style.backgroundColor, []);
|
|
984
|
+
React__namespace.default.useEffect(()=>{
|
|
985
|
+
return ()=>{
|
|
986
|
+
if (timeoutIdRef.current !== null) {
|
|
987
|
+
window.clearTimeout(timeoutIdRef.current);
|
|
988
|
+
timeoutIdRef.current = null;
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
}, []);
|
|
976
992
|
function getScale() {
|
|
977
993
|
return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
|
|
978
994
|
}
|
|
979
995
|
React__namespace.default.useEffect(()=>{
|
|
980
996
|
if (isOpen && shouldScaleBackground) {
|
|
981
|
-
if (timeoutIdRef.current)
|
|
997
|
+
if (timeoutIdRef.current !== null) {
|
|
998
|
+
clearTimeout(timeoutIdRef.current);
|
|
999
|
+
timeoutIdRef.current = null;
|
|
1000
|
+
}
|
|
982
1001
|
const wrapper = document.querySelector('[data-drawer-wrapper]');
|
|
983
1002
|
if (!wrapper) return;
|
|
984
1003
|
chain(setBackgroundColorOnScale && !noBodyStyles ? assignStyle(document.body, {
|
|
@@ -1006,6 +1025,7 @@ function useScaleBackground() {
|
|
|
1006
1025
|
} else {
|
|
1007
1026
|
document.body.style.removeProperty('background');
|
|
1008
1027
|
}
|
|
1028
|
+
timeoutIdRef.current = null;
|
|
1009
1029
|
}, TRANSITIONS.DURATION * 1000);
|
|
1010
1030
|
};
|
|
1011
1031
|
}
|
|
@@ -1017,6 +1037,14 @@ function useScaleBackground() {
|
|
|
1017
1037
|
}
|
|
1018
1038
|
|
|
1019
1039
|
let previousBodyPosition = null;
|
|
1040
|
+
const activeBodyPositionLocks = new Set();
|
|
1041
|
+
let bodyPositionTimeoutId = null;
|
|
1042
|
+
function clearBodyPositionTimeout() {
|
|
1043
|
+
if (bodyPositionTimeoutId !== null) {
|
|
1044
|
+
window.clearTimeout(bodyPositionTimeoutId);
|
|
1045
|
+
bodyPositionTimeoutId = null;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1020
1048
|
/**
|
|
1021
1049
|
* This hook is necessary to prevent buggy behavior on iOS devices (need to test on Android).
|
|
1022
1050
|
* I won't get into too much detail about what bugs it solves, but so far I've found that setting the body to `position: fixed` is the most reliable way to prevent those bugs.
|
|
@@ -1024,9 +1052,18 @@ let previousBodyPosition = null;
|
|
|
1024
1052
|
*/ function usePositionFixed({ isOpen, modal, nested, hasBeenOpened, preventScrollRestoration, noBodyStyles }) {
|
|
1025
1053
|
const [activeUrl, setActiveUrl] = React__namespace.default.useState(()=>typeof window !== 'undefined' ? window.location.href : '');
|
|
1026
1054
|
const scrollPos = React__namespace.default.useRef(0);
|
|
1055
|
+
const lockIdRef = React__namespace.default.useRef();
|
|
1056
|
+
if (!lockIdRef.current) {
|
|
1057
|
+
lockIdRef.current = Symbol('drawer-body-position-lock');
|
|
1058
|
+
}
|
|
1027
1059
|
const setPositionFixed = React__namespace.default.useCallback(()=>{
|
|
1028
1060
|
// All browsers on iOS will return true here.
|
|
1029
1061
|
if (!isSafari()) return;
|
|
1062
|
+
const lockId = lockIdRef.current;
|
|
1063
|
+
if (activeBodyPositionLocks.has(lockId)) {
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
activeBodyPositionLocks.add(lockId);
|
|
1030
1067
|
// If previousBodyPosition is already set, don't set it again.
|
|
1031
1068
|
if (previousBodyPosition === null && isOpen && !noBodyStyles) {
|
|
1032
1069
|
previousBodyPosition = {
|
|
@@ -1045,7 +1082,8 @@ let previousBodyPosition = null;
|
|
|
1045
1082
|
right: '0px',
|
|
1046
1083
|
height: 'auto'
|
|
1047
1084
|
});
|
|
1048
|
-
|
|
1085
|
+
clearBodyPositionTimeout();
|
|
1086
|
+
bodyPositionTimeoutId = window.setTimeout(()=>window.requestAnimationFrame(()=>{
|
|
1049
1087
|
// Attempt to check if the bottom bar appeared due to the position change
|
|
1050
1088
|
const bottomBarHeight = innerHeight - window.innerHeight;
|
|
1051
1089
|
if (bottomBarHeight && scrollPos.current >= innerHeight) {
|
|
@@ -1055,12 +1093,19 @@ let previousBodyPosition = null;
|
|
|
1055
1093
|
}), 300);
|
|
1056
1094
|
}
|
|
1057
1095
|
}, [
|
|
1058
|
-
isOpen
|
|
1096
|
+
isOpen,
|
|
1097
|
+
noBodyStyles
|
|
1059
1098
|
]);
|
|
1060
1099
|
const restorePositionSetting = React__namespace.default.useCallback(()=>{
|
|
1061
1100
|
// All browsers on iOS will return true here.
|
|
1062
1101
|
if (!isSafari()) return;
|
|
1102
|
+
const lockId = lockIdRef.current;
|
|
1103
|
+
activeBodyPositionLocks.delete(lockId);
|
|
1104
|
+
if (activeBodyPositionLocks.size > 0) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1063
1107
|
if (previousBodyPosition !== null && !noBodyStyles) {
|
|
1108
|
+
clearBodyPositionTimeout();
|
|
1064
1109
|
// Convert the position from "px" to Int
|
|
1065
1110
|
const y = -parseInt(document.body.style.top, 10);
|
|
1066
1111
|
const x = -parseInt(document.body.style.left, 10);
|
|
@@ -1076,7 +1121,9 @@ let previousBodyPosition = null;
|
|
|
1076
1121
|
previousBodyPosition = null;
|
|
1077
1122
|
}
|
|
1078
1123
|
}, [
|
|
1079
|
-
activeUrl
|
|
1124
|
+
activeUrl,
|
|
1125
|
+
noBodyStyles,
|
|
1126
|
+
setActiveUrl
|
|
1080
1127
|
]);
|
|
1081
1128
|
React__namespace.default.useEffect(()=>{
|
|
1082
1129
|
function onScroll() {
|
|
@@ -1426,8 +1473,15 @@ function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeS
|
|
|
1426
1473
|
};
|
|
1427
1474
|
}
|
|
1428
1475
|
|
|
1476
|
+
const useSafeLayoutEffect$1 = typeof window === 'undefined' ? React__namespace.default.useEffect : React__namespace.default.useLayoutEffect;
|
|
1429
1477
|
function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction = 'bottom', defaultOpen = false, disablePreventScroll = true, snapToSequentialPoint = false, preventScrollRestoration = false, repositionInputs = true, onAnimationEnd, container, autoFocus = false }) {
|
|
1430
1478
|
var _drawerRef_current, _drawerRef_current1;
|
|
1479
|
+
const animationEndTimeoutRef = React__namespace.default.useRef(null);
|
|
1480
|
+
const nonModalPointerEventsRafRef = React__namespace.default.useRef(null);
|
|
1481
|
+
const shouldAnimateRafRef = React__namespace.default.useRef(null);
|
|
1482
|
+
const snapPointsResetTimeoutRef = React__namespace.default.useRef(null);
|
|
1483
|
+
const justReleasedTimeoutRef = React__namespace.default.useRef(null);
|
|
1484
|
+
const touchEndHandlerRef = React__namespace.default.useRef(null);
|
|
1431
1485
|
const [isOpen = false, setIsOpen] = useControllableState({
|
|
1432
1486
|
defaultProp: defaultOpen,
|
|
1433
1487
|
prop: openProp,
|
|
@@ -1436,13 +1490,20 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1436
1490
|
if (!o && !nested) {
|
|
1437
1491
|
restorePositionSetting();
|
|
1438
1492
|
}
|
|
1439
|
-
|
|
1493
|
+
if (animationEndTimeoutRef.current !== null) {
|
|
1494
|
+
window.clearTimeout(animationEndTimeoutRef.current);
|
|
1495
|
+
}
|
|
1496
|
+
animationEndTimeoutRef.current = window.setTimeout(()=>{
|
|
1440
1497
|
onAnimationEnd == null ? void 0 : onAnimationEnd(o);
|
|
1441
1498
|
}, TRANSITIONS.DURATION * 1000);
|
|
1442
1499
|
if (o && !modal) {
|
|
1443
1500
|
if (typeof window !== 'undefined') {
|
|
1444
|
-
|
|
1501
|
+
if (nonModalPointerEventsRafRef.current !== null) {
|
|
1502
|
+
window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
|
|
1503
|
+
}
|
|
1504
|
+
nonModalPointerEventsRafRef.current = window.requestAnimationFrame(()=>{
|
|
1445
1505
|
document.body.style.pointerEvents = 'auto';
|
|
1506
|
+
nonModalPointerEventsRafRef.current = null;
|
|
1446
1507
|
});
|
|
1447
1508
|
}
|
|
1448
1509
|
}
|
|
@@ -1520,19 +1581,23 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1520
1581
|
noBodyStyles,
|
|
1521
1582
|
autoFocus
|
|
1522
1583
|
});
|
|
1523
|
-
|
|
1584
|
+
useSafeLayoutEffect$1(()=>{
|
|
1524
1585
|
var _drawerRef_current;
|
|
1525
1586
|
if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
|
|
1526
1587
|
return;
|
|
1527
1588
|
}
|
|
1528
1589
|
const activeElement = document.activeElement;
|
|
1529
|
-
if (!
|
|
1590
|
+
if (!activeElement || activeElement === document.body) {
|
|
1530
1591
|
return;
|
|
1531
1592
|
}
|
|
1532
|
-
|
|
1593
|
+
const activeElementNode = activeElement;
|
|
1594
|
+
if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElementNode)) || (activeElementNode.closest == null ? void 0 : activeElementNode.closest.call(activeElementNode, '[data-drawer]'))) {
|
|
1533
1595
|
return;
|
|
1534
1596
|
}
|
|
1535
|
-
|
|
1597
|
+
if (typeof activeElementNode.blur !== 'function') {
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
activeElementNode.blur();
|
|
1536
1601
|
}, [
|
|
1537
1602
|
autoFocus,
|
|
1538
1603
|
isOpen,
|
|
@@ -1551,7 +1616,15 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1551
1616
|
dragStartTime.current = new Date();
|
|
1552
1617
|
// iOS doesn't trigger mouseUp after scrolling so we need to listen to touched in order to disallow dragging
|
|
1553
1618
|
if (isIOS()) {
|
|
1554
|
-
|
|
1619
|
+
if (touchEndHandlerRef.current) {
|
|
1620
|
+
window.removeEventListener('touchend', touchEndHandlerRef.current);
|
|
1621
|
+
}
|
|
1622
|
+
const handleTouchEnd = ()=>{
|
|
1623
|
+
isAllowedToDrag.current = false;
|
|
1624
|
+
touchEndHandlerRef.current = null;
|
|
1625
|
+
};
|
|
1626
|
+
touchEndHandlerRef.current = handleTouchEnd;
|
|
1627
|
+
window.addEventListener('touchend', handleTouchEnd, {
|
|
1555
1628
|
once: true
|
|
1556
1629
|
});
|
|
1557
1630
|
}
|
|
@@ -1668,9 +1741,15 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1668
1741
|
}
|
|
1669
1742
|
}
|
|
1670
1743
|
React__namespace.default.useEffect(()=>{
|
|
1671
|
-
window.requestAnimationFrame(()=>{
|
|
1744
|
+
shouldAnimateRafRef.current = window.requestAnimationFrame(()=>{
|
|
1672
1745
|
shouldAnimate.current = true;
|
|
1673
1746
|
});
|
|
1747
|
+
return ()=>{
|
|
1748
|
+
if (shouldAnimateRafRef.current !== null) {
|
|
1749
|
+
window.cancelAnimationFrame(shouldAnimateRafRef.current);
|
|
1750
|
+
shouldAnimateRafRef.current = null;
|
|
1751
|
+
}
|
|
1752
|
+
};
|
|
1674
1753
|
}, []);
|
|
1675
1754
|
React__namespace.default.useEffect(()=>{
|
|
1676
1755
|
var _window_visualViewport;
|
|
@@ -1720,10 +1799,14 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1720
1799
|
if (!fromWithin) {
|
|
1721
1800
|
setIsOpen(false);
|
|
1722
1801
|
}
|
|
1723
|
-
|
|
1802
|
+
if (snapPointsResetTimeoutRef.current !== null) {
|
|
1803
|
+
window.clearTimeout(snapPointsResetTimeoutRef.current);
|
|
1804
|
+
}
|
|
1805
|
+
snapPointsResetTimeoutRef.current = window.setTimeout(()=>{
|
|
1724
1806
|
if (snapPoints) {
|
|
1725
1807
|
setActiveSnapPoint(snapPoints[0]);
|
|
1726
1808
|
}
|
|
1809
|
+
snapPointsResetTimeoutRef.current = null;
|
|
1727
1810
|
}, TRANSITIONS.DURATION * 1000); // seconds to ms
|
|
1728
1811
|
}
|
|
1729
1812
|
function resetDrawer() {
|
|
@@ -1797,8 +1880,12 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1797
1880
|
if (releaseResult.shouldPreventFocus) {
|
|
1798
1881
|
// `justReleased` is needed to prevent the drawer from focusing on an input when the drag ends, as it's not the intent most of the time.
|
|
1799
1882
|
setJustReleased(true);
|
|
1800
|
-
|
|
1883
|
+
if (justReleasedTimeoutRef.current !== null) {
|
|
1884
|
+
window.clearTimeout(justReleasedTimeoutRef.current);
|
|
1885
|
+
}
|
|
1886
|
+
justReleasedTimeoutRef.current = window.setTimeout(()=>{
|
|
1801
1887
|
setJustReleased(false);
|
|
1888
|
+
justReleasedTimeoutRef.current = null;
|
|
1802
1889
|
}, 200);
|
|
1803
1890
|
}
|
|
1804
1891
|
if (releaseResult.action === 'close') {
|
|
@@ -1875,12 +1962,45 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1875
1962
|
});
|
|
1876
1963
|
}
|
|
1877
1964
|
}
|
|
1965
|
+
React__namespace.default.useEffect(()=>{
|
|
1966
|
+
return ()=>{
|
|
1967
|
+
if (animationEndTimeoutRef.current !== null) {
|
|
1968
|
+
window.clearTimeout(animationEndTimeoutRef.current);
|
|
1969
|
+
}
|
|
1970
|
+
if (nonModalPointerEventsRafRef.current !== null) {
|
|
1971
|
+
window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
|
|
1972
|
+
}
|
|
1973
|
+
if (snapPointsResetTimeoutRef.current !== null) {
|
|
1974
|
+
window.clearTimeout(snapPointsResetTimeoutRef.current);
|
|
1975
|
+
}
|
|
1976
|
+
if (justReleasedTimeoutRef.current !== null) {
|
|
1977
|
+
window.clearTimeout(justReleasedTimeoutRef.current);
|
|
1978
|
+
}
|
|
1979
|
+
if (nestedOpenChangeTimer.current) {
|
|
1980
|
+
window.clearTimeout(nestedOpenChangeTimer.current);
|
|
1981
|
+
}
|
|
1982
|
+
if (touchEndHandlerRef.current) {
|
|
1983
|
+
window.removeEventListener('touchend', touchEndHandlerRef.current);
|
|
1984
|
+
touchEndHandlerRef.current = null;
|
|
1985
|
+
}
|
|
1986
|
+
};
|
|
1987
|
+
}, []);
|
|
1878
1988
|
React__namespace.default.useEffect(()=>{
|
|
1879
1989
|
if (!modal) {
|
|
1880
1990
|
// Need to do this manually unfortunately
|
|
1881
|
-
|
|
1991
|
+
if (nonModalPointerEventsRafRef.current !== null) {
|
|
1992
|
+
window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
|
|
1993
|
+
}
|
|
1994
|
+
nonModalPointerEventsRafRef.current = window.requestAnimationFrame(()=>{
|
|
1882
1995
|
document.body.style.pointerEvents = 'auto';
|
|
1996
|
+
nonModalPointerEventsRafRef.current = null;
|
|
1883
1997
|
});
|
|
1998
|
+
return ()=>{
|
|
1999
|
+
if (nonModalPointerEventsRafRef.current !== null) {
|
|
2000
|
+
window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
|
|
2001
|
+
nonModalPointerEventsRafRef.current = null;
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
1884
2004
|
}
|
|
1885
2005
|
}, [
|
|
1886
2006
|
modal
|
|
@@ -1964,15 +2084,25 @@ const Content = /*#__PURE__*/ React__namespace.default.forwardRef(function({ onP
|
|
|
1964
2084
|
const pointerStartRef = React__namespace.default.useRef(null);
|
|
1965
2085
|
const lastKnownPointerEventRef = React__namespace.default.useRef(null);
|
|
1966
2086
|
const wasBeyondThePointRef = React__namespace.default.useRef(false);
|
|
2087
|
+
const delayedSnapPointsRafRef = React__namespace.default.useRef(null);
|
|
1967
2088
|
const hasSnapPoints = snapPoints && snapPoints.length > 0;
|
|
1968
2089
|
useScaleBackground();
|
|
1969
2090
|
React__namespace.default.useEffect(()=>{
|
|
1970
2091
|
if (hasSnapPoints) {
|
|
1971
|
-
window.requestAnimationFrame(()=>{
|
|
2092
|
+
delayedSnapPointsRafRef.current = window.requestAnimationFrame(()=>{
|
|
1972
2093
|
setDelayedSnapPoints(true);
|
|
2094
|
+
delayedSnapPointsRafRef.current = null;
|
|
1973
2095
|
});
|
|
1974
2096
|
}
|
|
1975
|
-
|
|
2097
|
+
return ()=>{
|
|
2098
|
+
if (delayedSnapPointsRafRef.current !== null) {
|
|
2099
|
+
window.cancelAnimationFrame(delayedSnapPointsRafRef.current);
|
|
2100
|
+
delayedSnapPointsRafRef.current = null;
|
|
2101
|
+
}
|
|
2102
|
+
};
|
|
2103
|
+
}, [
|
|
2104
|
+
hasSnapPoints
|
|
2105
|
+
]);
|
|
1976
2106
|
function handleOnPointerUp(event) {
|
|
1977
2107
|
pointerStartRef.current = null;
|
|
1978
2108
|
wasBeyondThePointRef.current = false;
|
|
@@ -2073,6 +2203,7 @@ const DOUBLE_TAP_TIMEOUT = 120;
|
|
|
2073
2203
|
const Handle = /*#__PURE__*/ React__namespace.default.forwardRef(function({ preventCycle = false, children, ...rest }, ref) {
|
|
2074
2204
|
const { closeDrawer, isDragging, snapPoints, activeSnapPoint, setActiveSnapPoint, dismissible, handleOnly, isOpen, onPress, onDrag } = useDrawerContext();
|
|
2075
2205
|
const closeTimeoutIdRef = React__namespace.default.useRef(null);
|
|
2206
|
+
const cycleTimeoutIdRef = React__namespace.default.useRef(null);
|
|
2076
2207
|
const shouldCancelInteractionRef = React__namespace.default.useRef(false);
|
|
2077
2208
|
function handleStartCycle() {
|
|
2078
2209
|
// Stop if this is the second click of a double click
|
|
@@ -2080,7 +2211,7 @@ const Handle = /*#__PURE__*/ React__namespace.default.forwardRef(function({ prev
|
|
|
2080
2211
|
handleCancelInteraction();
|
|
2081
2212
|
return;
|
|
2082
2213
|
}
|
|
2083
|
-
window.setTimeout(()=>{
|
|
2214
|
+
cycleTimeoutIdRef.current = window.setTimeout(()=>{
|
|
2084
2215
|
handleCycleSnapPoints();
|
|
2085
2216
|
}, DOUBLE_TAP_TIMEOUT);
|
|
2086
2217
|
}
|
|
@@ -2113,9 +2244,19 @@ const Handle = /*#__PURE__*/ React__namespace.default.forwardRef(function({ prev
|
|
|
2113
2244
|
function handleCancelInteraction() {
|
|
2114
2245
|
if (closeTimeoutIdRef.current) {
|
|
2115
2246
|
window.clearTimeout(closeTimeoutIdRef.current);
|
|
2247
|
+
closeTimeoutIdRef.current = null;
|
|
2248
|
+
}
|
|
2249
|
+
if (cycleTimeoutIdRef.current) {
|
|
2250
|
+
window.clearTimeout(cycleTimeoutIdRef.current);
|
|
2251
|
+
cycleTimeoutIdRef.current = null;
|
|
2116
2252
|
}
|
|
2117
2253
|
shouldCancelInteractionRef.current = false;
|
|
2118
2254
|
}
|
|
2255
|
+
React__namespace.default.useEffect(()=>{
|
|
2256
|
+
return ()=>{
|
|
2257
|
+
handleCancelInteraction();
|
|
2258
|
+
};
|
|
2259
|
+
}, []);
|
|
2119
2260
|
return /*#__PURE__*/ React__namespace.default.createElement("div", {
|
|
2120
2261
|
onClick: handleStartCycle,
|
|
2121
2262
|
onPointerCancel: handleCancelInteraction,
|
|
@@ -2463,6 +2604,7 @@ function openAncestorChain(parentId) {
|
|
|
2463
2604
|
openAncestorChain(nextParentId);
|
|
2464
2605
|
}
|
|
2465
2606
|
if (!parentRuntime.controller.getSnapshot().state.isOpen) {
|
|
2607
|
+
releaseHiddenFocusBeforeOpen(parentRuntime.options);
|
|
2466
2608
|
parentRuntime.controller.setOpen(true);
|
|
2467
2609
|
notifyOpenStateChange(parentRuntime, true);
|
|
2468
2610
|
renderVanillaDrawer(parentRuntime.id);
|
|
@@ -2482,6 +2624,7 @@ function bindTriggerElement(runtime) {
|
|
|
2482
2624
|
}
|
|
2483
2625
|
const triggerElement = runtime.options.triggerElement;
|
|
2484
2626
|
const handleClick = ()=>{
|
|
2627
|
+
releaseHiddenFocusBeforeOpen(runtime.options);
|
|
2485
2628
|
runtime.controller.setOpen(true);
|
|
2486
2629
|
renderVanillaDrawer(runtime.id);
|
|
2487
2630
|
};
|
|
@@ -2517,6 +2660,16 @@ function notifyOpenStateChange(runtime, open) {
|
|
|
2517
2660
|
function canUseDOM() {
|
|
2518
2661
|
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
2519
2662
|
}
|
|
2663
|
+
function releaseHiddenFocusBeforeOpen(options) {
|
|
2664
|
+
if (!canUseDOM() || options.modal === false || options.autoFocus) {
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2667
|
+
const activeElement = document.activeElement;
|
|
2668
|
+
if (!activeElement || activeElement === document.body || typeof activeElement.blur !== 'function') {
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
activeElement.blur();
|
|
2672
|
+
}
|
|
2520
2673
|
function getRuntimeDrawerElement(runtime) {
|
|
2521
2674
|
if (!runtime.element) {
|
|
2522
2675
|
return null;
|
|
@@ -2567,6 +2720,9 @@ function renderVanillaDrawer(id) {
|
|
|
2567
2720
|
open: snapshot.state.isOpen,
|
|
2568
2721
|
onOpenChange: (open)=>{
|
|
2569
2722
|
const previousOpen = runtime.controller.getSnapshot().state.isOpen;
|
|
2723
|
+
if (open) {
|
|
2724
|
+
releaseHiddenFocusBeforeOpen(runtime.options);
|
|
2725
|
+
}
|
|
2570
2726
|
runtime.controller.setOpen(open);
|
|
2571
2727
|
if (previousOpen !== open) {
|
|
2572
2728
|
notifyOpenStateChange(runtime, open);
|
|
@@ -2619,6 +2775,9 @@ function buildVanillaController(id) {
|
|
|
2619
2775
|
open
|
|
2620
2776
|
}).getSnapshot();
|
|
2621
2777
|
}
|
|
2778
|
+
if (open) {
|
|
2779
|
+
releaseHiddenFocusBeforeOpen(runtime.options);
|
|
2780
|
+
}
|
|
2622
2781
|
const previousOpen = runtime.controller.getSnapshot().state.isOpen;
|
|
2623
2782
|
const snapshot = runtime.controller.setOpen(open);
|
|
2624
2783
|
if (previousOpen !== open) {
|
|
@@ -2712,6 +2871,9 @@ function createDrawer(options = {}) {
|
|
|
2712
2871
|
notifyOpenStateChange(existing, snapshot.state.isOpen);
|
|
2713
2872
|
}
|
|
2714
2873
|
}
|
|
2874
|
+
if (nextOptions.open && !previousOpen) {
|
|
2875
|
+
releaseHiddenFocusBeforeOpen(nextOptions);
|
|
2876
|
+
}
|
|
2715
2877
|
renderVanillaDrawer(id);
|
|
2716
2878
|
if (nextOptions.parentId && nextOptions.open) {
|
|
2717
2879
|
openAncestorChain(nextOptions.parentId);
|