react-modal-sheet 5.4.1 → 5.5.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/dist/index.js +140 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +140 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/sheet.tsx +21 -57
- package/src/snap.ts +205 -102
package/dist/index.js
CHANGED
|
@@ -137,7 +137,7 @@ var REDUCED_MOTION_TWEEN_CONFIG = {
|
|
|
137
137
|
duration: 0.01
|
|
138
138
|
};
|
|
139
139
|
var DEFAULT_DRAG_CLOSE_THRESHOLD = 0.6;
|
|
140
|
-
var DEFAULT_DRAG_VELOCITY_THRESHOLD =
|
|
140
|
+
var DEFAULT_DRAG_VELOCITY_THRESHOLD = 1200;
|
|
141
141
|
|
|
142
142
|
// src/utils.ts
|
|
143
143
|
function applyStyles(styles2, unstyled) {
|
|
@@ -1157,73 +1157,145 @@ function computeSnapPoints({
|
|
|
1157
1157
|
// Y value is inverted as `y = 0` means sheet is at the top
|
|
1158
1158
|
}));
|
|
1159
1159
|
}
|
|
1160
|
-
function
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1160
|
+
function clamp(value, min, max) {
|
|
1161
|
+
return Math.min(Math.max(value, min), max);
|
|
1162
|
+
}
|
|
1163
|
+
function sign(value) {
|
|
1164
|
+
if (value > 0) return 1;
|
|
1165
|
+
if (value < 0) return -1;
|
|
1166
|
+
return 0;
|
|
1167
|
+
}
|
|
1168
|
+
function toAscendingYSnaps(snapPoints) {
|
|
1169
|
+
return snapPoints.slice().sort((a, b) => a.snapValueY - b.snapValueY);
|
|
1170
|
+
}
|
|
1171
|
+
function findNearestSnapByY(snapPoints, y) {
|
|
1164
1172
|
return snapPoints.reduce(
|
|
1165
|
-
(closest, snap) => Math.abs(snap.snapValueY -
|
|
1173
|
+
(closest, snap) => Math.abs(snap.snapValueY - y) < Math.abs(closest.snapValueY - y) ? snap : closest
|
|
1166
1174
|
);
|
|
1167
1175
|
}
|
|
1168
|
-
function
|
|
1176
|
+
function findNearestSnapAboveY(snapPoints, y) {
|
|
1177
|
+
const snaps = toAscendingYSnaps(snapPoints);
|
|
1178
|
+
for (let i = snaps.length - 1; i >= 0; i--) {
|
|
1179
|
+
if (snaps[i].snapValueY < y) {
|
|
1180
|
+
return snaps[i];
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return null;
|
|
1184
|
+
}
|
|
1185
|
+
function findNearestSnapBelowY(snapPoints, y) {
|
|
1186
|
+
const snaps = toAscendingYSnaps(snapPoints);
|
|
1187
|
+
for (let i = 0; i < snaps.length; i++) {
|
|
1188
|
+
if (snaps[i].snapValueY > y) {
|
|
1189
|
+
return snaps[i];
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return null;
|
|
1193
|
+
}
|
|
1194
|
+
function resolveDirection({
|
|
1195
|
+
offsetY,
|
|
1196
|
+
velocityY,
|
|
1197
|
+
deltaY
|
|
1198
|
+
}) {
|
|
1199
|
+
if (Math.abs(velocityY) > 50) return sign(velocityY);
|
|
1200
|
+
const offsetDirection = sign(offsetY);
|
|
1201
|
+
if (offsetDirection !== 0) return offsetDirection;
|
|
1202
|
+
return sign(deltaY);
|
|
1203
|
+
}
|
|
1204
|
+
function classifyDragEnd({
|
|
1169
1205
|
y,
|
|
1206
|
+
info,
|
|
1207
|
+
sheetHeight,
|
|
1170
1208
|
snapPoints,
|
|
1171
|
-
|
|
1209
|
+
dragVelocityThreshold,
|
|
1210
|
+
dragCloseThreshold
|
|
1172
1211
|
}) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1212
|
+
const flickVelocity = dragVelocityThreshold;
|
|
1213
|
+
const strongFlickVelocity = Math.max(2e3, flickVelocity);
|
|
1214
|
+
const distanceCommitRatio = 0.35;
|
|
1215
|
+
const predictionTime = 0.2;
|
|
1216
|
+
const minDragDistance = 20;
|
|
1217
|
+
const snapStickiness = 24;
|
|
1218
|
+
const minY = 0;
|
|
1219
|
+
const maxY = sheetHeight;
|
|
1220
|
+
const offsetY = info.offset.y;
|
|
1221
|
+
const deltaY = info.delta.y;
|
|
1222
|
+
const velocityY = info.velocity.y;
|
|
1223
|
+
const predictedY = clamp(y + velocityY * predictionTime, minY, maxY);
|
|
1224
|
+
const absVelocity = Math.abs(velocityY);
|
|
1225
|
+
const direction = resolveDirection({ offsetY, velocityY, deltaY });
|
|
1226
|
+
const isStrongFlick = absVelocity > strongFlickVelocity;
|
|
1227
|
+
const isFlick = absVelocity > flickVelocity;
|
|
1228
|
+
if (snapPoints.length === 0) {
|
|
1229
|
+
if (isFlick) {
|
|
1230
|
+
return {
|
|
1231
|
+
yTo: direction < 0 ? minY : maxY,
|
|
1232
|
+
snapIndex: void 0
|
|
1233
|
+
};
|
|
1234
|
+
}
|
|
1235
|
+
const midpoint = minY + (maxY - minY) * dragCloseThreshold;
|
|
1236
|
+
return {
|
|
1237
|
+
yTo: predictedY < midpoint ? minY : maxY,
|
|
1238
|
+
snapIndex: void 0
|
|
1239
|
+
};
|
|
1177
1240
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
dragDirection,
|
|
1181
|
-
snapPoints
|
|
1182
|
-
}) {
|
|
1183
|
-
const bottomSnapPoint = snapPoints[0];
|
|
1184
|
-
const topSnapPoint = snapPoints[snapPoints.length - 1];
|
|
1185
|
-
if (dragDirection === "down") {
|
|
1241
|
+
const nearestSnap = findNearestSnapByY(snapPoints, y);
|
|
1242
|
+
if (!isFlick && Math.abs(offsetY) < minDragDistance) {
|
|
1186
1243
|
return {
|
|
1187
|
-
yTo:
|
|
1188
|
-
snapIndex:
|
|
1244
|
+
yTo: nearestSnap.snapValueY,
|
|
1245
|
+
snapIndex: nearestSnap.snapIndex
|
|
1189
1246
|
};
|
|
1190
1247
|
}
|
|
1191
|
-
|
|
1192
|
-
yTo: topSnapPoint.snapValueY,
|
|
1193
|
-
snapIndex: topSnapPoint.snapIndex
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
function handleLowVelocityDrag({
|
|
1197
|
-
currentSnapPoint,
|
|
1198
|
-
currentY,
|
|
1199
|
-
dragDirection,
|
|
1200
|
-
snapPoints,
|
|
1201
|
-
velocity
|
|
1202
|
-
}) {
|
|
1203
|
-
const closestSnapRelativeToCurrentY = findClosestSnapPoint({
|
|
1204
|
-
snapPoints,
|
|
1205
|
-
currentY
|
|
1206
|
-
});
|
|
1207
|
-
if (Math.abs(velocity) < 20) {
|
|
1248
|
+
if (!isFlick && Math.abs(y - nearestSnap.snapValueY) < snapStickiness) {
|
|
1208
1249
|
return {
|
|
1209
|
-
yTo:
|
|
1210
|
-
snapIndex:
|
|
1250
|
+
yTo: nearestSnap.snapValueY,
|
|
1251
|
+
snapIndex: nearestSnap.snapIndex
|
|
1211
1252
|
};
|
|
1212
1253
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
snapPoints,
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1254
|
+
if (isStrongFlick) {
|
|
1255
|
+
const target = direction < 0 ? minY : maxY;
|
|
1256
|
+
const targetSnap = findNearestSnapByY(snapPoints, target);
|
|
1257
|
+
return {
|
|
1258
|
+
yTo: target,
|
|
1259
|
+
snapIndex: targetSnap.snapIndex
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
if (isFlick) {
|
|
1263
|
+
const nextSnap2 = direction < 0 ? findNearestSnapAboveY(snapPoints, y) : findNearestSnapBelowY(snapPoints, y);
|
|
1264
|
+
const fallbackY = direction < 0 ? minY : maxY;
|
|
1265
|
+
const fallbackSnap = findNearestSnapByY(snapPoints, fallbackY);
|
|
1266
|
+
const targetSnap = nextSnap2 ?? fallbackSnap;
|
|
1267
|
+
return {
|
|
1268
|
+
yTo: targetSnap.snapValueY,
|
|
1269
|
+
snapIndex: targetSnap.snapIndex
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
const firstSnap = toAscendingYSnaps(snapPoints)[0];
|
|
1273
|
+
const lastSnap = toAscendingYSnaps(snapPoints)[snapPoints.length - 1];
|
|
1274
|
+
const prevSnap = findNearestSnapAboveY(snapPoints, y) ?? firstSnap;
|
|
1275
|
+
const nextSnap = findNearestSnapBelowY(snapPoints, y) ?? lastSnap;
|
|
1276
|
+
if (prevSnap.snapIndex === nextSnap.snapIndex) {
|
|
1219
1277
|
return {
|
|
1220
|
-
yTo:
|
|
1221
|
-
snapIndex:
|
|
1278
|
+
yTo: prevSnap.snapValueY,
|
|
1279
|
+
snapIndex: prevSnap.snapIndex
|
|
1222
1280
|
};
|
|
1223
1281
|
}
|
|
1282
|
+
const range = nextSnap.snapValueY - prevSnap.snapValueY;
|
|
1283
|
+
const progress = range > 0 ? (y - prevSnap.snapValueY) / range : 0;
|
|
1284
|
+
let selectedSnap = nearestSnap;
|
|
1285
|
+
if (direction > 0) {
|
|
1286
|
+
selectedSnap = progress > distanceCommitRatio ? nextSnap : prevSnap;
|
|
1287
|
+
} else if (direction < 0) {
|
|
1288
|
+
selectedSnap = progress < 1 - distanceCommitRatio ? prevSnap : nextSnap;
|
|
1289
|
+
}
|
|
1290
|
+
if (absVelocity > 200) {
|
|
1291
|
+
const predictedSnap = findNearestSnapByY(snapPoints, predictedY);
|
|
1292
|
+
if (Math.abs(predictedSnap.snapValueY - y) < Math.abs(selectedSnap.snapValueY - y)) {
|
|
1293
|
+
selectedSnap = predictedSnap;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1224
1296
|
return {
|
|
1225
|
-
yTo:
|
|
1226
|
-
snapIndex:
|
|
1297
|
+
yTo: selectedSnap.snapValueY,
|
|
1298
|
+
snapIndex: selectedSnap.snapIndex
|
|
1227
1299
|
};
|
|
1228
1300
|
}
|
|
1229
1301
|
|
|
@@ -1370,45 +1442,25 @@ var Sheet = React4.forwardRef(
|
|
|
1370
1442
|
blurActiveInput();
|
|
1371
1443
|
onDragEndProp == null ? void 0 : onDragEndProp(event, info);
|
|
1372
1444
|
const currentY = y.get();
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
currentSnapPoint,
|
|
1388
|
-
currentY,
|
|
1389
|
-
dragDirection: dragOffsetDirection,
|
|
1390
|
-
snapPoints,
|
|
1391
|
-
velocity: info.velocity.y
|
|
1392
|
-
});
|
|
1393
|
-
}
|
|
1394
|
-
yTo = result.yTo;
|
|
1395
|
-
if (disableDismiss && yTo + 1 >= sheetHeight) {
|
|
1396
|
-
const bottomSnapPoint = snapPoints.find((s) => s.snapValue > 0);
|
|
1397
|
-
if (bottomSnapPoint) {
|
|
1398
|
-
yTo = bottomSnapPoint.snapValueY;
|
|
1399
|
-
updateSnap(bottomSnapPoint.snapIndex);
|
|
1400
|
-
} else {
|
|
1401
|
-
yTo = currentY;
|
|
1402
|
-
}
|
|
1403
|
-
} else if (result.snapIndex !== void 0) {
|
|
1404
|
-
updateSnap(result.snapIndex);
|
|
1405
|
-
}
|
|
1406
|
-
} else if (info.velocity.y > dragVelocityThreshold || currentY > sheetHeight * dragCloseThreshold) {
|
|
1407
|
-
if (disableDismiss) {
|
|
1408
|
-
yTo = 0;
|
|
1445
|
+
const result = classifyDragEnd({
|
|
1446
|
+
y: currentY,
|
|
1447
|
+
info,
|
|
1448
|
+
sheetHeight,
|
|
1449
|
+
dragCloseThreshold,
|
|
1450
|
+
snapPoints,
|
|
1451
|
+
dragVelocityThreshold
|
|
1452
|
+
});
|
|
1453
|
+
let yTo = result.yTo;
|
|
1454
|
+
if (disableDismiss && yTo + 1 >= sheetHeight) {
|
|
1455
|
+
const bottomSnapPoint = snapPoints.find((s) => s.snapValue > 0);
|
|
1456
|
+
if (bottomSnapPoint) {
|
|
1457
|
+
yTo = bottomSnapPoint.snapValueY;
|
|
1458
|
+
updateSnap(bottomSnapPoint.snapIndex);
|
|
1409
1459
|
} else {
|
|
1410
|
-
yTo =
|
|
1460
|
+
yTo = currentY;
|
|
1411
1461
|
}
|
|
1462
|
+
} else if (result.snapIndex !== void 0) {
|
|
1463
|
+
updateSnap(result.snapIndex);
|
|
1412
1464
|
}
|
|
1413
1465
|
react.animate(y, yTo, animationOptions);
|
|
1414
1466
|
if (yTo + 1 >= sheetHeight && !disableDismiss) {
|