React-beautiful-dnd: Support custom placeholder

Created on 21 May 2018  路  39Comments  路  Source: atlassian/react-beautiful-dnd

Custom placeholder

There are in documentation a lot of examples with using placeholder like:

{provided.placeholder}

But it doesn't work, I saw that it was moved inside of library to add it automatically, but now there is no way to manage placeholder from outside, for example if I want to put custom placeholder like: Drop it here

Is it possible to add functionality to support custom placeholder?

P.S. I think the best way, just to pass property with React element and put it instead of empty placeholder.

Thanks.

idea 馃

Most helpful comment

It would be awesome if there's support for this.

All 39 comments

Hi @alexreardon Do you think it's possible to do?

It is not straight forward to add as we currently do not move the placeholders in the lists. We may consider adding this at some point but it is not on our immediate roadmap

It would be awesome if there's support for this.

I think would be enough if you could disable default placeholder altogether and provide some sort of info about where you should place it, if you want to. Maybe indexes of items in between or something like that.

You 'technically' could do this today if you have fixed sized items and you leaned on the onDragUpdate hook to know where the drop target is. Although managing the shadow by yourself will get crazy complex across multiple lists

Here be dragons!

I tried to add my custom placeholder instead of shadow placeholder, but issue that my placeholder should be higher than regular item, and if increase hight of shadow placeholder it break scroll functionality in the list...

You will probably want to use position:absolute to position it.

Just a reminder: this is not currently supported - i just offered a suggestion. I'll be removing myself from this convo for now

Yep but inside item, I have div that include 2 items: regular and placeholder under it and switch from one to another when user drag this particular item, I think it works for same size placeholder but for placeholder with other height - no.

Any update on this?

I have a use-case right now, that there should be no blank space, but an empty element with a dashed border the height of the dragged element.

@visualcookie did you manage to make that dashed placeholder work?

@visualcookie did you manage to make that dashed placeholder work?

@pbrandone Nope, still no idea how I would do that. :D

@pbrandone Were you able to have a custom placeholder? I am having a very similar use-case with two vertical lists stacked one above the other and I'd like to have a custom placeholder that is similar to what is being shown in the image below:

https://cdn-images-1.medium.com/max/1600/1*kUl5sYqeMgbCwaYJWCVS2w.gif

cc @alexreardon

@nramamurth unfortunately no

+1

Has anyone succeeded in this? I want to have the same like example

Any update on this? IMHO, this would make this library complete in terms of features provided w.r.t DnD.
Dear @alexreardon , please consider adding drop-shadow support.

I managed to implement a custom placeholder manually in my project.

I don't have time to clean up the code for easy reuse, but if someone wants to see the general approach I took, you can browse the source code here: https://github.com/canonical-debate-lab/client/blob/68dadee32832f2a555c7f9ac9b928362b45e9c45/Source/UI/%40Shared/Maps/MapNode/NodeUI/NodeChildHolder.tsx#L110

Here's a gif of the custom placeholder in action:

The drag-and-drop is also usable on the website itself here: https://canonicaldebate.com

However, I don't recommend that for quick testing since you'll need to create a new map (or new nodes in an existing map) to use it. (since you're not able to move other people's entries)

Again, it's not a ready-made solution, but is an example of how it can be implemented if you have the need.

@Venryx can you implement this inside a simple list?
I really need it for my application

  • A simple (e.g. https://codesandbox.io/) demo would be highly appreciated to showcase some implementation of how to add/style a custom placeholder.
  • Would be a ghost-like effect (e.g. https://sortablejs.github.io/Sortable/#simple-list _a styled preview of the new position within the list (blue in the example)_) possible as well?
    Kapture 2019-05-07 at 19 48 34

@ndrsllwngr Exactly that's what I want to see, except, that the users of the library can customize the ghost element to maybe an empty element with only a striped border.

You can do something simple like this:

{provider.placeholder && <MyCustomPlaceHolder />}
<div style={{ display: 'none' }}>{provider.placeholder}</div>

The second line is just satisfy the warning you get in development mode.

You can do something simple like this:

{provider.placeholder && <MyCustomPlaceHolder />}
<div style={{ display: 'none' }}>{provider.placeholder}</div>

The second line is just satisfy the warning you get in development mode.

If I remember correctly, the solution you provide is not sufficient because it doesn't take into account where to position the ghost element within the list. This is because the placeholder element (and ghost element) are always the last UI element in the children list. So when I implemented the ghost element, I had to add code that calculates where to place the ghost element in the list. (I took the approach of using getBoundingRect() and absolute-positioning the element, though I suppose you could also use children-reordering to accomplish it)

I managed to implement a custom placeholder manually in my project.

I don't have time to clean up the code for easy reuse, but if someone wants to see the general approach I took, you can browse the source code here: https://github.com/canonical-debate-lab/client/blob/68dadee32832f2a555c7f9ac9b928362b45e9c45/Source/UI/%40Shared/Maps/MapNode/NodeUI/NodeChildHolder.tsx#L110

Here's a gif of the custom placeholder in action:

The drag-and-drop is also usable on the website itself here: https://canonicaldebate.com

However, I don't recommend that for quick testing since you'll need to create a new map (or new nodes in an existing map) to use it. (since you're not able to move other people's entries)

Again, it's not a ready-made solution, but is an example of how it can be implemented if you have the need.

can you give an simple example custom placeholder please ?

I don't have time at the moment (not working on the website project above either). I might at some point.

The basic idea is just what I described in my previous comment. The code is messy, but the important parts in the large code file are:
1) The retrieval of the display-rectangle of the current list item being dragged
2) The lines with {provided.placeholder && ThingsRelatingToPlaceholder}, which start calculation of where to display the placeholder within the list, and then display it there once calculated
3) The StartGeneratingPositionedPlaceholder() function, which does the mentioned calculation based on sibling display-rectangles
4) The marking of a list item as a drag-preview when it's being dragged -- so that step 1 above can locate the element in the document and know its size

