angular / angular/components

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

Aperta
#25,045 1 commento 2 reazioni 0 assegnatari Vedi su GitHub
area: cdk/drag-drop feature P3
Lingua principale
TypeScript
Stelle
25k
Fork
6.8k
Merge medio
1g 8h
PR unite (30g)
91

Descrizione

### 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

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia dai punti di ingresso del calcolo delle dimensioni e della posizione di CdkDropList e CdkDrag descritti nell’issue, riproducendo i casi di un’area di drop ampliata e di elementi modificati dinamicamente. Il lavoro è completato quando un trigger manuale supportato aggiorna la geometria della zona di drop e dell’elemento trascinato durante un drag, inclusi i casi d’uso che riguardano solo la lista e il ridimensionamento degli elementi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
angular, typescript
Ambito
frontend
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.