@seed-design/react-drawer 1.0.6 → 1.0.8
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/lib/{Drawer-12s-DriAYAR2.cjs → Drawer-12s-DXUv7jE4.cjs} +47 -19
- package/lib/{Drawer-12s-BdeYHia6.js → Drawer-12s-DnXlK1K0.js} +47 -19
- package/lib/index.cjs +1 -1
- package/lib/index.d.ts +102 -19
- package/lib/index.js +2 -2
- package/package.json +2 -2
- package/src/Drawer.tsx +8 -8
- package/src/use-snap-points.ts +6 -4
- package/src/useDrawer.ts +26 -9
|
@@ -6,7 +6,7 @@ var reactUseCallbackRef = require('@radix-ui/react-use-callback-ref');
|
|
|
6
6
|
var domUtils = require('@seed-design/dom-utils');
|
|
7
7
|
var reactPrimitive = require('@seed-design/react-primitive');
|
|
8
8
|
var React = require('react');
|
|
9
|
-
var reactUseControllableState = require('@
|
|
9
|
+
var reactUseControllableState = require('@seed-design/react-use-controllable-state');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
12
|
|
|
@@ -380,7 +380,7 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
380
380
|
snapPointsOffset,
|
|
381
381
|
snapToPoint
|
|
382
382
|
]);
|
|
383
|
-
function onRelease({ draggedDistance, closeDrawer, velocity, dismissible }) {
|
|
383
|
+
function onRelease({ draggedDistance, closeDrawer, velocity, dismissible, event }) {
|
|
384
384
|
if (fadeFromIndex === undefined) return;
|
|
385
385
|
const currentPosition = direction === "bottom" || direction === "right" ? (activeSnapPointOffset ?? 0) - draggedDistance : (activeSnapPointOffset ?? 0) + draggedDistance;
|
|
386
386
|
const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
|
|
@@ -392,7 +392,10 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
392
392
|
});
|
|
393
393
|
}
|
|
394
394
|
if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
|
|
395
|
-
if (dismissible) closeDrawer(
|
|
395
|
+
if (dismissible) closeDrawer(false, {
|
|
396
|
+
reason: "drag",
|
|
397
|
+
event
|
|
398
|
+
});
|
|
396
399
|
else snapToPoint(snapPointsOffset[0]); // snap to initial point
|
|
397
400
|
return;
|
|
398
401
|
}
|
|
@@ -414,7 +417,10 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
414
417
|
return;
|
|
415
418
|
}
|
|
416
419
|
if (isFirst && dragDirection < 0 && dismissible) {
|
|
417
|
-
closeDrawer(
|
|
420
|
+
closeDrawer(false, {
|
|
421
|
+
reason: "drag",
|
|
422
|
+
event
|
|
423
|
+
});
|
|
418
424
|
}
|
|
419
425
|
if (activeSnapPointIndex === null) return;
|
|
420
426
|
snapToPoint(snapPointsOffset[activeSnapPointIndex + dragDirection]);
|
|
@@ -484,8 +490,8 @@ function useDrawer(props) {
|
|
|
484
490
|
const [isOpen = false, setIsOpen] = reactUseControllableState.useControllableState({
|
|
485
491
|
defaultProp: defaultOpen,
|
|
486
492
|
prop: openProp,
|
|
487
|
-
onChange: (o)=>{
|
|
488
|
-
onOpenChange?.(o);
|
|
493
|
+
onChange: (o, details)=>{
|
|
494
|
+
onOpenChange?.(o, details);
|
|
489
495
|
if (!o && !nested) {
|
|
490
496
|
restorePositionSetting();
|
|
491
497
|
}
|
|
@@ -680,11 +686,11 @@ function useDrawer(props) {
|
|
|
680
686
|
}, [
|
|
681
687
|
isDragging
|
|
682
688
|
]);
|
|
683
|
-
const closeDrawer = React.useCallback((fromWithin)=>{
|
|
689
|
+
const closeDrawer = React.useCallback((fromWithin, details)=>{
|
|
684
690
|
cancelDrag();
|
|
685
691
|
onClose?.();
|
|
686
692
|
if (!fromWithin) {
|
|
687
|
-
setIsOpen(false);
|
|
693
|
+
setIsOpen(false, details);
|
|
688
694
|
}
|
|
689
695
|
if (fadeFromIndex !== undefined && fadeFromIndex > 0 && activeSnapPointIndex === 0) {
|
|
690
696
|
set(overlayRef.current, {
|
|
@@ -734,7 +740,8 @@ function useDrawer(props) {
|
|
|
734
740
|
draggedDistance: distMoved * directionMultiplier,
|
|
735
741
|
closeDrawer,
|
|
736
742
|
velocity,
|
|
737
|
-
dismissible
|
|
743
|
+
dismissible,
|
|
744
|
+
event: event.nativeEvent
|
|
738
745
|
});
|
|
739
746
|
onReleaseProp?.(event, true);
|
|
740
747
|
return;
|
|
@@ -745,7 +752,10 @@ function useDrawer(props) {
|
|
|
745
752
|
return;
|
|
746
753
|
}
|
|
747
754
|
if (velocity > VELOCITY_THRESHOLD) {
|
|
748
|
-
closeDrawer(
|
|
755
|
+
closeDrawer(false, {
|
|
756
|
+
reason: "drag",
|
|
757
|
+
event: event.nativeEvent
|
|
758
|
+
});
|
|
749
759
|
onReleaseProp?.(event, false);
|
|
750
760
|
return;
|
|
751
761
|
}
|
|
@@ -753,7 +763,10 @@ function useDrawer(props) {
|
|
|
753
763
|
const visibleDrawerWidth = Math.min(drawerRef.current.getBoundingClientRect().width ?? 0, window.innerWidth);
|
|
754
764
|
const isHorizontalSwipe = direction === "left" || direction === "right";
|
|
755
765
|
if (Math.abs(swipeAmount) >= (isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold) {
|
|
756
|
-
closeDrawer(
|
|
766
|
+
closeDrawer(false, {
|
|
767
|
+
reason: "drag",
|
|
768
|
+
event: event.nativeEvent
|
|
769
|
+
});
|
|
757
770
|
onReleaseProp?.(event, false);
|
|
758
771
|
return;
|
|
759
772
|
}
|
|
@@ -1129,13 +1142,19 @@ const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1129
1142
|
onInteractOutside: (e)=>{
|
|
1130
1143
|
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
1131
1144
|
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
1132
|
-
closeDrawer(
|
|
1145
|
+
closeDrawer(false, {
|
|
1146
|
+
reason: "interactOutside",
|
|
1147
|
+
event: e.detail.originalEvent
|
|
1148
|
+
});
|
|
1133
1149
|
}
|
|
1134
1150
|
props.onInteractOutside?.(e);
|
|
1135
1151
|
},
|
|
1136
1152
|
onEscapeKeyDown: (e)=>{
|
|
1137
1153
|
if (dismissible && closeOnEscape) {
|
|
1138
|
-
closeDrawer(
|
|
1154
|
+
closeDrawer(false, {
|
|
1155
|
+
reason: "escapeKeyDown",
|
|
1156
|
+
event: e
|
|
1157
|
+
});
|
|
1139
1158
|
}
|
|
1140
1159
|
props.onEscapeKeyDown?.(e);
|
|
1141
1160
|
}
|
|
@@ -1162,7 +1181,10 @@ const DrawerCloseButton = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1162
1181
|
onClick: (e)=>{
|
|
1163
1182
|
props.onClick?.(e);
|
|
1164
1183
|
if (e.defaultPrevented) return;
|
|
1165
|
-
setIsOpen(false
|
|
1184
|
+
setIsOpen(false, {
|
|
1185
|
+
reason: "closeButton",
|
|
1186
|
+
event: e.nativeEvent
|
|
1187
|
+
});
|
|
1166
1188
|
}
|
|
1167
1189
|
});
|
|
1168
1190
|
});
|
|
@@ -1173,17 +1195,17 @@ const DrawerHandle = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1173
1195
|
const { closeDrawer, isDragging, snapPoints, activeSnapPoint, setActiveSnapPoint, dismissible, handleOnly, isOpen, onPress, onDrag, onRelease } = useDrawerContext();
|
|
1174
1196
|
const closeTimeoutIdRef = React.useRef(null);
|
|
1175
1197
|
const shouldCancelInteractionRef = React.useRef(false);
|
|
1176
|
-
function handleStartCycle() {
|
|
1198
|
+
function handleStartCycle(event) {
|
|
1177
1199
|
// Stop if this is the second click of a double click
|
|
1178
1200
|
if (shouldCancelInteractionRef.current) {
|
|
1179
1201
|
handleCancelInteraction();
|
|
1180
1202
|
return;
|
|
1181
1203
|
}
|
|
1182
1204
|
window.setTimeout(()=>{
|
|
1183
|
-
handleCycleSnapPoints();
|
|
1205
|
+
handleCycleSnapPoints(event);
|
|
1184
1206
|
}, DOUBLE_TAP_TIMEOUT);
|
|
1185
1207
|
}
|
|
1186
|
-
function handleCycleSnapPoints() {
|
|
1208
|
+
function handleCycleSnapPoints(event) {
|
|
1187
1209
|
// Prevent accidental taps while resizing drawer
|
|
1188
1210
|
if (isDragging || preventCycle || shouldCancelInteractionRef.current) {
|
|
1189
1211
|
handleCancelInteraction();
|
|
@@ -1193,13 +1215,19 @@ const DrawerHandle = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1193
1215
|
handleCancelInteraction();
|
|
1194
1216
|
if (!snapPoints || snapPoints.length === 0) {
|
|
1195
1217
|
if (!dismissible) {
|
|
1196
|
-
closeDrawer(
|
|
1218
|
+
closeDrawer(false, {
|
|
1219
|
+
reason: "handleClickOnLastSnapPoint",
|
|
1220
|
+
event: event.nativeEvent
|
|
1221
|
+
});
|
|
1197
1222
|
}
|
|
1198
1223
|
return;
|
|
1199
1224
|
}
|
|
1200
1225
|
const isLastSnapPoint = activeSnapPoint === snapPoints[snapPoints.length - 1];
|
|
1201
1226
|
if (isLastSnapPoint && dismissible) {
|
|
1202
|
-
closeDrawer(
|
|
1227
|
+
closeDrawer(false, {
|
|
1228
|
+
reason: "handleClickOnLastSnapPoint",
|
|
1229
|
+
event: event.nativeEvent
|
|
1230
|
+
});
|
|
1203
1231
|
return;
|
|
1204
1232
|
}
|
|
1205
1233
|
const currentSnapIndex = snapPoints.findIndex((point)=>point === activeSnapPoint);
|
|
@@ -6,7 +6,7 @@ import { useCallbackRef } from '@radix-ui/react-use-callback-ref';
|
|
|
6
6
|
import { dataAttr } from '@seed-design/dom-utils';
|
|
7
7
|
import { Primitive } from '@seed-design/react-primitive';
|
|
8
8
|
import React, { useState, useCallback, useRef, useEffect, useMemo, createContext, useContext, forwardRef } from 'react';
|
|
9
|
-
import { useControllableState } from '@
|
|
9
|
+
import { useControllableState } from '@seed-design/react-use-controllable-state';
|
|
10
10
|
|
|
11
11
|
function isMobileFirefox() {
|
|
12
12
|
if (typeof window === "undefined" || typeof navigator === "undefined") return false;
|
|
@@ -357,7 +357,7 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
357
357
|
snapPointsOffset,
|
|
358
358
|
snapToPoint
|
|
359
359
|
]);
|
|
360
|
-
function onRelease({ draggedDistance, closeDrawer, velocity, dismissible }) {
|
|
360
|
+
function onRelease({ draggedDistance, closeDrawer, velocity, dismissible, event }) {
|
|
361
361
|
if (fadeFromIndex === undefined) return;
|
|
362
362
|
const currentPosition = direction === "bottom" || direction === "right" ? (activeSnapPointOffset ?? 0) - draggedDistance : (activeSnapPointOffset ?? 0) + draggedDistance;
|
|
363
363
|
const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
|
|
@@ -369,7 +369,10 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
369
369
|
});
|
|
370
370
|
}
|
|
371
371
|
if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
|
|
372
|
-
if (dismissible) closeDrawer(
|
|
372
|
+
if (dismissible) closeDrawer(false, {
|
|
373
|
+
reason: "drag",
|
|
374
|
+
event
|
|
375
|
+
});
|
|
373
376
|
else snapToPoint(snapPointsOffset[0]); // snap to initial point
|
|
374
377
|
return;
|
|
375
378
|
}
|
|
@@ -391,7 +394,10 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
391
394
|
return;
|
|
392
395
|
}
|
|
393
396
|
if (isFirst && dragDirection < 0 && dismissible) {
|
|
394
|
-
closeDrawer(
|
|
397
|
+
closeDrawer(false, {
|
|
398
|
+
reason: "drag",
|
|
399
|
+
event
|
|
400
|
+
});
|
|
395
401
|
}
|
|
396
402
|
if (activeSnapPointIndex === null) return;
|
|
397
403
|
snapToPoint(snapPointsOffset[activeSnapPointIndex + dragDirection]);
|
|
@@ -461,8 +467,8 @@ function useDrawer(props) {
|
|
|
461
467
|
const [isOpen = false, setIsOpen] = useControllableState({
|
|
462
468
|
defaultProp: defaultOpen,
|
|
463
469
|
prop: openProp,
|
|
464
|
-
onChange: (o)=>{
|
|
465
|
-
onOpenChange?.(o);
|
|
470
|
+
onChange: (o, details)=>{
|
|
471
|
+
onOpenChange?.(o, details);
|
|
466
472
|
if (!o && !nested) {
|
|
467
473
|
restorePositionSetting();
|
|
468
474
|
}
|
|
@@ -657,11 +663,11 @@ function useDrawer(props) {
|
|
|
657
663
|
}, [
|
|
658
664
|
isDragging
|
|
659
665
|
]);
|
|
660
|
-
const closeDrawer = useCallback((fromWithin)=>{
|
|
666
|
+
const closeDrawer = useCallback((fromWithin, details)=>{
|
|
661
667
|
cancelDrag();
|
|
662
668
|
onClose?.();
|
|
663
669
|
if (!fromWithin) {
|
|
664
|
-
setIsOpen(false);
|
|
670
|
+
setIsOpen(false, details);
|
|
665
671
|
}
|
|
666
672
|
if (fadeFromIndex !== undefined && fadeFromIndex > 0 && activeSnapPointIndex === 0) {
|
|
667
673
|
set(overlayRef.current, {
|
|
@@ -711,7 +717,8 @@ function useDrawer(props) {
|
|
|
711
717
|
draggedDistance: distMoved * directionMultiplier,
|
|
712
718
|
closeDrawer,
|
|
713
719
|
velocity,
|
|
714
|
-
dismissible
|
|
720
|
+
dismissible,
|
|
721
|
+
event: event.nativeEvent
|
|
715
722
|
});
|
|
716
723
|
onReleaseProp?.(event, true);
|
|
717
724
|
return;
|
|
@@ -722,7 +729,10 @@ function useDrawer(props) {
|
|
|
722
729
|
return;
|
|
723
730
|
}
|
|
724
731
|
if (velocity > VELOCITY_THRESHOLD) {
|
|
725
|
-
closeDrawer(
|
|
732
|
+
closeDrawer(false, {
|
|
733
|
+
reason: "drag",
|
|
734
|
+
event: event.nativeEvent
|
|
735
|
+
});
|
|
726
736
|
onReleaseProp?.(event, false);
|
|
727
737
|
return;
|
|
728
738
|
}
|
|
@@ -730,7 +740,10 @@ function useDrawer(props) {
|
|
|
730
740
|
const visibleDrawerWidth = Math.min(drawerRef.current.getBoundingClientRect().width ?? 0, window.innerWidth);
|
|
731
741
|
const isHorizontalSwipe = direction === "left" || direction === "right";
|
|
732
742
|
if (Math.abs(swipeAmount) >= (isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold) {
|
|
733
|
-
closeDrawer(
|
|
743
|
+
closeDrawer(false, {
|
|
744
|
+
reason: "drag",
|
|
745
|
+
event: event.nativeEvent
|
|
746
|
+
});
|
|
734
747
|
onReleaseProp?.(event, false);
|
|
735
748
|
return;
|
|
736
749
|
}
|
|
@@ -1106,13 +1119,19 @@ const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1106
1119
|
onInteractOutside: (e)=>{
|
|
1107
1120
|
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
1108
1121
|
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
1109
|
-
closeDrawer(
|
|
1122
|
+
closeDrawer(false, {
|
|
1123
|
+
reason: "interactOutside",
|
|
1124
|
+
event: e.detail.originalEvent
|
|
1125
|
+
});
|
|
1110
1126
|
}
|
|
1111
1127
|
props.onInteractOutside?.(e);
|
|
1112
1128
|
},
|
|
1113
1129
|
onEscapeKeyDown: (e)=>{
|
|
1114
1130
|
if (dismissible && closeOnEscape) {
|
|
1115
|
-
closeDrawer(
|
|
1131
|
+
closeDrawer(false, {
|
|
1132
|
+
reason: "escapeKeyDown",
|
|
1133
|
+
event: e
|
|
1134
|
+
});
|
|
1116
1135
|
}
|
|
1117
1136
|
props.onEscapeKeyDown?.(e);
|
|
1118
1137
|
}
|
|
@@ -1139,7 +1158,10 @@ const DrawerCloseButton = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1139
1158
|
onClick: (e)=>{
|
|
1140
1159
|
props.onClick?.(e);
|
|
1141
1160
|
if (e.defaultPrevented) return;
|
|
1142
|
-
setIsOpen(false
|
|
1161
|
+
setIsOpen(false, {
|
|
1162
|
+
reason: "closeButton",
|
|
1163
|
+
event: e.nativeEvent
|
|
1164
|
+
});
|
|
1143
1165
|
}
|
|
1144
1166
|
});
|
|
1145
1167
|
});
|
|
@@ -1150,17 +1172,17 @@ const DrawerHandle = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1150
1172
|
const { closeDrawer, isDragging, snapPoints, activeSnapPoint, setActiveSnapPoint, dismissible, handleOnly, isOpen, onPress, onDrag, onRelease } = useDrawerContext();
|
|
1151
1173
|
const closeTimeoutIdRef = useRef(null);
|
|
1152
1174
|
const shouldCancelInteractionRef = useRef(false);
|
|
1153
|
-
function handleStartCycle() {
|
|
1175
|
+
function handleStartCycle(event) {
|
|
1154
1176
|
// Stop if this is the second click of a double click
|
|
1155
1177
|
if (shouldCancelInteractionRef.current) {
|
|
1156
1178
|
handleCancelInteraction();
|
|
1157
1179
|
return;
|
|
1158
1180
|
}
|
|
1159
1181
|
window.setTimeout(()=>{
|
|
1160
|
-
handleCycleSnapPoints();
|
|
1182
|
+
handleCycleSnapPoints(event);
|
|
1161
1183
|
}, DOUBLE_TAP_TIMEOUT);
|
|
1162
1184
|
}
|
|
1163
|
-
function handleCycleSnapPoints() {
|
|
1185
|
+
function handleCycleSnapPoints(event) {
|
|
1164
1186
|
// Prevent accidental taps while resizing drawer
|
|
1165
1187
|
if (isDragging || preventCycle || shouldCancelInteractionRef.current) {
|
|
1166
1188
|
handleCancelInteraction();
|
|
@@ -1170,13 +1192,19 @@ const DrawerHandle = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1170
1192
|
handleCancelInteraction();
|
|
1171
1193
|
if (!snapPoints || snapPoints.length === 0) {
|
|
1172
1194
|
if (!dismissible) {
|
|
1173
|
-
closeDrawer(
|
|
1195
|
+
closeDrawer(false, {
|
|
1196
|
+
reason: "handleClickOnLastSnapPoint",
|
|
1197
|
+
event: event.nativeEvent
|
|
1198
|
+
});
|
|
1174
1199
|
}
|
|
1175
1200
|
return;
|
|
1176
1201
|
}
|
|
1177
1202
|
const isLastSnapPoint = activeSnapPoint === snapPoints[snapPoints.length - 1];
|
|
1178
1203
|
if (isLastSnapPoint && dismissible) {
|
|
1179
|
-
closeDrawer(
|
|
1204
|
+
closeDrawer(false, {
|
|
1205
|
+
reason: "handleClickOnLastSnapPoint",
|
|
1206
|
+
event: event.nativeEvent
|
|
1207
|
+
});
|
|
1180
1208
|
return;
|
|
1181
1209
|
}
|
|
1182
1210
|
const currentSnapIndex = snapPoints.findIndex((point)=>point === activeSnapPoint);
|
package/lib/index.cjs
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -2,11 +2,34 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
3
3
|
import { PrimitiveProps } from '@seed-design/react-primitive';
|
|
4
4
|
import * as React$1 from 'react';
|
|
5
|
+
import React__default from 'react';
|
|
5
6
|
|
|
7
|
+
interface DrawerReasonToDetailMap {
|
|
8
|
+
closeButton: {
|
|
9
|
+
event: MouseEvent;
|
|
10
|
+
};
|
|
11
|
+
escapeKeyDown: {
|
|
12
|
+
event: KeyboardEvent;
|
|
13
|
+
};
|
|
14
|
+
interactOutside: {
|
|
15
|
+
event: PointerEvent | FocusEvent;
|
|
16
|
+
};
|
|
17
|
+
drag: {
|
|
18
|
+
event: PointerEvent;
|
|
19
|
+
};
|
|
20
|
+
handleClickOnLastSnapPoint: {
|
|
21
|
+
event: MouseEvent;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
type DrawerChangeDetails = {
|
|
25
|
+
[R in keyof DrawerReasonToDetailMap]: {
|
|
26
|
+
reason?: R;
|
|
27
|
+
} & DrawerReasonToDetailMap[R];
|
|
28
|
+
}[keyof DrawerReasonToDetailMap];
|
|
6
29
|
interface UseDrawerProps {
|
|
7
30
|
activeSnapPoint?: number | string | null;
|
|
8
31
|
setActiveSnapPoint?: (snapPoint: number | string | null) => void;
|
|
9
|
-
children?:
|
|
32
|
+
children?: React__default.ReactNode;
|
|
10
33
|
open?: boolean;
|
|
11
34
|
/**
|
|
12
35
|
* Number between 0 and 1 that determines when the drawer should be closed.
|
|
@@ -19,7 +42,7 @@ interface UseDrawerProps {
|
|
|
19
42
|
* @default true
|
|
20
43
|
*/
|
|
21
44
|
noBodyStyles?: boolean;
|
|
22
|
-
onOpenChange?: (open: boolean) => void;
|
|
45
|
+
onOpenChange?: (open: boolean, details?: DrawerChangeDetails) => void;
|
|
23
46
|
/**
|
|
24
47
|
* Duration for which the drawer is not draggable after scrolling content inside of the drawer.
|
|
25
48
|
* @default 500ms
|
|
@@ -40,8 +63,8 @@ interface UseDrawerProps {
|
|
|
40
63
|
* @default true
|
|
41
64
|
*/
|
|
42
65
|
dismissible?: boolean;
|
|
43
|
-
onDrag?: (event:
|
|
44
|
-
onRelease?: (event:
|
|
66
|
+
onDrag?: (event: React__default.PointerEvent<HTMLDivElement>, percentageDragged: number) => void;
|
|
67
|
+
onRelease?: (event: React__default.PointerEvent<HTMLDivElement>, open: boolean) => void;
|
|
45
68
|
/**
|
|
46
69
|
* When `false` it allows to interact with elements outside of the drawer without closing it.
|
|
47
70
|
* @default true
|
|
@@ -106,21 +129,21 @@ interface UseDrawerProps {
|
|
|
106
129
|
declare function useDrawer(props: UseDrawerProps): {
|
|
107
130
|
activeSnapPoint: string | number | null;
|
|
108
131
|
snapPoints: (string | number)[] | undefined;
|
|
109
|
-
setActiveSnapPoint: (value:
|
|
110
|
-
drawerRef:
|
|
111
|
-
overlayRef:
|
|
132
|
+
setActiveSnapPoint: (value: string | number | ((prev: string | number | null) => string | number | null) | null, details?: undefined) => void;
|
|
133
|
+
drawerRef: React__default.RefObject<HTMLDivElement | null>;
|
|
134
|
+
overlayRef: React__default.RefObject<HTMLDivElement | null>;
|
|
112
135
|
shouldOverlayAnimate: boolean;
|
|
113
|
-
onOpenChange: ((open: boolean) => void) | undefined;
|
|
114
|
-
onPress: (event:
|
|
115
|
-
onRelease: (event:
|
|
116
|
-
onDrag: (event:
|
|
136
|
+
onOpenChange: ((open: boolean, details?: DrawerChangeDetails) => void) | undefined;
|
|
137
|
+
onPress: (event: React__default.PointerEvent<HTMLDivElement>) => void;
|
|
138
|
+
onRelease: (event: React__default.PointerEvent<HTMLDivElement> | null) => void;
|
|
139
|
+
onDrag: (event: React__default.PointerEvent<HTMLDivElement>) => void;
|
|
117
140
|
dismissible: boolean;
|
|
118
141
|
handleOnly: boolean;
|
|
119
142
|
isOpen: boolean;
|
|
120
143
|
isDragging: boolean;
|
|
121
144
|
shouldFade: boolean;
|
|
122
|
-
closeDrawer: (fromWithin?: boolean) => void;
|
|
123
|
-
keyboardIsOpen:
|
|
145
|
+
closeDrawer: (fromWithin?: boolean, details?: DrawerChangeDetails) => void;
|
|
146
|
+
keyboardIsOpen: React__default.RefObject<boolean>;
|
|
124
147
|
modal: boolean;
|
|
125
148
|
snapPointsOffset: number[];
|
|
126
149
|
activeSnapPointIndex: number | null;
|
|
@@ -128,8 +151,8 @@ declare function useDrawer(props: UseDrawerProps): {
|
|
|
128
151
|
noBodyStyles: boolean;
|
|
129
152
|
container: HTMLElement | null | undefined;
|
|
130
153
|
autoFocus: boolean;
|
|
131
|
-
setHasBeenOpened:
|
|
132
|
-
setIsOpen: (value:
|
|
154
|
+
setHasBeenOpened: React__default.Dispatch<React__default.SetStateAction<boolean>>;
|
|
155
|
+
setIsOpen: (value: boolean | ((prev: boolean) => boolean), details?: DrawerChangeDetails | undefined) => void;
|
|
133
156
|
closeOnInteractOutside: boolean;
|
|
134
157
|
closeOnEscape: boolean;
|
|
135
158
|
hasAnimationDone: boolean;
|
|
@@ -174,11 +197,31 @@ type DrawerContextValue = ReturnType<typeof useDrawer>;
|
|
|
174
197
|
declare function useDrawerContext(): {
|
|
175
198
|
activeSnapPoint: string | number | null;
|
|
176
199
|
snapPoints: (string | number)[] | undefined;
|
|
177
|
-
setActiveSnapPoint: (value:
|
|
200
|
+
setActiveSnapPoint: (value: string | number | ((prev: string | number | null) => string | number | null) | null, details?: undefined) => void;
|
|
178
201
|
drawerRef: React$1.RefObject<HTMLDivElement | null>;
|
|
179
202
|
overlayRef: React$1.RefObject<HTMLDivElement | null>;
|
|
180
203
|
shouldOverlayAnimate: boolean;
|
|
181
|
-
onOpenChange: ((open: boolean
|
|
204
|
+
onOpenChange: ((open: boolean, details?: ({
|
|
205
|
+
reason?: "closeButton" | undefined;
|
|
206
|
+
} & {
|
|
207
|
+
event: MouseEvent;
|
|
208
|
+
}) | ({
|
|
209
|
+
reason?: "escapeKeyDown" | undefined;
|
|
210
|
+
} & {
|
|
211
|
+
event: KeyboardEvent;
|
|
212
|
+
}) | ({
|
|
213
|
+
reason?: "interactOutside" | undefined;
|
|
214
|
+
} & {
|
|
215
|
+
event: PointerEvent | FocusEvent;
|
|
216
|
+
}) | ({
|
|
217
|
+
reason?: "drag" | undefined;
|
|
218
|
+
} & {
|
|
219
|
+
event: PointerEvent;
|
|
220
|
+
}) | ({
|
|
221
|
+
reason?: "handleClickOnLastSnapPoint" | undefined;
|
|
222
|
+
} & {
|
|
223
|
+
event: MouseEvent;
|
|
224
|
+
})) => void) | undefined;
|
|
182
225
|
onPress: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
183
226
|
onRelease: (event: React.PointerEvent<HTMLDivElement> | null) => void;
|
|
184
227
|
onDrag: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
@@ -187,7 +230,27 @@ declare function useDrawerContext(): {
|
|
|
187
230
|
isOpen: boolean;
|
|
188
231
|
isDragging: boolean;
|
|
189
232
|
shouldFade: boolean;
|
|
190
|
-
closeDrawer: (fromWithin?: boolean
|
|
233
|
+
closeDrawer: (fromWithin?: boolean, details?: ({
|
|
234
|
+
reason?: "closeButton" | undefined;
|
|
235
|
+
} & {
|
|
236
|
+
event: MouseEvent;
|
|
237
|
+
}) | ({
|
|
238
|
+
reason?: "escapeKeyDown" | undefined;
|
|
239
|
+
} & {
|
|
240
|
+
event: KeyboardEvent;
|
|
241
|
+
}) | ({
|
|
242
|
+
reason?: "interactOutside" | undefined;
|
|
243
|
+
} & {
|
|
244
|
+
event: PointerEvent | FocusEvent;
|
|
245
|
+
}) | ({
|
|
246
|
+
reason?: "drag" | undefined;
|
|
247
|
+
} & {
|
|
248
|
+
event: PointerEvent;
|
|
249
|
+
}) | ({
|
|
250
|
+
reason?: "handleClickOnLastSnapPoint" | undefined;
|
|
251
|
+
} & {
|
|
252
|
+
event: MouseEvent;
|
|
253
|
+
})) => void;
|
|
191
254
|
keyboardIsOpen: React$1.RefObject<boolean>;
|
|
192
255
|
modal: boolean;
|
|
193
256
|
snapPointsOffset: number[];
|
|
@@ -197,7 +260,27 @@ declare function useDrawerContext(): {
|
|
|
197
260
|
container: HTMLElement | null | undefined;
|
|
198
261
|
autoFocus: boolean;
|
|
199
262
|
setHasBeenOpened: React$1.Dispatch<React$1.SetStateAction<boolean>>;
|
|
200
|
-
setIsOpen: (value:
|
|
263
|
+
setIsOpen: (value: boolean | ((prev: boolean) => boolean), details?: (({
|
|
264
|
+
reason?: "closeButton" | undefined;
|
|
265
|
+
} & {
|
|
266
|
+
event: MouseEvent;
|
|
267
|
+
}) | ({
|
|
268
|
+
reason?: "escapeKeyDown" | undefined;
|
|
269
|
+
} & {
|
|
270
|
+
event: KeyboardEvent;
|
|
271
|
+
}) | ({
|
|
272
|
+
reason?: "interactOutside" | undefined;
|
|
273
|
+
} & {
|
|
274
|
+
event: PointerEvent | FocusEvent;
|
|
275
|
+
}) | ({
|
|
276
|
+
reason?: "drag" | undefined;
|
|
277
|
+
} & {
|
|
278
|
+
event: PointerEvent;
|
|
279
|
+
}) | ({
|
|
280
|
+
reason?: "handleClickOnLastSnapPoint" | undefined;
|
|
281
|
+
} & {
|
|
282
|
+
event: MouseEvent;
|
|
283
|
+
})) | undefined) => void;
|
|
201
284
|
closeOnInteractOutside: boolean;
|
|
202
285
|
closeOnEscape: boolean;
|
|
203
286
|
hasAnimationDone: boolean;
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DrawerBackdrop, a as DrawerCloseButton, b as DrawerContent, c as DrawerDescription, d as DrawerHandle, e as DrawerHeader, f as DrawerPositioner, g as DrawerRoot, h as DrawerTitle, i as DrawerTrigger } from './Drawer-12s-
|
|
2
|
-
export { u as useDrawer, j as useDrawerContext } from './Drawer-12s-
|
|
1
|
+
import { D as DrawerBackdrop, a as DrawerCloseButton, b as DrawerContent, c as DrawerDescription, d as DrawerHandle, e as DrawerHeader, f as DrawerPositioner, g as DrawerRoot, h as DrawerTitle, i as DrawerTrigger } from './Drawer-12s-DnXlK1K0.js';
|
|
2
|
+
export { u as useDrawer, j as useDrawerContext } from './Drawer-12s-DnXlK1K0.js';
|
|
3
3
|
|
|
4
4
|
var Drawer_namespace = {
|
|
5
5
|
__proto__: null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/react-drawer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/daangn/seed-design.git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@radix-ui/react-compose-refs": "^1.1.2",
|
|
31
31
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
32
32
|
"@radix-ui/react-use-callback-ref": "^1.1.0",
|
|
33
|
-
"@
|
|
33
|
+
"@seed-design/react-use-controllable-state": "1.0.0",
|
|
34
34
|
"@seed-design/dom-utils": "1.0.0",
|
|
35
35
|
"@seed-design/react-primitive": "1.0.0"
|
|
36
36
|
},
|
package/src/Drawer.tsx
CHANGED
|
@@ -263,13 +263,13 @@ export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>((pro
|
|
|
263
263
|
onInteractOutside={(e) => {
|
|
264
264
|
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
265
265
|
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
266
|
-
closeDrawer();
|
|
266
|
+
closeDrawer(false, { reason: "interactOutside", event: e.detail.originalEvent });
|
|
267
267
|
}
|
|
268
268
|
props.onInteractOutside?.(e);
|
|
269
269
|
}}
|
|
270
270
|
onEscapeKeyDown={(e) => {
|
|
271
271
|
if (dismissible && closeOnEscape) {
|
|
272
|
-
closeDrawer();
|
|
272
|
+
closeDrawer(false, { reason: "escapeKeyDown", event: e });
|
|
273
273
|
}
|
|
274
274
|
props.onEscapeKeyDown?.(e);
|
|
275
275
|
}}
|
|
@@ -309,7 +309,7 @@ export const DrawerCloseButton = forwardRef<HTMLButtonElement, DrawerCloseButton
|
|
|
309
309
|
onClick={(e) => {
|
|
310
310
|
props.onClick?.(e);
|
|
311
311
|
if (e.defaultPrevented) return;
|
|
312
|
-
setIsOpen(false);
|
|
312
|
+
setIsOpen(false, { reason: "closeButton", event: e.nativeEvent });
|
|
313
313
|
}}
|
|
314
314
|
/>
|
|
315
315
|
);
|
|
@@ -342,18 +342,18 @@ export const DrawerHandle = forwardRef<HTMLDivElement, DrawerHandleProps>((props
|
|
|
342
342
|
const closeTimeoutIdRef = useRef<number | null>(null);
|
|
343
343
|
const shouldCancelInteractionRef = useRef(false);
|
|
344
344
|
|
|
345
|
-
function handleStartCycle() {
|
|
345
|
+
function handleStartCycle(event: React.MouseEvent<HTMLDivElement>) {
|
|
346
346
|
// Stop if this is the second click of a double click
|
|
347
347
|
if (shouldCancelInteractionRef.current) {
|
|
348
348
|
handleCancelInteraction();
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
351
|
window.setTimeout(() => {
|
|
352
|
-
handleCycleSnapPoints();
|
|
352
|
+
handleCycleSnapPoints(event);
|
|
353
353
|
}, DOUBLE_TAP_TIMEOUT);
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
function handleCycleSnapPoints() {
|
|
356
|
+
function handleCycleSnapPoints(event: React.MouseEvent<HTMLDivElement>) {
|
|
357
357
|
// Prevent accidental taps while resizing drawer
|
|
358
358
|
if (isDragging || preventCycle || shouldCancelInteractionRef.current) {
|
|
359
359
|
handleCancelInteraction();
|
|
@@ -364,7 +364,7 @@ export const DrawerHandle = forwardRef<HTMLDivElement, DrawerHandleProps>((props
|
|
|
364
364
|
|
|
365
365
|
if (!snapPoints || snapPoints.length === 0) {
|
|
366
366
|
if (!dismissible) {
|
|
367
|
-
closeDrawer();
|
|
367
|
+
closeDrawer(false, { reason: "handleClickOnLastSnapPoint", event: event.nativeEvent });
|
|
368
368
|
}
|
|
369
369
|
return;
|
|
370
370
|
}
|
|
@@ -372,7 +372,7 @@ export const DrawerHandle = forwardRef<HTMLDivElement, DrawerHandleProps>((props
|
|
|
372
372
|
const isLastSnapPoint = activeSnapPoint === snapPoints[snapPoints.length - 1];
|
|
373
373
|
|
|
374
374
|
if (isLastSnapPoint && dismissible) {
|
|
375
|
-
closeDrawer();
|
|
375
|
+
closeDrawer(false, { reason: "handleClickOnLastSnapPoint", event: event.nativeEvent });
|
|
376
376
|
return;
|
|
377
377
|
}
|
|
378
378
|
|
package/src/use-snap-points.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useControllableState } from "@
|
|
1
|
+
import { useControllableState } from "@seed-design/react-use-controllable-state";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { TRANSITIONS, VELOCITY_THRESHOLD } from "./constants";
|
|
4
4
|
import { isVertical, set } from "./helpers";
|
|
@@ -196,11 +196,13 @@ export function useSnapPoints({
|
|
|
196
196
|
closeDrawer,
|
|
197
197
|
velocity,
|
|
198
198
|
dismissible,
|
|
199
|
+
event,
|
|
199
200
|
}: {
|
|
200
201
|
draggedDistance: number;
|
|
201
|
-
closeDrawer: () => void;
|
|
202
|
+
closeDrawer: (fromWithin: boolean, details: { reason: "drag"; event: PointerEvent }) => void;
|
|
202
203
|
velocity: number;
|
|
203
204
|
dismissible: boolean;
|
|
205
|
+
event: PointerEvent;
|
|
204
206
|
}) {
|
|
205
207
|
if (fadeFromIndex === undefined) return;
|
|
206
208
|
|
|
@@ -219,7 +221,7 @@ export function useSnapPoints({
|
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
|
|
222
|
-
if (dismissible) closeDrawer();
|
|
224
|
+
if (dismissible) closeDrawer(false, { reason: "drag", event });
|
|
223
225
|
else snapToPoint(snapPointsOffset[0]); // snap to initial point
|
|
224
226
|
return;
|
|
225
227
|
}
|
|
@@ -247,7 +249,7 @@ export function useSnapPoints({
|
|
|
247
249
|
}
|
|
248
250
|
|
|
249
251
|
if (isFirst && dragDirection < 0 && dismissible) {
|
|
250
|
-
closeDrawer();
|
|
252
|
+
closeDrawer(false, { reason: "drag", event });
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
if (activeSnapPointIndex === null) return;
|
package/src/useDrawer.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { useControllableState } from "@
|
|
1
|
+
import { useControllableState } from "@seed-design/react-use-controllable-state";
|
|
2
|
+
import type React from "react";
|
|
2
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
4
|
import { isIOS, isMobileFirefox } from "./browser";
|
|
4
5
|
import {
|
|
@@ -13,6 +14,21 @@ import { dampenValue, getTranslate, isInput, isVertical, reset, set } from "./he
|
|
|
13
14
|
import { usePositionFixed } from "./use-position-fixed";
|
|
14
15
|
import { useSnapPoints } from "./use-snap-points";
|
|
15
16
|
|
|
17
|
+
interface DrawerReasonToDetailMap {
|
|
18
|
+
// we might add synthetic events later if needed; currently we aim consistency; DismissableLayer gives us native events
|
|
19
|
+
closeButton: { event: MouseEvent };
|
|
20
|
+
escapeKeyDown: { event: KeyboardEvent };
|
|
21
|
+
interactOutside: { event: PointerEvent | FocusEvent };
|
|
22
|
+
drag: { event: PointerEvent };
|
|
23
|
+
handleClickOnLastSnapPoint: { event: MouseEvent };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type DrawerChangeDetails = {
|
|
27
|
+
[R in keyof DrawerReasonToDetailMap]: {
|
|
28
|
+
reason?: R;
|
|
29
|
+
} & DrawerReasonToDetailMap[R];
|
|
30
|
+
}[keyof DrawerReasonToDetailMap];
|
|
31
|
+
|
|
16
32
|
export interface UseDrawerProps {
|
|
17
33
|
activeSnapPoint?: number | string | null;
|
|
18
34
|
setActiveSnapPoint?: (snapPoint: number | string | null) => void;
|
|
@@ -29,7 +45,7 @@ export interface UseDrawerProps {
|
|
|
29
45
|
* @default true
|
|
30
46
|
*/
|
|
31
47
|
noBodyStyles?: boolean;
|
|
32
|
-
onOpenChange?: (open: boolean) => void;
|
|
48
|
+
onOpenChange?: (open: boolean, details?: DrawerChangeDetails) => void;
|
|
33
49
|
/**
|
|
34
50
|
* Duration for which the drawer is not draggable after scrolling content inside of the drawer.
|
|
35
51
|
* @default 500ms
|
|
@@ -149,11 +165,11 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
149
165
|
closeOnEscape = true,
|
|
150
166
|
} = props;
|
|
151
167
|
|
|
152
|
-
const [isOpen = false, setIsOpen] = useControllableState({
|
|
168
|
+
const [isOpen = false, setIsOpen] = useControllableState<boolean, DrawerChangeDetails>({
|
|
153
169
|
defaultProp: defaultOpen,
|
|
154
170
|
prop: openProp,
|
|
155
|
-
onChange: (o: boolean) => {
|
|
156
|
-
onOpenChange?.(o);
|
|
171
|
+
onChange: (o: boolean, details?: DrawerChangeDetails) => {
|
|
172
|
+
onOpenChange?.(o, details);
|
|
157
173
|
|
|
158
174
|
if (!o && !nested) {
|
|
159
175
|
restorePositionSetting();
|
|
@@ -425,12 +441,12 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
425
441
|
}, [isDragging]);
|
|
426
442
|
|
|
427
443
|
const closeDrawer = useCallback(
|
|
428
|
-
(fromWithin?: boolean) => {
|
|
444
|
+
(fromWithin?: boolean, details?: DrawerChangeDetails) => {
|
|
429
445
|
cancelDrag();
|
|
430
446
|
onClose?.();
|
|
431
447
|
|
|
432
448
|
if (!fromWithin) {
|
|
433
|
-
setIsOpen(false);
|
|
449
|
+
setIsOpen(false, details);
|
|
434
450
|
}
|
|
435
451
|
|
|
436
452
|
if (fadeFromIndex !== undefined && fadeFromIndex > 0 && activeSnapPointIndex === 0) {
|
|
@@ -495,6 +511,7 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
495
511
|
closeDrawer,
|
|
496
512
|
velocity,
|
|
497
513
|
dismissible,
|
|
514
|
+
event: event.nativeEvent,
|
|
498
515
|
});
|
|
499
516
|
onReleaseProp?.(event, true);
|
|
500
517
|
return;
|
|
@@ -507,7 +524,7 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
507
524
|
}
|
|
508
525
|
|
|
509
526
|
if (velocity > VELOCITY_THRESHOLD) {
|
|
510
|
-
closeDrawer();
|
|
527
|
+
closeDrawer(false, { reason: "drag", event: event.nativeEvent });
|
|
511
528
|
onReleaseProp?.(event, false);
|
|
512
529
|
return;
|
|
513
530
|
}
|
|
@@ -526,7 +543,7 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
526
543
|
Math.abs(swipeAmount) >=
|
|
527
544
|
(isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold
|
|
528
545
|
) {
|
|
529
|
-
closeDrawer();
|
|
546
|
+
closeDrawer(false, { reason: "drag", event: event.nativeEvent });
|
|
530
547
|
onReleaseProp?.(event, false);
|
|
531
548
|
return;
|
|
532
549
|
}
|