react-modal-sheet 5.4.0 → 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/dist/index.d.mts +0 -5
- package/dist/index.d.ts +0 -5
- package/dist/index.js +234 -187
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +235 -188
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/SheetContent.tsx +9 -3
- 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 +58 -86
- package/src/types.tsx +1 -2
- package/src/utils.ts +26 -0
- package/src/hooks/use-focused-input.ts +0 -46
package/dist/index.d.mts
CHANGED
|
@@ -139,11 +139,6 @@ type UseVirtualKeyboardOptions = {
|
|
|
139
139
|
* @default 100
|
|
140
140
|
*/
|
|
141
141
|
visualViewportThreshold?: number;
|
|
142
|
-
/**
|
|
143
|
-
* Whether to treat contenteditable elements as text inputs.
|
|
144
|
-
* @default true
|
|
145
|
-
*/
|
|
146
|
-
includeContentEditable?: boolean;
|
|
147
142
|
/**
|
|
148
143
|
* Delay in ms for debouncing viewport changes.
|
|
149
144
|
* @default 100
|
package/dist/index.d.ts
CHANGED
|
@@ -139,11 +139,6 @@ type UseVirtualKeyboardOptions = {
|
|
|
139
139
|
* @default 100
|
|
140
140
|
*/
|
|
141
141
|
visualViewportThreshold?: number;
|
|
142
|
-
/**
|
|
143
|
-
* Whether to treat contenteditable elements as text inputs.
|
|
144
|
-
* @default true
|
|
145
|
-
*/
|
|
146
|
-
includeContentEditable?: boolean;
|
|
147
142
|
/**
|
|
148
143
|
* Delay in ms for debouncing viewport changes.
|
|
149
144
|
* @default 100
|
package/dist/index.js
CHANGED
|
@@ -203,6 +203,23 @@ function waitForElement(className, interval = 50, maxAttempts = 20) {
|
|
|
203
203
|
}, interval);
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
|
+
var nonTextInputTypes = /* @__PURE__ */ new Set([
|
|
207
|
+
"checkbox",
|
|
208
|
+
"radio",
|
|
209
|
+
"range",
|
|
210
|
+
"color",
|
|
211
|
+
"file",
|
|
212
|
+
"image",
|
|
213
|
+
"button",
|
|
214
|
+
"submit",
|
|
215
|
+
"reset"
|
|
216
|
+
]);
|
|
217
|
+
function willOpenKeyboard(target) {
|
|
218
|
+
return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
219
|
+
}
|
|
220
|
+
function isHTTPS() {
|
|
221
|
+
return typeof window !== "undefined" && window.isSecureContext;
|
|
222
|
+
}
|
|
206
223
|
|
|
207
224
|
// src/SheetBackdrop.tsx
|
|
208
225
|
var isClickable = (props) => !!props.onClick || !!props.onTap;
|
|
@@ -403,7 +420,7 @@ var SheetContent = React4.forwardRef(
|
|
|
403
420
|
};
|
|
404
421
|
const scrollStyle = applyStyles(styles.scroller, isUnstyled);
|
|
405
422
|
if (sheetContext.avoidKeyboard) {
|
|
406
|
-
scrollStyle.paddingBottom = "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))";
|
|
423
|
+
scrollStyle.paddingBottom = isHTTPS() ? "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))" : "var(--keyboard-inset-height, 0px)";
|
|
407
424
|
}
|
|
408
425
|
if (disableScroll) {
|
|
409
426
|
scrollStyle.overflowY = "hidden";
|
|
@@ -526,35 +543,194 @@ function useDimensions() {
|
|
|
526
543
|
}, []);
|
|
527
544
|
return dimensions;
|
|
528
545
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
546
|
+
var virtualKeyboardOverlayUsers = 0;
|
|
547
|
+
var initialVirtualKeyboardOverlaysContent = null;
|
|
548
|
+
function useVirtualKeyboard(options = {}) {
|
|
549
|
+
const {
|
|
550
|
+
containerRef,
|
|
551
|
+
isEnabled = true,
|
|
552
|
+
debounceDelay = 100,
|
|
553
|
+
visualViewportThreshold = 100
|
|
554
|
+
} = options;
|
|
555
|
+
const [state, setState] = React4.useState({
|
|
556
|
+
isVisible: false,
|
|
557
|
+
height: 0
|
|
558
|
+
});
|
|
559
|
+
const focusedElementRef = React4.useRef(null);
|
|
560
|
+
const debounceTimer = React4.useRef(null);
|
|
534
561
|
React4.useEffect(() => {
|
|
535
|
-
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
562
|
+
const vv = window.visualViewport;
|
|
563
|
+
const vk = getVirtualKeyboardApi();
|
|
564
|
+
function setKeyboardInsetHeightEnv(height) {
|
|
565
|
+
const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
|
|
566
|
+
if (vk) {
|
|
567
|
+
element.style.setProperty(
|
|
568
|
+
"--keyboard-inset-height",
|
|
569
|
+
`env(keyboard-inset-height, ${height}px)`
|
|
570
|
+
);
|
|
571
|
+
} else {
|
|
572
|
+
element.style.setProperty("--keyboard-inset-height", `${height}px`);
|
|
542
573
|
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
574
|
+
}
|
|
575
|
+
function setKeyboardState(nextState) {
|
|
576
|
+
setState(
|
|
577
|
+
(prevState) => prevState.isVisible === nextState.isVisible && prevState.height === nextState.height ? prevState : nextState
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
function resetKeyboardState() {
|
|
581
|
+
focusedElementRef.current = null;
|
|
582
|
+
setKeyboardInsetHeightEnv(0);
|
|
583
|
+
setKeyboardState({ isVisible: false, height: 0 });
|
|
584
|
+
}
|
|
585
|
+
if (!isEnabled) {
|
|
586
|
+
resetKeyboardState();
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
function updateKeyboardState() {
|
|
590
|
+
if (debounceTimer.current) {
|
|
591
|
+
clearTimeout(debounceTimer.current);
|
|
548
592
|
}
|
|
593
|
+
debounceTimer.current = setTimeout(() => {
|
|
594
|
+
const active = getActiveElement() ?? focusedElementRef.current;
|
|
595
|
+
const inputIsFocused = active ? willOpenKeyboard(active) : false;
|
|
596
|
+
if (!inputIsFocused) {
|
|
597
|
+
resetKeyboardState();
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
focusedElementRef.current = active;
|
|
601
|
+
if (vk == null ? void 0 : vk.overlaysContent) {
|
|
602
|
+
const keyboardHeight = vk.boundingRect.height;
|
|
603
|
+
setKeyboardInsetHeightEnv(keyboardHeight);
|
|
604
|
+
setKeyboardState({ isVisible: true, height: keyboardHeight });
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
if (vv) {
|
|
608
|
+
const heightDiff = window.innerHeight - vv.height;
|
|
609
|
+
if (heightDiff > visualViewportThreshold) {
|
|
610
|
+
setKeyboardInsetHeightEnv(heightDiff);
|
|
611
|
+
setKeyboardState({ isVisible: true, height: heightDiff });
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
resetKeyboardState();
|
|
616
|
+
}, debounceDelay);
|
|
617
|
+
}
|
|
618
|
+
function handleFocusIn(e) {
|
|
619
|
+
if (e.target instanceof HTMLElement && willOpenKeyboard(e.target)) {
|
|
620
|
+
focusedElementRef.current = e.target;
|
|
621
|
+
updateKeyboardState();
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
function handleFocusOut() {
|
|
625
|
+
requestAnimationFrame(() => {
|
|
626
|
+
focusedElementRef.current = getActiveElement();
|
|
627
|
+
updateKeyboardState();
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
document.addEventListener("focusin", handleFocusIn);
|
|
631
|
+
document.addEventListener("focusout", handleFocusOut);
|
|
632
|
+
if (vv) {
|
|
633
|
+
vv.addEventListener("resize", updateKeyboardState);
|
|
634
|
+
vv.addEventListener("scroll", updateKeyboardState);
|
|
635
|
+
}
|
|
636
|
+
if (vk) {
|
|
637
|
+
if (virtualKeyboardOverlayUsers === 0) {
|
|
638
|
+
initialVirtualKeyboardOverlaysContent = vk.overlaysContent;
|
|
639
|
+
vk.overlaysContent = true;
|
|
640
|
+
}
|
|
641
|
+
virtualKeyboardOverlayUsers++;
|
|
642
|
+
vk.addEventListener("geometrychange", updateKeyboardState);
|
|
643
|
+
}
|
|
644
|
+
focusedElementRef.current = getActiveElement();
|
|
645
|
+
updateKeyboardState();
|
|
646
|
+
return () => {
|
|
647
|
+
document.removeEventListener("focusin", handleFocusIn);
|
|
648
|
+
document.removeEventListener("focusout", handleFocusOut);
|
|
649
|
+
if (vv) {
|
|
650
|
+
vv.removeEventListener("resize", updateKeyboardState);
|
|
651
|
+
vv.removeEventListener("scroll", updateKeyboardState);
|
|
652
|
+
}
|
|
653
|
+
if (vk) {
|
|
654
|
+
vk.removeEventListener("geometrychange", updateKeyboardState);
|
|
655
|
+
virtualKeyboardOverlayUsers = Math.max(
|
|
656
|
+
0,
|
|
657
|
+
virtualKeyboardOverlayUsers - 1
|
|
658
|
+
);
|
|
659
|
+
if (virtualKeyboardOverlayUsers === 0) {
|
|
660
|
+
vk.overlaysContent = initialVirtualKeyboardOverlaysContent ?? false;
|
|
661
|
+
initialVirtualKeyboardOverlaysContent = null;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (debounceTimer.current) {
|
|
665
|
+
clearTimeout(debounceTimer.current);
|
|
666
|
+
}
|
|
667
|
+
resetKeyboardState();
|
|
549
668
|
};
|
|
669
|
+
}, [debounceDelay, isEnabled, visualViewportThreshold]);
|
|
670
|
+
return {
|
|
671
|
+
keyboardHeight: state.height,
|
|
672
|
+
isKeyboardOpen: state.isVisible
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function getVirtualKeyboardApi() {
|
|
676
|
+
return isHTTPS() && "virtualKeyboard" in navigator ? navigator.virtualKeyboard : null;
|
|
677
|
+
}
|
|
678
|
+
function getActiveElement() {
|
|
679
|
+
var _a;
|
|
680
|
+
let activeElement = document.activeElement;
|
|
681
|
+
while (activeElement instanceof HTMLElement && ((_a = activeElement.shadowRoot) == null ? void 0 : _a.activeElement)) {
|
|
682
|
+
activeElement = activeElement.shadowRoot.activeElement;
|
|
683
|
+
}
|
|
684
|
+
return activeElement && willOpenKeyboard(activeElement) ? activeElement : null;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// src/hooks/use-keyboard-avoidance.ts
|
|
688
|
+
function useKeyboardAvoidance({
|
|
689
|
+
isEnabled,
|
|
690
|
+
containerRef,
|
|
691
|
+
onWillOpenKeyboard,
|
|
692
|
+
onDidOpenKeyboard
|
|
693
|
+
}) {
|
|
694
|
+
const [focusedElement, setFocusedElement] = React4.useState(
|
|
695
|
+
null
|
|
696
|
+
);
|
|
697
|
+
const keyboard = useVirtualKeyboard({
|
|
698
|
+
isEnabled,
|
|
699
|
+
containerRef
|
|
700
|
+
});
|
|
701
|
+
const handleFocusIn = useStableCallback(async (event) => {
|
|
702
|
+
var _a;
|
|
703
|
+
const element = event.target;
|
|
704
|
+
if (willOpenKeyboard(element) && ((_a = containerRef.current) == null ? void 0 : _a.contains(element))) {
|
|
705
|
+
await (onWillOpenKeyboard == null ? void 0 : onWillOpenKeyboard(event));
|
|
706
|
+
setFocusedElement(element);
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
const handleFocusOut = useStableCallback((event) => {
|
|
710
|
+
const element = event.target;
|
|
711
|
+
if (focusedElement === element) {
|
|
712
|
+
setFocusedElement(null);
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
React4.useEffect(() => {
|
|
716
|
+
if (!isEnabled) return;
|
|
550
717
|
document.addEventListener("focusin", handleFocusIn);
|
|
551
718
|
document.addEventListener("focusout", handleFocusOut);
|
|
552
719
|
return () => {
|
|
553
720
|
document.removeEventListener("focusin", handleFocusIn);
|
|
554
721
|
document.removeEventListener("focusout", handleFocusOut);
|
|
555
722
|
};
|
|
556
|
-
}, [isEnabled
|
|
557
|
-
|
|
723
|
+
}, [isEnabled]);
|
|
724
|
+
React4.useEffect(() => {
|
|
725
|
+
const containerElement = containerRef.current;
|
|
726
|
+
if (!isEnabled || !focusedElement || !containerElement || !keyboard.isKeyboardOpen) {
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
requestAnimationFrame(() => {
|
|
730
|
+
onDidOpenKeyboard == null ? void 0 : onDidOpenKeyboard(focusedElement);
|
|
731
|
+
});
|
|
732
|
+
}, [isEnabled, keyboard.isKeyboardOpen, focusedElement]);
|
|
733
|
+
return keyboard;
|
|
558
734
|
}
|
|
559
735
|
function useSafeAreaInsets() {
|
|
560
736
|
const [insets] = React4.useState(() => {
|
|
@@ -698,13 +874,13 @@ function isScrollable(node, checkForOverflow) {
|
|
|
698
874
|
return false;
|
|
699
875
|
}
|
|
700
876
|
const style = window.getComputedStyle(node);
|
|
701
|
-
let
|
|
877
|
+
let scrollable = /(auto|scroll)/.test(
|
|
702
878
|
style.overflow + style.overflowX + style.overflowY
|
|
703
879
|
);
|
|
704
|
-
if (
|
|
705
|
-
|
|
880
|
+
if (scrollable && checkForOverflow) {
|
|
881
|
+
scrollable = node.scrollHeight !== node.clientHeight || node.scrollWidth !== node.clientWidth;
|
|
706
882
|
}
|
|
707
|
-
return
|
|
883
|
+
return scrollable;
|
|
708
884
|
}
|
|
709
885
|
function getScrollParent(node, checkForOverflow) {
|
|
710
886
|
let scrollableNode = node;
|
|
@@ -716,17 +892,6 @@ function getScrollParent(node, checkForOverflow) {
|
|
|
716
892
|
}
|
|
717
893
|
return scrollableNode || document.scrollingElement || document.documentElement;
|
|
718
894
|
}
|
|
719
|
-
var nonTextInputTypes = /* @__PURE__ */ new Set([
|
|
720
|
-
"checkbox",
|
|
721
|
-
"radio",
|
|
722
|
-
"range",
|
|
723
|
-
"color",
|
|
724
|
-
"file",
|
|
725
|
-
"image",
|
|
726
|
-
"button",
|
|
727
|
-
"submit",
|
|
728
|
-
"reset"
|
|
729
|
-
]);
|
|
730
895
|
var preventScrollCount = 0;
|
|
731
896
|
var restore;
|
|
732
897
|
function usePreventScroll(options = {}) {
|
|
@@ -893,9 +1058,6 @@ function scrollIntoView(target) {
|
|
|
893
1058
|
target = scrollable.parentElement;
|
|
894
1059
|
}
|
|
895
1060
|
}
|
|
896
|
-
function willOpenKeyboard(target) {
|
|
897
|
-
return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
898
|
-
}
|
|
899
1061
|
function useSheetState({
|
|
900
1062
|
isOpen,
|
|
901
1063
|
onClosed: _onClosed,
|
|
@@ -940,108 +1102,6 @@ function useSheetState({
|
|
|
940
1102
|
}, [state]);
|
|
941
1103
|
return state;
|
|
942
1104
|
}
|
|
943
|
-
function useVirtualKeyboard(options = {}) {
|
|
944
|
-
const {
|
|
945
|
-
containerRef,
|
|
946
|
-
isEnabled = true,
|
|
947
|
-
debounceDelay = 100,
|
|
948
|
-
includeContentEditable = true,
|
|
949
|
-
visualViewportThreshold = 100
|
|
950
|
-
} = options;
|
|
951
|
-
const [state, setState] = React4.useState({
|
|
952
|
-
isVisible: false,
|
|
953
|
-
height: 0
|
|
954
|
-
});
|
|
955
|
-
const focusedElementRef = React4.useRef(null);
|
|
956
|
-
const debounceTimer = React4.useRef(null);
|
|
957
|
-
const isTextInput = useStableCallback((el) => {
|
|
958
|
-
return (el == null ? void 0 : el.tagName) === "INPUT" || (el == null ? void 0 : el.tagName) === "TEXTAREA" || includeContentEditable && el instanceof HTMLElement && el.isContentEditable;
|
|
959
|
-
});
|
|
960
|
-
React4.useEffect(() => {
|
|
961
|
-
if (!isEnabled) return;
|
|
962
|
-
const vv = window.visualViewport;
|
|
963
|
-
const vk = navigator.virtualKeyboard;
|
|
964
|
-
function setKeyboardInsetHeightEnv(height) {
|
|
965
|
-
const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
|
|
966
|
-
if (window.isSecureContext) {
|
|
967
|
-
element.style.setProperty(
|
|
968
|
-
"--keyboard-inset-height",
|
|
969
|
-
`env(keyboard-inset-height, ${height}px)`
|
|
970
|
-
);
|
|
971
|
-
} else {
|
|
972
|
-
element.style.setProperty("--keyboard-inset-height", `${height}px`);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
function handleFocusIn(e) {
|
|
976
|
-
if (e.target instanceof HTMLElement && isTextInput(e.target)) {
|
|
977
|
-
focusedElementRef.current = e.target;
|
|
978
|
-
updateKeyboardState();
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
function handleFocusOut() {
|
|
982
|
-
focusedElementRef.current = null;
|
|
983
|
-
updateKeyboardState();
|
|
984
|
-
}
|
|
985
|
-
function updateKeyboardState() {
|
|
986
|
-
if (debounceTimer.current) {
|
|
987
|
-
clearTimeout(debounceTimer.current);
|
|
988
|
-
}
|
|
989
|
-
debounceTimer.current = setTimeout(() => {
|
|
990
|
-
const active = focusedElementRef.current;
|
|
991
|
-
const inputIsFocused = isTextInput(active);
|
|
992
|
-
if (!inputIsFocused) {
|
|
993
|
-
setKeyboardInsetHeightEnv(0);
|
|
994
|
-
setState({ isVisible: false, height: 0 });
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
if (vv) {
|
|
998
|
-
const heightDiff = window.innerHeight - vv.height;
|
|
999
|
-
if (heightDiff > visualViewportThreshold) {
|
|
1000
|
-
setKeyboardInsetHeightEnv(heightDiff);
|
|
1001
|
-
setState({ isVisible: true, height: heightDiff });
|
|
1002
|
-
} else {
|
|
1003
|
-
setKeyboardInsetHeightEnv(0);
|
|
1004
|
-
setState({ isVisible: false, height: 0 });
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
}, debounceDelay);
|
|
1008
|
-
}
|
|
1009
|
-
window.addEventListener("focusin", handleFocusIn);
|
|
1010
|
-
window.addEventListener("focusout", handleFocusOut);
|
|
1011
|
-
if (vv) {
|
|
1012
|
-
vv.addEventListener("resize", updateKeyboardState);
|
|
1013
|
-
vv.addEventListener("scroll", updateKeyboardState);
|
|
1014
|
-
}
|
|
1015
|
-
let currentOverlaysContent = false;
|
|
1016
|
-
if (vk) {
|
|
1017
|
-
currentOverlaysContent = vk.overlaysContent;
|
|
1018
|
-
vk.overlaysContent = true;
|
|
1019
|
-
}
|
|
1020
|
-
return () => {
|
|
1021
|
-
window.removeEventListener("focusin", handleFocusIn);
|
|
1022
|
-
window.removeEventListener("focusout", handleFocusOut);
|
|
1023
|
-
if (vv) {
|
|
1024
|
-
vv.removeEventListener("resize", updateKeyboardState);
|
|
1025
|
-
vv.removeEventListener("scroll", updateKeyboardState);
|
|
1026
|
-
}
|
|
1027
|
-
if (vk) {
|
|
1028
|
-
vk.overlaysContent = currentOverlaysContent;
|
|
1029
|
-
}
|
|
1030
|
-
if (debounceTimer.current) {
|
|
1031
|
-
clearTimeout(debounceTimer.current);
|
|
1032
|
-
}
|
|
1033
|
-
};
|
|
1034
|
-
}, [
|
|
1035
|
-
debounceDelay,
|
|
1036
|
-
includeContentEditable,
|
|
1037
|
-
isEnabled,
|
|
1038
|
-
visualViewportThreshold
|
|
1039
|
-
]);
|
|
1040
|
-
return {
|
|
1041
|
-
keyboardHeight: state.height,
|
|
1042
|
-
isKeyboardOpen: state.isVisible
|
|
1043
|
-
};
|
|
1044
|
-
}
|
|
1045
1105
|
|
|
1046
1106
|
// src/snap.ts
|
|
1047
1107
|
function computeSnapPoints({
|
|
@@ -1216,11 +1276,6 @@ var Sheet = React4.forwardRef(
|
|
|
1216
1276
|
type: "tween",
|
|
1217
1277
|
...reduceMotion ? REDUCED_MOTION_TWEEN_CONFIG : tweenConfig
|
|
1218
1278
|
};
|
|
1219
|
-
const keyboard = useVirtualKeyboard({
|
|
1220
|
-
isEnabled: isOpen && avoidKeyboard,
|
|
1221
|
-
containerRef: sheetRef
|
|
1222
|
-
});
|
|
1223
|
-
const disableDrag = keyboard.isKeyboardOpen || disableDragProp;
|
|
1224
1279
|
const zIndex = react.useTransform(
|
|
1225
1280
|
y,
|
|
1226
1281
|
(val) => val + 2 >= closedY ? -1 : (style == null ? void 0 : style.zIndex) ?? 9999
|
|
@@ -1264,14 +1319,45 @@ var Sheet = React4.forwardRef(
|
|
|
1264
1319
|
onComplete: () => updateSnap(snapIndex)
|
|
1265
1320
|
});
|
|
1266
1321
|
});
|
|
1322
|
+
const keyboard = useKeyboardAvoidance({
|
|
1323
|
+
isEnabled: isOpen && avoidKeyboard,
|
|
1324
|
+
containerRef: sheetRef,
|
|
1325
|
+
onWillOpenKeyboard: async () => {
|
|
1326
|
+
const lastSnapPoint = snapPoints[snapPoints.length - 1];
|
|
1327
|
+
if (lastSnapPoint && lastSnapPoint.snapIndex !== currentSnap) {
|
|
1328
|
+
await react.animate(y, lastSnapPoint.snapValueY, animationOptions);
|
|
1329
|
+
updateSnap(lastSnapPoint.snapIndex);
|
|
1330
|
+
}
|
|
1331
|
+
},
|
|
1332
|
+
onDidOpenKeyboard: (focusedElement) => {
|
|
1333
|
+
const sheetElement = sheetRef.current;
|
|
1334
|
+
if (!sheetElement) return;
|
|
1335
|
+
const inputRect = focusedElement.getBoundingClientRect();
|
|
1336
|
+
const containerRect = sheetElement.getBoundingClientRect();
|
|
1337
|
+
const scroller = sheetElement.querySelector(
|
|
1338
|
+
".react-modal-sheet-content-scroller"
|
|
1339
|
+
);
|
|
1340
|
+
const scrollTarget = Math.max(
|
|
1341
|
+
inputRect.top - containerRect.top + scroller.scrollTop - inputRect.height,
|
|
1342
|
+
0
|
|
1343
|
+
);
|
|
1344
|
+
requestAnimationFrame(() => {
|
|
1345
|
+
scroller.scrollTo({ top: scrollTarget, behavior: "smooth" });
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
const disableDrag = keyboard.isKeyboardOpen || disableDragProp;
|
|
1267
1350
|
const blurActiveInput = useStableCallback(() => {
|
|
1351
|
+
var _a;
|
|
1268
1352
|
const focusedElement = document.activeElement;
|
|
1269
|
-
if (
|
|
1270
|
-
const isInput = focusedElement.tagName === "INPUT" || focusedElement.tagName === "TEXTAREA";
|
|
1271
|
-
if (isInput && sheetRef.current.contains(focusedElement)) {
|
|
1353
|
+
if (focusedElement && willOpenKeyboard(focusedElement) && ((_a = sheetRef.current) == null ? void 0 : _a.contains(focusedElement))) {
|
|
1272
1354
|
focusedElement.blur();
|
|
1273
1355
|
}
|
|
1274
1356
|
});
|
|
1357
|
+
const onDragStart = useStableCallback((event, info) => {
|
|
1358
|
+
blurActiveInput();
|
|
1359
|
+
onDragStartProp == null ? void 0 : onDragStartProp(event, info);
|
|
1360
|
+
});
|
|
1275
1361
|
const onDrag = useStableCallback((event, info) => {
|
|
1276
1362
|
onDragProp == null ? void 0 : onDragProp(event, info);
|
|
1277
1363
|
const currentY = y.get();
|
|
@@ -1280,10 +1366,6 @@ var Sheet = React4.forwardRef(
|
|
|
1280
1366
|
if (velocity < 0) indicatorRotation.set(-10);
|
|
1281
1367
|
y.set(Math.max(currentY + info.delta.y, 0));
|
|
1282
1368
|
});
|
|
1283
|
-
const onDragStart = useStableCallback((event, info) => {
|
|
1284
|
-
blurActiveInput();
|
|
1285
|
-
onDragStartProp == null ? void 0 : onDragStartProp(event, info);
|
|
1286
|
-
});
|
|
1287
1369
|
const onDragEnd = useStableCallback((event, info) => {
|
|
1288
1370
|
blurActiveInput();
|
|
1289
1371
|
onDragEndProp == null ? void 0 : onDragEndProp(event, info);
|
|
@@ -1351,41 +1433,6 @@ var Sheet = React4.forwardRef(
|
|
|
1351
1433
|
usePreventScroll({
|
|
1352
1434
|
isDisabled: disableScrollLocking || !isOpen
|
|
1353
1435
|
});
|
|
1354
|
-
const focusedInput = useFocusedInput({
|
|
1355
|
-
isEnabled: isOpen && avoidKeyboard,
|
|
1356
|
-
sheetRef
|
|
1357
|
-
});
|
|
1358
|
-
React4.useEffect(() => {
|
|
1359
|
-
if (!isOpen || !avoidKeyboard) {
|
|
1360
|
-
return;
|
|
1361
|
-
}
|
|
1362
|
-
async function adjustSheetForKeyboard() {
|
|
1363
|
-
const sheetElement = sheetRef.current;
|
|
1364
|
-
if (!sheetElement || !focusedInput || !keyboard.isKeyboardOpen) {
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1367
|
-
const lastSnapPoint = snapPoints[snapPoints.length - 1];
|
|
1368
|
-
if (lastSnapPoint) {
|
|
1369
|
-
await react.animate(y, lastSnapPoint.snapValueY, animationOptions);
|
|
1370
|
-
updateSnap(lastSnapPoint.snapIndex);
|
|
1371
|
-
}
|
|
1372
|
-
requestAnimationFrame(() => {
|
|
1373
|
-
const inputRect = focusedInput.getBoundingClientRect();
|
|
1374
|
-
const sheetRect = sheetElement.getBoundingClientRect();
|
|
1375
|
-
const scroller = sheetElement.querySelector(
|
|
1376
|
-
".react-modal-sheet-content-scroller"
|
|
1377
|
-
);
|
|
1378
|
-
const scrollTarget = Math.max(
|
|
1379
|
-
inputRect.top - sheetRect.top + scroller.scrollTop - inputRect.height,
|
|
1380
|
-
0
|
|
1381
|
-
);
|
|
1382
|
-
requestAnimationFrame(() => {
|
|
1383
|
-
scroller.scrollTo({ top: scrollTarget, behavior: "smooth" });
|
|
1384
|
-
});
|
|
1385
|
-
});
|
|
1386
|
-
}
|
|
1387
|
-
adjustSheetForKeyboard();
|
|
1388
|
-
}, [isOpen, avoidKeyboard, keyboard.isKeyboardOpen, focusedInput]);
|
|
1389
1436
|
const state = useSheetState({
|
|
1390
1437
|
isOpen,
|
|
1391
1438
|
onOpen: async () => {
|