Giter Club home page Giter Club logo

react-native-drax's People

Contributors

chrisdrackett avatar dependabot[bot] avatar francoisdupayrat avatar jmarnold avatar lafiosca avatar negue avatar rnz269 avatar special-character avatar sturdynut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-drax's Issues

Provide drag translation value in events

In event handlers, it would be nice to know the cumulative drag translation, i.e., the x/y diff from the original absolute grab point to the current absolute drag point. This can let you do things based on how far a view has been dragged.

support styles on both `DraxList` and its `FlatList`

to have full control over the styles of this component I think it is currently needed to be able to pass styles both to the FlatList and to the DraxList. For example if I want to add padding to inside the FlatList or have effectively flex: 1 it is needed to add styles to both elements.

itemStyles are somewhat confusing

I'm finding itemStyles on DraxList somewhat confusing, but maybe I'm thinking about them incorrectly. Here is what I'm finding:

  • dragReleasedStyle: the style of the receiving "space" after an element is released.
  • draggingStyle: seems to be the style of the "space" that the picked up item came from, but only shown when being hovered
  • draggingWithoutReceiverStyle: the style of the "space" the element was picked up from if the element isn't over the list anymore.
  • draggingWithReceiverStyle the style of the element in the position the original item came from when not being hovered
  • receivingStyle: the style of the element that the current item will replace when released.

I found the above while trying to find a way to style the space (#37) and also trying to adjust the style of the item being dragged when it leaves the list (for example to reduce its opacity when it isn't over the list anymore.)

Ghost hoverView left behind after slow animation

If you use a slow enough snapback and reposition the dragged DraxView, it's possible to leave a ghost hoverView at the previous position of that DraxView which vanishes the next time it is dragged. This is most easily reproducible in react-native-drax-example's "Knight Moves" tab by setting a snapbackDelay, snapbackDuration, or custom snapbackAnimator with a 5+ second animation.

DraxList doesn't work correctly with numColumns > 1

h/t to Caleb Clarke for asking about this.

The shifting logic in DraxList assumes the underlying FlatList will only have a single column or row. When you increase the numColumns attribute above 1, the shifts don't look right:

multi-column

The existing shift-transform approach might work with some additional logic, but experimentation with Android will be necessary to determine if there is a similar problem to #1.

Note: in FlatList, numColumns only works with horizontal=false and specifically mentions that all items should be the same height. This might simplify some of the assumptions.

Provide viewState/grabOffset in event data?

The content rendering functions that can be passed to DraxView receive a DraxViewState prop which contains useful information like grabOffset and dragOffset:

/** If being dragged or released, the position in screen coordinates of the drag point */
dragScreenPosition?: Animated.ValueXY;
/** If being dragged or released, the relative offset of the drag point from the view */
dragOffset?: Animated.ValueXY;
/** If being dragged, the relative offset of where the view was grabbed */
grabOffset?: Position;
/** If being dragged, the relative offset/dimensions ratio of where the view was grabbed */
grabOffsetRatio?: Position;

These values are not currently provided in any of the drag event data passed to the drag-drop lifecycle callbacks. Should they be? I think it would be nice in some cases to have that data available.

And this raises a more general question: would adding required fields to the shape of an interface like DraxEventData be considered a breaking change? I think technically it would be. For example, if someone is using that interface to construct objects in their own code, that could break, although the average consumer of this library would presumably only be receiving/handling such objects from the library. The interfaces/types are exposed primarily for flexibility and convenience. Still, it doesn't hurt for us to release additional minor version bumps while in 0.x.

Please add PropTypes to the Drax components

The library is written in TypeScript, which provides basic compile-time type safety to developers who are using that. PropTypes should be added to the components for run-time type safety and for developers using JavaScript.

Is it possible to pass my own onScroll to DraxList?

I am trying to replace a react-native-draggable-flatlist with this library however they have a onScrollOffsetChange prop that allows me to do a parallax effect while scrolling. If I can pass my own onScroll to the FlatList I should be able to replicate the same effect.

example:

onScroll={({ nativeEvent }) => {
    this.state.scrollY.setValue(nativeEvent.contentOffset.y);
}}

Alternatively is there a way to use values form the useDraxRegistry?

Unify drag/receive event shapes

For consistency, let's consider generally unifying the shapes of the events for onDrag*, onReceive*, onMonitor*. It will make the implementation logic a little bit easier, and it will perhaps be less confusing.

For example, let's always group the dragged view data into a dragged object, rather than having it in dragged for onReceive* and in the root for onDrag*.

We will still need more specific extended shapes for events which have a receiver, events which can be "cancelled", and monitor events.

Upgrade react-native devDependency to 0.62.x

There is a security alert for logkitty, but we've inherited that dependency from the React Native CLI v3, which we've inherited from RN 0.61. Upgrading to 0.62 makes sense because it's the latest, and it resolves this security alert. (Note that this security alert probably should not impact our end users since it's only for a devDependency.)

