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-nested-drag

v0.7.1

Published

This library is a declarative drag-and-drop system for React Native, written in TypeScript. It is designed to be flexible and powerful with the goal of supporting many use cases. Default settings should cover the most common scenarios with minimal config

Downloads

16

Readme

Overview

This library is a declarative drag-and-drop system for React Native, written in TypeScript. It is designed to be flexible and powerful with the goal of supporting many use cases. Default settings should cover the most common scenarios with minimal configuration.

Screenshots

example nested example nested movable

More screenshots

example styles example dropsum

Snack

There is an example on snack though it works fine only on real device.

Installation

npm i react-native-nested-drag

or using yarn

yarn add react-native-nested-drag

Usage

Import the library components:

import { DragView, DropView, DragProvider } from 'react-native-nested-drag'

Basic example

<DragProvider>
  <DropView>
    <Text>drop here!</Text>
  </DropView>
  <DragView>
    <Text>drag me</Text>
  </DragView>
</DragProvider>

DragProvider

Wrap the part of your application that you want to enable drag and drop for inside DragProvider.

<DragProvider>
  {/*  */}
</DragProvider>

Props

All props are optional. | Prop | Type | Default | Description |
| ------------- | ---------- | ------------- | ------------- | | mockEventManager | IDndEventManager | | Only for testing | | overlapMode | OverlapMode | 'last' | Specifies events call order when multiple DropView in same area. After sorting with comparer, DropView events will be called last to first. You can't change it dynamically.|

DragView

The element that you want to make draggable.

The DragView won't be actually dragged, instead a copy appears on DragStart to make sure element always on top.

      <DragView payload={1}>
        <View style={styles.itemContainer}>
          <Text>+1</Text>
        </View>
      </DragView>

Props

All props are optional.

Available all ViewProps except for GestureResponderHandlers

| Prop | Type | Default | Description |
| ------------- | ---------- | ------------- | ------------- | | payload | any | | An arbitrary value (often) unique to this draggable that can later be used to determine which draggable item was dropped onto a droppable | | style | ViewStyle | | Style applied while this view is NOT being dragged | | dragStyle | ViewStyle | | Style applied while this view is being dragged | | overStyle | ViewStyle | | Style applied while this view is being dragged over a receiver | | copyDragStyle | ViewStyle | | Style applied to the copy while this view is being dragged | | copyOverStyle | ViewStyle | | Style applied to the copy while this view is being dragged over a receiver | | disabled | boolean | false | Specifies whether this view can be dragged | | longPressDelay | number | 0 | Time interval in ms after which this view can be dragged | | vibroDuration | number | 0 | Vibration duration on drag start in ms | | movable | boolean | false | Specifies whether this view stays where it has been dragged | | movableOffset | IPosition | {x:0,y:0} | It useful only when you want nested movable DragView appear correctly inside the draggable copy or for restoring movable state. This prop shouldn't be used just for formatting | | onDragStart | DraggableDragStart | | Callback that is triggerd when user starts dragging the DragView | | onDrag | DraggableDragStart | | Callback that is triggered repeatedly when user dragging the DragView not over any receiver | | onEnter | DraggableEnterOver | | Callback that is triggered when the DragView initially dragged over a new receiver | | onOver | DraggableEnterOver | | Callback that is triggered repeatedly when the DragView dragged over a receiver | | onExit | DraggableExit | | Callback that is triggered when the DragView leaves the droppable area | | onDragEnd | DraggableEnd | | Callback that is triggered when the DragView drag ends not over any receiver or is cancelled | | onDrop | DraggableDrop | | Callback that is triggered when the DragView drag ends over a receiver | | animationEndOptions | SpringAnimationConfig | { overshootClamping: true} | Animated.SpringAnimationConfig to customize dragEnd animation | | animationDropOptions | TimingAnimationConfig | | Animated.TimingAnimationConfig to customize drop fadeout animation |

DragHandleView

DragHandleView is useful when you want to restrict area where drag can start.

Just place one or more inside DragView. Notice that Button and TouchableOpacity work inside DragView and also restrict possible drag start area (you can't start drag on buttons).

    <DragView>
        <Text>part 1</Text>
        <DragHandleView style={styles.handle}>
          <Text>drag here!</Text>
        </DragHandleView>
    </DragView>

Props

All props are optional.

Available all ViewProps except for GestureResponderHandlers

DropView

The element that you want to receive droppable events.

  const drop = (_, payload) => {
    console.log(payload)
  }
  //...
  
    <DropView onDrop={add}>
      <Text>drop here!</Text>
    </DropView>

Props

All props are optional.

Available all ViewProps

| Prop | Type | Default | Description |
| ------------- | ---------- | ------------- | ------------- | | payload | any | | An arbitrary value (often) unique to this DropView that can later be used to determine in which DropView the DragView was dropped to | | style | ViewStyle | | Style applied while over this DropView is NOT dragging a DragView | | overStyle | ViewStyle | | Style applied while dragging a DragView over this DropView | | disabled | boolean | false | Specifies whether this view receives DnD events | | onEnter | DroppableEnterExit | | Callback that is triggered when a DragView initially dragged over this DropView | | onOver | DroppableDropOver | | Callback that is triggered repeatedly when a DragView dragged over this DropView | | onExit | DroppableEnterExit | | Callback that is triggered when a DragView leaves this DropView | | onDrop | DroppableDropOver | | Callback that is triggered when a DragView dragging ends over this DropView |

Testing

Import the library components:

import { DragProvider, MockDndEventManager } from 'react-native-nested-drag'

Create mockEventManager:

const mockEventManager = new MockDndEventManager()

Wrap your component for test render:

<DragProvider mockEventManager={mockEventManager}>
  <YourComponent>
</DragProvider>

Call DnD action like so:

mockEventManager.drop(mockEventManager.draggables[0], mockEventManager.droppables[0])

If you have animation errors set before the action:

jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
jest.useFakeTimers()

Full example with 'testing-library/react-native'

License

This software library is licensed under the MIT License.

Caveats and tips

  • If nested elements rendered base on own state clone appears as initial state. Possible workaround is move that state outside DragProvider (e.g. state management library).

  • If you want to store offset for movable DragView (may be because previous point) onDragEnd and onDrop receives it as parameter.

  • Don't put these styles on DragView (if necessary add View inside or outside):

    • margin
    • transform
    • position
    • opasity (allowed for dragStyle and overStyle only)
  • % width style doesn't work well in many cases.

  • There is useEffect listeners on props so make sure your props won't change on every render.

instead

...movableOffset={{x:50, y:-10}}...

use

...
const [movableOffset] = useState({x:50, y:-10});

...movableOffset={movableOffset}...
  • Available option for overlap handling is next callback (for onDrop and onOver)

  • Overlapping DropView is tricky especially when nested.

graph LR;
    A-->B;
    A-->C;
    D;

where B and C nested to A.

Droppables order: [B, C, A, D]

Moreover if you are using dynamic 'disabled' prop, which causes unregister order may become completely unpredictable.

You may try to use next callback or comparer function for overlapMode but much easier just avoid overlapping whenever it's possible.

  • onLayout event probably still calls only once (when component renders first time) inside DragView and DropView (also don't use it inside 'View' with onLayout if elements may change positions on screen besides dragging.)