npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-drag-n-drop-everywhere

v1.4.8

Published

Scrollable React Native Draglist library that doesn't use Flatlist, which sometimes may cause re-render issues. Designed to work on Web, iOS & Android.

Downloads

149

Readme

react-native-drag-n-drop-everywhere

A scrollable React Native drag-and-drop library that doesn't use FlatList, which can sometimes cause re-render issues. Designed to work on Web, iOS, and Android.
Built with react-native-reanimated and react-native-gesture-handler. Supports custom item rendering, grips for drag initiation, and more.

| Web Preview | iOS Preview | Android Preview | | ----------- | ----------- | --------------- | | | | |

Live Demo

Installation

npm install react-native-drag-n-drop-everywhere

Ensure you have installed and configured the following:

  • react-native-reanimated
  • react-native-gesture-handler
  • (Optional) For haptic feedback on iOS: expo-haptics

For setup instructions, refer to their documentation:

Usage

import { Platform, Text, View } from 'react-native';
import DragList from 'react-native-drag-n-drop-everywhere';
import { runOnJS } from 'react-native-reanimated';
import * as Haptics from 'expo-haptics';

const MyDragList = () => {
  const dataIDsArray = [
    "95a6885b-64ab-468c-9334-62c4095df459",
    "b592f039-b4d6-420a-b731-0964172ed142",
    "dba923d8-6743-47ab-8923-8e45eacdb204",
  ];

  const data = {
    "95a6885b-64ab-468c-9334-62c4095df459": 
      { title: 'Entertainment', type: "CATEGORY_TYPE_EXPENSES" },
    "b592f039-b4d6-420a-b731-0964172ed142": 
      { title: 'Groceries', type: "CATEGORY_TYPE_EXPENSES" },
    "dba923d8-6743-47ab-8923-8e45eacdb204": 
      { title: 'Sport', type: "CATEGORY_TYPE_EXPENSES" },
  };

  const renderItem = ({ item }) => (
    <View style={{ paddingHorizontal: 20 }}>
      <Text>{data[item].title}</Text>
      <Text>{data[item].type}</Text>
    </View>
  );

  const renderGrip = () => (
      <Text style={{ fontSize: 30, lineHeight: 30, fontWeight: "600" }}>:::</Text>
  );

  const onUpdateCallback = (newSortedData) => {
    // Do not change dataIDsArray directly in useState. It will cause two-way binding and extra re-renders. 
    // Instead, dispatch this value
    console.log(newSortedData);
  };

  return (
    <DragList
      dataIDs={dataIDsArray}                  // Array of IDs, required
      renderItem={renderItem}                 // Required
      callbackNewDataIds={onUpdateCallback}   // Required, callback for sorted result (dataIDs)
      renderGrip={renderGrip}

      style={{ paddingTop: 100 }}
      contentContainerStyle={{ paddingHorizontal: 10 }}
      itemContainerStyle={{ borderWidth: 2 }}

      itemsGap={10}
      itemHeight={60}
      itemBorderRadius={8}
      backgroundOnHold={"#f0f0f0"}
      passVibration={() => {
        if (Platform.OS === 'ios') {
          runOnJS(Haptics.impactAsync)(
            Haptics.ImpactFeedbackStyle.Medium
          );
        }
      }}
    />
  );
};

Preventing Extra Re-renders (Optional)

If you're using global state (e.g., Redux) to store arrayIDs and update them in callbackNewDataIds, and you want to prevent extra re-renders of your DragList component, use this approach in the parent component:


import { useStore } from 'react-redux';
import { useState } from 'react';
import { useFocusEffect } from '@react-navigation/native'

const ParentComponent = () => {
  const store = useStore();
  const [items, setItems] = useState(null);

  useFocusEffect(() => { // or, useEffect if you don't want to focus it onGoback / etc
    const state = store.getState();
    const itemsIDs = state.categories.itemsIds; // your itemsIds in state
    setItems(itemsIDs.slice()); // slice to avoid direct reference
  });

  if (!items) return null;

  return (
    // Your parent component JSX
  );
};

Props

| Prop | Type | Default | Required | Description | |------------------------|------------|------------|----------|-----------------------------------------------------------------------------| | dataIDs | Array | [] | Yes | An array of unique identifiers corresponding to each list item. | | renderItem | Function | - | Yes | Function to render each list item. Receives { item } as its first argument. | | callbackNewDataIds | Function | - | Yes | Callback that receives changes (sorted array of dataIDs). Note: do not change the provided dataIDs array directly in state, as it will cause two-way binding and extra re-renders. | | renderGrip | Function | null | No | Optional function to render a grip for dragging. | | itemsGap | Number | 5 | No | The space (in pixels) between each list item. | | itemHeight | Number | 50 | No | The height (in pixels) of each item. | | style | Object | {} | No | Custom styles for the ScrollView. | | contentContainerStyle| Object | {} | No | Custom styles for the content container of the ScrollView. | | itemContainerStyle | Object | {} | No | Custom styles for the container of each individual item. | | itemBorderRadius | Number | 10 | No | The border radius of each draggable item. | | backgroundOnHold | String | #e3e3e3 | No | The background color of an item while it's being dragged. | | passVibration | Function | null | No | Function to trigger haptic feedback when an item starts moving. |

Notes

  • dataIDs: Should be an array of unique identifiers (strings) that correspond to each list item.
  • keyExtractor: A function that extracts the key from each item in the data. Commonly, this will be the item's ID.
  • renderGrip: Customize the drag handle or "grip" for each item. Defaults to a Text grip if not provided.
  • passVibration: For iOS, you can use Expo Haptics to trigger haptic feedback when the drag starts.

License

MIT