This should be straightforward, but I am not currently set up to verify it by testing the lib after making the change. I'm leaving this issue here to remind me to take care of it for this repo and for react-native-drax-example while I'm at it.

DraxProvider should respect parent padding

Currently DraxProvider uses an absoluteFill to fill its parent view entirely. This means that it does not respect the parent's padding, which can be bad in some cases (e.g., when using certain implementations of SafeAreaView). Let's change it to use flex: 1 instead.

Bug: DraxList doesn't handle dragging out of the list and back in

I noticed that dragging an item outside the DragList and back into the list has odd behavior. Here is a screen cap.

DraxList Exit Bug

In the example, I drag an item over the tab bar which is outside the DraxProvider. I confirmed that pulling the DraxProvider up to the root of the app fixes the issue but I can't do that for my current use case.

It seems that it starts behaving as expected only after I drag it back to it's original position. I am guessing that the onMonitorDragExit is called when it exits but it doesn't call onMonitorDragEnter and set handlers back up accordingly. I will take a crack at making a PR for this!

Why DraxView is not working as it should be with ScrollView?

I am using the inside the when the is pressed it pops out from the original position and works smooth for all those which are visible, once we scroll it horizontally and pressed it, it do not pop out from position where it is pressed but comes out from the position where the is originally placed while loading.
image

image

image

add ability to not have "space" in `DraxList` when hovered item is not over list

Currently if you drag an item outside of a DraxList the empty space shifts back to the spot that the item came from. This leads to some undesirable visual issues with items jumping around. I would like to make the following suggestion:

  1. when an item is dragged outside of its parent list don't show any empty space in that list anymore
  2. if the item is released on another receiver everything is good to go
  3. if the item is released outside of any receiver, while the item is animating back to its place in the list open the space back up.

Basically the space would open if the item comes back over the list based on the items location OR if the item is released and needs to go back to its original location.

Determine compatibility with react-native-safe-area-context v3 and react-navigation v5

Drax needs to be updated to support RN 0.62+ (0.63 at time of writing this) as per #54

I'm in the process of updating my mobile app which uses Drax from RN 0.61 to 0.63, and as part of that effort I'm moving from react-navigation v3 to v5. That library used to provide a custom SafeAreaView, but in v5 they recommend using react-native-safe-area-context (which is on v3 currently).

I need to determine whether Drax is compatible with the latest react-native-safe-area-context and react-navigation, at least for the most common use.

Drax measurements for dynamic layout items are slightly off after orientation change

Issue #8 addressed the problem with Drax measurements breaking entirely after an orientation change. However it seems there may be a race condition when nesting using Drax with react-native-safe-area-context insets which change from an orientation change. All view measurements seem to become off by a bit diagonally, and even after returning to the original orientation they are broken. Let's see if we can make Drax even more resilient to this type of thing, perhaps by introducing a slight timeout delay for the DraxView remeasurement after orientation change. (Perhaps this delay could be configurable via a DraxProvider parameter, with a sensible default, for greater hacking flexibility.)

Change names to no longer refer to "screen"

Originally in Drax development, coordinates were measured absolutely on the screen. At some point, to work around gaps in functionality, we began measuring all views in relation to the DraxProvider root view. This means that the screenPosition values are not actually screen positions. Rather, they are absolute positions in the frame of reference of the DraxProvider. Let's change screen to absolute everywhere for consistency. Then if we decide to expose actual screen positions in the future, we can use that naming convention for those.

Feature Request: Add callback on DraxList for when the dragged item changed hover index

Thanks for the awesome project! It has already been the best drag and drop library that I have seen for react native.

I am using the DraxList to re-order my items and want to provide haptic feedback whenever the item is dragged to a new hover position. i.e. When dragging and item down the list I want to be able to know every step down the list it is dragged before it is released at the final position.

I will take a look at creating a PR for this. I think it should be straightforward given the amount of event hooks that are available.

Drop is not possible on the visible receiver when width is set dynamically.

