@@ -64,6 +64,11 @@ interface DragHelperTemplate<T = any> {
6464 context : T ;
6565}
6666
67+ /** Template that can be used to create a drag preview element. */
68+ interface DragPreviewTemplate < T = any > extends DragHelperTemplate < T > {
69+ matchSize ?: boolean ;
70+ }
71+
6772/** Point on the page or within an element. */
6873export interface Point {
6974 x : number ;
@@ -189,7 +194,7 @@ export class DragRef<T = any> {
189194 private _boundaryRect ?: ClientRect ;
190195
191196 /** Element that will be used as a template to create the draggable item's preview. */
192- private _previewTemplate ?: DragHelperTemplate | null ;
197+ private _previewTemplate ?: DragPreviewTemplate | null ;
193198
194199 /** Template for placeholder element rendered to show where a draggable would be dropped. */
195200 private _placeholderTemplate ?: DragHelperTemplate | null ;
@@ -321,7 +326,7 @@ export class DragRef<T = any> {
321326 * Registers the template that should be used for the drag preview.
322327 * @param template Template that from which to stamp out the preview.
323328 */
324- withPreviewTemplate ( template : DragHelperTemplate | null ) : this {
329+ withPreviewTemplate ( template : DragPreviewTemplate | null ) : this {
325330 this . _previewTemplate = template ;
326331 return this ;
327332 }
@@ -758,10 +763,12 @@ export class DragRef<T = any> {
758763 this . _boundaryRect = this . _boundaryElement . getBoundingClientRect ( ) ;
759764 }
760765
761- // If we have a custom preview template, the element won't be visible anyway so we avoid the
762- // extra `getBoundingClientRect` calls and just move the preview next to the cursor.
763- this . _pickupPositionInElement = this . _previewTemplate && this . _previewTemplate . template ?
764- { x : 0 , y : 0 } :
766+ // If we have a custom preview we can't know ahead of time how large it'll be so we position
767+ // it next to the cursor. The exception is when the consumer has opted into making the preview
768+ // the same size as the root element, in which case we do know the size.
769+ const previewTemplate = this . _previewTemplate ;
770+ this . _pickupPositionInElement = previewTemplate && previewTemplate . template &&
771+ ! previewTemplate . matchSize ? { x : 0 , y : 0 } :
765772 this . _getPointerPositionInElement ( referenceElement , event ) ;
766773 const pointerPosition = this . _pickupPositionOnPage = this . _getPointerPositionOnPage ( event ) ;
767774 this . _pointerDirectionDelta = { x : 0 , y : 0 } ;
@@ -861,16 +868,17 @@ export class DragRef<T = any> {
861868 previewConfig ! . context ) ;
862869 preview = getRootNode ( viewRef , this . _document ) ;
863870 this . _previewRef = viewRef ;
864- preview . style . transform =
865- getTransform ( this . _pickupPositionOnPage . x , this . _pickupPositionOnPage . y ) ;
871+
872+ if ( previewConfig ! . matchSize ) {
873+ matchElementSize ( preview , this . _rootElement ) ;
874+ } else {
875+ preview . style . transform =
876+ getTransform ( this . _pickupPositionOnPage . x , this . _pickupPositionOnPage . y ) ;
877+ }
866878 } else {
867879 const element = this . _rootElement ;
868- const elementRect = element . getBoundingClientRect ( ) ;
869-
870880 preview = deepCloneNode ( element ) ;
871- preview . style . width = `${ elementRect . width } px` ;
872- preview . style . height = `${ elementRect . height } px` ;
873- preview . style . transform = getTransform ( elementRect . left , elementRect . top ) ;
881+ matchElementSize ( preview , element ) ;
874882 }
875883
876884 extendStyles ( preview . style , {
@@ -1279,3 +1287,16 @@ function getRootNode(viewRef: EmbeddedViewRef<any>, _document: Document): HTMLEl
12791287
12801288 return rootNode as HTMLElement ;
12811289}
1290+
1291+ /**
1292+ * Matches the target element's size to the source's size.
1293+ * @param target Element that needs to be resized.
1294+ * @param source Element whose size needs to be matched.
1295+ */
1296+ function matchElementSize ( target : HTMLElement , source : HTMLElement ) : void {
1297+ const sourceRect = source . getBoundingClientRect ( ) ;
1298+
1299+ target . style . width = `${ sourceRect . width } px` ;
1300+ target . style . height = `${ sourceRect . height } px` ;
1301+ target . style . transform = getTransform ( sourceRect . left , sourceRect . top ) ;
1302+ }
0 commit comments