angular / angular/components

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

オープン
#25,045 コメント 1 件 リアクション 2 件 担当者 0 名 GitHub で見る
area: cdk/drag-drop feature P3
主要言語
TypeScript
スター
25k
フォーク
6.8k
平均マージ
1日 8時間
マージ済み PR(30日)
91

説明

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

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

issue に記載されている CdkDropList と CdkDrag のサイズおよび位置の計算エントリポイントから始め、ドロップ領域を拡大したケースと、動的に変更されたアイテムのケースを再現します。完了の条件は、サポートされている手動トリガーによって、ドラッグ中にドロップゾーンとドラッグアイテムのジオメトリが更新されることです。リストのみの場合とアイテムのサイズ変更のユースケースも含まれます。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
angular, typescript
領域
frontend
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。