The width of the <DraxScrollView /> is set to device width and height will take the autoscroll. When one card is dropped on the <DraxScrollView /> we increased the width dynamically using javascript. We can see width of the <DraxScrollView /> is increased but the visible receiver will not receive the new card dropped. It seems the receiver position is bound with the old width of the <DraxScrollView />.

How can we make the receiver receives even we are giving the width dynamically?

The attachments:
image 1, is the first view, image 3 is with dynamic width added, image 4 the receiver is not receiving the card.

image
image
image
image

onMonitorDragEnd is only called if drag is cancelled?

It's unclear to me why this block was wrapped in if (cancelled):

if (cancelled) {
response = monitorData.protocol.onMonitorDragEnd?.({
...monitorEventData,
...getRelativePosition(screenPosition, monitorData.absoluteMeasurements),
cancelled,
});
}

Especially because that makes the lines following the block meaningless.

This is the only place onMonitorDragEnd occurs, but it appears with the current logic that it would ONLY be called when a drag is cancelled, never from a drag naturally ending outside of a receiver within the monitor.

Only animated values should use Animated.ValueXY

Currently the API returns Animated.ValueXY for several items, such as:

/** The relative offset the drag point in the receiving view */
receiveOffset: Animated.ValueXY;
/** The relative offset/dimensions ratio of the drag point in the receiving view */
receiveOffsetRatio: Animated.ValueXY;

It's actually a hassle to deal with Animated.ValueXY if you're not using it for styling a view. For instance, if you want to read the x value to see if a receiveOffset is in the left/right edges of a receiver, you just want to compare receiveOffset.x to something. A Position value would be more helpful here.

When first building the library, I erred on the side of making more things Animated.ValueXY, but I've realized that there's really no point to using an Animated.ValueXY unless you're going to animate it. Currently only hoverPosition is being animated by the library, so I think we should change these other items into Positions. If/when we need to animate any more of them in the library, we can change them again or add extra fields.

Option to show target placeholder in DraxList reordering

When dragging an item to reorder a DraxList, there is already a feature that shows a semi-transparent item target position placeholder during the snapback after release. It might be nice to have an option to show this placeholder even before the item is released, for the user to visualize where the dragged item will go before releasing it. (This could probably be accomplished using the same shift transformation logic already being used for all of the other items shifting.)

Enhance DraxList onItemDragPositionChange to recognize original position index

The new logic in #42 introduces the DraxList onItemDragPositionChange event handler property. When dragging an item over any other item in the list, that callback receives the position index of the item being dragged over. When dragged anywhere else, including the dragged item's original position, the list header/footer, or outside the list, the callback receives an undefined index. It might be nice for the callback to receive the item's original position index rather than undefined when dragging over the item's own position. This would require additional logic in the DraxList monitoring because the original item can't receive its own drag like the rest of the list items do.

Horizontal DraxList items vanish while shifting on Android

With a DraxList in horizontal mode, on Android the items seem to vanish while they are shifted during a reordering drag. This does not happen on iOS, and it does not happen in vertical mode. It appears that Android may be doing some kind of additional view clipping on each view inside the underlying FlatList to cause this. Without digging into React Native's code, it's unclear why this would only apply to horizontal mode. It's also not obvious to me whether there could be a simple solution or workaround that we can apply within in this library.

Minimal reproduction example here: https://snack.expo.io/@lafiosca/horizontal-draxlist?platform=android

DraxScrollView scrollTo function is undefined.

I am trying to make the card center of the DraxScrollView which will have the dynamic width based upon the number of the cards DraxScrollView is acquiring.

I have used <DraxScrollView contentContainerStyle={[styles.receivedZone,]} alwaysBounceVertical={true} maximumZoomScale={10} minimumZoomScale={-2} directionalLockEnabled={false} horizontal={true} ref={(ref) => this.draxScrollViewRef = ref.getNodes()} > <View onLayout={event => this.layout = event.nativeEvent.layout} style={{ position: 'relative', width: 105, height: 105, overflow: 'visible' }} > <Text>Cards content</Text> </View> </DraxScrollView>

The reference is then used on ` componentDidMount = async () => {

	setTimeout(() => {
		this.draxScrollViewRef.getNodes().scrollTo({
			y: this.layout.y,
			x: this.layout.x - GlobalItem.deviceWidth / 2 + 55,
			animated: false
		})
	}, 100);

}`

But the end result is TypeError: _this.draxScrollViewRef.getNodes is not a function. (In '_this.draxScrollViewRef.getNodes()', '_this.draxScrollViewRef.getNodes' is undefined)

