angular / angular/components

feat(DragDropModule): Allow manual triggering of CdkDropList and CdkDragElement size recomputation

Offen
#25,045 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
area: cdk/drag-drop feature P3
Vorherrschende Sprache
TypeScript
Sterne
25k
Forks
6.8k
Ø Merge
1 T. 8 Std.
Gemergte PRs (30 T.)
91

Beschreibung

### Feature Description

From what I can tell about how Material Drag and Drop works, on drag start, the size of all drag elements is calculated and then stored. I assume that it's only done once to optimise performance which makes sense.

However, building higher levels of UX responsiveness into DropLists and Drag items often means altering their size. The particular example that I am working with at the moment is that of enlarging a drop area when the drag begins.

I would like to be able to manually trigger the CdkDropList to re-compute the height of both itself and any components within it (or at the very least just itself) so that it can respond to changes in the UI.

e.g. to have a method like: `cdkDropList.recomputeSizes()`

### Use Case

To make it easier for users to drag items into an empty list, I'd like to enlarge a target drop Area on drag start. And so on drag start, I apply a class to the DropList that changes its height. The problem is that while the DropList itself grows in height, the effective drop-zone does not. It seems that although the CdkDropList has increased in height, Angular is using its own internal calculation of the original height to determine the dropZone.

https://user-images.githubusercontent.com/168592/172834247-26f056dc-2846-4a5c-b34f-e766e04cadc3.mov

In the recording above you can see how the drop area is enlarged on drag start. The `cdkDropList` element is indicated using the green dotted line.

However you can see that although the DropList is enlarged to make it easier to drop the CdkDrag item into it, the majority of the list area will not receive the CdkDrag item. In fact it seems that the DropList will only receive the CdkDrag item once it enters the drop area that the list originally covered before it was enlarged.

The same effect is not observed when the minimum height set statically to be the larger size:

https://user-images.githubusercontent.com/168592/172837498-1b57ce31-5378-44b3-8e56-c143be296f66.mov

I would like to be able to trigger the list to recompute its own area so that it can behave correctly relative to its new, larger size.

### Bonus extra
Creating advanced drag and drop behaviour can require resizing items in the list as well as just the list itself. It would be really nice to be able to trigger the DropList to be able to recompute the size of all elements and not just the drop area.

An example of this is collapsing elements in the list when a drag begins. The example below illustrates using a single-tiered DropList to mimic the behaviour of a nested list. The mimicry is done by removing the child elements entirely from the list before the drag begins,

https://user-images.githubusercontent.com/168592/172834522-f9834d85-245a-4da5-ad90-23d409334907.mov

Although the example above illustrates what looks like a nested list, it is in fact just a single-level list that uses indentation to create the illusion of nesting. The "child" nodes are removed from the list on drag start and then re-inserted after drag finish. Happily, this seems to work robustly.

However it would be extremely useful to be able to change the items in the list during the drag process itself. Imagine for instance dragging an item over a folder that you wish to open. I can imagine that inserting items into a list during drag might be very complicated to code. However, a simple workaround could be achieved by having the items in the list from the start but with zero height and then enlarging their height when the parent folder opens.

However this would again require the list to recompute the sizing of all elements so that we don't end up with an effect similar to that below. In this example, the child nodes aren't consistently removed from the tree before CdkDrag computes the item heights. And so the DropList calculates the sizing of all elements within it and only then are some of them removed - which results in the peculiar effect we see.

https://user-images.githubusercontent.com/168592/172831293-fb17441d-926b-41e3-9a37-2982bffaa444.mov

If my understanding of the system is correct then all of this could potentially be worked around *if* it were possible to manully trigger recomputation of the size and position of `CdkDropList` and `CdkDrag` elements

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne bei den im Issue beschriebenen Einstiegspunkten für die Größen- und Positionsberechnung von CdkDropList und CdkDrag und reproduziere die Fälle mit vergrößertem Drop-Bereich und dynamisch geänderten Elementen. Erledigt ist dies, wenn ein unterstützter manueller Trigger während eines Drags die Geometrie der Drop-Zone und des Drag-Elements aktualisiert, einschließlich der Anwendungsfälle, die nur die Liste betreffen, und der Größenänderung von Elementen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
angular, typescript
Bereich
frontend
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.