Angular drag and drop event after cdkDragStartDelay ends

After the cdkDragStartDelay ends, I want to show user that the element can already be moved.

There is only an cdkDragStarted event, but it fires ONLY after the user has already moved the item.

I want to show same styles as for .cdk-drag-preview

Is there some easy way that I missed ?

Upvotes: 4

Views: 1508

Answers (2)

Dominik Ehrenberg
Dominik Ehrenberg

Reputation: 1746

Unfortunately, there does not seem to be a specific event for this. What I did, was to implement a delayed function listening on mousedown/touchstart with the same timeout. It looks more or less like this:

Template:

<li
  cdkDrag
  [cdkDragStartDelay]="dragStartDelay"
  (mousedown)="startTimeout()"
  (mouseup)="stopTimeout()"
>
  <span *ngIf="!canDrag">Hold me to drag</span>
  <span *ngIf="canDrag">Drag me</span>
</li>

Controller:

class SomeController {
  canDrag = false;
  readonly dragStartDelay = 600;

  private timeout = -1;

  startTimeout() {
    // Make sure only ever one timeout is active
    this.stopTimeout();
    
    this.timeout = window.setTimeout(() => this.canDrag = true, this.dragStartDelay);
  }

  stopTimeout() {
    window.clearTimeout(this.timeout);
    this.canDrag = false;
  }
}

If your application also needs to support touch devices, make sure to add the touchstart and touchend events besides the mousedown and mouseup events

Upvotes: 1

S&#233;bastien
S&#233;bastien

Reputation: 2394

I couldn't find a proper way to do it, either.

Here's an idea, with important limitations however:

<div class="item" cdkDrag [cdkDragStartDelay]="500">...</div>
/* Use the :active pseudo-class */
.item:active {
  /* Apply the same style as your .cdk-drag-preview, for example: */
  box-sizing: border-box;
  border-radius: 4px;
  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
              0 8px 10px 1px rgba(0, 0, 0, 0.14),
              0 3px 14px 2px rgba(0, 0, 0, 0.12);

  /* Add a transition delay, with the same duration as your cdkDragStartDelay */
  transition-delay: 500ms;
}

MDN documentation about transition-delay:
https://developer.mozilla.org/en-US/docs/Web/CSS/transition-delay

This is just a workaround, and suffers from several issues. Among others :

  • If you're using a cdkDragHandle, you won't be able to apply CSS rules to the cdkDrag element when the handle becomes :active, as there's no "parent" selector in CSS
  • If the users click/press the element and then move their mouse/finger outside of the element immediately (as if they were dragging without waiting), the :active styling turns on, although the element is not draggable.

Upvotes: 1

Related Questions