1 | /**
|
---|
2 | * @license
|
---|
3 | * Copyright Google LLC All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
6 | * found in the LICENSE file at https://angular.io/license
|
---|
7 | */
|
---|
8 | import { ElementRef, NgZone, ViewContainerRef, TemplateRef } from '@angular/core';
|
---|
9 | import { ViewportRuler } from '@angular/cdk/scrolling';
|
---|
10 | import { Direction } from '@angular/cdk/bidi';
|
---|
11 | import { Subject, Observable } from 'rxjs';
|
---|
12 | import { DropListRefInternal as DropListRef } from './drop-list-ref';
|
---|
13 | import { DragDropRegistry } from './drag-drop-registry';
|
---|
14 | /** Object that can be used to configure the behavior of DragRef. */
|
---|
15 | export interface DragRefConfig {
|
---|
16 | /**
|
---|
17 | * Minimum amount of pixels that the user should
|
---|
18 | * drag, before the CDK initiates a drag sequence.
|
---|
19 | */
|
---|
20 | dragStartThreshold: number;
|
---|
21 | /**
|
---|
22 | * Amount the pixels the user should drag before the CDK
|
---|
23 | * considers them to have changed the drag direction.
|
---|
24 | */
|
---|
25 | pointerDirectionChangeThreshold: number;
|
---|
26 | /** `z-index` for the absolutely-positioned elements that are created by the drag item. */
|
---|
27 | zIndex?: number;
|
---|
28 | /** Ref that the current drag item is nested in. */
|
---|
29 | parentDragRef?: DragRef;
|
---|
30 | }
|
---|
31 | /**
|
---|
32 | * Internal compile-time-only representation of a `DragRef`.
|
---|
33 | * Used to avoid circular import issues between the `DragRef` and the `DropListRef`.
|
---|
34 | * @docs-private
|
---|
35 | */
|
---|
36 | export interface DragRefInternal extends DragRef {
|
---|
37 | }
|
---|
38 | /** Template that can be used to create a drag helper element (e.g. a preview or a placeholder). */
|
---|
39 | interface DragHelperTemplate<T = any> {
|
---|
40 | template: TemplateRef<T> | null;
|
---|
41 | viewContainer: ViewContainerRef;
|
---|
42 | context: T;
|
---|
43 | }
|
---|
44 | /** Template that can be used to create a drag preview element. */
|
---|
45 | interface DragPreviewTemplate<T = any> extends DragHelperTemplate<T> {
|
---|
46 | matchSize?: boolean;
|
---|
47 | }
|
---|
48 | /** Point on the page or within an element. */
|
---|
49 | export interface Point {
|
---|
50 | x: number;
|
---|
51 | y: number;
|
---|
52 | }
|
---|
53 | /**
|
---|
54 | * Possible places into which the preview of a drag item can be inserted.
|
---|
55 | * - `global` - Preview will be inserted at the bottom of the `<body>`. The advantage is that
|
---|
56 | * you don't have to worry about `overflow: hidden` or `z-index`, but the item won't retain
|
---|
57 | * its inherited styles.
|
---|
58 | * - `parent` - Preview will be inserted into the parent of the drag item. The advantage is that
|
---|
59 | * inherited styles will be preserved, but it may be clipped by `overflow: hidden` or not be
|
---|
60 | * visible due to `z-index`. Furthermore, the preview is going to have an effect over selectors
|
---|
61 | * like `:nth-child` and some flexbox configurations.
|
---|
62 | * - `ElementRef<HTMLElement> | HTMLElement` - Preview will be inserted into a specific element.
|
---|
63 | * Same advantages and disadvantages as `parent`.
|
---|
64 | */
|
---|
65 | export declare type PreviewContainer = 'global' | 'parent' | ElementRef<HTMLElement> | HTMLElement;
|
---|
66 | /**
|
---|
67 | * Reference to a draggable item. Used to manipulate or dispose of the item.
|
---|
68 | */
|
---|
69 | export declare class DragRef<T = any> {
|
---|
70 | private _config;
|
---|
71 | private _document;
|
---|
72 | private _ngZone;
|
---|
73 | private _viewportRuler;
|
---|
74 | private _dragDropRegistry;
|
---|
75 | /** Element displayed next to the user's pointer while the element is dragged. */
|
---|
76 | private _preview;
|
---|
77 | /** Reference to the view of the preview element. */
|
---|
78 | private _previewRef;
|
---|
79 | /** Container into which to insert the preview. */
|
---|
80 | private _previewContainer;
|
---|
81 | /** Reference to the view of the placeholder element. */
|
---|
82 | private _placeholderRef;
|
---|
83 | /** Element that is rendered instead of the draggable item while it is being sorted. */
|
---|
84 | private _placeholder;
|
---|
85 | /** Coordinates within the element at which the user picked up the element. */
|
---|
86 | private _pickupPositionInElement;
|
---|
87 | /** Coordinates on the page at which the user picked up the element. */
|
---|
88 | private _pickupPositionOnPage;
|
---|
89 | /**
|
---|
90 | * Anchor node used to save the place in the DOM where the element was
|
---|
91 | * picked up so that it can be restored at the end of the drag sequence.
|
---|
92 | */
|
---|
93 | private _anchor;
|
---|
94 | /**
|
---|
95 | * CSS `transform` applied to the element when it isn't being dragged. We need a
|
---|
96 | * passive transform in order for the dragged element to retain its new position
|
---|
97 | * after the user has stopped dragging and because we need to know the relative
|
---|
98 | * position in case they start dragging again. This corresponds to `element.style.transform`.
|
---|
99 | */
|
---|
100 | private _passiveTransform;
|
---|
101 | /** CSS `transform` that is applied to the element while it's being dragged. */
|
---|
102 | private _activeTransform;
|
---|
103 | /** Inline `transform` value that the element had before the first dragging sequence. */
|
---|
104 | private _initialTransform?;
|
---|
105 | /**
|
---|
106 | * Whether the dragging sequence has been started. Doesn't
|
---|
107 | * necessarily mean that the element has been moved.
|
---|
108 | */
|
---|
109 | private _hasStartedDragging;
|
---|
110 | /** Whether the element has moved since the user started dragging it. */
|
---|
111 | private _hasMoved;
|
---|
112 | /** Drop container in which the DragRef resided when dragging began. */
|
---|
113 | private _initialContainer;
|
---|
114 | /** Index at which the item started in its initial container. */
|
---|
115 | private _initialIndex;
|
---|
116 | /** Cached positions of scrollable parent elements. */
|
---|
117 | private _parentPositions;
|
---|
118 | /** Emits when the item is being moved. */
|
---|
119 | private readonly _moveEvents;
|
---|
120 | /** Keeps track of the direction in which the user is dragging along each axis. */
|
---|
121 | private _pointerDirectionDelta;
|
---|
122 | /** Pointer position at which the last change in the delta occurred. */
|
---|
123 | private _pointerPositionAtLastDirectionChange;
|
---|
124 | /** Position of the pointer at the last pointer event. */
|
---|
125 | private _lastKnownPointerPosition;
|
---|
126 | /**
|
---|
127 | * Root DOM node of the drag instance. This is the element that will
|
---|
128 | * be moved around as the user is dragging.
|
---|
129 | */
|
---|
130 | private _rootElement;
|
---|
131 | /**
|
---|
132 | * Nearest ancestor SVG, relative to which coordinates are calculated if dragging SVGElement
|
---|
133 | */
|
---|
134 | private _ownerSVGElement;
|
---|
135 | /**
|
---|
136 | * Inline style value of `-webkit-tap-highlight-color` at the time the
|
---|
137 | * dragging was started. Used to restore the value once we're done dragging.
|
---|
138 | */
|
---|
139 | private _rootElementTapHighlight;
|
---|
140 | /** Subscription to pointer movement events. */
|
---|
141 | private _pointerMoveSubscription;
|
---|
142 | /** Subscription to the event that is dispatched when the user lifts their pointer. */
|
---|
143 | private _pointerUpSubscription;
|
---|
144 | /** Subscription to the viewport being scrolled. */
|
---|
145 | private _scrollSubscription;
|
---|
146 | /** Subscription to the viewport being resized. */
|
---|
147 | private _resizeSubscription;
|
---|
148 | /**
|
---|
149 | * Time at which the last touch event occurred. Used to avoid firing the same
|
---|
150 | * events multiple times on touch devices where the browser will fire a fake
|
---|
151 | * mouse event for each touch event, after a certain time.
|
---|
152 | */
|
---|
153 | private _lastTouchEventTime;
|
---|
154 | /** Time at which the last dragging sequence was started. */
|
---|
155 | private _dragStartTime;
|
---|
156 | /** Cached reference to the boundary element. */
|
---|
157 | private _boundaryElement;
|
---|
158 | /** Whether the native dragging interactions have been enabled on the root element. */
|
---|
159 | private _nativeInteractionsEnabled;
|
---|
160 | /** Cached dimensions of the preview element. */
|
---|
161 | private _previewRect?;
|
---|
162 | /** Cached dimensions of the boundary element. */
|
---|
163 | private _boundaryRect?;
|
---|
164 | /** Element that will be used as a template to create the draggable item's preview. */
|
---|
165 | private _previewTemplate?;
|
---|
166 | /** Template for placeholder element rendered to show where a draggable would be dropped. */
|
---|
167 | private _placeholderTemplate?;
|
---|
168 | /** Elements that can be used to drag the draggable item. */
|
---|
169 | private _handles;
|
---|
170 | /** Registered handles that are currently disabled. */
|
---|
171 | private _disabledHandles;
|
---|
172 | /** Droppable container that the draggable is a part of. */
|
---|
173 | private _dropContainer?;
|
---|
174 | /** Layout direction of the item. */
|
---|
175 | private _direction;
|
---|
176 | /** Ref that the current drag item is nested in. */
|
---|
177 | private _parentDragRef;
|
---|
178 | /**
|
---|
179 | * Cached shadow root that the element is placed in. `null` means that the element isn't in
|
---|
180 | * the shadow DOM and `undefined` means that it hasn't been resolved yet. Should be read via
|
---|
181 | * `_getShadowRoot`, not directly.
|
---|
182 | */
|
---|
183 | private _cachedShadowRoot;
|
---|
184 | /** Axis along which dragging is locked. */
|
---|
185 | lockAxis: 'x' | 'y';
|
---|
186 | /**
|
---|
187 | * Amount of milliseconds to wait after the user has put their
|
---|
188 | * pointer down before starting to drag the element.
|
---|
189 | */
|
---|
190 | dragStartDelay: number | {
|
---|
191 | touch: number;
|
---|
192 | mouse: number;
|
---|
193 | };
|
---|
194 | /** Class to be added to the preview element. */
|
---|
195 | previewClass: string | string[] | undefined;
|
---|
196 | /** Whether starting to drag this element is disabled. */
|
---|
197 | get disabled(): boolean;
|
---|
198 | set disabled(value: boolean);
|
---|
199 | private _disabled;
|
---|
200 | /** Emits as the drag sequence is being prepared. */
|
---|
201 | readonly beforeStarted: Subject<void>;
|
---|
202 | /** Emits when the user starts dragging the item. */
|
---|
203 | readonly started: Subject<{
|
---|
204 | source: DragRef;
|
---|
205 | }>;
|
---|
206 | /** Emits when the user has released a drag item, before any animations have started. */
|
---|
207 | readonly released: Subject<{
|
---|
208 | source: DragRef;
|
---|
209 | }>;
|
---|
210 | /** Emits when the user stops dragging an item in the container. */
|
---|
211 | readonly ended: Subject<{
|
---|
212 | source: DragRef;
|
---|
213 | distance: Point;
|
---|
214 | dropPoint: Point;
|
---|
215 | }>;
|
---|
216 | /** Emits when the user has moved the item into a new container. */
|
---|
217 | readonly entered: Subject<{
|
---|
218 | container: DropListRef;
|
---|
219 | item: DragRef;
|
---|
220 | currentIndex: number;
|
---|
221 | }>;
|
---|
222 | /** Emits when the user removes the item its container by dragging it into another container. */
|
---|
223 | readonly exited: Subject<{
|
---|
224 | container: DropListRef;
|
---|
225 | item: DragRef;
|
---|
226 | }>;
|
---|
227 | /** Emits when the user drops the item inside a container. */
|
---|
228 | readonly dropped: Subject<{
|
---|
229 | previousIndex: number;
|
---|
230 | currentIndex: number;
|
---|
231 | item: DragRef;
|
---|
232 | container: DropListRef;
|
---|
233 | previousContainer: DropListRef;
|
---|
234 | distance: Point;
|
---|
235 | dropPoint: Point;
|
---|
236 | isPointerOverContainer: boolean;
|
---|
237 | }>;
|
---|
238 | /**
|
---|
239 | * Emits as the user is dragging the item. Use with caution,
|
---|
240 | * because this event will fire for every pixel that the user has dragged.
|
---|
241 | */
|
---|
242 | readonly moved: Observable<{
|
---|
243 | source: DragRef;
|
---|
244 | pointerPosition: {
|
---|
245 | x: number;
|
---|
246 | y: number;
|
---|
247 | };
|
---|
248 | event: MouseEvent | TouchEvent;
|
---|
249 | distance: Point;
|
---|
250 | delta: {
|
---|
251 | x: -1 | 0 | 1;
|
---|
252 | y: -1 | 0 | 1;
|
---|
253 | };
|
---|
254 | }>;
|
---|
255 | /** Arbitrary data that can be attached to the drag item. */
|
---|
256 | data: T;
|
---|
257 | /**
|
---|
258 | * Function that can be used to customize the logic of how the position of the drag item
|
---|
259 | * is limited while it's being dragged. Gets called with a point containing the current position
|
---|
260 | * of the user's pointer on the page and should return a point describing where the item should
|
---|
261 | * be rendered.
|
---|
262 | */
|
---|
263 | constrainPosition?: (point: Point, dragRef: DragRef) => Point;
|
---|
264 | constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
|
---|
265 | /**
|
---|
266 | * Returns the element that is being used as a placeholder
|
---|
267 | * while the current element is being dragged.
|
---|
268 | */
|
---|
269 | getPlaceholderElement(): HTMLElement;
|
---|
270 | /** Returns the root draggable element. */
|
---|
271 | getRootElement(): HTMLElement;
|
---|
272 | /**
|
---|
273 | * Gets the currently-visible element that represents the drag item.
|
---|
274 | * While dragging this is the placeholder, otherwise it's the root element.
|
---|
275 | */
|
---|
276 | getVisibleElement(): HTMLElement;
|
---|
277 | /** Registers the handles that can be used to drag the element. */
|
---|
278 | withHandles(handles: (HTMLElement | ElementRef<HTMLElement>)[]): this;
|
---|
279 | /**
|
---|
280 | * Registers the template that should be used for the drag preview.
|
---|
281 | * @param template Template that from which to stamp out the preview.
|
---|
282 | */
|
---|
283 | withPreviewTemplate(template: DragPreviewTemplate | null): this;
|
---|
284 | /**
|
---|
285 | * Registers the template that should be used for the drag placeholder.
|
---|
286 | * @param template Template that from which to stamp out the placeholder.
|
---|
287 | */
|
---|
288 | withPlaceholderTemplate(template: DragHelperTemplate | null): this;
|
---|
289 | /**
|
---|
290 | * Sets an alternate drag root element. The root element is the element that will be moved as
|
---|
291 | * the user is dragging. Passing an alternate root element is useful when trying to enable
|
---|
292 | * dragging on an element that you might not have access to.
|
---|
293 | */
|
---|
294 | withRootElement(rootElement: ElementRef<HTMLElement> | HTMLElement): this;
|
---|
295 | /**
|
---|
296 | * Element to which the draggable's position will be constrained.
|
---|
297 | */
|
---|
298 | withBoundaryElement(boundaryElement: ElementRef<HTMLElement> | HTMLElement | null): this;
|
---|
299 | /** Sets the parent ref that the ref is nested in. */
|
---|
300 | withParent(parent: DragRef<unknown> | null): this;
|
---|
301 | /** Removes the dragging functionality from the DOM element. */
|
---|
302 | dispose(): void;
|
---|
303 | /** Checks whether the element is currently being dragged. */
|
---|
304 | isDragging(): boolean;
|
---|
305 | /** Resets a standalone drag item to its initial position. */
|
---|
306 | reset(): void;
|
---|
307 | /**
|
---|
308 | * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.
|
---|
309 | * @param handle Handle element that should be disabled.
|
---|
310 | */
|
---|
311 | disableHandle(handle: HTMLElement): void;
|
---|
312 | /**
|
---|
313 | * Enables a handle, if it has been disabled.
|
---|
314 | * @param handle Handle element to be enabled.
|
---|
315 | */
|
---|
316 | enableHandle(handle: HTMLElement): void;
|
---|
317 | /** Sets the layout direction of the draggable item. */
|
---|
318 | withDirection(direction: Direction): this;
|
---|
319 | /** Sets the container that the item is part of. */
|
---|
320 | _withDropContainer(container: DropListRef): void;
|
---|
321 | /**
|
---|
322 | * Gets the current position in pixels the draggable outside of a drop container.
|
---|
323 | */
|
---|
324 | getFreeDragPosition(): Readonly<Point>;
|
---|
325 | /**
|
---|
326 | * Sets the current position in pixels the draggable outside of a drop container.
|
---|
327 | * @param value New position to be set.
|
---|
328 | */
|
---|
329 | setFreeDragPosition(value: Point): this;
|
---|
330 | /**
|
---|
331 | * Sets the container into which to insert the preview element.
|
---|
332 | * @param value Container into which to insert the preview.
|
---|
333 | */
|
---|
334 | withPreviewContainer(value: PreviewContainer): this;
|
---|
335 | /** Updates the item's sort order based on the last-known pointer position. */
|
---|
336 | _sortFromLastPointerPosition(): void;
|
---|
337 | /** Unsubscribes from the global subscriptions. */
|
---|
338 | private _removeSubscriptions;
|
---|
339 | /** Destroys the preview element and its ViewRef. */
|
---|
340 | private _destroyPreview;
|
---|
341 | /** Destroys the placeholder element and its ViewRef. */
|
---|
342 | private _destroyPlaceholder;
|
---|
343 | /** Handler for the `mousedown`/`touchstart` events. */
|
---|
344 | private _pointerDown;
|
---|
345 | /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
|
---|
346 | private _pointerMove;
|
---|
347 | /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
|
---|
348 | private _pointerUp;
|
---|
349 | /**
|
---|
350 | * Clears subscriptions and stops the dragging sequence.
|
---|
351 | * @param event Browser event object that ended the sequence.
|
---|
352 | */
|
---|
353 | private _endDragSequence;
|
---|
354 | /** Starts the dragging sequence. */
|
---|
355 | private _startDragSequence;
|
---|
356 | /**
|
---|
357 | * Sets up the different variables and subscriptions
|
---|
358 | * that will be necessary for the dragging sequence.
|
---|
359 | * @param referenceElement Element that started the drag sequence.
|
---|
360 | * @param event Browser event object that started the sequence.
|
---|
361 | */
|
---|
362 | private _initializeDragSequence;
|
---|
363 | /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */
|
---|
364 | private _cleanupDragArtifacts;
|
---|
365 | /**
|
---|
366 | * Updates the item's position in its drop container, or moves it
|
---|
367 | * into a new one, depending on its current drag position.
|
---|
368 | */
|
---|
369 | private _updateActiveDropContainer;
|
---|
370 | /**
|
---|
371 | * Creates the element that will be rendered next to the user's pointer
|
---|
372 | * and will be used as a preview of the element that is being dragged.
|
---|
373 | */
|
---|
374 | private _createPreviewElement;
|
---|
375 | /**
|
---|
376 | * Animates the preview element from its current position to the location of the drop placeholder.
|
---|
377 | * @returns Promise that resolves when the animation completes.
|
---|
378 | */
|
---|
379 | private _animatePreviewToPlaceholder;
|
---|
380 | /** Creates an element that will be shown instead of the current element while dragging. */
|
---|
381 | private _createPlaceholderElement;
|
---|
382 | /**
|
---|
383 | * Figures out the coordinates at which an element was picked up.
|
---|
384 | * @param referenceElement Element that initiated the dragging.
|
---|
385 | * @param event Event that initiated the dragging.
|
---|
386 | */
|
---|
387 | private _getPointerPositionInElement;
|
---|
388 | /** Determines the point of the page that was touched by the user. */
|
---|
389 | private _getPointerPositionOnPage;
|
---|
390 | /** Gets the pointer position on the page, accounting for any position constraints. */
|
---|
391 | private _getConstrainedPointerPosition;
|
---|
392 | /** Updates the current drag delta, based on the user's current pointer position on the page. */
|
---|
393 | private _updatePointerDirectionDelta;
|
---|
394 | /** Toggles the native drag interactions, based on how many handles are registered. */
|
---|
395 | private _toggleNativeDragInteractions;
|
---|
396 | /** Removes the manually-added event listeners from the root element. */
|
---|
397 | private _removeRootElementListeners;
|
---|
398 | /**
|
---|
399 | * Applies a `transform` to the root element, taking into account any existing transforms on it.
|
---|
400 | * @param x New transform value along the X axis.
|
---|
401 | * @param y New transform value along the Y axis.
|
---|
402 | */
|
---|
403 | private _applyRootElementTransform;
|
---|
404 | /**
|
---|
405 | * Applies a `transform` to the preview, taking into account any existing transforms on it.
|
---|
406 | * @param x New transform value along the X axis.
|
---|
407 | * @param y New transform value along the Y axis.
|
---|
408 | */
|
---|
409 | private _applyPreviewTransform;
|
---|
410 | /**
|
---|
411 | * Gets the distance that the user has dragged during the current drag sequence.
|
---|
412 | * @param currentPosition Current position of the user's pointer.
|
---|
413 | */
|
---|
414 | private _getDragDistance;
|
---|
415 | /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */
|
---|
416 | private _cleanupCachedDimensions;
|
---|
417 | /**
|
---|
418 | * Checks whether the element is still inside its boundary after the viewport has been resized.
|
---|
419 | * If not, the position is adjusted so that the element fits again.
|
---|
420 | */
|
---|
421 | private _containInsideBoundaryOnResize;
|
---|
422 | /** Gets the drag start delay, based on the event type. */
|
---|
423 | private _getDragStartDelay;
|
---|
424 | /** Updates the internal state of the draggable element when scrolling has occurred. */
|
---|
425 | private _updateOnScroll;
|
---|
426 | /** Gets the scroll position of the viewport. */
|
---|
427 | private _getViewportScrollPosition;
|
---|
428 | /**
|
---|
429 | * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
|
---|
430 | * than saving it in property directly on init, because we want to resolve it as late as possible
|
---|
431 | * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
|
---|
432 | * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
|
---|
433 | */
|
---|
434 | private _getShadowRoot;
|
---|
435 | /** Gets the element into which the drag preview should be inserted. */
|
---|
436 | private _getPreviewInsertionPoint;
|
---|
437 | }
|
---|
438 | export {};
|
---|