react-native-swipeable-actions 1.0.0 → 1.2.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/CHANGELOG.md CHANGED
@@ -5,6 +5,41 @@ the entry for the matching version.
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 1.2.0 - 2026-11-13
9
+
10
+ Install it with `npx expo install react-native-swipeable-actions@^1`. The release
11
+ changes no native code. It has no breaking changes for typed callers. Read the entry
12
+ under Changed if a row passes a width with `undefined` content.
13
+
14
+ ### Added
15
+
16
+ - `isRTL` prop. It mirrors a row for a right-to-left layout: the `left` and `right`
17
+ props, `open(side)`, `Swipeable.open(key, side)`, `onLeftSwipeEnd` and
18
+ `onRightSwipeEnd` then refer to the opposite physical edge, and the `left` and
19
+ `right` values of `gestureInsets` swap. The default is `false`, so rows that map
20
+ their sides in the app do not change.
21
+ - A side with a width and no content. `<Swipeable leftActionsWidth={width}>` enables
22
+ the left side with an empty rail, so a swipe-to-go-back screen needs no empty
23
+ `<View />` as content.
24
+
25
+ ### Changed
26
+
27
+ - A side that has a width and `undefined` content is now enabled. Before, it was off
28
+ and a development warning said that the width was ignored. Pass `null` or `false`
29
+ as the content to keep a side off.
30
+
31
+ ## 1.1.0 - 2026-11-13
32
+
33
+ Install it with `npx expo install react-native-swipeable-actions@^1`. The release
34
+ changes native code, so rebuild the iOS and Android apps after you upgrade. It has
35
+ no breaking changes.
36
+
37
+ ### Added
38
+
39
+ - `gestureInsets` prop and the `GestureInsets` type. A touch that starts inside an
40
+ edge band does not start a swipe and goes to the children. Use it for a horizontal
41
+ pager inside a swipe-to-go-back screen.
42
+
8
43
  ## 1.0.0 - 2026-10-20
9
44
 
10
45
  First stable v1 release. Install it with
package/README.md CHANGED
@@ -81,7 +81,9 @@ Each side is a pair: content plus its width in layout units.
81
81
  - The width is the full reveal distance, including padding and gaps. The library
82
82
  does not measure action content.
83
83
  - The action rail spans the row. Give the action content its own width and height.
84
- - Omit a side, or pass `null` or `false`, to disable it. Omit its width too.
84
+ - A width alone enables its side with an empty rail. Nothing shows behind the content.
85
+ - To turn a side off, omit its width. `null` or `false` content also turns the side
86
+ off, with or without a width.
85
87
  - A disabled side never falls back to the other side.
86
88
 
87
89
  ## Two-sided rows
@@ -155,8 +157,8 @@ stays open and does not report `onSwipeEnd`.
155
157
  ## Swipe to go back
156
158
 
157
159
  Wrap a whole screen to slide it right with the finger. A full swipe goes back, and
158
- nothing shows behind the screen. Give the left side empty content as wide as the
159
- window. Do not pass `null`, because `null` disables the side.
160
+ nothing shows behind the screen. Give the left side a width as wide as the window and
161
+ no content.
160
162
 
161
163
  ```tsx
162
164
  const { width } = useWindowDimensions();
@@ -166,8 +168,8 @@ const key = useId();
166
168
  <Swipeable
167
169
  ref={screen}
168
170
  recyclingKey={key}
169
- leftActions={<View />}
170
171
  leftActionsWidth={width}
172
+ isRTL={I18nManager.isRTL}
171
173
  dragOffsetFromEdge={20}
172
174
  onSwipeStart={() => hasUnsavedDraft() && screen.current?.cancel()}
173
175
  onSwipeEnd={(state) => {
@@ -190,10 +192,40 @@ const key = useId();
190
192
  Then a later mount does not restore the open state of a screen that you swiped away.
191
193
  - If the navigator has its own back gesture on that screen, turn it off. For a
192
194
  native stack, set `gestureEnabled: false`.
195
+ - `isRTL={I18nManager.isRTL}` makes the screen slide left in a right-to-left layout.
196
+ Leave it out if the swipe must go right in every layout.
193
197
 
194
198
  The example app has a small reusable wrapper,
195
199
  [`SwipeToGoBack`](https://github.com/chocky335/react-native-swipeable-actions/blob/main/example/components/SwipeToGoBack.tsx).
196
200
 
201
+ ### A horizontal pager inside the screen
202
+
203
+ A horizontal pager or carousel inside the screen needs the same drag as the swipe.
204
+ On Android the row can take a drag in the swipe direction before the pager claims it.
205
+ The screen then moves and the page does not turn. Set `gestureInsets` to the area
206
+ that the pager covers. A touch that starts there goes to the pager. A touch anywhere
207
+ else still swipes the screen.
208
+
209
+ ```tsx
210
+ <Swipeable
211
+ recyclingKey={key}
212
+ leftActionsWidth={width}
213
+ gestureInsets={{ bottom: pagerHeight }}
214
+ >
215
+ {/* A horizontal pager fills the bottom `pagerHeight` of this screen. */}
216
+ <ChatScreen />
217
+ </Swipeable>
218
+ ```
219
+
220
+ - Each inset is a distance in layout units (dp on Android, pt on iOS) from that edge
221
+ of the row: `top`, `bottom`, `left`, `right`. An edge that you leave out has no band.
222
+ - The row reads the insets when a touch goes down. That touch keeps its answer until
223
+ the finger lifts: the row does not track it, intercept it or cancel the touches of
224
+ its children. If you change the insets during a touch, the next touch uses them.
225
+ - The insets apply while the row is closed and at rest. An open or moving row ignores
226
+ them, so a swipe from any point can always close it.
227
+ - `open()`, `close()` and `cancel()` do not depend on the insets.
228
+
197
229
  ## Commands
198
230
 
199
231
  ```tsx
@@ -251,10 +283,45 @@ The example list row uses the same pattern.
251
283
 
252
284
  ## RTL
253
285
 
254
- `left` and `right` are physical edges in every layout direction. RTL does not swap
255
- action content, widths, commands or side callbacks. If your app thinks in logical
256
- start/end actions, map them to left/right yourself.
286
+ By default `left` and `right` are physical edges in every layout direction. React
287
+ Native's global RTL setting does not swap action content, widths, commands or side
288
+ callbacks.
257
289
 
290
+ To mirror a row, pass `isRTL`. Write the row once for a left-to-right layout:
291
+
292
+ ```tsx
293
+ <Swipeable
294
+ isRTL={I18nManager.isRTL}
295
+ leftActions={<ReplyAction />}
296
+ leftActionsWidth={72}
297
+ rightActions={<DeleteAction />}
298
+ rightActionsWidth={88}
299
+ onRightSwipeEnd={(state) => state === "open" && remove(item.id)}
300
+ >
301
+ <Message item={item} />
302
+ </Swipeable>
303
+ ```
304
+
305
+ With `isRTL` on, every side name refers to the opposite physical edge:
306
+
307
+ - `rightActions` and `rightActionsWidth` sit on the left edge, and a drag to the
308
+ right reveals them. The `left` pair sits on the right edge.
309
+ - `open("right")` and `Swipeable.open(key, "right")` open the `rightActions`.
310
+ `open()` with no side still prefers `rightActions`, then `leftActions`.
311
+ - `onRightSwipeEnd` runs for the `rightActions`, and `onLeftSwipeEnd` for the
312
+ `leftActions`.
313
+
314
+ `isRTL` is a plain boolean. The library does not read `I18nManager` for it, so an app
315
+ that already maps its sides for RTL is not mirrored twice. Any other flag works too,
316
+ for example a chat that mirrors only incoming messages.
317
+
318
+ - `isRTL` moves whole sides. It does not reorder the buttons inside your action
319
+ content. React Native lays that content out in the app's layout direction.
320
+ - Each rail keeps its content against its own physical edge in both layout
321
+ directions (fixed in 1.0.0), so mirrored actions still start at the outer edge.
322
+ - `isRTL` also swaps the `left` and `right` values of `gestureInsets`.
323
+ - The raw `SwipeableView` props stay physical.
324
+ - A static command mirrors its side only while the `isRTL` row is mounted.
258
325
  - Close open rows before you swap which actions sit on which physical side.
259
326
  - A translated label can need a new width. Update the width with the label.
260
327
  - A change to React Native's global RTL setting (`I18nManager.forceRTL`) needs an
@@ -285,13 +352,15 @@ start/end actions, map them to left/right yourself.
285
352
  | Prop | Type | Default | Description |
286
353
  | --- | --- | --- | --- |
287
354
  | `children` | `ReactNode` | required | Row content. |
