> Markdown version of [Drag Source](https://vaadin.com/docs/latest/flow/component-internals/dnd/drag-source). Section index: [llms.txt](https://vaadin.com/docs/latest/flow/llms.txt)

# Creating a Drag Source

With the `DragSource` class, you can make any component draggable by the user, and configure the drag operation for it. By default, the entire component is made draggable. You can also make only a portion of the component draggable, this is covered later.

## <a id="making-a-component-draggable"></a>Making a Component Draggable

The `DragSource` class is a configuration object for the dragged item and contains static methods for configuring the given component instance.

Example 1. Making two `Div` components draggable in different ways

```java
Div box1 = new Div();
Div box2 = new Div();

// Make box 1 draggable and store reference to the configuration object.
DragSource<Div> box1DragSource = DragSource.create(box1);

// Access box 2 drag related configuration object without making it draggable.
DragSource<Div> box2DragSource = DragSource.configure(box2);

// Make box 2 draggable.
box2DragSource.setDraggable(true);

add(box1, box2);
```

The `DragSource` configuration object doesn’t itself store any data, as it’s a convenience proxy that facilitates making a component draggable. Creating a new `DragSource` instance of a component doesn’t reset any previous configuration, but any changes override the previous configuration.

When a component is set as draggable on the server side, the `draggable` attribute is assigned to its topmost element on the browser, thus making it draggable. When the user starts to drag the component, the root element of the component gets the `v-dragged` class name in the browser. This can be used to highlight the dragged component to the user.

Example 2. Painting a dotted outline around the dragged component with some transparency

```css
.v-dragged {
    outline: 1px dotted hotpink;
    opacity: 0.5;
}
```

## <a id="exposing-drag-source-api-to-a-component"></a>Exposing Drag Source API to a Component

As the `DragSource` is an interface, it can also be used as a mixin interface. It provides an easy way to add its API to your custom component. This is convenient when you want to reuse the component in many places for drag operation.

Example 3. Making a custom `CardComponent` draggable by default

```java
public class CardComponent extends Div implements DragSource<CardComponent>, HasStyle {
    public CardComponent() {
        // all cards are draggable by default
        setDraggable(true);
    }
    // all DragSource methods have default implementations
}
```

See [Using Vaadin Mixin Interfaces](https://vaadin.com/docs/latest/flow/component-internals/mixins.md) reference guide for more information about mixin interfaces.

## <a id="assigning-server-side-data-to-drag-source"></a>Assigning Server-Side Data to Drag Source

You can set any Java object as the server-side drag data for the drag source. When a drop occurs on a valid drop target **within the same UI** (browser window or tab) as the drag source component, this data is available from the `DropEvent`.

Example 4. Making two draggable `CardComponent` instances with different types of drag data

```java
// Continuing from the previous example, CardComponent implements DragSource.
CardComponent card1 = new CardComponent();
CardComponent card2 = new CardComponent();

card1.setDragData("Queen of Hearts");
card2.setDragData(new Card(11, Land.Spade)); // The data can be any object.
```

The data isn’t sent to the browser, as it’s stored in the component instance as server-side-only data.

It isn’t possible to configure the client-side drag data, the `dataTransfer` object, from the server side.

## <a id="drag-start-end-events"></a>Drag Start & End Events

The `DragSource` provides a way to react when the user starts and stops dragging a component. The `DragStartEvent` is fired when the drag starts in the browser, which means that you can’t cancel the drag. You should avoid doing any heavy synchronous processing there, since this blocks the user from dragging the component further in the browser. That would have a negative effect on the UX.

Example 5. Highlighting suitable drop targets when dragging starts

```java
// Continuing from the previous example with CardComponent.
card1.addDragStartListener(event -> {
    // Highlight suitable drop targets in the UI
    getVisibleCards().forEach(target -> {
        Card targetCard = target.getCard();
        if (targetCard.getLand() == ((Card) card1.getDragData()).getLand()
                && target != card1) {
            target.addClassName("possible-drop-zone");
        }
    })
});
```

When the user stops dragging the component by either dropping it or by canceling the drag with, for example, the escape key, the `DragEndEvent` is fired. The `isSuccessful()` method returns `true` if the drop occurred on a drop target that accepted the drop, **but only for Chrome and Firefox** (see the note after the example below).

```java
card1.addDragEndListener(event -> {
    getVisibleCards().forEach(target -> target.removeClassName("possible-drop-zone"));
    // NOTE: The following is always FALSE for Edge and Safari !!!
    if (event.isSuccessful()) {
        // Better to put logic for successful drop into DropEvent for the
        // DropTarget because of the above.
    }
});
```

> **Important: Handling Drag End in Edge & Safari**
>
> Edge and Safari don’t report whether the drop occurred successfully in the `DragEnd` event. You’ll need to take this into account if your users are using any of these browsers, and do any logic in the `DropEvent` handler of the `DropTarget`, instead. For Chrome and Firefox, it works correctly. See the [Creating a Drop Target](https://vaadin.com/docs/latest/flow/component-internals/dnd/drop-target.md) reference guide for more information about handling drop events.

### <a id="effect-allowed-drop-effect"></a>Effect Allowed & Drop Effect

The drag source’s `effectAllowed` property defines which drop operations (copy, move, link) are permitted for that element. The drop target’s `dropEffect` property specifies which single operation it wants to perform. These properties work together to control both the visual cursor feedback during dragging and the final operation performed.

The browser determines the final `dropEffect` through this process:

1. The drop target requests a specific `dropEffect` (copy, move, or link)

2. The browser checks if this effect is permitted by the drag source’s `effectAllowed`

3. The user can override using modifier keys (such as `Ctrl` for copy, `Shift` for move, etc.)

4. If there’s no match, the `dropEffect` becomes `NONE` and the drop is cancelled

The `DragEndEvent` reports the final `dropEffect` that was applied.

When the drop effect is `MOVE`, you should remove or relocate the drag source component from its original location. When the drop effect is `NONE`, the drop was cancelled and `dropEvent.isSuccessful()` returns `false`.

## <a id="customizing-the-draggable-element"></a>Customizing the Draggable Element

You can customize the element that is made draggable by overriding the `getDraggableElement()` method in the `DragSource` interface. This is useful if it’s not the whole component that’s to be draggable, but only a part of it.

Example 6. Making only an icon within a custom `RouteItem` component draggable

```java
/* NOTE: RouteItem is a made up custom component, not a core Vaadin component. */
public class DraggableRouteItem extends RouteItem implements DragSource<RouteItem> {
    private Icon dragHandle = VaadinIcon.MENU.create();

    public DraggableRouteItem(String destination) {
        super(destination);
        add(dragHandle);
    }

    // Instead of allowing the whole item to be draggable, only allow dragging
    // from the icon.
    @Override
    public Element getDraggableElement() {
        return dragHandle.getElement();
    }
}
```

Changing the draggable element also changes the drag image that the browser shows under the cursor.

## <a id="customizing-the-drag-image"></a>Customizing the Drag Image

The `DragSource` interface provides `setDragImage()` methods to customize the drag image shown under the cursor during dragging.

### <a id="using-image"></a>Using Image

The [`Image`](https://vaadin.com/docs/latest/building-apps/ui-basics/add-images-icons.md#images) component is the recommended and fully supported option for drag images.

Example 7. Setting an image of the Ace of Spades as the drag image

```java
// Continuing from the previous example
CardComponent card = new CardComponent();
card.setDragImage(new Image("/cards/ace_of_spades.png", "Ace of Spades"));
```

The `Image` component supports [DownloadHandler](https://vaadin.com/docs/latest/flow/advanced/downloads.md#download-content-from-inputstream) for dynamic image generation.

You can specify the cursor’s position relative to the drag image by providing x and y offsets from the image’s top-left corner:

Example 8. Positioning the cursor 20 pixels from left edge, aligned with top edge

```java
card.setDragImage(new Image("/cards/queen_of_hearts.png", "Queen of Hearts"), 20, 0);
```

### <a id="using-other-components"></a>Using Other Components

Components other than `Image` can be used as drag images, with these considerations:

- **Visible components**: If the component is already visible in the viewport, the browser uses it directly as the drag image

- **Off-screen components**: Components not in the viewport must be added to the DOM as off-screen elements. Vaadin handles this automatically when you call `setDragImage()` with an unattached component

To customize the positioning or styling of an off-screen drag image component, add it to the DOM manually before calling `setDragImage()`.

Example 9. Using a `Span` as a drag image by adding it off-screen

```java
Span dragImage = new Span("Drag Image Component");
Style dragImageStyle = dragImage.getElement().getStyle();
dragImageStyle.setPosition(Style.Position.ABSOLUTE);
dragImageStyle.setTop("-100px"); // (1)
dragImageStyle.setLeft("-100px");
dragImageStyle.setDisplay(Style.Display.NONE); // (2)
add(dragImage);
dragSource.setDragImage(dragImage);
```

1. Positioning the component off-screen prevents it from being visible to the user.

2. Setting `display: none` ensures the component doesn’t affect layout or visibility.

> **Note:** Browser support for non-Image components as drag images varies. Test your implementation across target browsers.

For more information, see the [HTML5 Drag & Drop API](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage).

`4FFD51BA-4736-44BD-8FCF-0E534A19FB8D`
