react-native-draggable-flatlist icon indicating copy to clipboard operation
react-native-draggable-flatlist copied to clipboard

Support for react native web

Open rlindskog opened this issue 5 years ago • 17 comments
trafficstars

✅I have completed ALL installation steps.

Describe the bug Trying to use with react-native-web, not sure if this package is supported for web so this might be a feature request.

To Reproduce import DraggableFlatList from 'react-native-draggable-flatlist'

Platform & Dependencies Please list any applicable dependencies in addition to those below (react-navigation etc).

  • Platform: web
  • React Native version: ^0.60.5
  • React Native web version: ^0.11.7
  • Reanimated version: ^1.7.0
  • React Native Gesture Handler version: ^1.5.3

Additional context Using create-react-app. Getting this error

Failed to compile.

./node_modules/react-native-draggable-flatlist/index.tsx 69:5
Module parse failed: Unexpected token (69:5)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| };
| 
> type AnimatedFlatListType<T> = { getNode: () => RNFlatList<T> };
| 
| export type DragEndParams<T> = {

rlindskog avatar Jan 24 '20 21:01 rlindskog

Looks like you're not running typescript? I just changed the export to be js in the latest release so you should no longer get that error. That said I've never tested web and would be a little surprised if it works. Please let me know how it goes!

computerjazz avatar Feb 01 '20 16:02 computerjazz

I tested this briefly. Ran into errors related to react-native-reanimated and react-native-gesture-handler.

ncaught TypeError: Cannot read property 'configureProps' of undefined
    at configureProps (ConfigHelper.js:107)
    at Object../node_modules/react-native-reanimated/src/ConfigHelper.js (ConfigHelper.js:126)
    at __webpack_require__ (bootstrap:723)
    at fn (bootstrap:100)
    at Object../node_modules/react-native-reanimated/src/Animated.js (Animated.js:25)
    at __webpack_require__ (bootstrap:723)
    at fn (bootstrap:100)
    at Object../node_modules/react-native-draggable-flatlist/lib/index.js (index.js:76)
    at __webpack_require__ (bootstrap:723)
    at fn (bootstrap:100)

If I mock react-native-reanimated to use Animated from react-native instead, I get this error:

invariant.js:40 Uncaught Invariant Violation: `createAnimatedComponent` does not support stateless functional components; use a class component instead.
    at invariant (https://player.curiousmedia.com:8080/bundle.js:118681:810)
    at Object.createAnimatedComponent (https://player.curiousmedia.com:8080/bundle.js:118130:1813)
    at Object../node_modules/react-native-draggable-flatlist/lib/index.js 

curiousdustin avatar Feb 06 '20 20:02 curiousdustin

Animated is pretty different from react-native-reanimated, I'd be surprised if that worked.

There isn't much in the docs, but both Reanimated and RNGH seem to have partial web support as of recently: https://github.com/software-mansion/react-native-gesture-handler/pull/555 https://github.com/software-mansion/react-native-reanimated/pull/390

computerjazz avatar Feb 06 '20 21:02 computerjazz

I'm also running into issues with web - running react-native-web through expo and getting the following:

Uncaught TypeError: 'set' on proxy: trap returned falsish for property '__val'
    at nodify (bundle.js:57680)
    at adapt (bundle.js:57692)
    at createAnimatedSet (bundle.js:59502)
    at nativeEvent (bundle.js:49646)
    at sanitizeArgMapping (bundle.js:58546)
    at new AnimatedEvent (bundle.js:58566)
    at createAnimatedEvent (bundle.js:58647)
    at new DraggableFlatList (bundle.js:49643)
    at constructClassInstance (bundle.js:36705)
    at updateClassComponent (bundle.js:40382)
    at beginWork$1 (bundle.js:41902)
    at HTMLUnknownElement.callCallback (bundle.js:23744)
    at Object.invokeGuardedCallbackDev (bundle.js:23794)
    at invokeGuardedCallback (bundle.js:23851)
    at beginWork$$1 (bundle.js:46614)
    at performUnitOfWork (bundle.js:45605)
    at workLoopSync (bundle.js:45582)
    at renderRoot (bundle.js:45275)
    at runRootCallback (bundle.js:44951)
    at bundle.js:34750
    at unstable_runWithPriority (bundle.js:88846)
    at runWithPriority$2 (bundle.js:34702)
    at flushSyncCallbackQueueImpl (bundle.js:34746)
    at flushSyncCallbackQueue (bundle.js:34735)
    at scheduleUpdateOnFiber (bundle.js:44828)
    at dispatchAction (bundle.js:39213)
    at bundle.js:91676```

Haven't really had time to look into it further.

robertherber avatar Mar 05 '20 11:03 robertherber

Getting the same error as @robertherber - using expo and expo start --web. It works on Android.

Krzychu81 avatar Mar 22 '20 00:03 Krzychu81

I created a blank Expo project and copy pasted the example, and it runs without any errors. The functionality seems to be broken though. Long-pressing an item moves it to the top of the list and locks it in the dragging state even if the finger is released, blocking interaction with other items too. Any idea how to go about fixing it? Here's the repo.

ezgif-3-a760f63fc90e

I'm also thinking the dragging functionality should work differently when tapping on a touchscreen and dragging with a mouse (don't need to wait for a longpress with a mouse), but I'm not sure if that's even possible to achieve with RNGH.

ianmartorell avatar Apr 07 '20 08:04 ianmartorell

Sounds like this currently doesn't work for react-native-web. Anyone know a good alternative for now?

tettoffensive avatar May 19 '20 04:05 tettoffensive

I've managed to get it moving on the web now. Essentially events triggered by react-native-gesture-handler are a bit different on the web, so the onPanGestureEvent needs to listen for GestureState.BEGAN as well:

onPanGestureEvent = event([
    {
      nativeEvent: ({ x, y }: PanGestureHandlerEventExtra) => cond(
        and(
          this.isHovering,
          Platform.OS === 'web' ? or( // <----------------------- here
            eq(this.panGestureState, GestureState.BEGAN),
            eq(this.panGestureState, GestureState.ACTIVE),
          ) : eq(this.panGestureState, GestureState.ACTIVE),
          not(this.disabled),
        ),
        [
          cond(not(this.hasMoved), set(this.hasMoved, 1)),
          set(
            this.touchAbsolute,
            add(this.props.horizontal ? x : y, this.activationDistance),
          ),
        ],
      ),
    },
  ]);

There are some quirks that needs more work for this to be fully useable, maybe someone can spot quick solutions for these?

  • The position before dragging is still at the top of the list.
  • The item offset doesn't catch on - which mean the item dragged will always be under the mouse pointer and causes the drop index to be slightly off.
  • Sometimes it gets stuck at the drop stage.

I feel this issue (at least the part I marked out involving states) would best be solved in react-native-gesture-handler in the long term - but I guess it might require replacing hammerjs which might be easier said than done. So if we could just solve it here for now it'd be great :)

robertherber avatar May 19 '20 13:05 robertherber

@robertherber Awesome stuff. I'm keen to get this working on web as well. Did you already have have a discussion with the react-native-gesture-handler maintainers about this as well?

sreuter avatar Jan 04 '21 00:01 sreuter

@sreuter I haven’t had time to pursue this further :(

robertherber avatar Jan 04 '21 05:01 robertherber

It seems to be working fairly well on web now. The issue that remains seems to be when there's a scroll offset - which makes it bug out.

robertherber avatar Apr 28 '21 17:04 robertherber

yeah so the issue on web is that onScroll doesn't seem to ever trigger, so the scrollOffset doesn't get updated. I'm guessing this is due to the scrolling div not being the flatlist div, but I haven't dug in too deep. possibly related: https://github.com/necolas/react-native-web/issues/1827

computerjazz avatar Apr 28 '21 18:04 computerjazz

Any news?

Edit: Hmm, it seems to be working at the repo snack: https://snack.expo.dev/@computerjazz/rndfl3

Edit2: Just saw that it uses 3.0.0, the beta version. Changing it to 2.6.2 won't work. Awaiting for the 3.0.0!

ftzi avatar Oct 05 '21 03:10 ftzi

In case this is helpful to anyone else who stumbles upon this thread:

Version 3.1.1 was working well for me on web, but started causing issues on Android. Version 4.0.1 works well for Android, but started throwing errors on web.

I finally solved this by using separate versions for web vs. mobile:

package.json

{
  ...
  "dependencies": {
    ...
    "react-native-draggable-flatlist": "^4.0.1",
    "react-native-draggable-flatlist-web": "npm:[email protected]",
    ...
  }
}

DraggableList.js

import React from "react";
import DraggableFlatList from "react-native-draggable-flatlist-web";

export default function DraggableList(props) {
  return <DraggableFlatList {...props} />;
}

DraggableList.native.js

import React from "react";
import DraggableFlatList from "react-native-draggable-flatlist";

export default function DraggableList(props) {
  return <DraggableFlatList {...props} />;
}

cannse avatar Jul 06 '23 21:07 cannse

@cannse did they need different versions of react-native-reanimated? which did you use? been trying various ones but can't seem to get it working on both web and Expo Go simultaneously.

Came to this thread because dnd for items at the bottom of the list (once you've scrolled down a bit) have dodgy behaviour for me on web (though no errors get logged). The auto scroll up/down when dragging an item have been triggering at odd times and and it's not letting me drop items outside a limited subset of positions the list. Works well in Expo Go though.

hannah-jemima avatar Apr 26 '24 12:04 hannah-jemima