For steps 1 through 3, there is also a simpler example here: https://github.com/canonical-debate-lab/client/blob/9494afe38fd002c6759eb14453519055c48934d0/Source/UI/%40Shared/Maps/MapUI/TimelinePanel/EditorSubpanel.tsx

However, that file is not finished being worked on, and I believe it has an issue relating to the placeholder positioning. That said, if you want to see the flow of logic, it might be easier there.

Apologies that I don't have a simple codepen/jsfiddle example ready. I know it's much easier to use in that form. I just didn't have time so figured it was better to post a short mention of my approach then nothing at all. (as I was leaning toward)

as i don't want to show placeholder in my destination, my solution:

<Droppable droppableId="delete">
  {
    (droppableProvided: DroppableProvided, droppableSnapshot) => {
      return <>
        <div ref={droppableProvided.innerRef}>
          <Icon type="delete" />
        </div>
        <div style={{display: 'none'}}>{droppableProvided.placeholder}</div>
      </>
    }
  }

</Droppable>

like this, you can wrap <div style={{display: 'none'}}>{droppableProvided.placeholder}</div> with your anyone component, eg:

<AnyComponent>
  <div style={{display: 'none'}}>{droppableProvided.placeholder}</div>
</AnyComponent>

oh, the same as @sscaff1 solution, it's repeated

I have a problem, after implementing @Utkarshbhimte solution, I find that if an item is different in height than others, I get a weird placeholder.

Thank you @Utkarshbhimte ! I liked your implementation but I need different sized list items. So I have added to it: https://codesandbox.io/s/vertical-list-5wnnz

Hi all,

Here is an article about this

@iamanas20 I have solved that issue for you!

@justsolarry there is a problem if we drag item to the right.
image

@chybisov I don't see the problem? Please explain further. Thanks!

@chybisov It is indeed a bug sir. I checked on react-beautiful-dnd examples, when they drag it out of the context, it removes the space and everything in the list moves up. So we need to find a way to hide the placeholder when they do that, but I can't seem to find the event where that happens. When I have some more time I will adjust that.

In the time being, the scenario above is less likely to occur. My list is full screen.

@chybisov @justsolarry No need for an event, just make this change:

-            {!isEmpty(placeholderProps) && (
+            {!isEmpty(placeholderProps) && snapshot.isDraggingOver && (

rbd-placeholder-dragover

@jesstelford Beautiful Sir 馃弳 I'll make the changes. I appreciate it!

Is it worth adding an example along these lines to the storybook examples. It would save others having to google to find an example demonstrating how this can be done.

I would be happy to make a PR to add this (assuming of-course @justsolarry or any of the others didn't want to).

I'm not sure if the concerns that @alexreardon raised 2 years ago still apply or not. (I've not looked into the complexities of multiple lists).

For those of you that wanted a ghosting effect (@ndrsllwngr) I modified the example given above:

https://codesandbox.io/s/react-beautiful-dnd-custom-placeholder-ghosting-61t3l

eyyy

Although I do wish the placeholder moving was a little smoother, I'm wondering what it would take to add transitions/smoothing to this.

<div style={{ maxHeight: "1px" }}>{provided.placeholder}</div>
Does the job of hiding placeholder

<div style={{ maxHeight: "1px" }}>{provided.placeholder}</div>
Does the job of hiding placeholder

This cannot work
Each element below the placeholder is translated downwards using JS by the library

Was this page helpful?
0 / 5 - 0 ratings