Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPFX and react-dnd #4808

Closed
1 of 4 tasks
ksdaniel opened this issue Oct 23, 2019 · 9 comments
Closed
1 of 4 tasks

SPFX and react-dnd #4808

ksdaniel opened this issue Oct 23, 2019 · 9 comments
Labels
area:spfx Category: SharePoint Framework (not extensions related) status:fixed-next-drop Issue planned to be fixed in an upcoming release.
Milestone

Comments

@ksdaniel
Copy link

ksdaniel commented Oct 23, 2019

Category

  • Question
  • Typo
  • Bug
  • Additional article idea

Is somebody using SPFX with react-dnd.

I am trying to get some basic drag and drop functionality in an SPFX webpart - in the local workbench it works as expected, as soon as I go to a live site, the onDrop will no longer trigger.

All help is appreciated - I am obsessing with this for days now and have well passed my chocolate/bug allowance.

Here is my code, just create a HelloWorld and replace the code as below:

import * as React from 'react';
import styles from './HelloWorld.module.scss';
import { IHelloWorldProps } from './IHelloWorldProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { DndProvider } from 'react-dnd'
import HTML5Backend from "react-dnd-html5-backend";

import { useDrag, DragSourceMonitor } from 'react-dnd'
import { useDrop } from 'react-dnd'


export default class HelloWorld extends React.Component<IHelloWorldProps, {}> {
  public render(): React.ReactElement<IHelloWorldProps> {
    return (
      <div className={ styles.helloWorld }>
            <DndProvider backend={HTML5Backend}>
                <Content></Content>
            </DndProvider>
      </div>
    );
  }
}

export interface Props {
  children?: React.ReactNode
}

export interface State {
}

class Content extends React.Component<Props, State> {

  constructor(props: Props) {
    super(props)

    this.state = {
    }
  }

  render() {
    return (
      <div>
        <div style={{ overflow: 'hidden', clear: 'both' }}>
          <Dustbin />
        </div>
        <Box name={"test"}></Box>
      </div>
    )
  }
}

const style: React.CSSProperties = {
  height: '12rem',
  width: '12rem',
  marginRight: '1.5rem',
  marginBottom: '1.5rem',
  color: 'white',
  padding: '1rem',
  textAlign: 'center',
  fontSize: '1rem',
  lineHeight: 'normal',
  float: 'left',
}

const Dustbin: React.FC = () => {
  const [{ canDrop, isOver }, drop] = useDrop({
    accept: 'Box',
    drop: () => ({ name: 'Dustbin' }),
    collect: monitor => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  })

  const isActive = canDrop && isOver
  let backgroundColor = '#222'
  if (isActive) {
    backgroundColor = 'darkgreen'
  } else if (canDrop) {
    backgroundColor = 'darkkhaki'
  }

  return (
    <div ref={drop} style={{ ...style, backgroundColor }}>
      {isActive ? 'Release to drop' : 'Drag a box here'}
    </div>
  )
}


const style1: React.CSSProperties = {
  border: '1px dashed gray',
  backgroundColor: 'white',
  padding: '0.5rem 1rem',
  marginRight: '1.5rem',
  marginBottom: '1.5rem',
  cursor: 'move',
  float: 'left',
}

interface BoxProps {
  name: string
}

const Box: React.FC<BoxProps> = ({ name }) => {
  const [{ isDragging }, drag] = useDrag({
    item: { name, type: 'Box' },
    end: (item: { name: string } | undefined, monitor: DragSourceMonitor) => {
      const dropResult = monitor.getDropResult()
      if (item && dropResult) {
        console.log(`You dropped ${item.name} into ${dropResult.name}!`)
      }
    },
    collect: monitor => ({
      isDragging: monitor.isDragging(),
    }),
  })
  const opacity = isDragging ? 0.4 : 1

  return (
    <div ref={drag} style={{ ...style1, opacity }}>
      {name}
    </div>
  )
}
@msft-github-bot
Copy link
Collaborator

Thank you for reporting this issue. We will be triaging your incoming issue as soon as possible.

