1
1
import { tick } from "svelte" ;
2
2
import { derived , get , type Writable } from "svelte/store" ;
3
3
import { TRANSITIONS , VELOCITY_THRESHOLD } from "./constants.js" ;
4
- import { effect , set } from "./helpers/index.js" ;
4
+ import { effect , set , isVertical , isBottomOrRight } from "./helpers/index.js" ;
5
+ import type { DrawerDirection } from "./types.js" ;
5
6
6
7
export function handleSnapPoints ( {
7
8
activeSnapPoint,
8
9
snapPoints,
9
10
drawerRef,
10
11
overlayRef,
11
12
fadeFromIndex,
12
- openTime
13
+ openTime,
14
+ direction
13
15
} : {
14
16
activeSnapPoint : Writable < number | string | null > ;
15
17
snapPoints : Writable < ( number | string ) [ ] | undefined > ;
16
18
fadeFromIndex : Writable < number | undefined > ;
17
19
drawerRef : Writable < HTMLDivElement | undefined > ;
18
20
overlayRef : Writable < HTMLDivElement | undefined > ;
19
21
openTime : Writable < Date | null > ;
22
+ direction : Writable < DrawerDirection > ;
20
23
} ) {
21
24
const isLastSnapPoint = derived (
22
25
[ snapPoints , activeSnapPoint ] ,
@@ -55,14 +58,27 @@ export function handleSnapPoints({
55
58
if ( isPx ) {
56
59
snapPointAsNumber = parseInt ( snapPoint , 10 ) ;
57
60
}
61
+ const $direction = get ( direction ) ;
58
62
59
- const height = isPx ? snapPointAsNumber : hasWindow ? snapPoint * window . innerHeight : 0 ;
63
+ if ( isVertical ( $direction ) ) {
64
+ const height = isPx ? snapPointAsNumber : hasWindow ? snapPoint * window . innerHeight : 0 ;
65
+
66
+ if ( hasWindow ) {
67
+ return $direction === "bottom"
68
+ ? window . innerHeight - height
69
+ : window . innerHeight + height ;
70
+ }
71
+
72
+ return height ;
73
+ }
74
+
75
+ const width = isPx ? snapPointAsNumber : hasWindow ? snapPoint * window . innerWidth : 0 ;
60
76
61
77
if ( hasWindow ) {
62
- return window . innerHeight - height ;
78
+ return $direction === "right" ? window . innerWidth - width : window . innerWidth + width ;
63
79
}
64
80
65
- return height ;
81
+ return width ;
66
82
} ) ;
67
83
}
68
84
return [ ] ;
@@ -78,29 +94,31 @@ export function handleSnapPoints({
78
94
if ( $activeSnapPoint && $drawerRef ) {
79
95
const $snapPoints = get ( snapPoints ) ;
80
96
const $snapPointsOffset = get ( snapPointsOffset ) ;
81
- const newIndex =
82
- $snapPoints ?. findIndex ( ( snapPoint ) => snapPoint === $activeSnapPoint ) ?? null ;
83
- if ( $snapPointsOffset && newIndex && typeof $snapPointsOffset [ newIndex ] === "number" ) {
97
+ const newIndex = $snapPoints ?. findIndex ( ( snapPoint ) => snapPoint === $activeSnapPoint ) ?? - 1 ;
98
+ if ( $snapPointsOffset && newIndex !== - 1 && typeof $snapPointsOffset [ newIndex ] === "number" ) {
84
99
snapToPoint ( $snapPointsOffset [ newIndex ] as number ) ;
85
100
}
86
101
}
87
102
} ) ;
88
103
89
- function snapToPoint ( height : number ) {
104
+ function snapToPoint ( dimension : number ) {
90
105
tick ( ) . then ( ( ) => {
91
106
const $snapPointsOffset = get ( snapPointsOffset ) ;
92
107
const newSnapPointIndex =
93
- $snapPointsOffset ?. findIndex ( ( snapPointHeight ) => snapPointHeight === height ) ?? null ;
108
+ $snapPointsOffset ?. findIndex ( ( snapPointDim ) => snapPointDim === dimension ) ?? null ;
94
109
95
110
const $drawerRef = get ( drawerRef ) ;
111
+ const $direction = get ( direction ) ;
96
112
97
113
onSnapPointChange ( newSnapPointIndex ) ;
98
114
99
115
set ( $drawerRef , {
100
116
transition : `transform ${ TRANSITIONS . DURATION } s cubic-bezier(${ TRANSITIONS . EASE . join (
101
117
","
102
118
) } )`,
103
- transform : `translate3d(0, ${ height } px, 0)`
119
+ transform : isVertical ( $direction )
120
+ ? `translate3d(0, ${ dimension } px, 0)`
121
+ : `translate3d(${ dimension } px, 0, 0)`
104
122
} ) ;
105
123
106
124
const $fadeFromIndex = get ( fadeFromIndex ) ;
@@ -151,13 +169,13 @@ export function handleSnapPoints({
151
169
const $overlayRef = get ( overlayRef ) ;
152
170
const $snapPointsOffset = get ( snapPointsOffset ) ;
153
171
const $snapPoints = get ( snapPoints ) ;
172
+ const $direction = get ( direction ) ;
154
173
155
- function getCurrPosition ( ) {
156
- const snapOffset = $activeSnapPointOffset ?? 0 ;
157
- return snapOffset - draggedDistance ;
158
- }
174
+ const currentPosition =
175
+ $direction === "bottom" || $direction === "right"
176
+ ? ( $activeSnapPointOffset ?? 0 ) - draggedDistance
177
+ : ( $activeSnapPointOffset ?? 0 ) + draggedDistance ;
159
178
160
- const currentPosition = getCurrPosition ( ) ;
161
179
const isOverlaySnapPoint = $activeSnapPointIndex === $fadeFromIndex - 1 ;
162
180
const isFirst = $activeSnapPointIndex === 0 ;
163
181
const hasDraggedUp = draggedDistance > 0 ;
@@ -186,7 +204,9 @@ export function handleSnapPoints({
186
204
return Math . abs ( curr - currentPosition ) < Math . abs ( prev - currentPosition ) ? curr : prev ;
187
205
} ) ;
188
206
189
- if ( velocity > VELOCITY_THRESHOLD && Math . abs ( draggedDistance ) < window . innerHeight * 0.4 ) {
207
+ const dim = isVertical ( $direction ) ? window . innerHeight : window . innerWidth ;
208
+
209
+ if ( velocity > VELOCITY_THRESHOLD && Math . abs ( draggedDistance ) < dim * 0.4 ) {
190
210
const dragDirection = hasDraggedUp ? 1 : - 1 ; // 1 = up, -1 = down
191
211
192
212
// Don't do anything if we swipe upwards while being on the last snap point
@@ -212,10 +232,29 @@ export function handleSnapPoints({
212
232
const $drawerRef = get ( drawerRef ) ;
213
233
const $activeSnapPointOffset = get ( activeSnapPointOffset ) ;
214
234
if ( $activeSnapPointOffset === null ) return ;
215
- const newYValue = $activeSnapPointOffset - draggedDistance ;
235
+ const $snapPointsOffset = get ( snapPointsOffset ) ;
236
+ const $direction = get ( direction ) ;
237
+
238
+ const newValue =
239
+ $direction === "bottom" || $direction === "right"
240
+ ? $activeSnapPointOffset - draggedDistance
241
+ : $activeSnapPointOffset + draggedDistance ;
242
+
243
+ const lastSnapPoint = $snapPointsOffset [ $snapPointsOffset . length - 1 ] ;
244
+
245
+ // Don't do anything if we exceed the last(biggest) snap point
246
+ if ( isBottomOrRight ( $direction ) && newValue < lastSnapPoint ) {
247
+ return ;
248
+ }
249
+
250
+ if ( ! isBottomOrRight ( $direction ) && newValue > lastSnapPoint ) {
251
+ return ;
252
+ }
216
253
217
254
set ( $drawerRef , {
218
- transform : `translate3d(0, ${ newYValue } px, 0)`
255
+ transform : isVertical ( $direction )
256
+ ? `translate3d(0, ${ newValue } px, 0)`
257
+ : `translate3d(${ newValue } px, 0, 0)`
219
258
} ) ;
220
259
}
221
260
0 commit comments