/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { ElementRef, NgZone, ViewContainerRef, TemplateRef } from '@angular/core'; import { ViewportRuler } from '@angular/cdk/scrolling'; import { Direction } from '@angular/cdk/bidi'; import { Subject, Observable } from 'rxjs'; import { DropListRefInternal as DropListRef } from './drop-list-ref'; import { DragDropRegistry } from './drag-drop-registry'; /** Object that can be used to configure the behavior of DragRef. */ export interface DragRefConfig { /** * Minimum amount of pixels that the user should * drag, before the CDK initiates a drag sequence. */ dragStartThreshold: number; /** * Amount the pixels the user should drag before the CDK * considers them to have changed the drag direction. */ pointerDirectionChangeThreshold: number; /** `z-index` for the absolutely-positioned elements that are created by the drag item. */ zIndex?: number; /** Ref that the current drag item is nested in. */ parentDragRef?: DragRef; } /** * Internal compile-time-only representation of a `DragRef`. * Used to avoid circular import issues between the `DragRef` and the `DropListRef`. * @docs-private */ export interface DragRefInternal extends DragRef { } /** Template that can be used to create a drag helper element (e.g. a preview or a placeholder). */ interface DragHelperTemplate { template: TemplateRef | null; viewContainer: ViewContainerRef; context: T; } /** Template that can be used to create a drag preview element. */ interface DragPreviewTemplate extends DragHelperTemplate { matchSize?: boolean; } /** Point on the page or within an element. */ export interface Point { x: number; y: number; } /** * Possible places into which the preview of a drag item can be inserted. * - `global` - Preview will be inserted at the bottom of the ``. The advantage is that * you don't have to worry about `overflow: hidden` or `z-index`, but the item won't retain * its inherited styles. * - `parent` - Preview will be inserted into the parent of the drag item. The advantage is that * inherited styles will be preserved, but it may be clipped by `overflow: hidden` or not be * visible due to `z-index`. Furthermore, the preview is going to have an effect over selectors * like `:nth-child` and some flexbox configurations. * - `ElementRef | HTMLElement` - Preview will be inserted into a specific element. * Same advantages and disadvantages as `parent`. */ export declare type PreviewContainer = 'global' | 'parent' | ElementRef | HTMLElement; /** * Reference to a draggable item. Used to manipulate or dispose of the item. */ export declare class DragRef { private _config; private _document; private _ngZone; private _viewportRuler; private _dragDropRegistry; /** Element displayed next to the user's pointer while the element is dragged. */ private _preview; /** Reference to the view of the preview element. */ private _previewRef; /** Container into which to insert the preview. */ private _previewContainer; /** Reference to the view of the placeholder element. */ private _placeholderRef; /** Element that is rendered instead of the draggable item while it is being sorted. */ private _placeholder; /** Coordinates within the element at which the user picked up the element. */ private _pickupPositionInElement; /** Coordinates on the page at which the user picked up the element. */ private _pickupPositionOnPage; /** * Anchor node used to save the place in the DOM where the element was * picked up so that it can be restored at the end of the drag sequence. */ private _anchor; /** * CSS `transform` applied to the element when it isn't being dragged. We need a * passive transform in order for the dragged element to retain its new position * after the user has stopped dragging and because we need to know the relative * position in case they start dragging again. This corresponds to `element.style.transform`. */ private _passiveTransform; /** CSS `transform` that is applied to the element while it's being dragged. */ private _activeTransform; /** Inline `transform` value that the element had before the first dragging sequence. */ private _initialTransform?; /** * Whether the dragging sequence has been started. Doesn't * necessarily mean that the element has been moved. */ private _hasStartedDragging; /** Whether the element has moved since the user started dragging it. */ private _hasMoved; /** Drop container in which the DragRef resided when dragging began. */ private _initialContainer; /** Index at which the item started in its initial container. */ private _initialIndex; /** Cached positions of scrollable parent elements. */ private _parentPositions; /** Emits when the item is being moved. */ private readonly _moveEvents; /** Keeps track of the direction in which the user is dragging along each axis. */ private _pointerDirectionDelta; /** Pointer position at which the last change in the delta occurred. */ private _pointerPositionAtLastDirectionChange; /** Position of the pointer at the last pointer event. */ private _lastKnownPointerPosition; /** * Root DOM node of the drag instance. This is the element that will * be moved around as the user is dragging. */ private _rootElement; /** * Nearest ancestor SVG, relative to which coordinates are calculated if dragging SVGElement */ private _ownerSVGElement; /** * Inline style value of `-webkit-tap-highlight-color` at the time the * dragging was started. Used to restore the value once we're done dragging. */ private _rootElementTapHighlight; /** Subscription to pointer movement events. */ private _pointerMoveSubscription; /** Subscription to the event that is dispatched when the user lifts their pointer. */ private _pointerUpSubscription; /** Subscription to the viewport being scrolled. */ private _scrollSubscription; /** Subscription to the viewport being resized. */ private _resizeSubscription; /** * Time at which the last touch event occurred. Used to avoid firing the same * events multiple times on touch devices where the browser will fire a fake * mouse event for each touch event, after a certain time. */ private _lastTouchEventTime; /** Time at which the last dragging sequence was started. */ private _dragStartTime; /** Cached reference to the boundary element. */ private _boundaryElement; /** Whether the native dragging interactions have been enabled on the root element. */ private _nativeInteractionsEnabled; /** Cached dimensions of the preview element. */ private _previewRect?; /** Cached dimensions of the boundary element. */ private _boundaryRect?; /** Element that will be used as a template to create the draggable item's preview. */ private _previewTemplate?; /** Template for placeholder element rendered to show where a draggable would be dropped. */ private _placeholderTemplate?; /** Elements that can be used to drag the draggable item. */ private _handles; /** Registered handles that are currently disabled. */ private _disabledHandles; /** Droppable container that the draggable is a part of. */ private _dropContainer?; /** Layout direction of the item. */ private _direction; /** Ref that the current drag item is nested in. */ private _parentDragRef; /** * Cached shadow root that the element is placed in. `null` means that the element isn't in * the shadow DOM and `undefined` means that it hasn't been resolved yet. Should be read via * `_getShadowRoot`, not directly. */ private _cachedShadowRoot; /** Axis along which dragging is locked. */ lockAxis: 'x' | 'y'; /** * Amount of milliseconds to wait after the user has put their * pointer down before starting to drag the element. */ dragStartDelay: number | { touch: number; mouse: number; }; /** Class to be added to the preview element. */ previewClass: string | string[] | undefined; /** Whether starting to drag this element is disabled. */ get disabled(): boolean; set disabled(value: boolean); private _disabled; /** Emits as the drag sequence is being prepared. */ readonly beforeStarted: Subject; /** Emits when the user starts dragging the item. */ readonly started: Subject<{ source: DragRef; }>; /** Emits when the user has released a drag item, before any animations have started. */ readonly released: Subject<{ source: DragRef; }>; /** Emits when the user stops dragging an item in the container. */ readonly ended: Subject<{ source: DragRef; distance: Point; dropPoint: Point; }>; /** Emits when the user has moved the item into a new container. */ readonly entered: Subject<{ container: DropListRef; item: DragRef; currentIndex: number; }>; /** Emits when the user removes the item its container by dragging it into another container. */ readonly exited: Subject<{ container: DropListRef; item: DragRef; }>; /** Emits when the user drops the item inside a container. */ readonly dropped: Subject<{ previousIndex: number; currentIndex: number; item: DragRef; container: DropListRef; previousContainer: DropListRef; distance: Point; dropPoint: Point; isPointerOverContainer: boolean; }>; /** * Emits as the user is dragging the item. Use with caution, * because this event will fire for every pixel that the user has dragged. */ readonly moved: Observable<{ source: DragRef; pointerPosition: { x: number; y: number; }; event: MouseEvent | TouchEvent; distance: Point; delta: { x: -1 | 0 | 1; y: -1 | 0 | 1; }; }>; /** Arbitrary data that can be attached to the drag item. */ data: T; /** * Function that can be used to customize the logic of how the position of the drag item * is limited while it's being dragged. Gets called with a point containing the current position * of the user's pointer on the page and should return a point describing where the item should * be rendered. */ constrainPosition?: (point: Point, dragRef: DragRef) => Point; constructor(element: ElementRef | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry); /** * Returns the element that is being used as a placeholder * while the current element is being dragged. */ getPlaceholderElement(): HTMLElement; /** Returns the root draggable element. */ getRootElement(): HTMLElement; /** * Gets the currently-visible element that represents the drag item. * While dragging this is the placeholder, otherwise it's the root element. */ getVisibleElement(): HTMLElement; /** Registers the handles that can be used to drag the element. */ withHandles(handles: (HTMLElement | ElementRef)[]): this; /** * Registers the template that should be used for the drag preview. * @param template Template that from which to stamp out the preview. */ withPreviewTemplate(template: DragPreviewTemplate | null): this; /** * Registers the template that should be used for the drag placeholder. * @param template Template that from which to stamp out the placeholder. */ withPlaceholderTemplate(template: DragHelperTemplate | null): this; /** * Sets an alternate drag root element. The root element is the element that will be moved as * the user is dragging. Passing an alternate root element is useful when trying to enable * dragging on an element that you might not have access to. */ withRootElement(rootElement: ElementRef | HTMLElement): this; /** * Element to which the draggable's position will be constrained. */ withBoundaryElement(boundaryElement: ElementRef | HTMLElement | null): this; /** Sets the parent ref that the ref is nested in. */ withParent(parent: DragRef | null): this; /** Removes the dragging functionality from the DOM element. */ dispose(): void; /** Checks whether the element is currently being dragged. */ isDragging(): boolean; /** Resets a standalone drag item to its initial position. */ reset(): void; /** * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging. * @param handle Handle element that should be disabled. */ disableHandle(handle: HTMLElement): void; /** * Enables a handle, if it has been disabled. * @param handle Handle element to be enabled. */ enableHandle(handle: HTMLElement): void; /** Sets the layout direction of the draggable item. */ withDirection(direction: Direction): this; /** Sets the container that the item is part of. */ _withDropContainer(container: DropListRef): void; /** * Gets the current position in pixels the draggable outside of a drop container. */ getFreeDragPosition(): Readonly; /** * Sets the current position in pixels the draggable outside of a drop container. * @param value New position to be set. */ setFreeDragPosition(value: Point): this; /** * Sets the container into which to insert the preview element. * @param value Container into which to insert the preview. */ withPreviewContainer(value: PreviewContainer): this; /** Updates the item's sort order based on the last-known pointer position. */ _sortFromLastPointerPosition(): void; /** Unsubscribes from the global subscriptions. */ private _removeSubscriptions; /** Destroys the preview element and its ViewRef. */ private _destroyPreview; /** Destroys the placeholder element and its ViewRef. */ private _destroyPlaceholder; /** Handler for the `mousedown`/`touchstart` events. */ private _pointerDown; /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */ private _pointerMove; /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */ private _pointerUp; /** * Clears subscriptions and stops the dragging sequence. * @param event Browser event object that ended the sequence. */ private _endDragSequence; /** Starts the dragging sequence. */ private _startDragSequence; /** * Sets up the different variables and subscriptions * that will be necessary for the dragging sequence. * @param referenceElement Element that started the drag sequence. * @param event Browser event object that started the sequence. */ private _initializeDragSequence; /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */ private _cleanupDragArtifacts; /** * Updates the item's position in its drop container, or moves it * into a new one, depending on its current drag position. */ private _updateActiveDropContainer; /** * Creates the element that will be rendered next to the user's pointer * and will be used as a preview of the element that is being dragged. */ private _createPreviewElement; /** * Animates the preview element from its current position to the location of the drop placeholder. * @returns Promise that resolves when the animation completes. */ private _animatePreviewToPlaceholder; /** Creates an element that will be shown instead of the current element while dragging. */ private _createPlaceholderElement; /** * Figures out the coordinates at which an element was picked up. * @param referenceElement Element that initiated the dragging. * @param event Event that initiated the dragging. */ private _getPointerPositionInElement; /** Determines the point of the page that was touched by the user. */ private _getPointerPositionOnPage; /** Gets the pointer position on the page, accounting for any position constraints. */ private _getConstrainedPointerPosition; /** Updates the current drag delta, based on the user's current pointer position on the page. */ private _updatePointerDirectionDelta; /** Toggles the native drag interactions, based on how many handles are registered. */ private _toggleNativeDragInteractions; /** Removes the manually-added event listeners from the root element. */ private _removeRootElementListeners; /** * Applies a `transform` to the root element, taking into account any existing transforms on it. * @param x New transform value along the X axis. * @param y New transform value along the Y axis. */ private _applyRootElementTransform; /** * Applies a `transform` to the preview, taking into account any existing transforms on it. * @param x New transform value along the X axis. * @param y New transform value along the Y axis. */ private _applyPreviewTransform; /** * Gets the distance that the user has dragged during the current drag sequence. * @param currentPosition Current position of the user's pointer. */ private _getDragDistance; /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */ private _cleanupCachedDimensions; /** * Checks whether the element is still inside its boundary after the viewport has been resized. * If not, the position is adjusted so that the element fits again. */ private _containInsideBoundaryOnResize; /** Gets the drag start delay, based on the event type. */ private _getDragStartDelay; /** Updates the internal state of the draggable element when scrolling has occurred. */ private _updateOnScroll; /** Gets the scroll position of the viewport. */ private _getViewportScrollPosition; /** * Lazily resolves and returns the shadow root of the element. We do this in a function, rather * than saving it in property directly on init, because we want to resolve it as late as possible * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`. */ private _getShadowRoot; /** Gets the element into which the drag preview should be inserted. */ private _getPreviewInsertionPoint; } export {};