Skip to content
Draft
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
47 changes: 47 additions & 0 deletions .github/workflows/publish-expo-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: 📲 Publish Expo example

# Publishes the Expo example app as an EAS Update so it can be opened in
# Expo Go via the QR code in the README / docs. Requires an EXPO_TOKEN
# repository secret (create a free token at https://expo.dev/settings/access-tokens).

on:
push:
branches: [main]
paths:
- 'example/expo/**'
- 'packages/react-native-sortables/src/**'
- '.github/workflows/publish-expo-example.yml'
workflow_dispatch:

concurrency:
group: publish-expo-example
cancel-in-progress: true

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: 🛒 Checkout code
uses: actions/checkout@v4

- name: 🔧 Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'

- name: 🚀 Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: 📦 Install dependencies
run: yarn install --immutable

- name: 📲 Publish EAS Update
working-directory: example/expo
run: eas update --channel production --message "${UPDATE_MESSAGE:-Manual publish}" --environment production --non-interactive
env:
UPDATE_MESSAGE: ${{ github.event.head_commit.message }}
24 changes: 0 additions & 24 deletions .yarn/patches/react-native-reanimated-npm-4.1.3-f13c1e8648.patch

This file was deleted.

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@

React Native Sortables is a powerful and easy-to-use library that brings smooth, intuitive content reordering to React Native. It provides specialized components whose children can be dynamically reordered through natural dragging gestures.

## Try it in Expo Go