@msft-github-bot msft-github-bot added the Needs: Triage 🔍 Awaiting categorization and initial review. label Oct 23, 2019
@andrewconnell andrewconnell added area:spfx Category: SharePoint Framework (not extensions related) type:question Question... if answered, will be tagged as such. and removed Needs: Triage 🔍 Awaiting categorization and initial review. labels Oct 23, 2019
@ksdaniel
Copy link
Author

Noticed something weird here - when I have the workbench in Edit mode it show the behavior described above.

When I click on Preview mode - it works as expected.

Any ideas why?

@RantingLemming
Copy link

RantingLemming commented Dec 17, 2019

Ran into a similar problem building a web part that closely reflects the out-of-the-box People (picker) web part. In our case, we used HTML5 drag/drop API to create a sortable list. We found that the drag/drop events (specifically, dragover and drop) were not triggering when in edit mode. However, once in preview/display mode, everything worked fine.

From what I could tell, the built-in web part drag/drop functionality is what's interfering here. While in edit mode, I could select my draggable elements and dragstart would fire, however, once I tried dragging the element, I'd see the web part drop zone indicator kick in, showing where my dragged element would be placed in respective web part drop zones on the page. Using Chrome dev tools, i could see that there's two <div> elements just under the .CanvasComponent that get a dynamic class "host_xyz" added which have their own dragover and drop event listeners. When inspecting my <li> draggable elements which have their own event listeners, I see that these are assigned to the document, not the element, and so the dragover/drop events of the aforementioned .host_xyz elements take precedence. This seems to be how React handles draggable components in general - the drag events are bound to the document instead of the elements.

The workaround to this seems to lie in properly leveraging React references (or something else I'm not knowledgeable enough to know more about) to bind the events to the elements you want. React-dnd seems to have features that help with this, such as the hooks useDrag and useDrop. The react-list-form web part seems to accomplish this using the legacy decorators to create a drag source/drop target. You can also read more about them in the overview documentation.

@jrichmond4
Copy link

Drag and drop with react-dnd does not appear to work at all for me in spfx. We just converted a react app to spfx and it was working fine before. Any help?

@hassanamjad91
Copy link

hassanamjad91 commented Jan 17, 2020

I am facing the same issue. In my case drag & drop was working fine in SPFx 1.9.1 but when I upgraded to SPFx 10.0, it stopped working.

@jason-appliedis
Copy link

jason-appliedis commented Apr 3, 2020

I am working on V1.10 and onDragEnd is not working either.

Here is the div element. The drag and drop works in the workbench like a champ, then in a live site stops functioning.
` <div
key = {stateControlItem}
id={stateControlItem}
draggable
onDragEnter={ev => this._onDragEnter(ev,value)}
onDragStart = {ev => this._onDragStart(ev,value)}
onDragEnd = {ev => this.props._onDragEnd(ev,this.draggedItem, this.dropZone)}

`

Upon further inspection, when I drop the

the onDragEnd event.datatransfer.dropEffect returns "move" in edit mode and "none" in preview/production site.

@AJIXuMuK
Copy link
Collaborator

Hello all,
Sorry for the long delay.
The fix has been made and will be available WW in the next few weeks.

@AJIXuMuK AJIXuMuK added status:fixed-next-drop Issue planned to be fixed in an upcoming release. and removed type:question Question... if answered, will be tagged as such. labels Oct 28, 2021
@AJIXuMuK AJIXuMuK added this to the 11-04 milestone Nov 1, 2021
@patmill
Copy link
Contributor

patmill commented Nov 16, 2021

This should now be rolled out fully

@patmill patmill closed this as completed Nov 16, 2021
@ghost
Copy link

ghost commented Nov 23, 2021

Issues that have been closed & had no follow-up activity for at least 7 days are automatically locked. Please refer to our wiki for more details, including how to remediate this action if you feel this was done prematurely or in error: Issue List: Our approach to locked issues

@ghost ghost locked as resolved and limited conversation to collaborators Nov 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area:spfx Category: SharePoint Framework (not extensions related) status:fixed-next-drop Issue planned to be fixed in an upcoming release.
Projects
None yet
Development

No branches or pull requests

9 participants