@seed-design/react-drawer 1.0.5 → 1.0.6
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-9vODHlci.js → Drawer-12s-BdeYHia6.js} +57 -15
- package/lib/{Drawer-12s-CTzxFYGf.cjs → Drawer-12s-DriAYAR2.cjs} +56 -13
- package/lib/index.cjs +3 -1
- package/lib/index.d.ts +39 -30
- package/lib/index.js +4 -3
- package/package.json +1 -1
- package/src/Drawer.namespace.ts +2 -0
- package/src/Drawer.tsx +24 -9
- package/src/index.ts +2 -0
- package/src/useDrawer.ts +32 -2
|
@@ -5,7 +5,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
|
5
5
|
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
|
-
import React, { useState,
|
|
8
|
+
import React, { useState, useCallback, useRef, useEffect, useMemo, createContext, useContext, forwardRef } from 'react';
|
|
9
9
|
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
10
10
|
|
|
11
11
|
function isMobileFirefox() {
|
|
@@ -482,8 +482,13 @@ function useDrawer(props) {
|
|
|
482
482
|
}
|
|
483
483
|
});
|
|
484
484
|
const [hasBeenOpened, setHasBeenOpened] = useState(false);
|
|
485
|
+
const [hasAnimationDone, setHasAnimationDone] = useState(false);
|
|
485
486
|
const [isDragging, setIsDragging] = useState(false);
|
|
486
487
|
const [shouldOverlayAnimate, setShouldOverlayAnimate] = useState(false);
|
|
488
|
+
const [isCloseButtonRendered, setIsCloseButtonRendered] = useState(false);
|
|
489
|
+
const closeButtonRef = useCallback((node)=>{
|
|
490
|
+
setIsCloseButtonRendered(!!node);
|
|
491
|
+
}, []);
|
|
487
492
|
const overlayRef = useRef(null);
|
|
488
493
|
const openTime = useRef(null);
|
|
489
494
|
const dragStartTime = useRef(null);
|
|
@@ -806,6 +811,7 @@ function useDrawer(props) {
|
|
|
806
811
|
}, [
|
|
807
812
|
modal
|
|
808
813
|
]);
|
|
814
|
+
// Effect 1: Track drawer open state
|
|
809
815
|
useEffect(()=>{
|
|
810
816
|
if (isOpen) {
|
|
811
817
|
setHasBeenOpened(true);
|
|
@@ -813,6 +819,24 @@ function useDrawer(props) {
|
|
|
813
819
|
}, [
|
|
814
820
|
isOpen
|
|
815
821
|
]);
|
|
822
|
+
// Effect 2: Handle animation state and timer
|
|
823
|
+
useEffect(()=>{
|
|
824
|
+
if (isOpen) {
|
|
825
|
+
// Only reset animation state if this is the first open
|
|
826
|
+
if (!hasBeenOpened) {
|
|
827
|
+
setHasAnimationDone(false);
|
|
828
|
+
}
|
|
829
|
+
const timeoutId = setTimeout(()=>{
|
|
830
|
+
setHasAnimationDone(true);
|
|
831
|
+
}, TRANSITIONS.ENTER_DURATION * 1000);
|
|
832
|
+
return ()=>clearTimeout(timeoutId);
|
|
833
|
+
}
|
|
834
|
+
// Reset animation state when drawer closes
|
|
835
|
+
setHasAnimationDone(false);
|
|
836
|
+
}, [
|
|
837
|
+
isOpen,
|
|
838
|
+
hasBeenOpened
|
|
839
|
+
]);
|
|
816
840
|
useEffect(()=>{
|
|
817
841
|
if (isOpen && snapPoints && fadeFromIndex === 0) {
|
|
818
842
|
setShouldOverlayAnimate(true);
|
|
@@ -855,7 +879,10 @@ function useDrawer(props) {
|
|
|
855
879
|
setHasBeenOpened,
|
|
856
880
|
setIsOpen,
|
|
857
881
|
closeOnInteractOutside,
|
|
858
|
-
closeOnEscape
|
|
882
|
+
closeOnEscape,
|
|
883
|
+
hasAnimationDone,
|
|
884
|
+
closeButtonRef,
|
|
885
|
+
isCloseButtonRendered
|
|
859
886
|
}), [
|
|
860
887
|
activeSnapPoint,
|
|
861
888
|
snapPoints,
|
|
@@ -880,7 +907,10 @@ function useDrawer(props) {
|
|
|
880
907
|
closeOnEscape,
|
|
881
908
|
onRelease,
|
|
882
909
|
onDrag,
|
|
883
|
-
onPress
|
|
910
|
+
onPress,
|
|
911
|
+
hasAnimationDone,
|
|
912
|
+
closeButtonRef,
|
|
913
|
+
isCloseButtonRendered
|
|
884
914
|
]);
|
|
885
915
|
}
|
|
886
916
|
|
|
@@ -930,11 +960,10 @@ const DrawerPositioner = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
930
960
|
});
|
|
931
961
|
DrawerPositioner.displayName = "DrawerPositioner";
|
|
932
962
|
const DrawerBackdrop = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
933
|
-
const { overlayRef, onRelease, modal, snapPoints, isOpen, shouldFade, shouldOverlayAnimate } = useDrawerContext();
|
|
963
|
+
const { overlayRef, onRelease, modal, snapPoints, isOpen, shouldFade, shouldOverlayAnimate, hasAnimationDone } = useDrawerContext();
|
|
934
964
|
const composedRef = useComposedRefs(ref, overlayRef);
|
|
935
965
|
const hasSnapPoints = snapPoints && snapPoints.length > 0;
|
|
936
966
|
const onMouseUp = useCallbackRef((event)=>onRelease(event));
|
|
937
|
-
// Overlay is the component that is locking scroll, removing it will unlock the scroll without having to dig into Radix's Dialog library
|
|
938
967
|
if (!modal) {
|
|
939
968
|
return null;
|
|
940
969
|
}
|
|
@@ -945,13 +974,14 @@ const DrawerBackdrop = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
945
974
|
"data-snap-points-overlay": isOpen && shouldFade ? "true" : "false",
|
|
946
975
|
"data-should-overlay-animate": shouldOverlayAnimate ? "true" : "false",
|
|
947
976
|
"data-open": dataAttr(isOpen),
|
|
977
|
+
"data-animation-done": hasAnimationDone ? "true" : "false",
|
|
948
978
|
...props
|
|
949
979
|
});
|
|
950
980
|
});
|
|
951
981
|
DrawerBackdrop.displayName = "DrawerBackdrop";
|
|
952
982
|
const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
953
983
|
const { onPointerDownOutside, style, onOpenAutoFocus, ...restProps } = props;
|
|
954
|
-
const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, autoFocus, closeDrawer, closeOnInteractOutside, closeOnEscape, dismissible } = useDrawerContext();
|
|
984
|
+
const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, autoFocus, closeDrawer, closeOnInteractOutside, closeOnEscape, dismissible, hasAnimationDone } = useDrawerContext();
|
|
955
985
|
// Needed to use transition instead of animations
|
|
956
986
|
const [delayedSnapPoints, setDelayedSnapPoints] = useState(false);
|
|
957
987
|
const composedRef = useComposedRefs(ref, drawerRef);
|
|
@@ -998,6 +1028,7 @@ const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
998
1028
|
"data-delayed-snap-points": delayedSnapPoints ? "true" : "false",
|
|
999
1029
|
"data-drawer-direction": direction,
|
|
1000
1030
|
"data-open": dataAttr(isOpen),
|
|
1031
|
+
"data-animation-done": hasAnimationDone ? "true" : "false",
|
|
1001
1032
|
"data-drawer": "",
|
|
1002
1033
|
"data-snap-points": isOpen && hasSnapPoints ? "true" : "false",
|
|
1003
1034
|
"data-custom-container": container ? "true" : "false",
|
|
@@ -1033,10 +1064,10 @@ const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1033
1064
|
}
|
|
1034
1065
|
},
|
|
1035
1066
|
onFocusOutside: (e)=>{
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1067
|
+
props.onFocusOutside?.(e);
|
|
1068
|
+
// Always prevent focusOutside to avoid conflicts when focus moves between modals
|
|
1069
|
+
// (e.g., when Dialog closes and restores focus while BottomSheet is opening)
|
|
1070
|
+
e.preventDefault();
|
|
1040
1071
|
},
|
|
1041
1072
|
onPointerMove: (event)=>{
|
|
1042
1073
|
lastKnownPointerEventRef.current = event;
|
|
@@ -1073,7 +1104,8 @@ const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1073
1104
|
}
|
|
1074
1105
|
},
|
|
1075
1106
|
onInteractOutside: (e)=>{
|
|
1076
|
-
if (
|
|
1107
|
+
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
1108
|
+
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
1077
1109
|
closeDrawer();
|
|
1078
1110
|
}
|
|
1079
1111
|
props.onInteractOutside?.(e);
|
|
@@ -1089,15 +1121,25 @@ const DrawerContent = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1089
1121
|
DrawerContent.displayName = "DrawerContent";
|
|
1090
1122
|
const DrawerTitle = DialogPrimitive.Title;
|
|
1091
1123
|
const DrawerDescription = DialogPrimitive.Description;
|
|
1124
|
+
const DrawerHeader = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
1125
|
+
const { isCloseButtonRendered } = useDrawerContext();
|
|
1126
|
+
return /*#__PURE__*/ jsx(Primitive.div, {
|
|
1127
|
+
ref: ref,
|
|
1128
|
+
"data-show-close-button": dataAttr(isCloseButtonRendered),
|
|
1129
|
+
...props
|
|
1130
|
+
});
|
|
1131
|
+
});
|
|
1132
|
+
DrawerHeader.displayName = "DrawerHeader";
|
|
1092
1133
|
const DrawerCloseButton = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
1093
|
-
const
|
|
1134
|
+
const { closeButtonRef, setIsOpen } = useDrawerContext();
|
|
1135
|
+
const composedRef = useComposedRefs(ref, closeButtonRef);
|
|
1094
1136
|
return /*#__PURE__*/ jsx(Primitive.button, {
|
|
1095
|
-
ref:
|
|
1137
|
+
ref: composedRef,
|
|
1096
1138
|
...props,
|
|
1097
1139
|
onClick: (e)=>{
|
|
1098
1140
|
props.onClick?.(e);
|
|
1099
1141
|
if (e.defaultPrevented) return;
|
|
1100
|
-
|
|
1142
|
+
setIsOpen(false);
|
|
1101
1143
|
}
|
|
1102
1144
|
});
|
|
1103
1145
|
});
|
|
@@ -1178,4 +1220,4 @@ const DrawerHandle = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
|
1178
1220
|
});
|
|
1179
1221
|
DrawerHandle.displayName = "DrawerHandle";
|
|
1180
1222
|
|
|
1181
|
-
export { DrawerBackdrop as D, DrawerCloseButton as a, DrawerContent as b, DrawerDescription as c, DrawerHandle as d,
|
|
1223
|
+
export { DrawerBackdrop as D, DrawerCloseButton as a, DrawerContent as b, DrawerDescription as c, DrawerHandle as d, DrawerHeader as e, DrawerPositioner as f, DrawerRoot as g, DrawerTitle as h, DrawerTrigger as i, useDrawerContext as j, useDrawer as u };
|
|
@@ -505,8 +505,13 @@ function useDrawer(props) {
|
|
|
505
505
|
}
|
|
506
506
|
});
|
|
507
507
|
const [hasBeenOpened, setHasBeenOpened] = React.useState(false);
|
|
508
|
+
const [hasAnimationDone, setHasAnimationDone] = React.useState(false);
|
|
508
509
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
509
510
|
const [shouldOverlayAnimate, setShouldOverlayAnimate] = React.useState(false);
|
|
511
|
+
const [isCloseButtonRendered, setIsCloseButtonRendered] = React.useState(false);
|
|
512
|
+
const closeButtonRef = React.useCallback((node)=>{
|
|
513
|
+
setIsCloseButtonRendered(!!node);
|
|
514
|
+
}, []);
|
|
510
515
|
const overlayRef = React.useRef(null);
|
|
511
516
|
const openTime = React.useRef(null);
|
|
512
517
|
const dragStartTime = React.useRef(null);
|
|
@@ -829,6 +834,7 @@ function useDrawer(props) {
|
|
|
829
834
|
}, [
|
|
830
835
|
modal
|
|
831
836
|
]);
|
|
837
|
+
// Effect 1: Track drawer open state
|
|
832
838
|
React.useEffect(()=>{
|
|
833
839
|
if (isOpen) {
|
|
834
840
|
setHasBeenOpened(true);
|
|
@@ -836,6 +842,24 @@ function useDrawer(props) {
|
|
|
836
842
|
}, [
|
|
837
843
|
isOpen
|
|
838
844
|
]);
|
|
845
|
+
// Effect 2: Handle animation state and timer
|
|
846
|
+
React.useEffect(()=>{
|
|
847
|
+
if (isOpen) {
|
|
848
|
+
// Only reset animation state if this is the first open
|
|
849
|
+
if (!hasBeenOpened) {
|
|
850
|
+
setHasAnimationDone(false);
|
|
851
|
+
}
|
|
852
|
+
const timeoutId = setTimeout(()=>{
|
|
853
|
+
setHasAnimationDone(true);
|
|
854
|
+
}, TRANSITIONS.ENTER_DURATION * 1000);
|
|
855
|
+
return ()=>clearTimeout(timeoutId);
|
|
856
|
+
}
|
|
857
|
+
// Reset animation state when drawer closes
|
|
858
|
+
setHasAnimationDone(false);
|
|
859
|
+
}, [
|
|
860
|
+
isOpen,
|
|
861
|
+
hasBeenOpened
|
|
862
|
+
]);
|
|
839
863
|
React.useEffect(()=>{
|
|
840
864
|
if (isOpen && snapPoints && fadeFromIndex === 0) {
|
|
841
865
|
setShouldOverlayAnimate(true);
|
|
@@ -878,7 +902,10 @@ function useDrawer(props) {
|
|
|
878
902
|
setHasBeenOpened,
|
|
879
903
|
setIsOpen,
|
|
880
904
|
closeOnInteractOutside,
|
|
881
|
-
closeOnEscape
|
|
905
|
+
closeOnEscape,
|
|
906
|
+
hasAnimationDone,
|
|
907
|
+
closeButtonRef,
|
|
908
|
+
isCloseButtonRendered
|
|
882
909
|
}), [
|
|
883
910
|
activeSnapPoint,
|
|
884
911
|
snapPoints,
|
|
@@ -903,7 +930,10 @@ function useDrawer(props) {
|
|
|
903
930
|
closeOnEscape,
|
|
904
931
|
onRelease,
|
|
905
932
|
onDrag,
|
|
906
|
-
onPress
|
|
933
|
+
onPress,
|
|
934
|
+
hasAnimationDone,
|
|
935
|
+
closeButtonRef,
|
|
936
|
+
isCloseButtonRendered
|
|
907
937
|
]);
|
|
908
938
|
}
|
|
909
939
|
|
|
@@ -953,11 +983,10 @@ const DrawerPositioner = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
953
983
|
});
|
|
954
984
|
DrawerPositioner.displayName = "DrawerPositioner";
|
|
955
985
|
const DrawerBackdrop = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
956
|
-
const { overlayRef, onRelease, modal, snapPoints, isOpen, shouldFade, shouldOverlayAnimate } = useDrawerContext();
|
|
986
|
+
const { overlayRef, onRelease, modal, snapPoints, isOpen, shouldFade, shouldOverlayAnimate, hasAnimationDone } = useDrawerContext();
|
|
957
987
|
const composedRef = reactComposeRefs.useComposedRefs(ref, overlayRef);
|
|
958
988
|
const hasSnapPoints = snapPoints && snapPoints.length > 0;
|
|
959
989
|
const onMouseUp = reactUseCallbackRef.useCallbackRef((event)=>onRelease(event));
|
|
960
|
-
// Overlay is the component that is locking scroll, removing it will unlock the scroll without having to dig into Radix's Dialog library
|
|
961
990
|
if (!modal) {
|
|
962
991
|
return null;
|
|
963
992
|
}
|
|
@@ -968,13 +997,14 @@ const DrawerBackdrop = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
968
997
|
"data-snap-points-overlay": isOpen && shouldFade ? "true" : "false",
|
|
969
998
|
"data-should-overlay-animate": shouldOverlayAnimate ? "true" : "false",
|
|
970
999
|
"data-open": domUtils.dataAttr(isOpen),
|
|
1000
|
+
"data-animation-done": hasAnimationDone ? "true" : "false",
|
|
971
1001
|
...props
|
|
972
1002
|
});
|
|
973
1003
|
});
|
|
974
1004
|
DrawerBackdrop.displayName = "DrawerBackdrop";
|
|
975
1005
|
const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
976
1006
|
const { onPointerDownOutside, style, onOpenAutoFocus, ...restProps } = props;
|
|
977
|
-
const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, autoFocus, closeDrawer, closeOnInteractOutside, closeOnEscape, dismissible } = useDrawerContext();
|
|
1007
|
+
const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, autoFocus, closeDrawer, closeOnInteractOutside, closeOnEscape, dismissible, hasAnimationDone } = useDrawerContext();
|
|
978
1008
|
// Needed to use transition instead of animations
|
|
979
1009
|
const [delayedSnapPoints, setDelayedSnapPoints] = React.useState(false);
|
|
980
1010
|
const composedRef = reactComposeRefs.useComposedRefs(ref, drawerRef);
|
|
@@ -1021,6 +1051,7 @@ const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1021
1051
|
"data-delayed-snap-points": delayedSnapPoints ? "true" : "false",
|
|
1022
1052
|
"data-drawer-direction": direction,
|
|
1023
1053
|
"data-open": domUtils.dataAttr(isOpen),
|
|
1054
|
+
"data-animation-done": hasAnimationDone ? "true" : "false",
|
|
1024
1055
|
"data-drawer": "",
|
|
1025
1056
|
"data-snap-points": isOpen && hasSnapPoints ? "true" : "false",
|
|
1026
1057
|
"data-custom-container": container ? "true" : "false",
|
|
@@ -1056,10 +1087,10 @@ const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1056
1087
|
}
|
|
1057
1088
|
},
|
|
1058
1089
|
onFocusOutside: (e)=>{
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1090
|
+
props.onFocusOutside?.(e);
|
|
1091
|
+
// Always prevent focusOutside to avoid conflicts when focus moves between modals
|
|
1092
|
+
// (e.g., when Dialog closes and restores focus while BottomSheet is opening)
|
|
1093
|
+
e.preventDefault();
|
|
1063
1094
|
},
|
|
1064
1095
|
onPointerMove: (event)=>{
|
|
1065
1096
|
lastKnownPointerEventRef.current = event;
|
|
@@ -1096,7 +1127,8 @@ const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1096
1127
|
}
|
|
1097
1128
|
},
|
|
1098
1129
|
onInteractOutside: (e)=>{
|
|
1099
|
-
if (
|
|
1130
|
+
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
1131
|
+
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
1100
1132
|
closeDrawer();
|
|
1101
1133
|
}
|
|
1102
1134
|
props.onInteractOutside?.(e);
|
|
@@ -1112,15 +1144,25 @@ const DrawerContent = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
|
1112
1144
|
DrawerContent.displayName = "DrawerContent";
|
|
1113
1145
|
const DrawerTitle = DialogPrimitive__namespace.Title;
|
|
1114
1146
|
const DrawerDescription = DialogPrimitive__namespace.Description;
|
|
1147
|
+
const DrawerHeader = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
1148
|
+
const { isCloseButtonRendered } = useDrawerContext();
|
|
1149
|
+
return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.div, {
|
|
1150
|
+
ref: ref,
|
|
1151
|
+
"data-show-close-button": domUtils.dataAttr(isCloseButtonRendered),
|
|
1152
|
+
...props
|
|
1153
|
+
});
|
|
1154
|
+
});
|
|
1155
|
+
DrawerHeader.displayName = "DrawerHeader";
|
|
1115
1156
|
const DrawerCloseButton = /*#__PURE__*/ React.forwardRef((props, ref)=>{
|
|
1116
|
-
const
|
|
1157
|
+
const { closeButtonRef, setIsOpen } = useDrawerContext();
|
|
1158
|
+
const composedRef = reactComposeRefs.useComposedRefs(ref, closeButtonRef);
|
|
1117
1159
|
return /*#__PURE__*/ jsxRuntime.jsx(reactPrimitive.Primitive.button, {
|
|
1118
|
-
ref:
|
|
1160
|
+
ref: composedRef,
|
|
1119
1161
|
...props,
|
|
1120
1162
|
onClick: (e)=>{
|
|
1121
1163
|
props.onClick?.(e);
|
|
1122
1164
|
if (e.defaultPrevented) return;
|
|
1123
|
-
|
|
1165
|
+
setIsOpen(false);
|
|
1124
1166
|
}
|
|
1125
1167
|
});
|
|
1126
1168
|
});
|
|
@@ -1206,6 +1248,7 @@ exports.DrawerCloseButton = DrawerCloseButton;
|
|
|
1206
1248
|
exports.DrawerContent = DrawerContent;
|
|
1207
1249
|
exports.DrawerDescription = DrawerDescription;
|
|
1208
1250
|
exports.DrawerHandle = DrawerHandle;
|
|
1251
|
+
exports.DrawerHeader = DrawerHeader;
|
|
1209
1252
|
exports.DrawerPositioner = DrawerPositioner;
|
|
1210
1253
|
exports.DrawerRoot = DrawerRoot;
|
|
1211
1254
|
exports.DrawerTitle = DrawerTitle;
|
package/lib/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var Drawer12s = require('./Drawer-12s-
|
|
1
|
+
var Drawer12s = require('./Drawer-12s-DriAYAR2.cjs');
|
|
2
2
|
|
|
3
3
|
var Drawer_namespace = {
|
|
4
4
|
__proto__: null,
|
|
@@ -7,6 +7,7 @@ var Drawer_namespace = {
|
|
|
7
7
|
Content: Drawer12s.DrawerContent,
|
|
8
8
|
Description: Drawer12s.DrawerDescription,
|
|
9
9
|
Handle: Drawer12s.DrawerHandle,
|
|
10
|
+
Header: Drawer12s.DrawerHeader,
|
|
10
11
|
Positioner: Drawer12s.DrawerPositioner,
|
|
11
12
|
Root: Drawer12s.DrawerRoot,
|
|
12
13
|
Title: Drawer12s.DrawerTitle,
|
|
@@ -18,6 +19,7 @@ exports.DrawerCloseButton = Drawer12s.DrawerCloseButton;
|
|
|
18
19
|
exports.DrawerContent = Drawer12s.DrawerContent;
|
|
19
20
|
exports.DrawerDescription = Drawer12s.DrawerDescription;
|
|
20
21
|
exports.DrawerHandle = Drawer12s.DrawerHandle;
|
|
22
|
+
exports.DrawerHeader = Drawer12s.DrawerHeader;
|
|
21
23
|
exports.DrawerPositioner = Drawer12s.DrawerPositioner;
|
|
22
24
|
exports.DrawerRoot = Drawer12s.DrawerRoot;
|
|
23
25
|
exports.DrawerTitle = Drawer12s.DrawerTitle;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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
|
-
import * as
|
|
4
|
+
import * as React$1 from 'react';
|
|
5
5
|
|
|
6
6
|
interface UseDrawerProps {
|
|
7
7
|
activeSnapPoint?: number | string | null;
|
|
@@ -106,9 +106,9 @@ interface UseDrawerProps {
|
|
|
106
106
|
declare function useDrawer(props: UseDrawerProps): {
|
|
107
107
|
activeSnapPoint: string | number | null;
|
|
108
108
|
snapPoints: (string | number)[] | undefined;
|
|
109
|
-
setActiveSnapPoint: (value:
|
|
110
|
-
drawerRef:
|
|
111
|
-
overlayRef:
|
|
109
|
+
setActiveSnapPoint: (value: React$1.SetStateAction<string | number | null>) => void;
|
|
110
|
+
drawerRef: React$1.RefObject<HTMLDivElement | null>;
|
|
111
|
+
overlayRef: React$1.RefObject<HTMLDivElement | null>;
|
|
112
112
|
shouldOverlayAnimate: boolean;
|
|
113
113
|
onOpenChange: ((open: boolean) => void) | undefined;
|
|
114
114
|
onPress: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
@@ -120,7 +120,7 @@ declare function useDrawer(props: UseDrawerProps): {
|
|
|
120
120
|
isDragging: boolean;
|
|
121
121
|
shouldFade: boolean;
|
|
122
122
|
closeDrawer: (fromWithin?: boolean) => void;
|
|
123
|
-
keyboardIsOpen:
|
|
123
|
+
keyboardIsOpen: React$1.RefObject<boolean>;
|
|
124
124
|
modal: boolean;
|
|
125
125
|
snapPointsOffset: number[];
|
|
126
126
|
activeSnapPointIndex: number | null;
|
|
@@ -128,49 +128,55 @@ declare function useDrawer(props: UseDrawerProps): {
|
|
|
128
128
|
noBodyStyles: boolean;
|
|
129
129
|
container: HTMLElement | null | undefined;
|
|
130
130
|
autoFocus: boolean;
|
|
131
|
-
setHasBeenOpened:
|
|
132
|
-
setIsOpen: (value:
|
|
131
|
+
setHasBeenOpened: React$1.Dispatch<React$1.SetStateAction<boolean>>;
|
|
132
|
+
setIsOpen: (value: React$1.SetStateAction<boolean>) => void;
|
|
133
133
|
closeOnInteractOutside: boolean;
|
|
134
134
|
closeOnEscape: boolean;
|
|
135
|
+
hasAnimationDone: boolean;
|
|
136
|
+
closeButtonRef: (node: HTMLButtonElement | null) => void;
|
|
137
|
+
isCloseButtonRendered: boolean;
|
|
135
138
|
};
|
|
136
139
|
|
|
137
140
|
interface DrawerRootProps extends UseDrawerProps {
|
|
138
|
-
children?:
|
|
141
|
+
children?: React$1.ReactNode;
|
|
139
142
|
}
|
|
140
143
|
declare const DrawerRoot: (props: DrawerRootProps) => react_jsx_runtime.JSX.Element;
|
|
141
144
|
interface DrawerTriggerProps extends DialogPrimitive.DialogTriggerProps {
|
|
142
145
|
}
|
|
143
|
-
declare const DrawerTrigger:
|
|
144
|
-
interface DrawerPositionerProps extends PrimitiveProps,
|
|
146
|
+
declare const DrawerTrigger: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
147
|
+
interface DrawerPositionerProps extends PrimitiveProps, React$1.HTMLAttributes<HTMLDivElement> {
|
|
145
148
|
}
|
|
146
|
-
declare const DrawerPositioner:
|
|
147
|
-
interface DrawerBackdropProps extends DialogPrimitive.DialogOverlayProps,
|
|
149
|
+
declare const DrawerPositioner: React$1.ForwardRefExoticComponent<DrawerPositionerProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
150
|
+
interface DrawerBackdropProps extends DialogPrimitive.DialogOverlayProps, React$1.HTMLAttributes<HTMLDivElement> {
|
|
148
151
|
}
|
|
149
|
-
declare const DrawerBackdrop:
|
|
150
|
-
interface DrawerContentProps extends DialogPrimitive.DialogContentProps,
|
|
152
|
+
declare const DrawerBackdrop: React$1.ForwardRefExoticComponent<DrawerBackdropProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
153
|
+
interface DrawerContentProps extends DialogPrimitive.DialogContentProps, React$1.HTMLAttributes<HTMLDivElement> {
|
|
151
154
|
}
|
|
152
|
-
declare const DrawerContent:
|
|
155
|
+
declare const DrawerContent: React$1.ForwardRefExoticComponent<DrawerContentProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
153
156
|
interface DrawerTitleProps extends DialogPrimitive.DialogTitleProps {
|
|
154
157
|
}
|
|
155
|
-
declare const DrawerTitle:
|
|
158
|
+
declare const DrawerTitle: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogTitleProps & React$1.RefAttributes<HTMLHeadingElement>>;
|
|
156
159
|
interface DrawerDescriptionProps extends DialogPrimitive.DialogDescriptionProps {
|
|
157
160
|
}
|
|
158
|
-
declare const DrawerDescription:
|
|
161
|
+
declare const DrawerDescription: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogDescriptionProps & React$1.RefAttributes<HTMLParagraphElement>>;
|
|
162
|
+
interface DrawerHeaderProps extends PrimitiveProps, React$1.HTMLAttributes<HTMLDivElement> {
|
|
163
|
+
}
|
|
164
|
+
declare const DrawerHeader: React$1.ForwardRefExoticComponent<DrawerHeaderProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
159
165
|
interface DrawerCloseButtonProps extends DialogPrimitive.DialogCloseProps {
|
|
160
166
|
}
|
|
161
|
-
declare const DrawerCloseButton:
|
|
162
|
-
interface DrawerHandleProps extends
|
|
167
|
+
declare const DrawerCloseButton: React$1.ForwardRefExoticComponent<DrawerCloseButtonProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
168
|
+
interface DrawerHandleProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
163
169
|
preventCycle?: boolean;
|
|
164
170
|
}
|
|
165
|
-
declare const DrawerHandle:
|
|
171
|
+
declare const DrawerHandle: React$1.ForwardRefExoticComponent<DrawerHandleProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
166
172
|
|
|
167
173
|
type DrawerContextValue = ReturnType<typeof useDrawer>;
|
|
168
174
|
declare function useDrawerContext(): {
|
|
169
175
|
activeSnapPoint: string | number | null;
|
|
170
176
|
snapPoints: (string | number)[] | undefined;
|
|
171
|
-
setActiveSnapPoint: (value:
|
|
172
|
-
drawerRef:
|
|
173
|
-
overlayRef:
|
|
177
|
+
setActiveSnapPoint: (value: React$1.SetStateAction<string | number | null>) => void;
|
|
178
|
+
drawerRef: React$1.RefObject<HTMLDivElement | null>;
|
|
179
|
+
overlayRef: React$1.RefObject<HTMLDivElement | null>;
|
|
174
180
|
shouldOverlayAnimate: boolean;
|
|
175
181
|
onOpenChange: ((open: boolean) => void) | undefined;
|
|
176
182
|
onPress: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
@@ -182,7 +188,7 @@ declare function useDrawerContext(): {
|
|
|
182
188
|
isDragging: boolean;
|
|
183
189
|
shouldFade: boolean;
|
|
184
190
|
closeDrawer: (fromWithin?: boolean) => void;
|
|
185
|
-
keyboardIsOpen:
|
|
191
|
+
keyboardIsOpen: React$1.RefObject<boolean>;
|
|
186
192
|
modal: boolean;
|
|
187
193
|
snapPointsOffset: number[];
|
|
188
194
|
activeSnapPointIndex: number | null;
|
|
@@ -190,16 +196,19 @@ declare function useDrawerContext(): {
|
|
|
190
196
|
noBodyStyles: boolean;
|
|
191
197
|
container: HTMLElement | null | undefined;
|
|
192
198
|
autoFocus: boolean;
|
|
193
|
-
setHasBeenOpened:
|
|
194
|
-
setIsOpen: (value:
|
|
199
|
+
setHasBeenOpened: React$1.Dispatch<React$1.SetStateAction<boolean>>;
|
|
200
|
+
setIsOpen: (value: React$1.SetStateAction<boolean>) => void;
|
|
195
201
|
closeOnInteractOutside: boolean;
|
|
196
202
|
closeOnEscape: boolean;
|
|
203
|
+
hasAnimationDone: boolean;
|
|
204
|
+
closeButtonRef: (node: HTMLButtonElement | null) => void;
|
|
205
|
+
isCloseButtonRendered: boolean;
|
|
197
206
|
};
|
|
198
207
|
|
|
199
208
|
declare namespace Drawer_namespace {
|
|
200
|
-
export { DrawerBackdrop as Backdrop, DrawerCloseButton as CloseButton, DrawerContent as Content, DrawerDescription as Description, DrawerHandle as Handle, DrawerPositioner as Positioner, DrawerRoot as Root, DrawerTitle as Title, DrawerTrigger as Trigger };
|
|
201
|
-
export type { DrawerBackdropProps as BackdropProps, DrawerCloseButtonProps as CloseButtonProps, DrawerContentProps as ContentProps, DrawerDescriptionProps as DescriptionProps, DrawerHandleProps as HandleProps, DrawerPositionerProps as PositionerProps, DrawerRootProps as RootProps, DrawerTitleProps as TitleProps, DrawerTriggerProps as TriggerProps };
|
|
209
|
+
export { DrawerBackdrop as Backdrop, DrawerCloseButton as CloseButton, DrawerContent as Content, DrawerDescription as Description, DrawerHandle as Handle, DrawerHeader as Header, DrawerPositioner as Positioner, DrawerRoot as Root, DrawerTitle as Title, DrawerTrigger as Trigger };
|
|
210
|
+
export type { DrawerBackdropProps as BackdropProps, DrawerCloseButtonProps as CloseButtonProps, DrawerContentProps as ContentProps, DrawerDescriptionProps as DescriptionProps, DrawerHandleProps as HandleProps, DrawerHeaderProps as HeaderProps, DrawerPositionerProps as PositionerProps, DrawerRootProps as RootProps, DrawerTitleProps as TitleProps, DrawerTriggerProps as TriggerProps };
|
|
202
211
|
}
|
|
203
212
|
|
|
204
|
-
export { Drawer_namespace as Drawer, DrawerBackdrop, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerHandle, DrawerPositioner, DrawerRoot, DrawerTitle, DrawerTrigger, useDrawer, useDrawerContext };
|
|
205
|
-
export type { DrawerBackdropProps, DrawerCloseButtonProps, DrawerContentProps, DrawerContextValue, DrawerDescriptionProps, DrawerHandleProps, DrawerPositionerProps, DrawerRootProps, DrawerTitleProps, DrawerTriggerProps, UseDrawerProps };
|
|
213
|
+
export { Drawer_namespace as Drawer, DrawerBackdrop, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerHandle, DrawerHeader, DrawerPositioner, DrawerRoot, DrawerTitle, DrawerTrigger, useDrawer, useDrawerContext };
|
|
214
|
+
export type { DrawerBackdropProps, DrawerCloseButtonProps, DrawerContentProps, DrawerContextValue, DrawerDescriptionProps, DrawerHandleProps, DrawerHeaderProps, DrawerPositionerProps, DrawerRootProps, DrawerTitleProps, DrawerTriggerProps, UseDrawerProps };
|
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
|
|
2
|
-
export { u as useDrawer,
|
|
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-BdeYHia6.js';
|
|
2
|
+
export { u as useDrawer, j as useDrawerContext } from './Drawer-12s-BdeYHia6.js';
|
|
3
3
|
|
|
4
4
|
var Drawer_namespace = {
|
|
5
5
|
__proto__: null,
|
|
@@ -8,10 +8,11 @@ var Drawer_namespace = {
|
|
|
8
8
|
Content: DrawerContent,
|
|
9
9
|
Description: DrawerDescription,
|
|
10
10
|
Handle: DrawerHandle,
|
|
11
|
+
Header: DrawerHeader,
|
|
11
12
|
Positioner: DrawerPositioner,
|
|
12
13
|
Root: DrawerRoot,
|
|
13
14
|
Title: DrawerTitle,
|
|
14
15
|
Trigger: DrawerTrigger
|
|
15
16
|
};
|
|
16
17
|
|
|
17
|
-
export { Drawer_namespace as Drawer, DrawerBackdrop, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerHandle, DrawerPositioner, DrawerRoot, DrawerTitle, DrawerTrigger };
|
|
18
|
+
export { Drawer_namespace as Drawer, DrawerBackdrop, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerHandle, DrawerHeader, DrawerPositioner, DrawerRoot, DrawerTitle, DrawerTrigger };
|
package/package.json
CHANGED
package/src/Drawer.namespace.ts
CHANGED
|
@@ -4,6 +4,7 @@ export {
|
|
|
4
4
|
DrawerContent as Content,
|
|
5
5
|
DrawerDescription as Description,
|
|
6
6
|
DrawerHandle as Handle,
|
|
7
|
+
DrawerHeader as Header,
|
|
7
8
|
DrawerPositioner as Positioner,
|
|
8
9
|
DrawerRoot as Root,
|
|
9
10
|
DrawerTitle as Title,
|
|
@@ -13,6 +14,7 @@ export {
|
|
|
13
14
|
type DrawerContentProps as ContentProps,
|
|
14
15
|
type DrawerDescriptionProps as DescriptionProps,
|
|
15
16
|
type DrawerHandleProps as HandleProps,
|
|
17
|
+
type DrawerHeaderProps as HeaderProps,
|
|
16
18
|
type DrawerPositionerProps as PositionerProps,
|
|
17
19
|
type DrawerRootProps as RootProps,
|
|
18
20
|
type DrawerTitleProps as TitleProps,
|
package/src/Drawer.tsx
CHANGED
|
@@ -72,12 +72,12 @@ export const DrawerBackdrop = forwardRef<HTMLDivElement, DrawerBackdropProps>((p
|
|
|
72
72
|
isOpen,
|
|
73
73
|
shouldFade,
|
|
74
74
|
shouldOverlayAnimate,
|
|
75
|
+
hasAnimationDone,
|
|
75
76
|
} = useDrawerContext();
|
|
76
77
|
const composedRef = useComposedRefs(ref, overlayRef);
|
|
77
78
|
const hasSnapPoints = snapPoints && snapPoints.length > 0;
|
|
78
79
|
const onMouseUp = useCallbackRef((event: React.PointerEvent<HTMLDivElement>) => onRelease(event));
|
|
79
80
|
|
|
80
|
-
// Overlay is the component that is locking scroll, removing it will unlock the scroll without having to dig into Radix's Dialog library
|
|
81
81
|
if (!modal) {
|
|
82
82
|
return null;
|
|
83
83
|
}
|
|
@@ -90,6 +90,7 @@ export const DrawerBackdrop = forwardRef<HTMLDivElement, DrawerBackdropProps>((p
|
|
|
90
90
|
data-snap-points-overlay={isOpen && shouldFade ? "true" : "false"}
|
|
91
91
|
data-should-overlay-animate={shouldOverlayAnimate ? "true" : "false"}
|
|
92
92
|
data-open={dataAttr(isOpen)}
|
|
93
|
+
data-animation-done={hasAnimationDone ? "true" : "false"}
|
|
93
94
|
{...props}
|
|
94
95
|
/>
|
|
95
96
|
);
|
|
@@ -121,6 +122,7 @@ export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>((pro
|
|
|
121
122
|
closeOnInteractOutside,
|
|
122
123
|
closeOnEscape,
|
|
123
124
|
dismissible,
|
|
125
|
+
hasAnimationDone,
|
|
124
126
|
} = useDrawerContext();
|
|
125
127
|
// Needed to use transition instead of animations
|
|
126
128
|
const [delayedSnapPoints, setDelayedSnapPoints] = useState(false);
|
|
@@ -177,6 +179,7 @@ export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>((pro
|
|
|
177
179
|
data-delayed-snap-points={delayedSnapPoints ? "true" : "false"}
|
|
178
180
|
data-drawer-direction={direction}
|
|
179
181
|
data-open={dataAttr(isOpen)}
|
|
182
|
+
data-animation-done={hasAnimationDone ? "true" : "false"}
|
|
180
183
|
data-drawer=""
|
|
181
184
|
data-snap-points={isOpen && hasSnapPoints ? "true" : "false"}
|
|
182
185
|
data-custom-container={container ? "true" : "false"}
|
|
@@ -216,10 +219,10 @@ export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>((pro
|
|
|
216
219
|
}
|
|
217
220
|
}}
|
|
218
221
|
onFocusOutside={(e) => {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
222
|
+
props.onFocusOutside?.(e);
|
|
223
|
+
// Always prevent focusOutside to avoid conflicts when focus moves between modals
|
|
224
|
+
// (e.g., when Dialog closes and restores focus while BottomSheet is opening)
|
|
225
|
+
e.preventDefault();
|
|
223
226
|
}}
|
|
224
227
|
onPointerMove={(event) => {
|
|
225
228
|
lastKnownPointerEventRef.current = event;
|
|
@@ -258,7 +261,8 @@ export const DrawerContent = forwardRef<HTMLDivElement, DrawerContentProps>((pro
|
|
|
258
261
|
}
|
|
259
262
|
}}
|
|
260
263
|
onInteractOutside={(e) => {
|
|
261
|
-
if (
|
|
264
|
+
// Only close if event is not prevented (e.g., by onFocusOutside or onPointerDownOutside)
|
|
265
|
+
if (dismissible && closeOnInteractOutside && !e.defaultPrevented) {
|
|
262
266
|
closeDrawer();
|
|
263
267
|
}
|
|
264
268
|
props.onInteractOutside?.(e);
|
|
@@ -282,19 +286,30 @@ export interface DrawerDescriptionProps extends DialogPrimitive.DialogDescriptio
|
|
|
282
286
|
|
|
283
287
|
export const DrawerDescription = DialogPrimitive.Description;
|
|
284
288
|
|
|
289
|
+
export interface DrawerHeaderProps extends PrimitiveProps, React.HTMLAttributes<HTMLDivElement> {}
|
|
290
|
+
|
|
291
|
+
export const DrawerHeader = forwardRef<HTMLDivElement, DrawerHeaderProps>((props, ref) => {
|
|
292
|
+
const { isCloseButtonRendered } = useDrawerContext();
|
|
293
|
+
return (
|
|
294
|
+
<Primitive.div ref={ref} data-show-close-button={dataAttr(isCloseButtonRendered)} {...props} />
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
DrawerHeader.displayName = "DrawerHeader";
|
|
298
|
+
|
|
285
299
|
export interface DrawerCloseButtonProps extends DialogPrimitive.DialogCloseProps {}
|
|
286
300
|
|
|
287
301
|
export const DrawerCloseButton = forwardRef<HTMLButtonElement, DrawerCloseButtonProps>(
|
|
288
302
|
(props, ref) => {
|
|
289
|
-
const
|
|
303
|
+
const { closeButtonRef, setIsOpen } = useDrawerContext();
|
|
304
|
+
const composedRef = useComposedRefs(ref, closeButtonRef);
|
|
290
305
|
return (
|
|
291
306
|
<Primitive.button
|
|
292
|
-
ref={
|
|
307
|
+
ref={composedRef}
|
|
293
308
|
{...props}
|
|
294
309
|
onClick={(e) => {
|
|
295
310
|
props.onClick?.(e);
|
|
296
311
|
if (e.defaultPrevented) return;
|
|
297
|
-
|
|
312
|
+
setIsOpen(false);
|
|
298
313
|
}}
|
|
299
314
|
/>
|
|
300
315
|
);
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export {
|
|
|
4
4
|
DrawerContent,
|
|
5
5
|
DrawerDescription,
|
|
6
6
|
DrawerHandle,
|
|
7
|
+
DrawerHeader,
|
|
7
8
|
DrawerPositioner,
|
|
8
9
|
DrawerRoot,
|
|
9
10
|
DrawerTitle,
|
|
@@ -13,6 +14,7 @@ export {
|
|
|
13
14
|
type DrawerContentProps,
|
|
14
15
|
type DrawerDescriptionProps,
|
|
15
16
|
type DrawerHandleProps,
|
|
17
|
+
type DrawerHeaderProps,
|
|
16
18
|
type DrawerPositionerProps,
|
|
17
19
|
type DrawerRootProps,
|
|
18
20
|
type DrawerTitleProps,
|
package/src/useDrawer.ts
CHANGED
|
@@ -116,7 +116,6 @@ export interface UseDrawerProps {
|
|
|
116
116
|
* @default true
|
|
117
117
|
*/
|
|
118
118
|
closeOnEscape?: boolean;
|
|
119
|
-
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
export function useDrawer(props: UseDrawerProps) {
|
|
@@ -179,9 +178,15 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
179
178
|
});
|
|
180
179
|
|
|
181
180
|
const [hasBeenOpened, setHasBeenOpened] = useState<boolean>(false);
|
|
181
|
+
const [hasAnimationDone, setHasAnimationDone] = useState<boolean>(false);
|
|
182
182
|
const [isDragging, setIsDragging] = useState<boolean>(false);
|
|
183
183
|
const [shouldOverlayAnimate, setShouldOverlayAnimate] = useState<boolean>(false);
|
|
184
184
|
|
|
185
|
+
const [isCloseButtonRendered, setIsCloseButtonRendered] = useState<boolean>(false);
|
|
186
|
+
const closeButtonRef = useCallback((node: HTMLButtonElement | null) => {
|
|
187
|
+
setIsCloseButtonRendered(!!node);
|
|
188
|
+
}, []);
|
|
189
|
+
|
|
185
190
|
const overlayRef = useRef<HTMLDivElement>(null);
|
|
186
191
|
const openTime = useRef<Date | null>(null);
|
|
187
192
|
const dragStartTime = useRef<Date | null>(null);
|
|
@@ -543,7 +548,6 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
543
548
|
};
|
|
544
549
|
}, [isOpen]);
|
|
545
550
|
|
|
546
|
-
|
|
547
551
|
useEffect(() => {
|
|
548
552
|
function onVisualViewportChange() {
|
|
549
553
|
if (!drawerRef.current || !repositionInputs) return;
|
|
@@ -609,12 +613,32 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
609
613
|
}
|
|
610
614
|
}, [modal]);
|
|
611
615
|
|
|
616
|
+
// Effect 1: Track drawer open state
|
|
612
617
|
useEffect(() => {
|
|
613
618
|
if (isOpen) {
|
|
614
619
|
setHasBeenOpened(true);
|
|
615
620
|
}
|
|
616
621
|
}, [isOpen]);
|
|
617
622
|
|
|
623
|
+
// Effect 2: Handle animation state and timer
|
|
624
|
+
useEffect(() => {
|
|
625
|
+
if (isOpen) {
|
|
626
|
+
// Only reset animation state if this is the first open
|
|
627
|
+
if (!hasBeenOpened) {
|
|
628
|
+
setHasAnimationDone(false);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const timeoutId = setTimeout(() => {
|
|
632
|
+
setHasAnimationDone(true);
|
|
633
|
+
}, TRANSITIONS.ENTER_DURATION * 1000);
|
|
634
|
+
|
|
635
|
+
return () => clearTimeout(timeoutId);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Reset animation state when drawer closes
|
|
639
|
+
setHasAnimationDone(false);
|
|
640
|
+
}, [isOpen, hasBeenOpened]);
|
|
641
|
+
|
|
618
642
|
useEffect(() => {
|
|
619
643
|
if (isOpen && snapPoints && fadeFromIndex === 0) {
|
|
620
644
|
setShouldOverlayAnimate(true);
|
|
@@ -659,6 +683,9 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
659
683
|
setIsOpen,
|
|
660
684
|
closeOnInteractOutside,
|
|
661
685
|
closeOnEscape,
|
|
686
|
+
hasAnimationDone,
|
|
687
|
+
closeButtonRef,
|
|
688
|
+
isCloseButtonRendered,
|
|
662
689
|
}),
|
|
663
690
|
[
|
|
664
691
|
activeSnapPoint,
|
|
@@ -685,6 +712,9 @@ export function useDrawer(props: UseDrawerProps) {
|
|
|
685
712
|
onRelease,
|
|
686
713
|
onDrag,
|
|
687
714
|
onPress,
|
|
715
|
+
hasAnimationDone,
|
|
716
|
+
closeButtonRef,
|
|
717
|
+
isCloseButtonRendered,
|
|
688
718
|
],
|
|
689
719
|
);
|
|
690
720
|
}
|