Install [Expo Go](https://expo.dev/go) and scan the QR code below to open the example app on your device:

<p align="center">
<img src="https://raw.githubusercontent.com/MatiPl01/react-native-sortables/main/packages/docs/static/img/expo-go-qr.png" width="200" alt="Open the example app in Expo Go" />
</p>

## Key Features

- 🎯 **Flexible Layouts**
Expand Down
5 changes: 3 additions & 2 deletions example/app/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ const config: JestConfigWithTsJest = {
fakeTimers: {
enableGlobally: true
},
moduleDirectories: ['../../node_modules', '<rootDir>'],
moduleDirectories: ['node_modules', '../../node_modules', '<rootDir>'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths ?? {}, {
prefix: '<rootDir>/'
}),
preset: 'react-native',
preset: '@react-native/jest-preset',
resolver: 'react-native-worklets/jest/resolver.js',
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
transform: {
'^.+\\.jsx?$': [
Expand Down
33 changes: 17 additions & 16 deletions example/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,40 @@
"@react-navigation/bottom-tabs": "7.3.10",
"@react-navigation/native": "7.0.14",
"@react-navigation/native-stack": "7.2.0",
"@shopify/flash-list": "2.0.3",
"react": "19.1.0",
"react-native": "0.81.4",
"react-native-gesture-handler": "2.28.0",
"@shopify/flash-list": "2.0.2",
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-gesture-handler": "2.31.1",
"react-native-haptic-feedback": "2.3.3",
"react-native-reanimated": "patch:react-native-reanimated@npm%3A4.1.3#~/.yarn/patches/react-native-reanimated-npm-4.1.3-f13c1e8648.patch",
"react-native-safe-area-context": "5.3.0",
"react-native-screens": "4.15.4",
"react-native-reanimated": "4.4.1",
"react-native-safe-area-context": "5.7.0",
"react-native-screens": "4.25.2",
"react-native-sortables": "workspace:*",
"react-native-svg": "15.12.1",
"react-native-worklets": "0.5.0"
"react-native-svg": "15.15.4",
"react-native-worklets": "0.9.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@gorhom/portal": "^1.0.14",
"@react-native-community/cli": "19.1.2",
"@react-native-community/cli-platform-android": "20.0.0",
"@react-native-community/cli-platform-ios": "20.0.0",
"@react-native/babel-preset": "0.81.4",
"@react-native/metro-config": "0.81.4",
"@react-native-community/cli": "20.1.0",
"@react-native-community/cli-platform-android": "20.1.0",
"@react-native-community/cli-platform-ios": "20.1.0",
"@react-native/babel-preset": "0.85.3",
"@react-native/jest-preset": "0.85.3",
"@react-native/metro-config": "0.85.3",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/react-native": "^12.5.1",
"@types/react": "^19.1.0",
"@types/react": "^19.2.0",
"@types/react-test-renderer": "^19.1.0",
"babel-plugin-module-resolver": "^5.0.2",
"eslint": "^9.28.0",
"jest": "^29.7.0",
"lint-staged": "^15.5.0",
"madge": "^8.0.0",
"prettier": "^3.3.2",
"react-test-renderer": "19.1.0",
"react-test-renderer": "19.2.3",
"typescript": "^5.8.3"
},
"lint-staged": {
Expand Down
5 changes: 3 additions & 2 deletions example/app/src/components/inputs/TabSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback } from 'react';
import type { ViewStyle } from 'react-native';
import type { StyleProp, ViewStyle } from 'react-native';
import { StyleSheet, TouchableOpacity, View } from 'react-native';
import type { AnimatedStyle } from 'react-native-reanimated';
import Animated, {
interpolateColor,
runOnUI,
Expand Down Expand Up @@ -74,7 +75,7 @@ export default function TabSelector<T extends number | string>({
type TabProps<T> = {
isSelected: boolean;
tab: T;
style: ViewStyle;
style: StyleProp<AnimatedStyle<ViewStyle>>;
onSelectTab: (tab: T) => void;
onMeasureWidth: (width: number) => void;
};
Expand Down
8 changes: 6 additions & 2 deletions example/app/src/components/misc/ActionSheetDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,12 @@ function Backdrop({ handleClose }: BackdropProps): JSX.Element {

const styles = StyleSheet.create({
backdrop: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0, 0, 0, 0.2)'
backgroundColor: 'rgba(0, 0, 0, 0.2)',
bottom: 0,
left: 0,
position: 'absolute',
right: 0,
top: 0
},
scrollBarThumb: {
backgroundColor: 'rgba(0, 0, 0, 0.5)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function ScrollViewExample() {
}

function FlatListExample() {
const scrollableRef = useAnimatedRef<Animated.FlatList<string>>();
const scrollableRef = useAnimatedRef<FlatList<string>>();

return (
<AnimatedFlatList
Expand Down Expand Up @@ -139,10 +139,10 @@ function FlashListExample() {

type CategoriesSectionProps = {
scrollableRef:
| AnimatedRef<Animated.FlatList>
| AnimatedRef<Animated.ScrollView>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
| AnimatedRef<FlashListRef<any>>;
| AnimatedRef<FlashListRef<any>>
| AnimatedRef<FlatList<string>>;
};

function ManyCategories({ scrollableRef }: CategoriesSectionProps) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function ScrollViewExample() {
}

function FlatListExample() {
const scrollableRef = useAnimatedRef<Animated.FlatList<string>>();
const scrollableRef = useAnimatedRef<FlatList<string>>();

return (
<AnimatedFlatList
Expand Down Expand Up @@ -140,10 +140,10 @@ function FlashListExample() {

type CardsSectionProps = {
scrollableRef:
| AnimatedRef<Animated.FlatList>
| AnimatedRef<Animated.ScrollView>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
| AnimatedRef<FlashListRef<any>>;
| AnimatedRef<FlashListRef<any>>
| AnimatedRef<FlatList<string>>;
};

function ManyCards({ scrollableRef }: CardsSectionProps) {
Expand Down
11 changes: 11 additions & 0 deletions example/expo/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@
},
"web": {
"favicon": "./assets/favicon.png"
},
"extra": {
"eas": {
"projectId": "219b2578-ff49-49c2-9e9c-72f481b378bb"
}
},
"runtimeVersion": {
"policy": "appVersion"
},
"updates": {
"url": "https://u.expo.dev/219b2578-ff49-49c2-9e9c-72f481b378bb"
}
}
}
29 changes: 29 additions & 0 deletions example/expo/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Don't edit this file directly if you don't have to.
* Modify the babel config file in the project root directory.
*/
const path = require('path');

const appDir = path.resolve(__dirname, '../app');

module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
'@babel/plugin-transform-export-namespace-from',
[
'module-resolver',
{
root: ['./'],
extensions: ['.ts', '.tsx', '.svg', '.json'],
// This needs to be mirrored in ../app/tsconfig.json
alias: {
'@': path.join(appDir, 'src')
}
}
],
'react-native-worklets/plugin'
]
};
};
17 changes: 17 additions & 0 deletions example/expo/eas.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"cli": {
"version": ">= 12.0.0",
"appVersionSource": "local"
},
"build": {
"preview": {
"channel": "preview"
},
"production": {
"channel": "production"
}
},
"submit": {
"production": {}
}
}
18 changes: 10 additions & 8 deletions example/expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
"name": "example-expo",
"version": "1.0.0",
"dependencies": {
"expo": "54.0.20",
"expo-status-bar": "~3.0.8",
"react": "19.1.0",
"react-native": "0.81.5",
"react-native-gesture-handler": "~2.28.0",
"react-native-reanimated": "~4.1.1",
"react-native-worklets": "0.5.1"
"expo": "56.0.9",
"expo-haptics": "~56.0.3",
"expo-status-bar": "~56.0.4",
"expo-updates": "~56.0.18",
"react": "19.2.3",
"react-native": "0.85.3",
"react-native-gesture-handler": "~2.31.1",
"react-native-reanimated": "4.4.1",
"react-native-worklets": "0.9.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@types/react": "~19.1.10",
"@types/react": "~19.2.0",
"typescript": "~5.9.2"
},
"installConfig": {
Expand Down
2 changes: 1 addition & 1 deletion example/fabric/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "example-fabric",
"version": "1.0.0",
"dependencies": {
"react-native": "0.81.4",
"react-native": "0.85.3",
"react-native-sortables": "workspace:*"
},
"installConfig": {
Expand Down
3 changes: 2 additions & 1 deletion example/paper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"version": "1.0.0",
"dependencies": {
"@shopify/flash-list": "1.8.3",
"react": "19.1.0",
"react-native": "0.81.4",
"react-native-reanimated": "3.19.3",
"react-native-reanimated": "3.19.5",
"react-native-sortables": "workspace:*"
},
"installConfig": {
Expand Down
10 changes: 5 additions & 5 deletions example/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"name": "example-web",
"version": "0.0.1",
"dependencies": {
"expo": "^54.0.7",
"react-dom": "19.1.0",
"react-native": "0.81.4",
"expo": "56.0.9",
"react-dom": "19.2.3",
"react-native": "0.85.3",
"react-native-sortables": "workspace:*",
"react-native-web": "0.21.1"
},
"devDependencies": {
"@expo/metro-runtime": "~6.1.2",
"babel-preset-expo": "~54.0.0",
"@expo/metro-runtime": "~56.0.14",
"babel-preset-expo": "~56.0.0",
"serve": "^14.2.4"
},
"installConfig": {
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,8 @@
"example/web",
"packages/react-native-sortables"
]
},
"resolutions": {
"@types/react": "19.2.17"
}
}
6 changes: 6 additions & 0 deletions packages/docs/docs/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import bannerVideo from '@site/static/video/banner.mp4';

**React Native Sortables** is a library for smooth **drag-and-drop reordering** of items. It offers ready-to-use **sortable components** with **intuitive gesture-based reordering**, working seamlessly across iOS and Android platforms.

## 📱 Try it in Expo Go

Install [Expo Go](https://expo.dev/go) and scan the QR code below to open the example app on your phone — no setup required:

<img src="/img/expo-go-qr.png" width="220" alt="Open the example app in Expo Go" />

## ⭐ Key Features

### 🎯 Flexible Layouts
Expand Down
Binary file added packages/docs/static/img/expo-go-qr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading