react-modal-sheet 5.1.1 → 5.2.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.
- package/README.md +114 -0
- package/dist/index.d.mts +110 -2
- package/dist/index.d.ts +110 -2
- package/dist/index.js +72 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/SheetContent.tsx +5 -3
- package/src/hooks/use-scroll-position.ts +69 -12
- package/src/hooks/use-virtual-keyboard.ts +58 -17
- package/src/index.tsx +3 -0
- package/src/sheet.tsx +10 -3
- package/src/snap.ts +17 -1
- package/src/types.tsx +10 -9
- package/src/utils.ts +21 -0
package/dist/index.mjs
CHANGED
|
@@ -181,6 +181,21 @@ var isIPad = cached(function() {
|
|
|
181
181
|
var isIOS = cached(function() {
|
|
182
182
|
return isIPhone() || isIPad();
|
|
183
183
|
});
|
|
184
|
+
function waitForElement(className, interval = 50, maxAttempts = 20) {
|
|
185
|
+
return new Promise((resolve) => {
|
|
186
|
+
let attempts = 0;
|
|
187
|
+
const timer = setInterval(() => {
|
|
188
|
+
const element = document.getElementsByClassName(
|
|
189
|
+
className
|
|
190
|
+
)[0];
|
|
191
|
+
attempts++;
|
|
192
|
+
if (element || attempts >= maxAttempts) {
|
|
193
|
+
clearInterval(timer);
|
|
194
|
+
resolve(element);
|
|
195
|
+
}
|
|
196
|
+
}, interval);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
184
199
|
|
|
185
200
|
// src/SheetBackdrop.tsx
|
|
186
201
|
var isClickable = (props) => !!props.onClick || !!props.onTap;
|
|
@@ -255,12 +270,12 @@ function useDragConstraints() {
|
|
|
255
270
|
const onMeasure = useCallback(() => constraints, []);
|
|
256
271
|
return { ref, onMeasure };
|
|
257
272
|
}
|
|
258
|
-
function useScrollPosition() {
|
|
259
|
-
const
|
|
273
|
+
function useScrollPosition(options = {}) {
|
|
274
|
+
const { debounceDelay = 32, isEnabled = true } = options;
|
|
275
|
+
const [element, setElement] = useState(null);
|
|
260
276
|
const [scrollPosition, setScrollPosition] = useState(void 0);
|
|
261
277
|
useEffect(() => {
|
|
262
|
-
|
|
263
|
-
if (!element) return;
|
|
278
|
+
if (!element || !isEnabled) return;
|
|
264
279
|
let scrollTimeout = null;
|
|
265
280
|
function determineScrollPosition(element2) {
|
|
266
281
|
const { scrollTop, scrollHeight, clientHeight } = element2;
|
|
@@ -283,14 +298,21 @@ function useScrollPosition() {
|
|
|
283
298
|
setScrollPosition(position);
|
|
284
299
|
}
|
|
285
300
|
function onScroll(event) {
|
|
286
|
-
if (event.currentTarget instanceof
|
|
301
|
+
if (event.currentTarget instanceof HTMLElement) {
|
|
287
302
|
const el = event.currentTarget;
|
|
288
303
|
if (scrollTimeout) clearTimeout(scrollTimeout);
|
|
289
|
-
|
|
304
|
+
if (debounceDelay === 0) {
|
|
305
|
+
determineScrollPosition(el);
|
|
306
|
+
} else {
|
|
307
|
+
scrollTimeout = setTimeout(
|
|
308
|
+
() => determineScrollPosition(el),
|
|
309
|
+
debounceDelay
|
|
310
|
+
);
|
|
311
|
+
}
|
|
290
312
|
}
|
|
291
313
|
}
|
|
292
314
|
function onTouchStart(event) {
|
|
293
|
-
if (event.currentTarget instanceof
|
|
315
|
+
if (event.currentTarget instanceof HTMLElement) {
|
|
294
316
|
determineScrollPosition(event.currentTarget);
|
|
295
317
|
}
|
|
296
318
|
}
|
|
@@ -302,8 +324,11 @@ function useScrollPosition() {
|
|
|
302
324
|
element.removeEventListener("scroll", onScroll);
|
|
303
325
|
element.removeEventListener("touchstart", onTouchStart);
|
|
304
326
|
};
|
|
305
|
-
}, []);
|
|
306
|
-
return {
|
|
327
|
+
}, [element, isEnabled]);
|
|
328
|
+
return {
|
|
329
|
+
scrollRef: (element2) => setElement(element2),
|
|
330
|
+
scrollPosition
|
|
331
|
+
};
|
|
307
332
|
}
|
|
308
333
|
|
|
309
334
|
// src/SheetContent.tsx
|
|
@@ -314,6 +339,8 @@ var SheetContent = forwardRef(
|
|
|
314
339
|
children,
|
|
315
340
|
style: styleProp,
|
|
316
341
|
className = "",
|
|
342
|
+
scrollClassName = "",
|
|
343
|
+
scrollStyle: scrollStyleProp,
|
|
317
344
|
scrollRef: scrollRefProp = null,
|
|
318
345
|
unstyled,
|
|
319
346
|
...rest
|
|
@@ -358,9 +385,9 @@ var SheetContent = forwardRef(
|
|
|
358
385
|
/* @__PURE__ */ React4.createElement(
|
|
359
386
|
motion.div,
|
|
360
387
|
{
|
|
361
|
-
ref: mergeRefs([scroll.
|
|
362
|
-
style: scrollStyle,
|
|
363
|
-
className:
|
|
388
|
+
ref: mergeRefs([scroll.scrollRef, scrollRefProp]),
|
|
389
|
+
style: { ...scrollStyle, ...scrollStyleProp },
|
|
390
|
+
className: `react-modal-sheet-content-scroller ${scrollClassName}`
|
|
364
391
|
},
|
|
365
392
|
children
|
|
366
393
|
)
|
|
@@ -858,13 +885,14 @@ function useSheetState({
|
|
|
858
885
|
}, [state]);
|
|
859
886
|
return state;
|
|
860
887
|
}
|
|
861
|
-
function useVirtualKeyboard({
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
888
|
+
function useVirtualKeyboard(options = {}) {
|
|
889
|
+
const {
|
|
890
|
+
containerRef,
|
|
891
|
+
isEnabled = true,
|
|
892
|
+
debounceDelay = 100,
|
|
893
|
+
includeContentEditable = true,
|
|
894
|
+
visualViewportThreshold = 100
|
|
895
|
+
} = options;
|
|
868
896
|
const [state, setState] = useState({
|
|
869
897
|
isVisible: false,
|
|
870
898
|
height: 0
|
|
@@ -879,11 +907,15 @@ function useVirtualKeyboard({
|
|
|
879
907
|
const vv = window.visualViewport;
|
|
880
908
|
const vk = navigator.virtualKeyboard;
|
|
881
909
|
function setKeyboardInsetHeightEnv(height) {
|
|
882
|
-
|
|
883
|
-
(
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
910
|
+
const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
|
|
911
|
+
if (window.isSecureContext) {
|
|
912
|
+
element.style.setProperty(
|
|
913
|
+
"--keyboard-inset-height",
|
|
914
|
+
`env(keyboard-inset-height, ${height}px)`
|
|
915
|
+
);
|
|
916
|
+
} else {
|
|
917
|
+
element.style.setProperty("--keyboard-inset-height", `${height}px`);
|
|
918
|
+
}
|
|
887
919
|
}
|
|
888
920
|
function handleFocusIn(e) {
|
|
889
921
|
if (e.target instanceof HTMLElement && isTextInput(e.target)) {
|
|
@@ -961,8 +993,20 @@ function computeSnapPoints({
|
|
|
961
993
|
snapPointsProp,
|
|
962
994
|
sheetHeight
|
|
963
995
|
}) {
|
|
996
|
+
if (snapPointsProp[0] !== 0) {
|
|
997
|
+
console.error(
|
|
998
|
+
`First snap point should be 0 to ensure the sheet can be fully closed. Got: [${snapPointsProp.join(", ")}]`
|
|
999
|
+
);
|
|
1000
|
+
snapPointsProp.unshift(0);
|
|
1001
|
+
}
|
|
1002
|
+
if (snapPointsProp[snapPointsProp.length - 1] !== 1) {
|
|
1003
|
+
console.error(
|
|
1004
|
+
`Last snap point should be 1 to ensure the sheet can be fully opened. Got: [${snapPointsProp.join(", ")}]`
|
|
1005
|
+
);
|
|
1006
|
+
snapPointsProp.push(1);
|
|
1007
|
+
}
|
|
964
1008
|
if (sheetHeight <= 0) {
|
|
965
|
-
console.
|
|
1009
|
+
console.error(
|
|
966
1010
|
`Sheet height is ${sheetHeight}, cannot compute snap points. Make sure the sheet is mounted and has a valid height.`
|
|
967
1011
|
);
|
|
968
1012
|
return [];
|
|
@@ -1256,6 +1300,7 @@ var Sheet = forwardRef(
|
|
|
1256
1300
|
isOpen,
|
|
1257
1301
|
onOpen: async () => {
|
|
1258
1302
|
onOpenStart == null ? void 0 : onOpenStart();
|
|
1303
|
+
await waitForElement("react-modal-sheet-container");
|
|
1259
1304
|
const initialSnapPoint = initialSnap !== void 0 ? getSnapPoint(initialSnap) : null;
|
|
1260
1305
|
const yTo = (initialSnapPoint == null ? void 0 : initialSnapPoint.snapValueY) ?? 0;
|
|
1261
1306
|
await animate(y, yTo, animationOptions);
|
|
@@ -1322,6 +1367,6 @@ var Sheet2 = Object.assign(Sheet, {
|
|
|
1322
1367
|
Backdrop: SheetBackdrop
|
|
1323
1368
|
});
|
|
1324
1369
|
|
|
1325
|
-
export { Sheet2 as Sheet };
|
|
1370
|
+
export { Sheet2 as Sheet, useScrollPosition, useVirtualKeyboard };
|
|
1326
1371
|
//# sourceMappingURL=index.mjs.map
|
|
1327
1372
|
//# sourceMappingURL=index.mjs.map
|