288
- | `leftActions` / `rightActions` | `ReactNode` | - | Action content for that physical side. `null`/`false` disables the side. At least one side is required. |
289
- | `leftActionsWidth` / `rightActionsWidth` | `number` | - | Required with its content. Finite and positive. |
355
+ | `leftActions` / `rightActions` | `ReactNode` | - | Action content for that side. Optional when the side has a width. `null`/`false` disables the side. |
356
+ | `leftActionsWidth` / `rightActionsWidth` | `number` | - | Enables its side. Finite and positive. At least one side is required. |
357
+ | `isRTL` | `boolean` | `false` | Mirrors the sides, the commands and the side callbacks. See [RTL](#rtl). |
290
358
  | `recyclingKey` | `string \| number` | - | Stable item key. Required for ref commands, static commands and list state restoration. |
291
359
  | `threshold` | `number` | `0.4` | Fraction (0-1) of the active side's width a release must pass to open. |
292
360
  | `friction` | `number` | `1` | Drag damping (0-1). Lower values add resistance. |
293
361
  | `dragOffsetFromEdge` | `number` | `0` | Horizontal distance before the swipe starts. |
294
362
  | `gestureEnabled` | `boolean` | `true` | Turns the gesture off. Commands still work. |
363
+ | `gestureInsets` | `{ top?, bottom?, left?, right?: number }` | - | Edge bands where a touch does not start a swipe and goes to the children. See [a horizontal pager inside the screen](#a-horizontal-pager-inside-the-screen). |
295
364
  | `autoClose` | `boolean` | `false` | Snap back after a completed swipe. |
296
365
  | `autoCloseTimeout` | `number` | `0` | Delay in ms before the auto-close. |
297
366
  | `appearance` | `'default' \| 'ios26'` | `'default'` | iOS action motion preset. |
@@ -317,7 +386,7 @@ not swipes.
317
386
 
318
387
  | Ref method | Static method | Description |
319
388
  | --- | --- | --- |
320
- | `open(side?)` | `Swipeable.open(key, side?)` | Open a side. Without a side: right if enabled, else left. |
389
+ | `open(side?)` | `Swipeable.open(key, side?)` | Open a side by its prop name. Without a side: right if enabled, else left. |
321
390
  | `close(animated = true)` | `Swipeable.close(key, animated = true)` | Close the row. |
322
391
  | `cancel()` | `Swipeable.cancel(key)` | Close at once. A gesture in progress or a pending open does not complete. |
323
392
  | - | `Swipeable.closeAll(animated = true)` | Close all rows, including rows that are not mounted (scrolled off or on a covered screen). Those rows come back closed. |
@@ -332,6 +401,7 @@ import type {
332
401
  SwipeableStatic, // Static methods
333
402
  SwipeSide, // 'left' | 'right'
334
403
  SwipeAppearance, // 'default' | 'ios26'
404
+ GestureInsets, // { top?, bottom?, left?, right? } in layout units
335
405
  } from "react-native-swipeable-actions";
336
406
  ```
337
407
 
@@ -381,6 +451,9 @@ fireEvent(row, "swipeEnd", {
381
451
  The other native events are `swipeStateChange` (`{ state, side }`) and
382
452
  `swipeProgress` (`{ progress, translationX, side }`).
383
453
 
454
+ The `side` in a native event is the physical side. For a row with `isRTL`, a native
455
+ `side: "left"` runs `onRightSwipeEnd`.
456
+
384
457
  ## Compatibility
385
458
 
386
459
  | | Tested for 1.0 |
@@ -47,6 +47,9 @@ class SwipeableModule : Module() {
47
47
  Prop("gestureEnabled") { view: SwipeableView, enabled: Boolean ->
48
48
  view.gestureEnabled = enabled
49
49
  }
50
+ Prop("gestureInsets") { view: SwipeableView, insets: Map<String, Double>? ->
51
+ view.setGestureInsets(insets)
52
+ }
50
53
  Prop("dragOffsetFromEdge") { view: SwipeableView, offset: Float ->
51
54
  view.dragOffsetFromEdge = offset
52
55
  }
@@ -257,6 +257,41 @@ class SwipeableView(context: Context, appContext: AppContext) : ExpoView(context
257
257
  var dragOffsetFromEdge: Float = 0f
258
258
  set(value) { field = maxOf(0f, value) }
259
259
 
260
+ private var gestureInsetTopPx = 0f
261
+ private var gestureInsetBottomPx = 0f
262
+ private var gestureInsetLeftPx = 0f
263
+ private var gestureInsetRightPx = 0f
264
+ private var isInsetTouch = false
265
+
266
+ // No configurationChanged(): the bands are read at ACTION_DOWN, so a change waits for the next touch.
267
+ fun setGestureInsets(insets: Map<String, Double>?) {
268
+ gestureInsetTopPx = gestureInsetPx(insets?.get("top"))
269
+ gestureInsetBottomPx = gestureInsetPx(insets?.get("bottom"))
270
+ gestureInsetLeftPx = gestureInsetPx(insets?.get("left"))
271
+ gestureInsetRightPx = gestureInsetPx(insets?.get("right"))
272
+ }
273
+
274
+ private fun gestureInsetPx(dp: Double?): Float =
275
+ if (dp != null && dp.isFinite() && dp > 0.0) dp.toFloat() * density else 0f
276
+
277
+ /**
278
+ * True for a whole touch sequence that went down inside an inset band. The row
279
+ * leaves that sequence to its children. An open or moving row ignores the bands,
280
+ * so a swipe from any point can close it.
281
+ */
282
+ private fun passesInsetTouch(event: MotionEvent): Boolean {
283
+ if (event.actionMasked == MotionEvent.ACTION_DOWN) {
284
+ val closedAtRest = !isOpen && !isAnimating && !isDragging && currentTranslation == 0f
285
+ isInsetTouch = closedAtRest && (
286
+ gestureInsetTopPx > 0f && event.y < gestureInsetTopPx ||
287
+ gestureInsetBottomPx > 0f && event.y >= height - gestureInsetBottomPx ||
288
+ gestureInsetLeftPx > 0f && event.x < gestureInsetLeftPx ||
289
+ gestureInsetRightPx > 0f && event.x >= width - gestureInsetRightPx
290
+ )
291
+ }
292
+ return isInsetTouch
293
+ }
294
+
260
295
  var autoClose: Boolean = false
261
296
 
262
297
  var autoCloseTimeout: Float = 0f // milliseconds
@@ -516,7 +551,10 @@ class SwipeableView(context: Context, appContext: AppContext) : ExpoView(context
516
551
  */
517
552
  override fun dispatchTouchEvent(event: MotionEvent): Boolean {
518
553
  // Every native touch entry point shares the same cancellation boundary.
519
- if (suppressCancelledTouch(event)) return true
554
+ val cancelled = suppressCancelledTouch(event)
555
+ // A cancel must not cut the children off from a touch the row never took.
556
+ if (passesInsetTouch(event)) return super.dispatchTouchEvent(event)
557
+ if (cancelled) return true
520
558
  if (!gestureEnabled || !hasEnabledSide()) {
521
559
  return super.dispatchTouchEvent(event)
522
560
  }
@@ -604,7 +642,8 @@ class SwipeableView(context: Context, appContext: AppContext) : ExpoView(context
604
642
  }
605
643
 
606
644
  override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
607
- if (suppressCancelledTouch(event)) return false
645
+ val cancelled = suppressCancelledTouch(event)
646
+ if (passesInsetTouch(event) || cancelled) return false
608
647
  if (!gestureEnabled || !hasEnabledSide()) return false
609
648
 
610
649
  when (event.actionMasked) {
@@ -643,7 +682,9 @@ class SwipeableView(context: Context, appContext: AppContext) : ExpoView(context
643
682
  }
644
683
 
645
684
  override fun onTouchEvent(event: MotionEvent): Boolean {
646
- if (suppressCancelledTouch(event)) return true
685
+ val cancelled = suppressCancelledTouch(event)
686
+ if (passesInsetTouch(event)) return false
687
+ if (cancelled) return true
647
688
  if (!gestureEnabled || !hasEnabledSide()) return false
648
689
 
649
690
  velocityTracker?.addMovement(event)
@@ -1 +1 @@
1
- {"version":3,"file":"Swipeable.d.ts","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAQnB,MAAM,OAAO,CAAA;AAYd,OAAO,KAAK,EAIV,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EAIhB,MAAM,mBAAmB,CAAA;AAmQ1B,KAAK,mBAAmB,GAAG,yBAAyB,CAClD,uBAAuB,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAC1D,GACC,eAAe,CAAA;AAEjB,QAAA,MAAM,eAAe,EAAgB,mBAAmB,CAAA;AA+BxD,eAAe,eAAe,CAAA"}
1
+ {"version":3,"file":"Swipeable.d.ts","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EASnB,MAAM,OAAO,CAAA;AAYd,OAAO,KAAK,EAIV,uBAAuB,EACvB,gBAAgB,EAChB,eAAe,EAIhB,MAAM,mBAAmB,CAAA;AAgU1B,KAAK,mBAAmB,GAAG,yBAAyB,CAClD,uBAAuB,GAAG,aAAa,CAAC,gBAAgB,CAAC,CAC1D,GACC,eAAe,CAAA;AAEjB,QAAA,MAAM,eAAe,EAAgB,mBAAmB,CAAA;AA8BxD,eAAe,eAAe,CAAA"}
@@ -19,14 +19,58 @@ function normalizeRecyclingKey(key) {
19
19
  }
20
20
  return undefined;
21
21
  }
22
- const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftActions, leftActionsWidth, rightActions, rightActionsWidth, onLeftSwipeEnd, onRightSwipeEnd, appearance = 'default', hapticFeedback, friction = constants_1.SWIPE_DEFAULTS.FRICTION, threshold = constants_1.SWIPE_DEFAULTS.THRESHOLD, gestureEnabled = constants_1.SWIPE_DEFAULTS.GESTURE_ENABLED, dragOffsetFromEdge = constants_1.SWIPE_DEFAULTS.DRAG_OFFSET_FROM_EDGE, style, testID, onSwipeStart, onSwipeStateChange, onSwipeEnd, onProgress, autoClose = false, autoCloseTimeout = 0, recyclingKey }, ref) {
22
+ const mirror = (side) => (side === 'left' ? 'right' : 'left');
23
+ // A static command has only the key, so each mounted isRTL row lists its default side here.
24
+ const mirroredRows = new Map();
25
+ /** The native side for a command, `undefined` for the native default, `null` for no side. */
26
+ function nativeOpenSide(side, defaultSide) {
27
+ if (!defaultSide)
28
+ return side;
29
+ const named = side ?? defaultSide();
30
+ return named ? mirror(named) : null;
31
+ }
32
+ /** Like the native default: the right side if it is enabled, else the left side. */
33
+ function defaultOpenSide(leftWidth, rightWidth) {
34
+ if (rightWidth > 0)
35
+ return 'right';
36
+ return leftWidth > 0 ? 'left' : null;
37
+ }
38
+ function openNative(key, side) {
39
+ if (side === undefined)
40
+ (0, nativeModuleUtils_1.openByKey)(key);
41
+ else if (side)
42
+ (0, nativeModuleUtils_1.openByKeyOnSide)(key, side);
43
+ }
44
+ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftActions, leftActionsWidth, rightActions, rightActionsWidth, isRTL = false, onLeftSwipeEnd, onRightSwipeEnd, appearance = 'default', hapticFeedback, friction = constants_1.SWIPE_DEFAULTS.FRICTION, threshold = constants_1.SWIPE_DEFAULTS.THRESHOLD, gestureEnabled = constants_1.SWIPE_DEFAULTS.GESTURE_ENABLED, gestureInsets, dragOffsetFromEdge = constants_1.SWIPE_DEFAULTS.DRAG_OFFSET_FROM_EDGE, style, testID, onSwipeStart, onSwipeStateChange, onSwipeEnd, onProgress, autoClose = false, autoCloseTimeout = 0, recyclingKey }, ref) {
23
45
  const nativeRef = (0, react_1.useRef)(null);
24
- const resolved = (0, react_1.useMemo)(() => (0, resolveSwipeableActions_1.resolveSwipeableActions)({
46
+ const named = (0, react_1.useMemo)(() => (0, resolveSwipeableActions_1.resolveSwipeableActions)({
25
47
  leftActions,
26
48
  ...(leftActionsWidth !== undefined ? { leftActionsWidth } : {}),
27
49
  rightActions,
28
50
  ...(rightActionsWidth !== undefined ? { rightActionsWidth } : {})
29
51
  }), [leftActions, leftActionsWidth, rightActions, rightActionsWidth]);
52
+ // From here on `resolved` holds the native, physical sides.
53
+ const resolved = (0, react_1.useMemo)(() => (isRTL ? { ...named, left: named.right, right: named.left } : named), [isRTL, named]);
54
+ const insetProps = (0, react_1.useMemo)(() => {
55
+ if (!gestureInsets)
56
+ return null;
57
+ if (!isRTL)
58
+ return { gestureInsets };
59
+ const { left, right, ...vertical } = gestureInsets;
60
+ return {
61
+ gestureInsets: {
62
+ ...vertical,
63
+ ...(right !== undefined ? { left: right } : {}),
64
+ ...(left !== undefined ? { right: left } : {})
65
+ }
66
+ };
67
+ }, [gestureInsets, isRTL]);
68
+ // The ref handle and the static registry outlive a render, so they read through refs.
69
+ const isRTLRef = (0, react_1.useRef)(isRTL);
70
+ isRTLRef.current = isRTL;
71
+ const defaultSideRef = (0, react_1.useRef)(null);
72
+ defaultSideRef.current = defaultOpenSide(named.left.width, named.right.width);
73
+ const readDefaultSide = (0, react_1.useCallback)(() => defaultSideRef.current, []);
30
74
  // Normalize recyclingKey before hooks that depend on it
31
75
  const normalizedKey = normalizeRecyclingKey(recyclingKey);
32
76
  const recyclingKeyRef = (0, react_1.useRef)(undefined);
@@ -45,6 +89,16 @@ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftAct
45
89
  setRenderedSides((previous) => (previous.key === normalizedKey ? previous : initialSides));
46
90
  swipeStartedRef.current = false;
47
91
  }, [initialSides, normalizedKey]);
92
+ // A layout effect, so a static command from any passive mount effect sees the row.
93
+ (0, react_1.useLayoutEffect)(() => {
94
+ if (!isRTL || !normalizedKey)
95
+ return;
96
+ mirroredRows.set(normalizedKey, readDefaultSide);
97
+ return () => {
98
+ if (mirroredRows.get(normalizedKey) === readDefaultSide)
99
+ mirroredRows.delete(normalizedKey);
100
+ };
101
+ }, [isRTL, normalizedKey, readDefaultSide]);
48
102
  const warningText = resolved.warnings.join('\n');
49
103
  (0, react_1.useEffect)(() => {
50
104
  if (__DEV__ && warningText)
@@ -70,10 +124,7 @@ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftAct
70
124
  open: (side) => {
71
125
  const key = recyclingKeyRef.current;
72
126
  if (key) {
73
- if (side === undefined)
74
- (0, nativeModuleUtils_1.openByKey)(key);
75
- else
76
- (0, nativeModuleUtils_1.openByKeyOnSide)(key, side);
127
+ openNative(key, nativeOpenSide(side, isRTLRef.current ? readDefaultSide : undefined));
77
128
  }
78
129
  else if (__DEV__) {
79
130
  console.warn('[Swipeable] open() called without recyclingKey - method has no effect');
@@ -92,7 +143,7 @@ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftAct
92
143
  console.warn('[Swipeable] cancel() called without recyclingKey - method has no effect');
93
144
  }
94
145
  }
95
- }), []);
146
+ }), [readDefaultSide]);
96
147
  const handleSwipeStart = (0, react_1.useCallback)((event) => {
97
148
  // Missing metadata identifies the unkeyed native binding. It must not
98
149
  // bypass identity checks after recycling into a keyed row.
@@ -136,15 +187,16 @@ const Swipeable = (0, react_1.forwardRef)(function Swipeable({ children, leftAct
136
187
  return;
137
188
  swipeStartedRef.current = false;
138
189
  onSwipeEnd?.(event.nativeEvent.state);
139
- const side = event.nativeEvent.side;
190
+ const nativeSide = event.nativeEvent.side;
191
+ const side = isRTL && nativeSide ? mirror(nativeSide) : nativeSide;
140
192
  if (side === 'left')
141
193
  onLeftSwipeEnd?.(event.nativeEvent.state);
142
194
  if (side === 'right')
143
195
  onRightSwipeEnd?.(event.nativeEvent.state);
144
- }, [normalizedKey, onLeftSwipeEnd, onRightSwipeEnd, onSwipeEnd]);
196
+ }, [isRTL, normalizedKey, onLeftSwipeEnd, onRightSwipeEnd, onSwipeEnd]);
145
197
  return (<SwipeableView_1.SwipeableView ref={nativeRef} style={[styles.container, style]} leftActionsWidth={resolved.left.width} rightActionsWidth={resolved.right.width} onActionsNeeded={handleActionsNeeded} {...(react_native_1.Platform.OS === 'ios'
146
198
  ? { appearance, hapticFeedback: hapticFeedback ?? appearance === 'ios26' }
147
- : {})} friction={friction} threshold={threshold} gestureEnabled={gestureEnabled} dragOffsetFromEdge={dragOffsetFromEdge} autoClose={autoClose} autoCloseTimeout={autoCloseTimeout} {...(normalizedKey ? { recyclingKey: normalizedKey } : {})} {...(testID ? { testID } : {})} onSwipeStart={handleSwipeStart} onGestureCancelled={handleGestureCancelled} onSwipeProgress={handleSwipeProgress} onSwipeStateChange={handleSwipeStateChange} onSwipeEnd={handleSwipeEnd}>
199
+ : {})} friction={friction} threshold={threshold} gestureEnabled={gestureEnabled} {...insetProps} dragOffsetFromEdge={dragOffsetFromEdge} autoClose={autoClose} autoCloseTimeout={autoCloseTimeout} {...(normalizedKey ? { recyclingKey: normalizedKey } : {})} {...(testID ? { testID } : {})} onSwipeStart={handleSwipeStart} onGestureCancelled={handleGestureCancelled} onSwipeProgress={handleSwipeProgress} onSwipeStateChange={handleSwipeStateChange} onSwipeEnd={handleSwipeEnd}>
148
200
  <SwipeableActions_1.SwipeableActions key='left-slot' actionsPosition='left' {...(testID ? { testID: `${testID}-left-actions` } : {})}>
149
201
  <react_1.Fragment key={normalizedKey ?? ''}>
150
202
  {sides.left && resolved.left.width > 0 ? resolved.left.node : null}
@@ -177,10 +229,7 @@ SwipeableExport.open = (recyclingKey, side) => {
177
229
  console.warn('[Swipeable.open] recyclingKey must be a non-empty string');
178
230
  return;
179
231
  }
180
- if (side === undefined)
181
- (0, nativeModuleUtils_1.openByKey)(recyclingKey);
182
- else
183
- (0, nativeModuleUtils_1.openByKeyOnSide)(recyclingKey, side);
232
+ openNative(recyclingKey, nativeOpenSide(side, mirroredRows.get(recyclingKey)));
184
233
  };
185
234
  SwipeableExport.close = (recyclingKey, animated) => {
186
235
  if (__DEV__ && (!recyclingKey || typeof recyclingKey !== 'string')) {
@@ -1 +1 @@
1
- {"version":3,"file":"Swipeable.js","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":";;AAAA,iCAWc;AACd,+CAAyD;AACzD,2CAA4C;AAC5C,2DAO4B;AAC5B,uEAAmE;AAYnE,yDAAqD;AACrD,mDAA+C;AAE/C,SAAS,qBAAqB,CAAC,GAAgC;IAC7D,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IAEvE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,qCAAqC,CAAC,CAAA;IAC7F,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAA,kBAAU,EAA4C,SAAS,SAAS,CACxF,EACE,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,UAAU,GAAG,SAAS,EACtB,cAAc,EACd,QAAQ,GAAG,0BAAc,CAAC,QAAQ,EAClC,SAAS,GAAG,0BAAc,CAAC,SAAS,EACpC,cAAc,GAAG,0BAAc,CAAC,eAAe,EAC/C,kBAAkB,GAAG,0BAAc,CAAC,qBAAqB,EACzD,KAAK,EACL,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,gBAAgB,GAAG,CAAC,EACpB,YAAY,EACb,EACD,GAAG;IAEH,MAAM,SAAS,GAAG,IAAA,cAAM,EAAqB,IAAI,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,IAAA,eAAO,EACtB,GAAG,EAAE,CACH,IAAA,iDAAuB,EAAC;QACtB,WAAW;QACX,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,YAAY;QACZ,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,EACJ,CAAC,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,CAAC,CACjE,CAAA;IAED,wDAAwD;IACxD,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,IAAA,cAAM,EAAqB,SAAS,CAAC,CAAA;IAC7D,eAAe,CAAC,OAAO,GAAG,aAAa,CAAA;IAEvC,0EAA0E;IAC1E,MAAM,eAAe,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IACrC,MAAM,UAAU,GAAG,IAAA,eAAO,EACxB,GAAG,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAA,oCAAgB,EAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACtE,CAAC,aAAa,CAAC,CAChB,CAAA;IACD,MAAM,YAAY,GAAG,IAAA,eAAO,EAC1B,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,UAAU,KAAK,MAAM;QAC3B,KAAK,EAAE,UAAU,KAAK,OAAO;KAC9B,CAAC,EACF,CAAC,aAAa,EAAE,UAAU,CAAC,CAC5B,CAAA;IACD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAA,gBAAQ,EAAC,YAAY,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAA;IAEhF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;QAC1F,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;IACjC,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;IAEjC,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,IAAI,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,eAAe,WAAW,EAAE,CAAC,CAAA;IACxE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,SAAS,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CACV,gEAAgE;gBAC9D,kFAAkF,CACrF,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAA,2BAAmB,EACjB,GAAG,EACH,GAAG,EAAE,CAAC,CAAC;QACL,KAAK,EAAE,CAAC,QAAkB,EAAE,EAAE;YAC5B,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,8BAAU,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YAC3B,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;YACxF,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,IAAgB,EAAE,EAAE;YACzB,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,IAAI,KAAK,SAAS;oBAAE,IAAA,6BAAS,EAAC,GAAG,CAAC,CAAA;;oBACjC,IAAA,mCAAe,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;YACjC,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAA;YACvF,CAAC;QACH,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,+BAAW,EAAC,GAAG,CAAC,CAAA;gBAChB,qEAAqE;gBACrE,qEAAqE;gBACrE,sCAAsC;gBACtC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;YACjC,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;YACzF,CAAC;QACH,CAAC;KACF,CAAC,EACF,EAAE,CACH,CAAA;IAED,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAClC,CAAC,KAAsB,EAAE,EAAE;QACzB,sEAAsE;QACtE,2DAA2D;QAC3D,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC7B,eAAe,CAAC,OAAO,GAAG,IAAI,CAAA;YAC9B,YAAY,EAAE,EAAE,CAAA;QAClB,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,YAAY,CAAC,CAC9B,CAAA;IAED,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CAAC,KAAiD,EAAE,EAAE;QACpD,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;IACjC,CAAC,EACD,CAAC,aAAa,CAAC,CAChB,CAAA;IAED,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,KAAyB,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;QACnC,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;YAAE,OAAM;QAC9E,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAA;YACxE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;QAC/D,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,YAAY,EAAE,aAAa,EAAE,QAAQ,CAAC,CACxC,CAAA;IAED,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,KAAyB,EAAE,EAAE;QAC5B,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAA;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;QACrD,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC,EACD,CAAC,aAAa,EAAE,UAAU,CAAC,CAC5B,CAAA;IAED,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CAAC,KAAsB,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,kBAAkB,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC,EACD,CAAC,aAAa,EAAE,kBAAkB,CAAC,CACpC,CAAA;IAED,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,KAAsB,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;QAC/B,UAAU,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;QACnC,IAAI,IAAI,KAAK,MAAM;YAAE,cAAc,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAC9D,IAAI,IAAI,KAAK,OAAO;YAAE,eAAe,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAClE,CAAC,EACD,CAAC,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,CAAC,CAC7D,CAAA;IAED,OAAO,CACL,CAAC,6BAAa,CACZ,GAAG,CAAC,CAAC,SAAS,CAAC,CACf,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACjC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CACtC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CACxC,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,IAAI,CAAC,uBAAQ,CAAC,EAAE,KAAK,KAAK;QACxB,CAAC,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,IAAI,UAAU,KAAK,OAAO,EAAE;QAC1E,CAAC,CAAC,EAAE,CAAC,CAAC,CACR,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,cAAc,CAAC,CAAC,cAAc,CAAC,CAC/B,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CACvC,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,CACnC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC/B,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAC/B,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAC3C,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAC3C,UAAU,CAAC,CAAC,cAAc,CAAC,CAE3B;MAAA,CAAC,mCAAgB,CACf,GAAG,CAAC,WAAW,CACf,eAAe,CAAC,MAAM,CACtB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEzD;QAAA,CAAC,gBAAQ,CAAC,GAAG,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CACjC;UAAA,CAAC,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACpE;QAAA,EAAE,gBAAQ,CACZ;MAAA,EAAE,mCAAgB,CAClB;MAAA,CAAC,mCAAgB,CACf,GAAG,CAAC,YAAY,CAChB,eAAe,CAAC,OAAO,CACvB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAE1D;QAAA,CAAC,gBAAQ,CAAC,GAAG,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CACjC;UAAA,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACvE;QAAA,EAAE,gBAAQ,CACZ;MAAA,EAAE,mCAAgB,CAClB;MAAA,CAAC,mBAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAC5D;QAAA,CAAC,QAAQ,CACX;MAAA,EAAE,mBAAI,CACR;IAAA,EAAE,6BAAa,CAAC,CACjB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,uDAAuD;QACvD,8DAA8D;QAC9D,QAAQ,EAAE,uBAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KACvD;IACD,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;KACd;CACF,CAAC,CAAA;AAEF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AAQnC,MAAM,eAAe,GAAG,SAAgC,CAAA;AAExD,eAAe,CAAC,IAAI,GAAG,CAAC,YAAoB,EAAE,IAAgB,EAAE,EAAE;IAChE,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACxE,OAAM;IACR,CAAC;IACD,IAAI,IAAI,KAAK,SAAS;QAAE,IAAA,6BAAS,EAAC,YAAY,CAAC,CAAA;;QAC1C,IAAA,mCAAe,EAAC,YAAY,EAAE,IAAI,CAAC,CAAA;AAC1C,CAAC,CAAA;AAED,eAAe,CAAC,KAAK,GAAG,CAAC,YAAoB,EAAE,QAAkB,EAAE,EAAE;IACnE,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QACzE,OAAM;IACR,CAAC;IACD,IAAA,8BAAU,EAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC,CAAA;AAED,eAAe,CAAC,MAAM,GAAG,CAAC,YAAoB,EAAE,EAAE;IAChD,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;QAC1E,OAAM;IACR,CAAC;IACD,IAAA,+BAAW,EAAC,YAAY,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,eAAe,CAAC,QAAQ,GAAG,CAAC,QAAkB,EAAE,EAAE;IAChD,IAAA,4BAAQ,EAAC,QAAQ,CAAC,CAAA;AACpB,CAAC,CAAA;AAED,kBAAe,eAAe,CAAA"}
1
+ {"version":3,"file":"Swipeable.js","sourceRoot":"","sources":["../src/Swipeable.tsx"],"names":[],"mappings":";;AAAA,iCAYc;AACd,+CAAyD;AACzD,2CAA4C;AAC5C,2DAO4B;AAC5B,uEAAmE;AAYnE,yDAAqD;AACrD,mDAA+C;AAE/C,SAAS,qBAAqB,CAAC,GAAgC;IAC7D,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAA;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IAEvE,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,qCAAqC,GAAG,qCAAqC,CAAC,CAAA;IAC7F,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,IAAe,EAAa,EAAE,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnF,4FAA4F;AAC5F,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkC,CAAA;AAE9D,6FAA6F;AAC7F,SAAS,cAAc,CACrB,IAA2B,EAC3B,WAAiD;IAEjD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAA;IAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,WAAW,EAAE,CAAA;IACnC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACrC,CAAC;AAED,oFAAoF;AACpF,SAAS,eAAe,CAAC,SAAiB,EAAE,UAAkB;IAC5D,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,OAAO,CAAA;IAClC,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AACtC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,IAAkC;IACjE,IAAI,IAAI,KAAK,SAAS;QAAE,IAAA,6BAAS,EAAC,GAAG,CAAC,CAAA;SACjC,IAAI,IAAI;QAAE,IAAA,mCAAe,EAAC,GAAG,EAAE,IAAI,CAAC,CAAA;AAC3C,CAAC;AAED,MAAM,SAAS,GAAG,IAAA,kBAAU,EAA4C,SAAS,SAAS,CACxF,EACE,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,GAAG,KAAK,EACb,cAAc,EACd,eAAe,EACf,UAAU,GAAG,SAAS,EACtB,cAAc,EACd,QAAQ,GAAG,0BAAc,CAAC,QAAQ,EAClC,SAAS,GAAG,0BAAc,CAAC,SAAS,EACpC,cAAc,GAAG,0BAAc,CAAC,eAAe,EAC/C,aAAa,EACb,kBAAkB,GAAG,0BAAc,CAAC,qBAAqB,EACzD,KAAK,EACL,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,gBAAgB,GAAG,CAAC,EACpB,YAAY,EACb,EACD,GAAG;IAEH,MAAM,SAAS,GAAG,IAAA,cAAM,EAAqB,IAAI,CAAC,CAAA;IAClD,MAAM,KAAK,GAAG,IAAA,eAAO,EACnB,GAAG,EAAE,CACH,IAAA,iDAAuB,EAAC;QACtB,WAAW;QACX,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,YAAY;QACZ,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,EACJ,CAAC,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,CAAC,CACjE,CAAA;IACD,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,IAAA,eAAO,EACtB,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAC1E,CAAC,KAAK,EAAE,KAAK,CAAC,CACf,CAAA;IACD,MAAM,UAAU,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC9B,IAAI,CAAC,aAAa;YAAE,OAAO,IAAI,CAAA;QAC/B,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,aAAa,EAAE,CAAA;QACpC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,aAAa,CAAA;QAClD,OAAO;YACL,aAAa,EAAE;gBACb,GAAG,QAAQ;gBACX,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C;SACF,CAAA;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAA;IAC1B,sFAAsF;IACtF,MAAM,QAAQ,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IAC9B,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAA;IACxB,MAAM,cAAc,GAAG,IAAA,cAAM,EAAmB,IAAI,CAAC,CAAA;IACrD,cAAc,CAAC,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC7E,MAAM,eAAe,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IAErE,wDAAwD;IACxD,MAAM,aAAa,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAA;IACzD,MAAM,eAAe,GAAG,IAAA,cAAM,EAAqB,SAAS,CAAC,CAAA;IAC7D,eAAe,CAAC,OAAO,GAAG,aAAa,CAAA;IAEvC,0EAA0E;IAC1E,MAAM,eAAe,GAAG,IAAA,cAAM,EAAC,KAAK,CAAC,CAAA;IACrC,MAAM,UAAU,GAAG,IAAA,eAAO,EACxB,GAAG,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,CAAC,CAAC,IAAA,oCAAgB,EAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACtE,CAAC,aAAa,CAAC,CAChB,CAAA;IACD,MAAM,YAAY,GAAG,IAAA,eAAO,EAC1B,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,UAAU,KAAK,MAAM;QAC3B,KAAK,EAAE,UAAU,KAAK,OAAO;KAC9B,CAAC,EACF,CAAC,aAAa,EAAE,UAAU,CAAC,CAC5B,CAAA;IACD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,IAAA,gBAAQ,EAAC,YAAY,CAAC,CAAA;IAChE,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAA;IAEhF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;QAC1F,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;IACjC,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;IAEjC,mFAAmF;IACnF,IAAA,uBAAe,EAAC,GAAG,EAAE;QACnB,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa;YAAE,OAAM;QACpC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;QAChD,OAAO,GAAG,EAAE;YACV,IAAI,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,eAAe;gBAAE,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAC7F,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAA;IAE3C,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,IAAI,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,eAAe,WAAW,EAAE,CAAC,CAAA;IACxE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,8BAA8B;IAC9B,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,SAAS,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CACV,gEAAgE;gBAC9D,kFAAkF,CACrF,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAA,2BAAmB,EACjB,GAAG,EACH,GAAG,EAAE,CAAC,CAAC;QACL,KAAK,EAAE,CAAC,QAAkB,EAAE,EAAE;YAC5B,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,8BAAU,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YAC3B,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAA;YACxF,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,IAAgB,EAAE,EAAE;YACzB,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,UAAU,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;YACvF,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAA;YACvF,CAAC;QACH,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,MAAM,GAAG,GAAG,eAAe,CAAC,OAAO,CAAA;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,IAAA,+BAAW,EAAC,GAAG,CAAC,CAAA;gBAChB,qEAAqE;gBACrE,qEAAqE;gBACrE,sCAAsC;gBACtC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;YACjC,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAA;YACzF,CAAC;QACH,CAAC;KACF,CAAC,EACF,CAAC,eAAe,CAAC,CAClB,CAAA;IAED,MAAM,gBAAgB,GAAG,IAAA,mBAAW,EAClC,CAAC,KAAsB,EAAE,EAAE;QACzB,sEAAsE;QACtE,2DAA2D;QAC3D,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC7B,eAAe,CAAC,OAAO,GAAG,IAAI,CAAA;YAC9B,YAAY,EAAE,EAAE,CAAA;QAClB,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,YAAY,CAAC,CAC9B,CAAA;IAED,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CAAC,KAAiD,EAAE,EAAE;QACpD,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;IACjC,CAAC,EACD,CAAC,aAAa,CAAC,CAChB,CAAA;IAED,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,KAAyB,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;QACnC,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;YAAE,OAAM;QAC9E,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC5B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAA;YACxE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;QAC/D,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,YAAY,EAAE,aAAa,EAAE,QAAQ,CAAC,CACxC,CAAA;IAED,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,KAAyB,EAAE,EAAE;QAC5B,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAA;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;QACrD,UAAU,EAAE,CAAC,OAAO,CAAC,CAAA;IACvB,CAAC,EACD,CAAC,aAAa,EAAE,UAAU,CAAC,CAC5B,CAAA;IAED,MAAM,sBAAsB,GAAG,IAAA,mBAAW,EACxC,CAAC,KAAsB,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,kBAAkB,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC,EACD,CAAC,aAAa,EAAE,kBAAkB,CAAC,CACpC,CAAA;IAED,MAAM,cAAc,GAAG,IAAA,mBAAW,EAChC,CAAC,KAAsB,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;YAAE,OAAM;QAC3E,eAAe,CAAC,OAAO,GAAG,KAAK,CAAA;QAC/B,UAAU,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;QACzC,MAAM,IAAI,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;QAClE,IAAI,IAAI,KAAK,MAAM;YAAE,cAAc,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAC9D,IAAI,IAAI,KAAK,OAAO;YAAE,eAAe,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAClE,CAAC,EACD,CAAC,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,CAAC,CACpE,CAAA;IAED,OAAO,CACL,CAAC,6BAAa,CACZ,GAAG,CAAC,CAAC,SAAS,CAAC,CACf,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACjC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CACtC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CACxC,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,IAAI,CAAC,uBAAQ,CAAC,EAAE,KAAK,KAAK;QACxB,CAAC,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,IAAI,UAAU,KAAK,OAAO,EAAE;QAC1E,CAAC,CAAC,EAAE,CAAC,CAAC,CACR,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,cAAc,CAAC,CAAC,cAAc,CAAC,CAC/B,IAAI,UAAU,CAAC,CACf,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CACvC,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,gBAAgB,CAAC,CAAC,gBAAgB,CAAC,CACnC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC/B,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAC/B,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAC3C,eAAe,CAAC,CAAC,mBAAmB,CAAC,CACrC,kBAAkB,CAAC,CAAC,sBAAsB,CAAC,CAC3C,UAAU,CAAC,CAAC,cAAc,CAAC,CAE3B;MAAA,CAAC,mCAAgB,CACf,GAAG,CAAC,WAAW,CACf,eAAe,CAAC,MAAM,CACtB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEzD;QAAA,CAAC,gBAAQ,CAAC,GAAG,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CACjC;UAAA,CAAC,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACpE;QAAA,EAAE,gBAAQ,CACZ;MAAA,EAAE,mCAAgB,CAClB;MAAA,CAAC,mCAAgB,CACf,GAAG,CAAC,YAAY,CAChB,eAAe,CAAC,OAAO,CACvB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAE1D;QAAA,CAAC,gBAAQ,CAAC,GAAG,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CACjC;UAAA,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACvE;QAAA,EAAE,gBAAQ,CACZ;MAAA,EAAE,mCAAgB,CAClB;MAAA,CAAC,mBAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAC5D;QAAA,CAAC,QAAQ,CACX;MAAA,EAAE,mBAAI,CACR;IAAA,EAAE,6BAAa,CAAC,CACjB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,yBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,uDAAuD;QACvD,8DAA8D;QAC9D,QAAQ,EAAE,uBAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KACvD;IACD,OAAO,EAAE;QACP,KAAK,EAAE,MAAM;KACd;CACF,CAAC,CAAA;AAEF,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AAQnC,MAAM,eAAe,GAAG,SAAgC,CAAA;AAExD,eAAe,CAAC,IAAI,GAAG,CAAC,YAAoB,EAAE,IAAgB,EAAE,EAAE;IAChE,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACxE,OAAM;IACR,CAAC;IACD,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;AAChF,CAAC,CAAA;AAED,eAAe,CAAC,KAAK,GAAG,CAAC,YAAoB,EAAE,QAAkB,EAAE,EAAE;IACnE,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QACzE,OAAM;IACR,CAAC;IACD,IAAA,8BAAU,EAAC,YAAY,EAAE,QAAQ,CAAC,CAAA;AACpC,CAAC,CAAA;AAED,eAAe,CAAC,MAAM,GAAG,CAAC,YAAoB,EAAE,EAAE;IAChD,IAAI,OAAO,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,CAAC,EAAE,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAA;QAC1E,OAAM;IACR,CAAC;IACD,IAAA,+BAAW,EAAC,YAAY,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,eAAe,CAAC,QAAQ,GAAG,CAAC,QAAkB,EAAE,EAAE;IAChD,IAAA,4BAAQ,EAAC,QAAQ,CAAC,CAAA;AACpB,CAAC,CAAA;AAED,kBAAe,eAAe,CAAA"}
@@ -2,6 +2,16 @@ import type { ReactNode, Ref } from 'react';
2
2
  import type { StyleProp, ViewProps, ViewStyle } from 'react-native';
3
3
  export type SwipeSide = 'left' | 'right';
4
4
  export type SwipeAppearance = 'default' | 'ios26';
5
+ /**
6
+ * Bands along the edges of the row, in layout units (dp on Android, pt on iOS).
7
+ * A touch that starts inside a band does not start a swipe.
8
+ */
9
+ export interface GestureInsets {
10
+ top?: number;
11
+ bottom?: number;
12
+ left?: number;
13
+ right?: number;
14
+ }
5
15
  /** Internal native identity; the consumer's onSwipeStart remains zero-argument. */
6
16
  export interface SwipeStartEvent {
7
17
  nativeEvent: {
@@ -45,6 +55,7 @@ export interface SwipeableViewProps extends ViewProps {
45
55
  friction?: number;
46
56
  threshold?: number;
47
57
  gestureEnabled?: boolean;
58
+ gestureInsets?: GestureInsets;
48
59
  dragOffsetFromEdge?: number;
49
60
  recyclingKey?: string;
50
61
  onSwipeProgress?: (event: SwipeProgressEvent) => void;
@@ -68,6 +79,18 @@ export interface SwipeableCommonProps {
68
79
  friction?: number;
69
80
  threshold?: number;
70
81
  gestureEnabled?: boolean;
82
+ /**
83
+ * Mirrors the row for a right-to-left layout. The `left` props, `open('left')` and
84
+ * `onLeftSwipeEnd` then act on the right edge, and the `right` ones on the left edge.
85
+ * The `left` and `right` values of `gestureInsets` swap too.
86
+ * Defaults to `false`: the sides are physical edges in every layout direction.
87
+ */
88
+ isRTL?: boolean;
89
+ /**
90
+ * Edge bands where a touch does not start a swipe. The children handle that touch,
91
+ * for example a horizontal pager. Applies while the row is closed and at rest.
92
+ */
93
+ gestureInsets?: GestureInsets;
71
94
  dragOffsetFromEdge?: number;
72
95
  style?: StyleProp<ViewStyle>;
73
96
  testID?: string;
@@ -82,7 +105,7 @@ export interface SwipeableCommonProps {
82
105
  }
83
106
  export interface SwipeableMethods {
84
107
  close: (animated?: boolean) => void;
85
- /** Open the requested physical edge; without a side, prefer enabled right, then left. */
108
+ /** Open the requested side; without a side, prefer enabled right, then left. */
86
109
  open: (side?: SwipeSide) => void;
87
110
  cancel: () => void;
88
111
  }
@@ -93,24 +116,28 @@ export interface SwipeableStatic {
93
116
  closeAll: (animated?: boolean) => void;
94
117
  }
95
118
  type LeftActionsConfiguration = {
96
- leftActions: ReactNode;
119
+ leftActions?: ReactNode;
97
120
  leftActionsWidth: number;
98
121
  } | {
99
122
  leftActions?: null | false | undefined;
100
123
  leftActionsWidth?: never;
101
124
  };
102
125
  type RightActionsConfiguration = {
103
- rightActions: ReactNode;
126
+ rightActions?: ReactNode;
104
127
  rightActionsWidth: number;
105
128
  } | {
106
129
  rightActions?: null | false | undefined;
107
130
  rightActionsWidth?: never;
108
131
  };
109
- /** The sole action API: explicit physical-edge pairs, including single-sided rows. */
132
+ /** The sole action API: explicit side pairs, physical edges unless `isRTL` mirrors them. */
110
133
  export type SwipeableProps = SwipeableCommonProps & LeftActionsConfiguration & RightActionsConfiguration & ({
111
134
  leftActions: ReactNode;
112
135
  } | {
113
136
  rightActions: ReactNode;
137
+ } | {
138
+ leftActionsWidth: number;
139
+ } | {
140
+ rightActionsWidth: number;
114
141
  });
115
142
  /** Descriptive alias for the same explicit-side API, not a separate implementation. */
116
143
  export type TwoSidedSwipeableProps = SwipeableProps;
@@ -1 +1 @@
1
- {"version":3,"file":"Swipeable.types.d.ts","sourceRoot":"","sources":["../src/Swipeable.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Swipeable.types.d.ts","sourceRoot":"","sources":["../src/Swipeable.types.ts"],"names":[],"mappings":"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"}
package/build/index.d.ts CHANGED
@@ -2,6 +2,6 @@ export { SWIPE_DEFAULTS, SWIPE_PROGRESS } from './constants';
2
2
  export type { NativeModuleError, SwipeableErrorHandler } from './nativeModuleUtils';
3
3
  export { setGlobalErrorHandler } from './nativeModuleUtils';
4
4
  export { default as Swipeable } from './Swipeable';
5
- export type { ActionsNeededEvent, NativeSwipeableRef, SwipeAppearance, SwipeSide, SwipeableCommonProps, SwipeableComponentProps, TwoSidedSwipeableProps, SwipeableMethods, SwipeableProps, SwipeableStatic, SwipeableViewProps, SwipeProgressEvent, SwipeStartEvent, SwipeStateEvent } from './Swipeable.types';
5
+ export type { ActionsNeededEvent, GestureInsets, NativeSwipeableRef, SwipeAppearance, SwipeSide, SwipeableCommonProps, SwipeableComponentProps, TwoSidedSwipeableProps, SwipeableMethods, SwipeableProps, SwipeableStatic, SwipeableViewProps, SwipeProgressEvent, SwipeStartEvent, SwipeStateEvent } from './Swipeable.types';
6
6
  export { SwipeableView } from './SwipeableView';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAEnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAEnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,yCAA4D;AAAnD,2GAAA,cAAc,OAAA;AAAE,2GAAA,cAAc,OAAA;AAEvC,2BAA2B;AAC3B,yDAA2D;AAAlD,0HAAA,qBAAqB,OAAA;AAC9B,yCAAkD;AAAzC,uHAAA,OAAO,OAAa;AAiB7B,iDAA+C;AAAtC,8GAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,yCAA4D;AAAnD,2GAAA,cAAc,OAAA;AAAE,2GAAA,cAAc,OAAA;AAEvC,2BAA2B;AAC3B,yDAA2D;AAAlD,0HAAA,qBAAqB,OAAA;AAC9B,yCAAkD;AAAzC,uHAAA,OAAO,OAAa;AAkB7B,iDAA+C;AAAtC,8GAAA,aAAa,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSwipeableActions.d.ts","sourceRoot":"","sources":["../src/resolveSwipeableActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,UAAU,YAAY;IACpB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY;;;;EAiB1D"}
1
+ {"version":3,"file":"resolveSwipeableActions.d.ts","sourceRoot":"","sources":["../src/resolveSwipeableActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,UAAU,YAAY;IACpB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY;;;;EAgB1D"}
@@ -6,16 +6,16 @@ const isWidth = (width) => width !== undefined && Number.isFinite(width) && widt
6
6
  function resolveSwipeableActions(input) {
7
7
  const warnings = [];
8
8
  const resolve = (side, node, width) => {
9
+ // null and false turn a side off. undefined leaves the width in charge: an empty rail.
10
+ if (node !== undefined && !isContent(node))
11
+ return { node: null, width: 0 };
12
+ if (isWidth(width))
13
+ return { node: node ?? null, width };
9
14
  if (node !== undefined) {
10
- if (!isContent(node))
11
- return { node: null, width: 0 };
12
- if (isWidth(width))
13
- return { node, width };
14
15
  warnings.push(side + 'Actions requires a finite, positive ' + side + 'ActionsWidth.');
15
- return { node: null, width: 0 };
16
16
  }
17
- if (width !== undefined) {
18
- warnings.push(side + 'ActionsWidth is ignored without explicit ' + side + 'Actions.');
17
+ else if (width !== undefined) {
18
+ warnings.push(`${side}ActionsWidth must be finite and positive.`);
19
19
  }
20
20
  return { node: null, width: 0 };
21
21
  };
@@ -1 +1 @@
1
- {"version":3,"file":"resolveSwipeableActions.js","sourceRoot":"","sources":["../src/resolveSwipeableActions.ts"],"names":[],"mappings":";;AAmBA,0DAiBC;AArBD,MAAM,SAAS,GAAG,CAAC,IAAe,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,SAAS,CAAA;AAChF,MAAM,OAAO,GAAG,CAAC,KAAyB,EAAmB,EAAE,CAC7D,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA;AAE5D,SAAgB,uBAAuB,CAAC,KAAmB;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,CAAC,IAAe,EAAE,IAAe,EAAE,KAAc,EAAmB,EAAE;QACpF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;YACrD,IAAI,OAAO,CAAC,KAAK,CAAC;gBAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;YAC1C,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,sCAAsC,GAAG,IAAI,GAAG,eAAe,CAAC,CAAA;YACrF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;QACjC,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,2CAA2C,GAAG,IAAI,GAAG,UAAU,CAAC,CAAA;QACvF,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC3E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAClC,CAAC"}
1
+ {"version":3,"file":"resolveSwipeableActions.js","sourceRoot":"","sources":["../src/resolveSwipeableActions.ts"],"names":[],"mappings":";;AAmBA,0DAgBC;AApBD,MAAM,SAAS,GAAG,CAAC,IAAe,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,SAAS,CAAA;AAChF,MAAM,OAAO,GAAG,CAAC,KAAyB,EAAmB,EAAE,CAC7D,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA;AAE5D,SAAgB,uBAAuB,CAAC,KAAmB;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,CAAC,IAAe,EAAE,IAAe,EAAE,KAAc,EAAmB,EAAE;QACpF,uFAAuF;QACvF,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;QAC3E,IAAI,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,EAAE,CAAA;QACxD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,sCAAsC,GAAG,IAAI,GAAG,eAAe,CAAC,CAAA;QACvF,CAAC;aAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,2CAA2C,CAAC,CAAA;QACnE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACjC,CAAC,CAAA;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC3E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAClC,CAAC"}
@@ -92,13 +92,14 @@ the whole screen, for example to swipe back. Before:
92
92
  After:
93
93
 
94
94
  ```tsx
95
- <Swipeable leftActions={<View />} leftActionsWidth={width}>
95
+ <Swipeable leftActionsWidth={width}>
96
96
  <Screen />
97
97
  </Swipeable>
98
98
  ```
99
99
 
100
- In v1, `null` disables the side, so the swipe does not start. An empty `<View />`
101
- keeps the side enabled and shows nothing behind the content. See
100
+ In v1, `null` disables the side, so the swipe does not start. A width with no content
101
+ keeps the side enabled and shows nothing behind the content. This form needs 1.2.0
102
+ or later. On 1.0 and 1.1, pass an empty view: `leftActions={<View />}`. See
102
103
  [Swipe to go back](../README.md#swipe-to-go-back) for the full recipe.
103
104
 
104
105
  ## Types: removed inputs versus retained aliases
@@ -178,7 +179,8 @@ one or both explicit sides; they do not restore removed API inputs or behaviors.
178
179
 
179
180
  ## RTL and app migration checklist
180
181
 
181
- 1. Map logical start/end actions to physical left/right in your app. RTL does not
182
+ 1. Map logical start/end actions to physical left/right in your app, or pass `isRTL`
183
+ (1.2.0 or later) and let the library mirror the row. Without `isRTL`, RTL does not
182
184
  exchange the library's sides, widths, command arguments or side callbacks.
183
185
  2. Update examples, wrappers, mocks and type fixtures to complete explicit pairs.
184
186
  3. Keep action padding/gaps inside the declared width and preserve usable targets.
package/docs/support.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Support and tested configurations
2
2
 
3
- This page states what 1.0 was tested on. A configuration that is not listed here
3
+ This page states what 1.x is tested on. A configuration that is not listed here
4
4
  can work, but nobody has checked it.
5
5
 
6
6
  ## Requirements
@@ -42,18 +42,18 @@ The package declares these ranges. They are minimums, not a tested matrix.
42
42
  | iOS deployment target | 13.4 |
43
43
  | Android `minSdkVersion` | 23 |
44
44
 
45
- ## Tested for 1.0
45
+ ## Tested for 1.x
46
46
 
47
- Each 1.0 release must pass a full CI run on every configuration below. The E2E suite has 62 cases
48
- (25 single-sided, 19 two-sided, 14 RTL, 3 swipe to go back, 1 performance) plus the
47
+ Each 1.x release must pass a full CI run on every configuration below. The E2E suite has 65 cases
48
+ (25 single-sided, 21 two-sided, 14 RTL, 4 swipe to go back, 1 performance) plus the
49
49
  Maestro flows.
50
50
 
51
51
  | Area | Configuration | What ran |
52
52
  | --- | --- | --- |
53
53
  | App stack | Expo SDK 54.0, React Native 0.81.5, React 19.1.0 | Example app and a clean app that installs the packed tarball |
54
54
  | Architecture | New Architecture (Fabric), Hermes | All runs below |
55
- | Android | API 34 x86_64 emulator (Pixel 6 profile) | 62 E2E cases, Robolectric unit tests |
56
- | iOS | iOS 26.4 simulator (iPhone 17 Pro), Xcode 26.6 | 62 E2E cases, Maestro flows, Swift unit tests |
55
+ | Android | API 34 x86_64 emulator (Pixel 6 profile) | 65 E2E cases, Robolectric unit tests |
56
+ | iOS | iOS 26.4 simulator (iPhone 17 Pro), Xcode 26.6 | 65 E2E cases, Maestro flows, Swift unit tests |
57
57
  | Packaging | `npm pack` tarball in a clean Expo app | Install, type check, autolinking, release builds on both platforms |
58
58
 
59
59
  The Swift unit tests run with `swift test` on macOS in the `test-ios` CI job. They
@@ -72,7 +72,7 @@ the UIKit view on the simulator.
72
72
  ## Not tested
73
73
 
74
74
  - iOS versions below the simulator runtime above, and Android API levels other than 34.
75
- - Physical Android devices for 1.0. Earlier 0.x benchmarks used a Pixel 8 Pro.
75
+ - Physical Android devices for 1.x. Earlier 0.x benchmarks used a Pixel 8 Pro.
76
76
  - Automated tests of how haptics feel and how Reduce Motion behaves on a device.
77
77
  The maintainer checks them by hand on a physical iPhone. The check runs when no
78
78
  earlier check is recorded, and after a change to the iOS code, the haptics,
@@ -72,6 +72,52 @@ enum SwipeSide: String, CaseIterable {
72
72
  var sign: CGFloat { self == .left ? 1 : -1 }
73
73
  }
74
74
 
75
+ /// Bands along the row edges, in points, where a touch does not start a swipe.
76
+ struct SwipeGestureInsets: Equatable {
77
+ var top: CGFloat = 0
78
+ var bottom: CGFloat = 0
79
+ var left: CGFloat = 0
80
+ var right: CGFloat = 0
81
+
82
+ init(_ values: [String: Double]? = nil) {
83
+ top = Self.band(values?["top"])
84
+ bottom = Self.band(values?["bottom"])
85
+ left = Self.band(values?["left"])
86
+ right = Self.band(values?["right"])
87
+ }
88
+
89
+ private static func band(_ value: Double?) -> CGFloat {
90
+ guard let value = value, value.isFinite, value > 0 else { return 0 }
91
+ return CGFloat(value)
92
+ }
93
+
94
+ /// An open or moving row ignores the bands, so a swipe from any point can close it.
95
+ func blocksTouch(at point: CGPoint, in size: CGSize, isClosedAtRest: Bool) -> Bool {
96
+ guard isClosedAtRest else { return false }
97
+ return top > 0 && point.y < top
98
+ || bottom > 0 && point.y >= size.height - bottom
99
+ || left > 0 && point.x < left
100
+ || right > 0 && point.x >= size.width - right
101
+ }
102
+ }
103
+
104
+ /// The first finger of a touch sequence decides for every later finger, as Android does at ACTION_DOWN.
105
+ struct SwipeInsetTouchLatch<Touch: AnyObject> {
106
+ private struct WeakTouch {
107
+ weak var value: Touch?
108
+ }
109
+
110
+ private var touches: [WeakTouch] = []
111
+ private var blocksSequence = false
112
+
113
+ mutating func receives(_ touch: Touch, blockedIfFirst: Bool, isActive: (Touch) -> Bool) -> Bool {
114
+ touches.removeAll { $0.value.map(isActive) != true }
115
+ if touches.isEmpty { blocksSequence = blockedIfFirst }
116
+ touches.append(WeakTouch(value: touch))
117
+ return !blocksSequence
118
+ }
119
+ }
120
+
75
121
  /// Gesture-owned completion survives width reconciliation, but not commands or rebinding.
76
122
  enum SwipeAutoCloseState: Equatable {
77
123
  case waiting(side: SwipeSide, deadline: TimeInterval)
@@ -69,6 +69,10 @@ public class SwipeableModule: Module {
69
69
  view.gestureEnabled = enabled
70
70
  }
71
71
 
72
+ Prop("gestureInsets") { (view: SwipeableView, insets: [String: Double]?) in
73
+ view.gestureInsets = SwipeGestureInsets(insets)
74
+ }
75
+
72
76
  Prop("dragOffsetFromEdge") { (view: SwipeableView, offset: CGFloat) in
73
77
  view.dragOffsetFromEdge = offset
74
78
  }
@@ -325,6 +325,12 @@ public class SwipeableView: ExpoView {
325
325
  scheduleReconciliation()
326
326
  }
327
327
  }
328
+ // Read only when a touch begins: no reconciliation, so a change waits for the next touch.
329
+ var gestureInsets = SwipeGestureInsets() {
330
+ didSet { if gestureInsets != oldValue { syncInsetTouchObserver() } }
331
+ }
332
+ private var insetTouchLatch = SwipeInsetTouchLatch<UITouch>()
333
+
328
334
  /// Explicit cancellation consumes the rest of the pan and any pending reopen,
329
335
  /// but leaves the binding identity intact for later commands in the same JS turn.
330
336
  func cancelGesture() {
@@ -684,6 +690,24 @@ public class SwipeableView: ExpoView {
684
690
  return gesture
685
691
  }()
686
692
 
693
+ // UIKit skips a disabled pan's delegate, so this one feeds the inset latch and never takes a touch.
694
+ private var insetTouchObserver: UIGestureRecognizer?
695
+
696
+ /// Only a row that sets gestureInsets carries the observer.
697
+ private func syncInsetTouchObserver() {
698
+ guard gestureInsets != SwipeGestureInsets() else {
699
+ insetTouchObserver.map(removeGestureRecognizer)
700
+ return
701
+ }
702
+ let observer = insetTouchObserver ?? UIGestureRecognizer(target: nil, action: nil)
703
+ observer.delegate = self
704
+ insetTouchObserver = observer
705
+ if observer.view !== self {
706
+ observer.view?.removeGestureRecognizer(observer)
707
+ addGestureRecognizer(observer)
708
+ }
709
+ }
710
+
687
711
  // MARK: - Init and attachment
688
712
 
689
713
  public required init(appContext: AppContext? = nil) {
@@ -768,6 +792,7 @@ public class SwipeableView: ExpoView {
768
792
  panGesture.view?.removeGestureRecognizer(panGesture)
769
793
  addGestureRecognizer(panGesture)
770
794
  }
795
+ syncInsetTouchObserver()
771
796
  commitProps()
772
797
  scheduleVisualRestore()
773
798
  // A detached timer/animation must not restart and fabricate an end-open event.
@@ -1465,6 +1490,21 @@ extension SwipeableView: UIGestureRecognizerDelegate {
1465
1490
  return shouldBegin
1466
1491
  }
1467
1492
 
1493
+ public func gestureRecognizer(
1494
+ _ gestureRecognizer: UIGestureRecognizer,
1495
+ shouldReceive touch: UITouch
1496
+ ) -> Bool {
1497
+ guard gestureRecognizer === panGesture || gestureRecognizer === insetTouchObserver else { return true }
1498
+ let blocked = gestureInsets.blocksTouch(
1499
+ at: touch.location(in: self), in: bounds.size,
1500
+ isClosedAtRest: !isOpen && !isAnimating && !isDragging && currentTranslation == 0
1501
+ )
1502
+ let receives = insetTouchLatch.receives(touch, blockedIfFirst: blocked) {
1503
+ $0.phase != .ended && $0.phase != .cancelled
1504
+ }
1505
+ return gestureRecognizer === panGesture && receives
1506
+ }
1507
+
1468
1508
  public func gestureRecognizer(
1469
1509
  _ gestureRecognizer: UIGestureRecognizer,
1470
1510
  shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-swipeable-actions",
3
- "version": "1.0.0",
4
- "description": "High-performance native swipeable row component for React Native using Expo Modules",
3
+ "version": "1.2.0",
4
+ "description": "Native swipeable rows with swipe actions for React Native (iOS/Android). No Reanimated.",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
7
7
  "files": [
@@ -49,11 +49,20 @@
49
49
  "keywords": [
50
50
  "react-native",
51
51
  "expo",
52
+ "expo-module",
53
+ "ios",
54
+ "android",
55
+ "swipe",
52
56
  "swipeable",
57
+ "swipeable-row",
58
+ "swipeable-list",
59
+ "swipe-actions",
60
+ "swipe-to-delete",
61
+ "list-item",
53
62
  "gesture",
54
63
  "native",
55
- "ios",
56
- "android"
64
+ "new-architecture",
65
+ "typescript"
57
66
  ],
58
67
  "repository": {
59
68
  "type": "git",
@@ -63,7 +72,7 @@
63
72
  "bugs": {
64
73
  "url": "https://github.com/chocky335/react-native-swipeable-actions/issues"
65
74
  },
66
- "author": "chocky335",
75
+ "author": "chocky335 (https://github.com/chocky335)",
67
76
  "license": "MIT",
68
77
  "peerDependencies": {
69
78
  "expo": ">=54.0.0",
package/src/Swipeable.tsx CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  useCallback,
7
7
  useEffect,
8
8
  useImperativeHandle,
9
+ useLayoutEffect,
9
10
  useMemo,
10
11
  useRef,
11
12
  useState
@@ -46,6 +47,32 @@ function normalizeRecyclingKey(key: string | number | undefined): string | undef
46
47
  return undefined
47
48
  }
48
49
 
50
+ const mirror = (side: SwipeSide): SwipeSide => (side === 'left' ? 'right' : 'left')
51
+
52
+ // A static command has only the key, so each mounted isRTL row lists its default side here.
53
+ const mirroredRows = new Map<string, () => SwipeSide | null>()
54
+
55
+ /** The native side for a command, `undefined` for the native default, `null` for no side. */
56
+ function nativeOpenSide(
57
+ side: SwipeSide | undefined,
58
+ defaultSide: (() => SwipeSide | null) | undefined
59
+ ): SwipeSide | null | undefined {
60
+ if (!defaultSide) return side
61
+ const named = side ?? defaultSide()
62
+ return named ? mirror(named) : null
63
+ }
64
+
65
+ /** Like the native default: the right side if it is enabled, else the left side. */
66
+ function defaultOpenSide(leftWidth: number, rightWidth: number): SwipeSide | null {
67
+ if (rightWidth > 0) return 'right'
68
+ return leftWidth > 0 ? 'left' : null
69
+ }
70
+
71
+ function openNative(key: string, side: SwipeSide | null | undefined) {
72
+ if (side === undefined) openByKey(key)
73
+ else if (side) openByKeyOnSide(key, side)
74
+ }
75
+
49
76
  const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function Swipeable(
50
77
  {
51
78
  children,
@@ -53,6 +80,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
53
80
  leftActionsWidth,
54
81
  rightActions,
55
82
  rightActionsWidth,
83
+ isRTL = false,
56
84
  onLeftSwipeEnd,
57
85
  onRightSwipeEnd,
58
86
  appearance = 'default',
@@ -60,6 +88,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
60
88
  friction = SWIPE_DEFAULTS.FRICTION,
61
89
  threshold = SWIPE_DEFAULTS.THRESHOLD,
62
90
  gestureEnabled = SWIPE_DEFAULTS.GESTURE_ENABLED,
91
+ gestureInsets,
63
92
  dragOffsetFromEdge = SWIPE_DEFAULTS.DRAG_OFFSET_FROM_EDGE,
64
93
  style,
65
94
  testID,
@@ -74,7 +103,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
74
103
  ref
75
104
  ) {
76
105
  const nativeRef = useRef<NativeSwipeableRef>(null)
77
- const resolved = useMemo(
106
+ const named = useMemo(
78
107
  () =>
79
108
  resolveSwipeableActions({
80
109
  leftActions,
@@ -84,6 +113,29 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
84
113
  }),
85
114
  [leftActions, leftActionsWidth, rightActions, rightActionsWidth]
86
115
  )
116
+ // From here on `resolved` holds the native, physical sides.
117
+ const resolved = useMemo(
118
+ () => (isRTL ? { ...named, left: named.right, right: named.left } : named),
119
+ [isRTL, named]
120
+ )
121
+ const insetProps = useMemo(() => {
122
+ if (!gestureInsets) return null
123
+ if (!isRTL) return { gestureInsets }
124
+ const { left, right, ...vertical } = gestureInsets
125
+ return {
126
+ gestureInsets: {
127
+ ...vertical,
128
+ ...(right !== undefined ? { left: right } : {}),
129
+ ...(left !== undefined ? { right: left } : {})
130
+ }
131
+ }
132
+ }, [gestureInsets, isRTL])
133
+ // The ref handle and the static registry outlive a render, so they read through refs.
134
+ const isRTLRef = useRef(isRTL)
135
+ isRTLRef.current = isRTL
136
+ const defaultSideRef = useRef<SwipeSide | null>(null)
137
+ defaultSideRef.current = defaultOpenSide(named.left.width, named.right.width)
138
+ const readDefaultSide = useCallback(() => defaultSideRef.current, [])
87
139
 
88
140
  // Normalize recyclingKey before hooks that depend on it
89
141
  const normalizedKey = normalizeRecyclingKey(recyclingKey)
@@ -112,6 +164,15 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
112
164
  swipeStartedRef.current = false
113
165
  }, [initialSides, normalizedKey])
114
166
 
167
+ // A layout effect, so a static command from any passive mount effect sees the row.
168
+ useLayoutEffect(() => {
169
+ if (!isRTL || !normalizedKey) return
170
+ mirroredRows.set(normalizedKey, readDefaultSide)
171
+ return () => {
172
+ if (mirroredRows.get(normalizedKey) === readDefaultSide) mirroredRows.delete(normalizedKey)
173
+ }
174
+ }, [isRTL, normalizedKey, readDefaultSide])
175
+
115
176
  const warningText = resolved.warnings.join('\n')
116
177
  useEffect(() => {
117
178
  if (__DEV__ && warningText) console.warn(`[Swipeable] ${warningText}`)
@@ -141,8 +202,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
141
202
  open: (side?: SwipeSide) => {
142
203
  const key = recyclingKeyRef.current
143
204
  if (key) {
144
- if (side === undefined) openByKey(key)
145
- else openByKeyOnSide(key, side)
205
+ openNative(key, nativeOpenSide(side, isRTLRef.current ? readDefaultSide : undefined))
146
206
  } else if (__DEV__) {
147
207
  console.warn('[Swipeable] open() called without recyclingKey - method has no effect')
148
208
  }
@@ -160,7 +220,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
160
220
  }
161
221
  }
162
222
  }),
163
- []
223
+ [readDefaultSide]
164
224
  )
165
225
 
166
226
  const handleSwipeStart = useCallback(
@@ -220,11 +280,12 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
220
280
  if (event.nativeEvent.recyclingKey !== (normalizedKey || undefined)) return
221
281
  swipeStartedRef.current = false
222
282
  onSwipeEnd?.(event.nativeEvent.state)
223
- const side = event.nativeEvent.side
283
+ const nativeSide = event.nativeEvent.side
284
+ const side = isRTL && nativeSide ? mirror(nativeSide) : nativeSide
224
285
  if (side === 'left') onLeftSwipeEnd?.(event.nativeEvent.state)
225
286
  if (side === 'right') onRightSwipeEnd?.(event.nativeEvent.state)
226
287
  },
227
- [normalizedKey, onLeftSwipeEnd, onRightSwipeEnd, onSwipeEnd]
288
+ [isRTL, normalizedKey, onLeftSwipeEnd, onRightSwipeEnd, onSwipeEnd]
228
289
  )
229
290
 
230
291
  return (
@@ -240,6 +301,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableComponentProps>(function
240
301
  friction={friction}
241
302
  threshold={threshold}
242
303
  gestureEnabled={gestureEnabled}
304
+ {...insetProps}
243
305
  dragOffsetFromEdge={dragOffsetFromEdge}
244
306
  autoClose={autoClose}
245
307
  autoCloseTimeout={autoCloseTimeout}
@@ -302,8 +364,7 @@ SwipeableExport.open = (recyclingKey: string, side?: SwipeSide) => {
302
364
  console.warn('[Swipeable.open] recyclingKey must be a non-empty string')
303
365
  return
304
366
  }
305
- if (side === undefined) openByKey(recyclingKey)
306
- else openByKeyOnSide(recyclingKey, side)
367
+ openNative(recyclingKey, nativeOpenSide(side, mirroredRows.get(recyclingKey)))
307
368
  }
308
369
 
309
370
  SwipeableExport.close = (recyclingKey: string, animated?: boolean) => {
@@ -4,6 +4,17 @@ import type { StyleProp, ViewProps, ViewStyle } from 'react-native'
4
4
  export type SwipeSide = 'left' | 'right'
5
5
  export type SwipeAppearance = 'default' | 'ios26'
6
6
 
7
+ /**
8
+ * Bands along the edges of the row, in layout units (dp on Android, pt on iOS).
9
+ * A touch that starts inside a band does not start a swipe.
10
+ */
11
+ export interface GestureInsets {
12
+ top?: number
13
+ bottom?: number
14
+ left?: number
15
+ right?: number
16
+ }
17
+
7
18
  /** Internal native identity; the consumer's onSwipeStart remains zero-argument. */
8
19
  export interface SwipeStartEvent {
9
20
  nativeEvent: { recyclingKey?: string; side?: SwipeSide }
@@ -46,6 +57,7 @@ export interface SwipeableViewProps extends ViewProps {
46
57
  friction?: number
47
58
  threshold?: number
48
59
  gestureEnabled?: boolean
60
+ gestureInsets?: GestureInsets
49
61
  dragOffsetFromEdge?: number
50
62
  recyclingKey?: string
51
63
  onSwipeProgress?: (event: SwipeProgressEvent) => void
@@ -70,6 +82,18 @@ export interface SwipeableCommonProps {
70
82
  friction?: number
71
83
  threshold?: number
72
84
  gestureEnabled?: boolean
85
+ /**
86
+ * Mirrors the row for a right-to-left layout. The `left` props, `open('left')` and
87
+ * `onLeftSwipeEnd` then act on the right edge, and the `right` ones on the left edge.
88
+ * The `left` and `right` values of `gestureInsets` swap too.
89
+ * Defaults to `false`: the sides are physical edges in every layout direction.
90
+ */
91
+ isRTL?: boolean
92
+ /**
93
+ * Edge bands where a touch does not start a swipe. The children handle that touch,
94
+ * for example a horizontal pager. Applies while the row is closed and at rest.
95
+ */
96
+ gestureInsets?: GestureInsets
73
97
  dragOffsetFromEdge?: number
74
98
  style?: StyleProp<ViewStyle>
75
99
  testID?: string
@@ -85,7 +109,7 @@ export interface SwipeableCommonProps {
85
109
 
86
110
  export interface SwipeableMethods {
87
111
  close: (animated?: boolean) => void
88
- /** Open the requested physical edge; without a side, prefer enabled right, then left. */
112
+ /** Open the requested side; without a side, prefer enabled right, then left. */
89
113
  open: (side?: SwipeSide) => void
90
114
  cancel: () => void
91
115
  }
@@ -97,19 +121,25 @@ export interface SwipeableStatic {
97
121
  closeAll: (animated?: boolean) => void
98
122
  }
99
123
 
124
+ // A width enables its side. Content is optional: without it the rail is empty.
100
125
  type LeftActionsConfiguration =
101
- | { leftActions: ReactNode; leftActionsWidth: number }
126
+ | { leftActions?: ReactNode; leftActionsWidth: number }
102
127
  | { leftActions?: null | false | undefined; leftActionsWidth?: never }
103
128
 
104
129
  type RightActionsConfiguration =
105
- | { rightActions: ReactNode; rightActionsWidth: number }
130
+ | { rightActions?: ReactNode; rightActionsWidth: number }
106
131
  | { rightActions?: null | false | undefined; rightActionsWidth?: never }
107
132
 
108
- /** The sole action API: explicit physical-edge pairs, including single-sided rows. */
133
+ /** The sole action API: explicit side pairs, physical edges unless `isRTL` mirrors them. */
109
134
  export type SwipeableProps = SwipeableCommonProps &
110
135
  LeftActionsConfiguration &
111
136
  RightActionsConfiguration &
112
- ({ leftActions: ReactNode } | { rightActions: ReactNode })
137
+ (
138
+ | { leftActions: ReactNode }
139
+ | { rightActions: ReactNode }
140
+ | { leftActionsWidth: number }
141
+ | { rightActionsWidth: number }
142
+ )
113
143
 
114
144
  /** Descriptive alias for the same explicit-side API, not a separate implementation. */
115
145
  export type TwoSidedSwipeableProps = SwipeableProps
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ export { setGlobalErrorHandler } from './nativeModuleUtils'
5
5
  export { default as Swipeable } from './Swipeable'
6
6
  export type {
7
7
  ActionsNeededEvent,
8
+ GestureInsets,
8
9
  NativeSwipeableRef,
9
10
  SwipeAppearance,
10
11
  SwipeSide,
@@ -20,14 +20,13 @@ const isWidth = (width: number | undefined): width is number =>
20
20
  export function resolveSwipeableActions(input: ActionsInput) {
21
21
  const warnings: string[] = []
22
22
  const resolve = (side: SwipeSide, node: ReactNode, width?: number): ResolvedActions => {
23
+ // null and false turn a side off. undefined leaves the width in charge: an empty rail.
24
+ if (node !== undefined && !isContent(node)) return { node: null, width: 0 }
25
+ if (isWidth(width)) return { node: node ?? null, width }
23
26
  if (node !== undefined) {
24
- if (!isContent(node)) return { node: null, width: 0 }
25
- if (isWidth(width)) return { node, width }
26
27
  warnings.push(side + 'Actions requires a finite, positive ' + side + 'ActionsWidth.')
27
- return { node: null, width: 0 }
28
- }
29
- if (width !== undefined) {
30
- warnings.push(side + 'ActionsWidth is ignored without explicit ' + side + 'Actions.')
28
+ } else if (width !== undefined) {
29
+ warnings.push(`${side}ActionsWidth must be finite and positive.`)
31
30
  }
32
31
  return { node: null, width: 0 }
33
32
  }