What can be done?

Changing length of DraxList data array causes app to crash

When a DraxList is reused with a new data array of a shorter length, the cached reorder logic causes it to send undefined items to the underlying FlatList, which can crash the app when the keyExtractor or renderItem methods try to access fields of the undefined item.

Feature Request: Allow specifying custom Animated function for moving/snapping dropped items

It would be great to be able to specify the animation for a dropped item. Right now it is this timing function:

https://github.com/nuclearpasta/react-native-drax/blob/master/src/hooks/useDraxRegistry.ts#L493

I confirmed that I could manually change that to the spring function and it worked as expected. I could probably take a look at doing this. It should be a fairly straightforward option to configure.

Explicitly set useNativeDriver for animated views

In RN 0.63, we have this new warning when dragging views:

Animated: `useNativeDriver` was not specified. This is a required option and must be explicitly set to `true` or `false`

Update the library to fix this.

Improve reorder behavior when dragging beyond DraxList item content

If you have a short DraxList where the length of the content does not fill the entire list container, the drag-to-reorder behavior may feel a bit unintuitive when dragging an item to the end of the list.

image

Specifically, in the screenshot above, dragging one of the letter items down will cause the list to reorder only as long as the drag is over one of the other letter items. If you drag one down into the grey zone at the bottom of the list, the drag is no longer considered to be internal to the list, and the items all return to their original positions.

It might be nice if dragging over this end zone were considered the same as dragging over the final item in the list. This becomes more apparent when looking at a real life example in which the user could be frustrated that the item snaps back to where it was when dragging past this "invisible" border:

image

Here is the Snack reproduction that the first screenshot comes from: https://snack.expo.io/@lafiosca/short-draxlist?platform=ios

Should DraxView longPressDelay default to 0?

Currently, there's a default longPressDelay of 250ms on DraxView:

export const defaultLongPressDelay = 250;

Why? I mean, I know why as the author: the initial use case was to implement a drag-reorderable list, which meant that I needed the delay to prevent the drags from capturing list scroll gestures. But for the standard DraxView use case, might we not want to default to 0, which allows instant grabbing of the view to drag?

One possible counterpoint would be when the draggable views may have standard Touchable buttons embedded in them. The longPressDelay prevents the drag from hijacking those touches. But it can be lowered a little bit for that case as well. The 250ms value came from what "felt right" for reorderable lists.

Android drag offset issues

Now that react-native-drax-example has been updated to the latest react-native, react-navigation, react-native-safe-area-context, and react-native-gesture-handler, I'm experiencing a few functionality problems with drags on the Android build.

On a physical Galaxy S7 Edge, everything seems to work as expected until I rotate the phone into a different orientation. The display automatically rotates, but the drag offsets are wrong, to the point of almost completely breaking the Knight Moves example.

On an emulated Pixel 3a, the drag offsets are wrong when the Color Drag/Drop screen first loads. Specifically, when grabbing a color block, it hovers what appears to be roughly one Android status bar height vertically above where the gesture is touching. The other examples work as expected. Then when I rotate the emulated device, it doesn't automatically reorient the app, but a little software rotation button shows up, as seen in the upper-right corner of this screenshot:

image

When I click this, the app reorients into landscape, and all offsets work fine. Then if I rotate back into portrait and click the button again, everything behaves as it should. This implies to me that during the initialization of the app, Drax is somehow calibrating its base coordinates in the wrong place (perhaps not accounting for status bar), but that when the orientation change handler recalibrates, it's fine. As with all Android issues, I dread trying to determine whether this is specific to only certain devices.

Dragging a DraxList item more than one container length on Android cancels the drag

If you have a DraxList with content extending beyond the length of the list container, dragging one of its list items over one of the ends of the list container will auto-scroll the list contents. If this auto-scrolling takes your item drag more than one full length of the container from the item's initial position, on Android the drag will be cancelled at that point.

DraxList has a logic to mitigate this behavior in regard to list item reordering. Rather than losing the drag progress entirely, it considers the item to have been dragged and dropped to the point of cancellation. Still, it would be preferable if the cancellation didn't happen at all. I'm not sure if there is anything we can do within this library to fix it. The answer likely lies in react-native-gesture-handler, if anywhere.

You can reproduce this behavior in the basic reorderable list example on the Android device: https://snack.expo.io/@lafiosca/react-native-drax---basic-reorderable-list?platform=android

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.