react-modal-sheet 5.3.1 → 5.4.1
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 +9 -6
- package/dist/index.d.mts +0 -5
- package/dist/index.d.ts +0 -5
- package/dist/index.js +253 -160
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +254 -161
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/SheetBackdrop.tsx +10 -4
- package/src/SheetContent.tsx +9 -3
- package/src/debug.ts +3 -2
- package/src/hooks/use-keyboard-avoidance.ts +75 -0
- package/src/hooks/use-prevent-scroll.ts +5 -27
- package/src/hooks/use-scroll-position.ts +0 -1
- package/src/hooks/use-virtual-keyboard.ts +127 -52
- package/src/sheet.tsx +59 -73
- package/src/types.tsx +2 -2
- package/src/utils.ts +26 -0
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { motion, useMotionValue, useTransform, useReducedMotion, animate } from 'motion/react';
|
|
2
|
-
import React4, { createContext, forwardRef, useRef, useState, useImperativeHandle,
|
|
2
|
+
import React4, { createContext, forwardRef, useRef, useState, useImperativeHandle, useContext, useCallback, useMemo, useEffect, useLayoutEffect } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import useMeasure from 'react-use-measure';
|
|
5
5
|
import { transform } from 'motion';
|
|
@@ -196,6 +196,23 @@ function waitForElement(className, interval = 50, maxAttempts = 20) {
|
|
|
196
196
|
}, interval);
|
|
197
197
|
});
|
|
198
198
|
}
|
|
199
|
+
var nonTextInputTypes = /* @__PURE__ */ new Set([
|
|
200
|
+
"checkbox",
|
|
201
|
+
"radio",
|
|
202
|
+
"range",
|
|
203
|
+
"color",
|
|
204
|
+
"file",
|
|
205
|
+
"image",
|
|
206
|
+
"button",
|
|
207
|
+
"submit",
|
|
208
|
+
"reset"
|
|
209
|
+
]);
|
|
210
|
+
function willOpenKeyboard(target) {
|
|
211
|
+
return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
212
|
+
}
|
|
213
|
+
function isHTTPS() {
|
|
214
|
+
return typeof window !== "undefined" && window.isSecureContext;
|
|
215
|
+
}
|
|
199
216
|
|
|
200
217
|
// src/SheetBackdrop.tsx
|
|
201
218
|
var isClickable = (props) => !!props.onClick || !!props.onTap;
|
|
@@ -211,13 +228,16 @@ var SheetBackdrop = forwardRef(
|
|
|
211
228
|
...style,
|
|
212
229
|
pointerEvents
|
|
213
230
|
};
|
|
231
|
+
const animationProps = sheetContext.prefersReducedMotion ? {} : {
|
|
232
|
+
initial: { opacity: 0 },
|
|
233
|
+
animate: { opacity: 1 },
|
|
234
|
+
exit: { opacity: 0 },
|
|
235
|
+
transition: { duration: 1 }
|
|
236
|
+
};
|
|
214
237
|
return /* @__PURE__ */ React4.createElement(
|
|
215
238
|
Comp,
|
|
216
239
|
{
|
|
217
|
-
|
|
218
|
-
animate: { opacity: 1 },
|
|
219
|
-
exit: { opacity: 0 },
|
|
220
|
-
transition: { duration: 1 },
|
|
240
|
+
...animationProps,
|
|
221
241
|
...rest,
|
|
222
242
|
ref,
|
|
223
243
|
className: `react-modal-sheet-backdrop ${className}`,
|
|
@@ -393,7 +413,7 @@ var SheetContent = forwardRef(
|
|
|
393
413
|
};
|
|
394
414
|
const scrollStyle = applyStyles(styles.scroller, isUnstyled);
|
|
395
415
|
if (sheetContext.avoidKeyboard) {
|
|
396
|
-
scrollStyle.paddingBottom = "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))";
|
|
416
|
+
scrollStyle.paddingBottom = isHTTPS() ? "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))" : "var(--keyboard-inset-height, 0px)";
|
|
397
417
|
}
|
|
398
418
|
if (disableScroll) {
|
|
399
419
|
scrollStyle.overflowY = "hidden";
|
|
@@ -516,6 +536,195 @@ function useDimensions() {
|
|
|
516
536
|
}, []);
|
|
517
537
|
return dimensions;
|
|
518
538
|
}
|
|
539
|
+
var virtualKeyboardOverlayUsers = 0;
|
|
540
|
+
var initialVirtualKeyboardOverlaysContent = null;
|
|
541
|
+
function useVirtualKeyboard(options = {}) {
|
|
542
|
+
const {
|
|
543
|
+
containerRef,
|
|
544
|
+
isEnabled = true,
|
|
545
|
+
debounceDelay = 100,
|
|
546
|
+
visualViewportThreshold = 100
|
|
547
|
+
} = options;
|
|
548
|
+
const [state, setState] = useState({
|
|
549
|
+
isVisible: false,
|
|
550
|
+
height: 0
|
|
551
|
+
});
|
|
552
|
+
const focusedElementRef = useRef(null);
|
|
553
|
+
const debounceTimer = useRef(null);
|
|
554
|
+
useEffect(() => {
|
|
555
|
+
const vv = window.visualViewport;
|
|
556
|
+
const vk = getVirtualKeyboardApi();
|
|
557
|
+
function setKeyboardInsetHeightEnv(height) {
|
|
558
|
+
const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
|
|
559
|
+
if (vk) {
|
|
560
|
+
element.style.setProperty(
|
|
561
|
+
"--keyboard-inset-height",
|
|
562
|
+
`env(keyboard-inset-height, ${height}px)`
|
|
563
|
+
);
|
|
564
|
+
} else {
|
|
565
|
+
element.style.setProperty("--keyboard-inset-height", `${height}px`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function setKeyboardState(nextState) {
|
|
569
|
+
setState(
|
|
570
|
+
(prevState) => prevState.isVisible === nextState.isVisible && prevState.height === nextState.height ? prevState : nextState
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
function resetKeyboardState() {
|
|
574
|
+
focusedElementRef.current = null;
|
|
575
|
+
setKeyboardInsetHeightEnv(0);
|
|
576
|
+
setKeyboardState({ isVisible: false, height: 0 });
|
|
577
|
+
}
|
|
578
|
+
if (!isEnabled) {
|
|
579
|
+
resetKeyboardState();
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
function updateKeyboardState() {
|
|
583
|
+
if (debounceTimer.current) {
|
|
584
|
+
clearTimeout(debounceTimer.current);
|
|
585
|
+
}
|
|
586
|
+
debounceTimer.current = setTimeout(() => {
|
|
587
|
+
const active = getActiveElement() ?? focusedElementRef.current;
|
|
588
|
+
const inputIsFocused = active ? willOpenKeyboard(active) : false;
|
|
589
|
+
if (!inputIsFocused) {
|
|
590
|
+
resetKeyboardState();
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
focusedElementRef.current = active;
|
|
594
|
+
if (vk == null ? void 0 : vk.overlaysContent) {
|
|
595
|
+
const keyboardHeight = vk.boundingRect.height;
|
|
596
|
+
setKeyboardInsetHeightEnv(keyboardHeight);
|
|
597
|
+
setKeyboardState({ isVisible: true, height: keyboardHeight });
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
if (vv) {
|
|
601
|
+
const heightDiff = window.innerHeight - vv.height;
|
|
602
|
+
if (heightDiff > visualViewportThreshold) {
|
|
603
|
+
setKeyboardInsetHeightEnv(heightDiff);
|
|
604
|
+
setKeyboardState({ isVisible: true, height: heightDiff });
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
resetKeyboardState();
|
|
609
|
+
}, debounceDelay);
|
|
610
|
+
}
|
|
611
|
+
function handleFocusIn(e) {
|
|
612
|
+
if (e.target instanceof HTMLElement && willOpenKeyboard(e.target)) {
|
|
613
|
+
focusedElementRef.current = e.target;
|
|
614
|
+
updateKeyboardState();
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
function handleFocusOut() {
|
|
618
|
+
requestAnimationFrame(() => {
|
|
619
|
+
focusedElementRef.current = getActiveElement();
|
|
620
|
+
updateKeyboardState();
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
document.addEventListener("focusin", handleFocusIn);
|
|
624
|
+
document.addEventListener("focusout", handleFocusOut);
|
|
625
|
+
if (vv) {
|
|
626
|
+
vv.addEventListener("resize", updateKeyboardState);
|
|
627
|
+
vv.addEventListener("scroll", updateKeyboardState);
|
|
628
|
+
}
|
|
629
|
+
if (vk) {
|
|
630
|
+
if (virtualKeyboardOverlayUsers === 0) {
|
|
631
|
+
initialVirtualKeyboardOverlaysContent = vk.overlaysContent;
|
|
632
|
+
vk.overlaysContent = true;
|
|
633
|
+
}
|
|
634
|
+
virtualKeyboardOverlayUsers++;
|
|
635
|
+
vk.addEventListener("geometrychange", updateKeyboardState);
|
|
636
|
+
}
|
|
637
|
+
focusedElementRef.current = getActiveElement();
|
|
638
|
+
updateKeyboardState();
|
|
639
|
+
return () => {
|
|
640
|
+
document.removeEventListener("focusin", handleFocusIn);
|
|
641
|
+
document.removeEventListener("focusout", handleFocusOut);
|
|
642
|
+
if (vv) {
|
|
643
|
+
vv.removeEventListener("resize", updateKeyboardState);
|
|
644
|
+
vv.removeEventListener("scroll", updateKeyboardState);
|
|
645
|
+
}
|
|
646
|
+
if (vk) {
|
|
647
|
+
vk.removeEventListener("geometrychange", updateKeyboardState);
|
|
648
|
+
virtualKeyboardOverlayUsers = Math.max(
|
|
649
|
+
0,
|
|
650
|
+
virtualKeyboardOverlayUsers - 1
|
|
651
|
+
);
|
|
652
|
+
if (virtualKeyboardOverlayUsers === 0) {
|
|
653
|
+
vk.overlaysContent = initialVirtualKeyboardOverlaysContent ?? false;
|
|
654
|
+
initialVirtualKeyboardOverlaysContent = null;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (debounceTimer.current) {
|
|
658
|
+
clearTimeout(debounceTimer.current);
|
|
659
|
+
}
|
|
660
|
+
resetKeyboardState();
|
|
661
|
+
};
|
|
662
|
+
}, [debounceDelay, isEnabled, visualViewportThreshold]);
|
|
663
|
+
return {
|
|
664
|
+
keyboardHeight: state.height,
|
|
665
|
+
isKeyboardOpen: state.isVisible
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function getVirtualKeyboardApi() {
|
|
669
|
+
return isHTTPS() && "virtualKeyboard" in navigator ? navigator.virtualKeyboard : null;
|
|
670
|
+
}
|
|
671
|
+
function getActiveElement() {
|
|
672
|
+
var _a;
|
|
673
|
+
let activeElement = document.activeElement;
|
|
674
|
+
while (activeElement instanceof HTMLElement && ((_a = activeElement.shadowRoot) == null ? void 0 : _a.activeElement)) {
|
|
675
|
+
activeElement = activeElement.shadowRoot.activeElement;
|
|
676
|
+
}
|
|
677
|
+
return activeElement && willOpenKeyboard(activeElement) ? activeElement : null;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// src/hooks/use-keyboard-avoidance.ts
|
|
681
|
+
function useKeyboardAvoidance({
|
|
682
|
+
isEnabled,
|
|
683
|
+
containerRef,
|
|
684
|
+
onWillOpenKeyboard,
|
|
685
|
+
onDidOpenKeyboard
|
|
686
|
+
}) {
|
|
687
|
+
const [focusedElement, setFocusedElement] = useState(
|
|
688
|
+
null
|
|
689
|
+
);
|
|
690
|
+
const keyboard = useVirtualKeyboard({
|
|
691
|
+
isEnabled,
|
|
692
|
+
containerRef
|
|
693
|
+
});
|
|
694
|
+
const handleFocusIn = useStableCallback(async (event) => {
|
|
695
|
+
var _a;
|
|
696
|
+
const element = event.target;
|
|
697
|
+
if (willOpenKeyboard(element) && ((_a = containerRef.current) == null ? void 0 : _a.contains(element))) {
|
|
698
|
+
await (onWillOpenKeyboard == null ? void 0 : onWillOpenKeyboard(event));
|
|
699
|
+
setFocusedElement(element);
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
const handleFocusOut = useStableCallback((event) => {
|
|
703
|
+
const element = event.target;
|
|
704
|
+
if (focusedElement === element) {
|
|
705
|
+
setFocusedElement(null);
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
useEffect(() => {
|
|
709
|
+
if (!isEnabled) return;
|
|
710
|
+
document.addEventListener("focusin", handleFocusIn);
|
|
711
|
+
document.addEventListener("focusout", handleFocusOut);
|
|
712
|
+
return () => {
|
|
713
|
+
document.removeEventListener("focusin", handleFocusIn);
|
|
714
|
+
document.removeEventListener("focusout", handleFocusOut);
|
|
715
|
+
};
|
|
716
|
+
}, [isEnabled]);
|
|
717
|
+
useEffect(() => {
|
|
718
|
+
const containerElement = containerRef.current;
|
|
719
|
+
if (!isEnabled || !focusedElement || !containerElement || !keyboard.isKeyboardOpen) {
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
requestAnimationFrame(() => {
|
|
723
|
+
onDidOpenKeyboard == null ? void 0 : onDidOpenKeyboard(focusedElement);
|
|
724
|
+
});
|
|
725
|
+
}, [isEnabled, keyboard.isKeyboardOpen, focusedElement]);
|
|
726
|
+
return keyboard;
|
|
727
|
+
}
|
|
519
728
|
function useSafeAreaInsets() {
|
|
520
729
|
const [insets] = useState(() => {
|
|
521
730
|
const fallback = { top: 0, left: 0, right: 0, bottom: 0 };
|
|
@@ -658,13 +867,13 @@ function isScrollable(node, checkForOverflow) {
|
|
|
658
867
|
return false;
|
|
659
868
|
}
|
|
660
869
|
const style = window.getComputedStyle(node);
|
|
661
|
-
let
|
|
870
|
+
let scrollable = /(auto|scroll)/.test(
|
|
662
871
|
style.overflow + style.overflowX + style.overflowY
|
|
663
872
|
);
|
|
664
|
-
if (
|
|
665
|
-
|
|
873
|
+
if (scrollable && checkForOverflow) {
|
|
874
|
+
scrollable = node.scrollHeight !== node.clientHeight || node.scrollWidth !== node.clientWidth;
|
|
666
875
|
}
|
|
667
|
-
return
|
|
876
|
+
return scrollable;
|
|
668
877
|
}
|
|
669
878
|
function getScrollParent(node, checkForOverflow) {
|
|
670
879
|
let scrollableNode = node;
|
|
@@ -676,17 +885,6 @@ function getScrollParent(node, checkForOverflow) {
|
|
|
676
885
|
}
|
|
677
886
|
return scrollableNode || document.scrollingElement || document.documentElement;
|
|
678
887
|
}
|
|
679
|
-
var nonTextInputTypes = /* @__PURE__ */ new Set([
|
|
680
|
-
"checkbox",
|
|
681
|
-
"radio",
|
|
682
|
-
"range",
|
|
683
|
-
"color",
|
|
684
|
-
"file",
|
|
685
|
-
"image",
|
|
686
|
-
"button",
|
|
687
|
-
"submit",
|
|
688
|
-
"reset"
|
|
689
|
-
]);
|
|
690
888
|
var preventScrollCount = 0;
|
|
691
889
|
var restore;
|
|
692
890
|
function usePreventScroll(options = {}) {
|
|
@@ -853,9 +1051,6 @@ function scrollIntoView(target) {
|
|
|
853
1051
|
target = scrollable.parentElement;
|
|
854
1052
|
}
|
|
855
1053
|
}
|
|
856
|
-
function willOpenKeyboard(target) {
|
|
857
|
-
return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
858
|
-
}
|
|
859
1054
|
function useSheetState({
|
|
860
1055
|
isOpen,
|
|
861
1056
|
onClosed: _onClosed,
|
|
@@ -900,108 +1095,6 @@ function useSheetState({
|
|
|
900
1095
|
}, [state]);
|
|
901
1096
|
return state;
|
|
902
1097
|
}
|
|
903
|
-
function useVirtualKeyboard(options = {}) {
|
|
904
|
-
const {
|
|
905
|
-
containerRef,
|
|
906
|
-
isEnabled = true,
|
|
907
|
-
debounceDelay = 100,
|
|
908
|
-
includeContentEditable = true,
|
|
909
|
-
visualViewportThreshold = 100
|
|
910
|
-
} = options;
|
|
911
|
-
const [state, setState] = useState({
|
|
912
|
-
isVisible: false,
|
|
913
|
-
height: 0
|
|
914
|
-
});
|
|
915
|
-
const focusedElementRef = useRef(null);
|
|
916
|
-
const debounceTimer = useRef(null);
|
|
917
|
-
const isTextInput = useStableCallback((el) => {
|
|
918
|
-
return (el == null ? void 0 : el.tagName) === "INPUT" || (el == null ? void 0 : el.tagName) === "TEXTAREA" || includeContentEditable && el instanceof HTMLElement && el.isContentEditable;
|
|
919
|
-
});
|
|
920
|
-
useEffect(() => {
|
|
921
|
-
if (!isEnabled) return;
|
|
922
|
-
const vv = window.visualViewport;
|
|
923
|
-
const vk = navigator.virtualKeyboard;
|
|
924
|
-
function setKeyboardInsetHeightEnv(height) {
|
|
925
|
-
const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
|
|
926
|
-
if (window.isSecureContext) {
|
|
927
|
-
element.style.setProperty(
|
|
928
|
-
"--keyboard-inset-height",
|
|
929
|
-
`env(keyboard-inset-height, ${height}px)`
|
|
930
|
-
);
|
|
931
|
-
} else {
|
|
932
|
-
element.style.setProperty("--keyboard-inset-height", `${height}px`);
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
function handleFocusIn(e) {
|
|
936
|
-
if (e.target instanceof HTMLElement && isTextInput(e.target)) {
|
|
937
|
-
focusedElementRef.current = e.target;
|
|
938
|
-
updateKeyboardState();
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
function handleFocusOut() {
|
|
942
|
-
focusedElementRef.current = null;
|
|
943
|
-
updateKeyboardState();
|
|
944
|
-
}
|
|
945
|
-
function updateKeyboardState() {
|
|
946
|
-
if (debounceTimer.current) {
|
|
947
|
-
clearTimeout(debounceTimer.current);
|
|
948
|
-
}
|
|
949
|
-
debounceTimer.current = setTimeout(() => {
|
|
950
|
-
const active = focusedElementRef.current;
|
|
951
|
-
const inputIsFocused = isTextInput(active);
|
|
952
|
-
if (!inputIsFocused) {
|
|
953
|
-
setKeyboardInsetHeightEnv(0);
|
|
954
|
-
setState({ isVisible: false, height: 0 });
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
if (vv) {
|
|
958
|
-
const heightDiff = window.innerHeight - vv.height;
|
|
959
|
-
if (heightDiff > visualViewportThreshold) {
|
|
960
|
-
setKeyboardInsetHeightEnv(heightDiff);
|
|
961
|
-
setState({ isVisible: true, height: heightDiff });
|
|
962
|
-
} else {
|
|
963
|
-
setKeyboardInsetHeightEnv(0);
|
|
964
|
-
setState({ isVisible: false, height: 0 });
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
}, debounceDelay);
|
|
968
|
-
}
|
|
969
|
-
window.addEventListener("focusin", handleFocusIn);
|
|
970
|
-
window.addEventListener("focusout", handleFocusOut);
|
|
971
|
-
if (vv) {
|
|
972
|
-
vv.addEventListener("resize", updateKeyboardState);
|
|
973
|
-
vv.addEventListener("scroll", updateKeyboardState);
|
|
974
|
-
}
|
|
975
|
-
let currentOverlaysContent = false;
|
|
976
|
-
if (vk) {
|
|
977
|
-
currentOverlaysContent = vk.overlaysContent;
|
|
978
|
-
vk.overlaysContent = true;
|
|
979
|
-
}
|
|
980
|
-
return () => {
|
|
981
|
-
window.removeEventListener("focusin", handleFocusIn);
|
|
982
|
-
window.removeEventListener("focusout", handleFocusOut);
|
|
983
|
-
if (vv) {
|
|
984
|
-
vv.removeEventListener("resize", updateKeyboardState);
|
|
985
|
-
vv.removeEventListener("scroll", updateKeyboardState);
|
|
986
|
-
}
|
|
987
|
-
if (vk) {
|
|
988
|
-
vk.overlaysContent = currentOverlaysContent;
|
|
989
|
-
}
|
|
990
|
-
if (debounceTimer.current) {
|
|
991
|
-
clearTimeout(debounceTimer.current);
|
|
992
|
-
}
|
|
993
|
-
};
|
|
994
|
-
}, [
|
|
995
|
-
debounceDelay,
|
|
996
|
-
includeContentEditable,
|
|
997
|
-
isEnabled,
|
|
998
|
-
visualViewportThreshold
|
|
999
|
-
]);
|
|
1000
|
-
return {
|
|
1001
|
-
keyboardHeight: state.height,
|
|
1002
|
-
isKeyboardOpen: state.isVisible
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
1098
|
|
|
1006
1099
|
// src/snap.ts
|
|
1007
1100
|
function computeSnapPoints({
|
|
@@ -1176,11 +1269,6 @@ var Sheet = forwardRef(
|
|
|
1176
1269
|
type: "tween",
|
|
1177
1270
|
...reduceMotion ? REDUCED_MOTION_TWEEN_CONFIG : tweenConfig
|
|
1178
1271
|
};
|
|
1179
|
-
const keyboard = useVirtualKeyboard({
|
|
1180
|
-
isEnabled: isOpen && avoidKeyboard,
|
|
1181
|
-
containerRef: sheetRef
|
|
1182
|
-
});
|
|
1183
|
-
const disableDrag = keyboard.isKeyboardOpen || disableDragProp;
|
|
1184
1272
|
const zIndex = useTransform(
|
|
1185
1273
|
y,
|
|
1186
1274
|
(val) => val + 2 >= closedY ? -1 : (style == null ? void 0 : style.zIndex) ?? 9999
|
|
@@ -1224,14 +1312,45 @@ var Sheet = forwardRef(
|
|
|
1224
1312
|
onComplete: () => updateSnap(snapIndex)
|
|
1225
1313
|
});
|
|
1226
1314
|
});
|
|
1315
|
+
const keyboard = useKeyboardAvoidance({
|
|
1316
|
+
isEnabled: isOpen && avoidKeyboard,
|
|
1317
|
+
containerRef: sheetRef,
|
|
1318
|
+
onWillOpenKeyboard: async () => {
|
|
1319
|
+
const lastSnapPoint = snapPoints[snapPoints.length - 1];
|
|
1320
|
+
if (lastSnapPoint && lastSnapPoint.snapIndex !== currentSnap) {
|
|
1321
|
+
await animate(y, lastSnapPoint.snapValueY, animationOptions);
|
|
1322
|
+
updateSnap(lastSnapPoint.snapIndex);
|
|
1323
|
+
}
|
|
1324
|
+
},
|
|
1325
|
+
onDidOpenKeyboard: (focusedElement) => {
|
|
1326
|
+
const sheetElement = sheetRef.current;
|
|
1327
|
+
if (!sheetElement) return;
|
|
1328
|
+
const inputRect = focusedElement.getBoundingClientRect();
|
|
1329
|
+
const containerRect = sheetElement.getBoundingClientRect();
|
|
1330
|
+
const scroller = sheetElement.querySelector(
|
|
1331
|
+
".react-modal-sheet-content-scroller"
|
|
1332
|
+
);
|
|
1333
|
+
const scrollTarget = Math.max(
|
|
1334
|
+
inputRect.top - containerRect.top + scroller.scrollTop - inputRect.height,
|
|
1335
|
+
0
|
|
1336
|
+
);
|
|
1337
|
+
requestAnimationFrame(() => {
|
|
1338
|
+
scroller.scrollTo({ top: scrollTarget, behavior: "smooth" });
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
const disableDrag = keyboard.isKeyboardOpen || disableDragProp;
|
|
1227
1343
|
const blurActiveInput = useStableCallback(() => {
|
|
1344
|
+
var _a;
|
|
1228
1345
|
const focusedElement = document.activeElement;
|
|
1229
|
-
if (
|
|
1230
|
-
const isInput = focusedElement.tagName === "INPUT" || focusedElement.tagName === "TEXTAREA";
|
|
1231
|
-
if (isInput && sheetRef.current.contains(focusedElement)) {
|
|
1346
|
+
if (focusedElement && willOpenKeyboard(focusedElement) && ((_a = sheetRef.current) == null ? void 0 : _a.contains(focusedElement))) {
|
|
1232
1347
|
focusedElement.blur();
|
|
1233
1348
|
}
|
|
1234
1349
|
});
|
|
1350
|
+
const onDragStart = useStableCallback((event, info) => {
|
|
1351
|
+
blurActiveInput();
|
|
1352
|
+
onDragStartProp == null ? void 0 : onDragStartProp(event, info);
|
|
1353
|
+
});
|
|
1235
1354
|
const onDrag = useStableCallback((event, info) => {
|
|
1236
1355
|
onDragProp == null ? void 0 : onDragProp(event, info);
|
|
1237
1356
|
const currentY = y.get();
|
|
@@ -1240,10 +1359,6 @@ var Sheet = forwardRef(
|
|
|
1240
1359
|
if (velocity < 0) indicatorRotation.set(-10);
|
|
1241
1360
|
y.set(Math.max(currentY + info.delta.y, 0));
|
|
1242
1361
|
});
|
|
1243
|
-
const onDragStart = useStableCallback((event, info) => {
|
|
1244
|
-
blurActiveInput();
|
|
1245
|
-
onDragStartProp == null ? void 0 : onDragStartProp(event, info);
|
|
1246
|
-
});
|
|
1247
1362
|
const onDragEnd = useStableCallback((event, info) => {
|
|
1248
1363
|
blurActiveInput();
|
|
1249
1364
|
onDragEndProp == null ? void 0 : onDragEndProp(event, info);
|
|
@@ -1300,29 +1415,6 @@ var Sheet = forwardRef(
|
|
|
1300
1415
|
height: sheetHeight,
|
|
1301
1416
|
snapTo
|
|
1302
1417
|
}));
|
|
1303
|
-
useEffect(() => {
|
|
1304
|
-
if (isOpen && snapPoints.length > 0 && avoidKeyboard && keyboard.isKeyboardOpen) {
|
|
1305
|
-
const focusedElement = document.activeElement;
|
|
1306
|
-
const visibleSheetHeight = yInverted.get() - keyboard.keyboardHeight;
|
|
1307
|
-
if (visibleSheetHeight <= 0 && focusedElement) {
|
|
1308
|
-
const currentY = y.get();
|
|
1309
|
-
const diffY = Math.max(currentY - Math.abs(visibleSheetHeight), 0);
|
|
1310
|
-
requestAnimationFrame(() => {
|
|
1311
|
-
var _a;
|
|
1312
|
-
const inputRect = focusedElement.getBoundingClientRect();
|
|
1313
|
-
const sheetRect = (_a = sheetRef.current) == null ? void 0 : _a.getBoundingClientRect();
|
|
1314
|
-
let inputOffset = 0;
|
|
1315
|
-
if (sheetRect) {
|
|
1316
|
-
inputOffset = inputRect.top - sheetRect.top + inputRect.height;
|
|
1317
|
-
}
|
|
1318
|
-
animate(y, diffY - inputOffset, animationOptions);
|
|
1319
|
-
});
|
|
1320
|
-
return () => {
|
|
1321
|
-
animate(y, currentY, animationOptions);
|
|
1322
|
-
};
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
}, [isOpen, keyboard.isKeyboardOpen]);
|
|
1326
1418
|
useModalEffect({
|
|
1327
1419
|
y,
|
|
1328
1420
|
detent,
|
|
@@ -1369,6 +1461,7 @@ var Sheet = forwardRef(
|
|
|
1369
1461
|
dragProps,
|
|
1370
1462
|
indicatorRotation,
|
|
1371
1463
|
avoidKeyboard,
|
|
1464
|
+
prefersReducedMotion,
|
|
1372
1465
|
sheetBoundsRef,
|
|
1373
1466
|
sheetRef,
|
|
1374
1467
|
unstyled,
|