Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ enum EAnimationType {
'right-swipe' = 'right-swipe', // Reveals content when swiping right
'left-right-swipe' = 'left-right-swipe', // Reveals content when swiping either direction
'right-full-swipe' = 'right-full-swipe', // Triggers action on full right swipe
'left-full-swipe' = 'left-full-swipe' // Triggers action on full left swipe
'left-full-swipe' = 'left-full-swipe', // Triggers action on full left swipe
'combo-left-swipe' = 'combo-left-swipe', // Combines full left swipe with left swipe actions (e.g. iOS notifications)
}
```

Expand Down
2 changes: 1 addition & 1 deletion example/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const SONGS = [
title: 'Viva La Vida',
singer: 'Coldplay',
imageSrc: 'https://i.ytimg.com/vi/dvgZkm1xWPE/maxresdefault.jpg',
type: EAnimationType['left-right-swipe'],
type: EAnimationType['combo-left-swipe'],
},
{
id: 3,
Expand Down
7 changes: 5 additions & 2 deletions example/src/screens/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const List = () => {
animationType={item.type}
leftSwipeView={
item.type === EAnimationType['left-swipe'] ||
item.type === EAnimationType['left-right-swipe'] ? (
item.type === EAnimationType['left-right-swipe'] ||
item.type === EAnimationType['combo-left-swipe'] ? (
<View style={{ flexDirection: 'row', height: '100%' }}>
<TouchableOpacity
style={[
Expand Down Expand Up @@ -104,7 +105,8 @@ export const List = () => {
) : undefined
}
leftFullSwipeView={
item.type === EAnimationType['left-full-swipe'] ? (
item.type === EAnimationType['left-full-swipe'] ||
item.type === EAnimationType['combo-left-swipe'] ? (
<View
style={[
styles.reavealView,
Expand Down Expand Up @@ -139,6 +141,7 @@ export const List = () => {
</SwipeableItemWrapper>
)}
keyExtractor={(item) => item.id.toString()}
contentContainerStyle={styles.listContentContainer}
/>
</View>
);
Expand Down
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-swipe-reveal",
"version": "0.1.6",
"version": "0.2.0",
"description": "✨ Buttery-smooth Swipeable Wrapper for React Native - Powered by Reanimated V3 ✨",
"source": "./src/index.tsx",
"main": "./lib/commonjs/index.js",
Expand Down Expand Up @@ -56,6 +56,12 @@
"url": "git+https://github.com/varunkukade/react-native-swipe-reveal.git"
},
"author": "varunkukade <varunkukade999@gmail.com> (https://github.com/varunkukade)",
"contributors": [
{
"name": "savaughn",
"url": "https://github.com/savaughn"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/varunkukade/react-native-swipe-reveal/issues"
Expand All @@ -65,6 +71,7 @@
"registry": "https://registry.npmjs.org/"
},
"devDependencies": {
"@babel/runtime": "^7.27.6",
"@commitlint/config-conventional": "^17.0.2",
"@evilmartians/lefthook": "^1.5.0",
"@react-native-community/cli": "15.0.1",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
packages:
- 'example'
- '.'
2 changes: 1 addition & 1 deletion src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
it.todo('write a test');
it.todo('write a test');
10 changes: 9 additions & 1 deletion src/components/GestureDetectorComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ export const GestureDetectorComponent = ({
return animationType === EAnimationType['right-full-swipe'];
}, [animationType]);

const isComboLeftSwipe = useMemo(() => {
return (
animationType === EAnimationType['combo-left-swipe'] &&
leftSwipeViewWidth !== 0
);
}, [animationType, leftSwipeViewWidth, rightSwipeViewWidth]);

const { panXAnimatedStyles, panXGesture } = usePanXGesture(
leftSwipeViewWidth,
rightSwipeViewWidth,
Expand All @@ -52,10 +59,11 @@ export const GestureDetectorComponent = ({
isRightSwipe,
isLeftFullSwipe,
isRightFullSwipe,
isComboLeftSwipe,
itemWidth
);

return isLeftSwipe || isRightSwipe || isLeftFullSwipe || isRightFullSwipe ? (
return isLeftSwipe || isRightSwipe || isLeftFullSwipe || isRightFullSwipe || isComboLeftSwipe ? (
<GestureDetector gesture={panXGesture}>
<Animated.View
style={[
Expand Down
3 changes: 2 additions & 1 deletion src/components/SwipeRevealWrapper/SwipeRevealWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export const SwipeableItemWrapperComponent = ({
{children}
</GestureDetectorComponent>
{(animationType === EAnimationType['left-swipe'] ||
animationType === EAnimationType['left-right-swipe']) &&
animationType === EAnimationType['left-right-swipe'] ||
animationType === EAnimationType['combo-left-swipe']) &&
leftSwipeView ? (
<View
onLayout={onLayoutLeftSwipeView}
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum EAnimationType {
'left-right-swipe' = 'left-right-swipe',
'right-full-swipe' = 'right-full-swipe',
'left-full-swipe' = 'left-full-swipe',
'combo-left-swipe' = 'combo-left-swipe',
}

export const ANIMATION_DURATION = 200;
Expand Down
104 changes: 72 additions & 32 deletions src/hooks/usePanXGesture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const usePanXGesture = (
isRightSwipe: boolean,
isLeftFullSwipe: boolean,
isRightFullSwipe: boolean,
isComboLeftSwipe: boolean,
itemWidth: number
) => {
//this is used to make scrollview active with pangesture
Expand Down Expand Up @@ -145,18 +146,30 @@ export const usePanXGesture = (
}
}
if (dragDirectionShared.value === EDraggingDirection.left) {
if (!isLeftSwipe && !isLeftFullSwipe) {
return;
}
if (dragX < 0) {
if (isLeftSwipe && getLeftPanX(dragX) > leftSwipeViewWidth) {
return;
if (isComboLeftSwipe) {
if (dragX < 0) {
// Limit to leftSwipeViewWidth for half swipe, allow up to -itemWidth for full swipe
if (getLeftPanX(dragX) > itemWidth) {
return;
}
offsetX.value = dragX;
} else {
resetOffsets();
}
//drag item to left
offsetX.value = dragX;
} else {
//while dragging left, if dragged to rightmost end reset values
resetOffsets();
if (!isLeftSwipe && !isLeftFullSwipe) {
return;
}
if (dragX < 0) {
if (isLeftSwipe && getLeftPanX(dragX) > leftSwipeViewWidth) {
return;
}
//drag item to left
offsetX.value = dragX;
} else {
//while dragging left, if dragged to rightmost end reset values
resetOffsets();
}
}
}
})
Expand Down Expand Up @@ -200,27 +213,9 @@ export const usePanXGesture = (
}
} else if (dragDirectionShared.value === EDraggingDirection.left) {
//moving to left side

if (isLeftSwipe) {
if (getLeftPanX(offsetX.value) >= leftSwipeViewWidth / 2) {
//move to left drag boundary

//we set -leftSwipeViewWidth, as moving from left to right, values should be negative.
offsetX.value = withTiming(-leftSwipeViewWidth, {
duration: ANIMATION_DURATION,
});
startX.value = -leftSwipeViewWidth;
} else if (getLeftPanX(offsetX.value) < leftSwipeViewWidth / 2) {
//move to rightmost end
resetOffsets(ANIMATION_DURATION);
}
}

if (isLeftFullSwipe) {
if (isComboLeftSwipe) {
if (getLeftPanX(offsetX.value) >= itemWidth / 2) {
//move to leftmost end and remove item

//we set -itemWidth, as moving from left to right, values should be negative.
// Full swipe: move off screen and call function
offsetX.value = withTiming(
-itemWidth,
{
Expand All @@ -233,10 +228,55 @@ export const usePanXGesture = (
}
);
startX.value = -itemWidth;
} else if (getLeftPanX(offsetX.value) < itemWidth / 2) {
//move to rightmost end
} else if (getLeftPanX(offsetX.value) >= leftSwipeViewWidth / 2) {
// Half swipe: snap to leftSwipeViewWidth
offsetX.value = withTiming(-leftSwipeViewWidth, {
duration: ANIMATION_DURATION,
});
startX.value = -leftSwipeViewWidth;
} else {
// Not enough swipe: reset
resetOffsets(ANIMATION_DURATION);
}
} else {

if (isLeftSwipe) {
if (getLeftPanX(offsetX.value) >= leftSwipeViewWidth / 2) {
//move to left drag boundary

//we set -leftSwipeViewWidth, as moving from left to right, values should be negative.
offsetX.value = withTiming(-leftSwipeViewWidth, {
duration: ANIMATION_DURATION,
});
startX.value = -leftSwipeViewWidth;
} else if (getLeftPanX(offsetX.value) < leftSwipeViewWidth / 2) {
//move to rightmost end
resetOffsets(ANIMATION_DURATION);
}
}

if (isLeftFullSwipe) {
if (getLeftPanX(offsetX.value) >= itemWidth / 2) {
//move to leftmost end and remove item

//we set -itemWidth, as moving from left to right, values should be negative.
offsetX.value = withTiming(
-itemWidth,
{
duration: ANIMATION_DURATION,
},
() => {
if (typeof onLeftFullSwipe === 'function') {
runOnJS(onLeftFullSwipe)(id);
}
}
);
startX.value = -itemWidth;
} else if (getLeftPanX(offsetX.value) < itemWidth / 2) {
//move to rightmost end
resetOffsets(ANIMATION_DURATION);
}
}
}
} else {
//reset all values
Expand Down