Skip to content

Commit dcbf5d4

Browse files
committed
add 'animated' option to open/close
1 parent f7db50e commit dcbf5d4

File tree

2 files changed

+78
-53
lines changed

2 files changed

+78
-53
lines changed

README.md

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,17 @@ Compatible with [React Native Draggable Flatlist](https://github.com/computerjaz
1818
_NOTE:_ Naming is hard. When you swipe _right_, you reveal the item on the _left_. So what do you name these things? I have decided to name everything according to swipe direction. Therefore, a swipe left reveals the `renderUnderlayLeft()` component with width `underlayWidthLeft`. Not perfect but it works.
1919

2020
```ts
21+
type OpenCloseOptions = { animated?: boolean };
22+
type OpenPromiseFn = (
23+
snapPoint?: number,
24+
options?: OpenCloseOptions
25+
) => Promise<void>;
26+
type ClosePromiseFn = (options?: OpenCloseOptions) => Promise<void>;
27+
2128
export type UnderlayParams<T> = {
2229
item: T;
2330
open: OpenPromiseFn;
24-
close: VoidPromiseFn;
31+
close: ClosePromiseFn;
2532
percentOpen: Animated.DerivedValue<number>;
2633
isGestureActive: Animated.DerivedValue<boolean>;
2734
direction: OpenDirection;
@@ -31,21 +38,11 @@ export type OverlayParams<T> = {
3138
item: T;
3239
openLeft: OpenPromiseFn;
3340
openRight: OpenPromiseFn;
34-
close: VoidPromiseFn;
41+
close: ClosePromiseFn;
3542
openDirection: OpenDirection;
3643
percentOpenLeft: Animated.DerivedValue<number>;
3744
percentOpenRight: Animated.DerivedValue<number>;
3845
};
39-
40-
type RenderUnderlay<T> = (params: UnderlayParams<T>) => React.ReactNode;
41-
42-
type RenderOverlay<T> = (params: OverlayParams<T>) => React.ReactNode;
43-
44-
enum OpenDirection {
45-
LEFT = "left",
46-
RIGHT = "right",
47-
NONE = "none",
48-
}
4946
```
5047

5148
| Name | Type | Description |
@@ -84,10 +81,10 @@ function MyOverlayComponent() {
8481

8582
### Instance Methods
8683

87-
| Name | Type | Description |
88-
| :------ | :--------------------------------------------------------------------------------- | :----------------------------------------------------------- |
89-
| `open` | `(OpenDirection.LEFT \| OpenDirection.RIGHT, snapIndex?: number) => Promise<void>` | Imperatively open left or right. Promise resolves once open. |
90-
| `close` | `() => Promise<void>` | Close all. Promise resolves once closed. |
84+
| Name | Type | Description |
85+
| :------ | :------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------- |
86+
| `open` | `(OpenDirection.LEFT \| OpenDirection.RIGHT, snapIndex?: number, options?: { animated: boolean }) => Promise<void>` | Imperatively open left or right. Promise resolves once open. |
87+
| `close` | `(options?: { animated?: boolean}) => Promise<void>` | Close all. Promise resolves once closed. |
9188

9289
```tsx
9390
// Imperative open example

src/index.tsx

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ export enum OpenDirection {
3232

3333
const renderNull = () => null;
3434

35-
type VoidPromiseFn = () => Promise<void>;
36-
type OpenPromiseFn = (snapPoint?: number) => Promise<void>;
35+
type OpenCloseOptions = { animated?: boolean };
36+
type OpenPromiseFn = (
37+
snapPoint?: number,
38+
options?: OpenCloseOptions
39+
) => Promise<void>;
40+
type ClosePromiseFn = (options?: OpenCloseOptions) => Promise<void>;
3741

3842
export type UnderlayParams<T> = {
3943
item: T;
4044
open: OpenPromiseFn;
41-
close: VoidPromiseFn;
45+
close: ClosePromiseFn;
4246
percentOpen: Animated.DerivedValue<number>;
4347
isGestureActive: Animated.DerivedValue<boolean>;
4448
direction: OpenDirection;
@@ -48,7 +52,7 @@ export type OverlayParams<T> = {
4852
item: T;
4953
openLeft: OpenPromiseFn;
5054
openRight: OpenPromiseFn;
51-
close: VoidPromiseFn;
55+
close: ClosePromiseFn;
5256
openDirection: OpenDirection;
5357
percentOpenLeft: Animated.DerivedValue<number>;
5458
percentOpenRight: Animated.DerivedValue<number>;
@@ -81,8 +85,12 @@ type Props<T> = {
8185
};
8286

8387
export type SwipeableItemImperativeRef = {
84-
open: (openDirection: OpenDirection, snapPoint?: number) => Promise<void>;
85-
close: () => Promise<void>;
88+
open: (
89+
openDirection: OpenDirection,
90+
snapPoint?: number,
91+
options?: OpenCloseOptions
92+
) => Promise<void>;
93+
close: ClosePromiseFn;
8694
};
8795

8896
function SwipeableItem<T>(
@@ -178,60 +186,80 @@ function SwipeableItem<T>(
178186
[animStatePos]
179187
);
180188

181-
function openLeft(snapPoint?: number) {
189+
const openLeft: OpenPromiseFn = (snapPoint, options) => {
182190
return new Promise<void>((resolve) => {
183191
function resolvePromiseIfFinished(isFinished: boolean) {
184192
if (isFinished) resolve();
185193
}
186-
animStatePos.value = withSpring(
187-
snapPoint ?? maxSnapPointLeft,
188-
springConfig,
189-
(isFinished) => {
194+
195+
const toValue = snapPoint ?? maxSnapPointLeft;
196+
197+
if (options?.animated === false) {
198+
animStatePos.value = toValue;
199+
resolve();
200+
} else {
201+
animStatePos.value = withSpring(toValue, springConfig, (isFinished) => {
190202
if (isFinished) {
191203
runOnJS(resolvePromiseIfFinished)(isFinished);
192204
}
193-
}
194-
);
205+
});
206+
}
195207
});
196-
}
197-
function openRight(snapPoint?: number) {
208+
};
209+
210+
const openRight: OpenPromiseFn = (snapPoint, options) => {
198211
return new Promise<void>((resolve) => {
199212
function resolvePromiseIfFinished(isFinished: boolean) {
200213
if (isFinished) resolve();
201214
}
202-
animStatePos.value = withSpring(
203-
snapPoint ?? maxSnapPointRight,
204-
springConfig,
205-
(isFinished) => {
215+
216+
const toValue = snapPoint ?? maxSnapPointRight;
217+
218+
if (options?.animated === false) {
219+
animStatePos.value = toValue;
220+
resolve();
221+
} else {
222+
animStatePos.value = withSpring(toValue, springConfig, (isFinished) => {
206223
if (isFinished) {
207224
runOnJS(resolvePromiseIfFinished)(isFinished);
208225
}
209-
}
210-
);
226+
});
227+
}
211228
});
212-
}
229+
};
213230

214-
function close() {
231+
const close: ClosePromiseFn = (options) => {
215232
return new Promise<void>((resolve) => {
216233
function resolvePromiseIfFinished(isFinished: boolean) {
217234
if (isFinished) resolve();
218235
}
219-
animStatePos.value = withSpring(0, springConfig, (isFinished) => {
220-
if (isFinished) {
221-
runOnJS(resolvePromiseIfFinished)(isFinished);
222-
}
223-
});
236+
237+
if (options?.animated === false) {
238+
animStatePos.value = 0;
239+
resolve();
240+
} else {
241+
animStatePos.value = withSpring(0, springConfig, (isFinished) => {
242+
if (isFinished) {
243+
runOnJS(resolvePromiseIfFinished)(isFinished);
244+
}
245+
});
246+
}
224247
});
225-
}
248+
};
226249

227-
useImperativeHandle(ref, () => ({
228-
open: (openDirection: OpenDirection, snapPoint?: number) => {
229-
if (openDirection === OpenDirection.LEFT) return openLeft(snapPoint);
230-
if (openDirection === OpenDirection.RIGHT) return openRight(snapPoint);
231-
return close();
232-
},
233-
close,
234-
}));
250+
useImperativeHandle(ref, () => {
251+
const refObject: SwipeableItemImperativeRef = {
252+
open: (openDirection, snapPoint, options) => {
253+
if (openDirection === OpenDirection.LEFT)
254+
return openLeft(snapPoint, options);
255+
if (openDirection === OpenDirection.RIGHT)
256+
return openRight(snapPoint, options);
257+
return close();
258+
},
259+
close,
260+
};
261+
return refObject;
262+
});
235263

236264
function onAnimationEnd(openDirection: OpenDirection, snapPoint: number) {
237265
setOpenDirection(openDirection);

0 commit comments

Comments
 (0)