-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Support nesting DragDropContext #302
Comments
What's the reasoning behind not supporting nested When rendering a tree structure of n depth where each tier has a collection of sortable items, the logic in the top level's For example, in the snippet you refactored here, https://codesandbox.io/s/vmm0nplz5y, the Any plans to include nested |
It is possible @epferrari!! And as you said - it would make some things easier. This issue is more a stop gap - at least warn people that it is currently not supported. A lot of the features are already context aware - however some are not. It would be a matter of going through and ensuring everything works as intended in nested contexts - adding tests and so on. |
@alexreardon please add this feature, would like to be able to do a WorkFlowy clone! |
For anything file-browser like, we need to be able to drop "files" into "folders" at the same level. |
Just for the sake of nitpicking, without more freedom, react-beautiful-dnd's name is misleading. It should be "react-beautiful-reordering-with-dnd" :) |
We hope to support this feature soon. We try to ensure that everything we build is done well with all the details thought through. From there we can grow feature sets and expand use cases. |
This will be great. I have nested modules that are isolated from each other and aren't reliant on the parent ordering. 👍 |
First thing: awesome library, it seems incredibly polished. Thank you for open-sourcing this. Alternative solution to this problem: Would it be possible to move EDIT: I just saw this comment: #498 (comment). That is exactly what I'm talking about. It looks you all have awareness of this idea already. I guess just count this as me throwing in my support! Thanks again. |
I made a wrapper that allows passing With those caveats, here is the code: https://gist.github.com/dwaltrip/005a520aeaebe328a8a33998be2babc4 Change the import statement to use |
I love the passion behind this issue. Please keep your ideas coming! We hope to look at this after #484 ships (it is a beast!) |
Just an idea: Having the ability of disabling In my case, I need to force a re-render (with a condition) to allow "nested" drag and drops. Here is an example: But this leads to a bad UX (hello flickering), and performance issues due to the re-render. So, if Any thoughts? Can this be achieved in a different way? Thanks! |
Any news on plans for implementing this? |
Just FYI to anyone else looking for this functionality, I used a separate library for DnD nesting: Works really nicely |
@alexreardon a colleague and I have implemented a way to do this, I can submit a PR for your review if you would like. The way we solved it is by having the child contexts determine that they are nested, and subscribe the onDrag* handlers to the parent context return (
<NestedDragDropContext.Consumer>
{context => {
if (context) {
// if context is defined, render as nested consumer using it.
return <NestedDragDropContextConsumer{...this.props} context={context} />;
} else {
// if context is undefined, render as parent/provider to create a new context.
return <NestedDragDropContextProvider {...this.props} />;
}
}}
</NestedDragDropContext.Consumer>
);
class NestedDragDropContextProvider extends React.Component {
private _onDragStartListeners: OnDragStartFunc[];
private _onDragEndListeners: OnDragEndFunc[];
private _context: INestedDragDropContextData;
constructor(props) {
super(props);
this._onDragStartListeners = [];
this._onDragEndListeners = [];
this._context = {
subscribeOnDragStart: this._subscribeOnDragStartListeners,
subscribeOnDragEnd: this._subscribeOnDragEndListeners
};
}
public render(): JSX.Element {
return (
<NestedDragDropContextContext.Provider value={this._context}>
<DragDropContext onDragStart={this._onDragStart} onDragEnd={this._onDragEnd}>
<NestedDragDropContextConsumer {...this.props} context={this._context} />;
</DragDropContext>
</NestedDragDropContextContext.Provider>
);
}
/**
* Track provided onDragStart listener function to receive future onDragStart events.
* Returns function to unsubscribe and remove this listener from the collection.
*/
private _subscribeOnDragStartListeners = (listener: OnDragStartFunc): UnsubscribeFunc => {
this._onDragStartListeners.push(listener);
return () => {
this._onDragStartListeners = this._onDragStartListeners.filter(l => l != listener);
};
};
/**
* Track provided onDragEnd listener function to receive future onDragEnd events.
* Returns function to unsubscribe and remove this listener from the collection.
*/
private _subscribeOnDragEndListeners = (listener: OnDragEndFunc): UnsubscribeFunc => {
this._onDragEndListeners.push(listener);
return () => {
this._onDragEndListeners = this._onDragEndListeners.filter(l => l != listener);
};
};
/**
* Pass onDragStart events from the react-beautiful-dnd DragDropContext to all registered listeners.
*/
private _onDragStart = (initial: DragStart, provided: HookProvided): void => {
this._onDragStartListeners.forEach(listener => listener && listener(initial, provided));
};
/**
* Pass onDragEnd events from the react-beautiful-dnd DragDropContext to all registered listeners.
*/
private _onDragEnd = (result: DropResult, provided: HookProvided): void => {
this._onDragEndListeners.forEach(listener => listener && listener(result, provided));
};
}
class NestedDragDropContextConsumer extends React.Component {
private _unsubscribeOnDragStart: UnsubscribeFunc;
private _unsubscribeOnDragEnd: UnsubscribeFunc;
public render(): JSX.Element {
return <>{this.props.children}</>;
}
public componentWillMount() {
const { context, onDragStart, onDragEnd } = this.props;
if (onDragStart) {
this._unsubscribeOnDragStart = context.subscribeOnDragStart(onDragStart);
}
if (onDragEnd) {
this._unsubscribeOnDragEnd = context.subscribeOnDragEnd(onDragEnd);
}
}
public componentWillUnmount() {
if (this._unsubscribeOnDragStart) {
this._unsubscribeOnDragStart();
}
if (this._unsubscribeOnDragEnd) {
this._unsubscribeOnDragEnd();
}
}
} The parent context will multicast the drag drop events to the nested children with this approach. Right now, this wraps the library's DragDropContext, but we could modify the DragDropContext itself to make this multicasting of events transparent to the user. What are your thoughts? |
@abettadapur can you show a demo? |
Do you have any update for this? Thanks :) |
@navneet-g, can you show some code here? |
can you help me? I want to do this, https://codesandbox.io/s/34l0l98x75, but with the subfields also changing.
Drap |
Hi there, See here: https://codesandbox.io/vnzw490w0y |
@elvisvasc it seems like your https://codesandbox.io/ demo is down, would you mind reposting it again? thank you in advance! |
@ndrsllwngr , check this link: https://codesandbox.io/embed/vnzw490w0y |
hi! i understand that some time has passed, but is your solution still alive?) how to use it? what is |
Any news about this feature? |
Any https://codesandbox.io for nested list items for multi drag examples? |
I hope this feature implemented in the react-beautiful-dnd, its must-have feature. In the meanwhile, you may want to look at the atlaskit tree component, you may find it useful. https://atlaskit.atlassian.com/packages/core/tree/example/drag_and_drop_with_nesting |
@vestimir, hi! I assume you're trying to implement some sort of tree, which has branches and leaves and stuff. I wanted to do some sort of it, and wanted to be able to drag any leaf/branch and drop it in any other branch/root. And i managed it only after rearranging drop areas in order, when they are not overlayed by others. I mean, drop zone of a child is not on top of larger drop zone of parent, but comes after it! Does it make sense?) |
@DarthVitalus nope it's not a tree view – it's a CMS – we want to use the DND for managing idividual widgets on pages, and the widgets can have nested DND in their settings (for example to reorder UI cards inside of a card widget). |
Hello @alexreardon, what is going on with this feature ? |
Hi @alexreardon Is there any news on this feature? I assume it's not started yet, is it planned for some near future, I'd like to switch my current implementation to this library, but I'm not able to without nested drag/drop logic. So my question is should I wait for it, or should I just carry on with what I already have? |
Hey guys! Check out this sandbox: https://codesandbox.io/embed/vnzw490w0y |
@elvisvasc thanks, but that's not actually what this issue is about, those kind of examples do exist already. Issue here is with changing droppable targets, something like CMS as someone said earlier, so that in your example you could take one item from one list and put it on lists level, so it can be sorted with lists, or taking list and putting it into another list etc. |
Nested drag/drop is available using It works great if your nested drag and drops are relatively close to each other (they can span multiple components) but not if your Context is rendered too high up in the app. |
@grrowl I saw that example, but it doesn't support what I'm looking for, on the side those flaws you've mentioned, there is still one bigger problem - you can't pull item from "top list" into "nested list" or vice versa. In given example "nested list" is seen as an element of a "top list", and other "top list" elements can't be added to "nested list" (because it's just another element), and that is basically the core of my issue |
Im looking for same solution as you @Ackos95 i just use workaround by handling all by myself i found this example as start point.. https://codesandbox.io/s/5v2yvpjn7n?file=/ServiceCommandUnit.js:2242-2253 |
I have a project which looks like was nesting DragDropContext's but it looks like in react-beautiful-dnd 11 it was working, however I needed to upgrade and in 12 and 13 it is not? Here is an example of it working: And if you change the version to 12 or 13, reload the right panel and then try drag sub items, Has anyone come across this? I see here the solution is to not nest the DragDropContext, So in the mean time ill look at what refactor is required to do this. |
@Serivy i noticed the same, works in version 11 but broken after that |
Hi, Is there any way we can implement DnD with mutliple depths? |
Hi , Any example with multi-level/nesting drag and drop? |
@Serivy I’m facing the same problem, did you find any workaround without removing the nested context? |
@alexmarqs It is a bad work around but it managed something for my legacy purposes. I created a new component |
Thanks @Serivy for sharing your workaround, in my case I just implemented an event mechanism, in the parent |
Nesting |
Currently this is not supported. It would be worth adding a warning if this is detected
The text was updated successfully, but these errors were encountered: