frontend.fyi

Building a Drag & Drop kanban board with view transitions

Who said view transitions can't be used with React? We'll be adding animations to this kanban board in no-time. And on top of that, we explore the drag and drop API together.

Code on Github
🧑‍💻 🎥
... Almost ready!

The View Transitions API

Using the view transitions api is so easy, that I had to come up with some more interesting content to share in this video. That’s why we’ll be building a very basic Kanban board, where we’ll be adding drag and drop functionality, to then animate this with the view transitions API.

The HTML Drag and Drop API

The HTML Drag and Drop API allows us to make elements draggable, and make them droppable on other elements. It all starts with the draggable attribute, which we can add to any element. Setting the value to true will make any element draggable like in the example below.

1
<div draggable="true">Drag me</div>
Drag me

It might look like nothing special is happening when dragging the element. But this single line of code, enabled a lot of functionality for us.

Define a droppable target

Any element can be a droppable target. There’s two event handlers that can be listened to, to handle the drag and drop events. These events are the onDragEnter and onDragLeave. These two events are fired when a draggable element respectively enters or leaves a droppable target. You can for example use this to highlight the droppable target when the draggable element enters it.

1
import { useState } from "react";
2
import classNames from "classnames";
3
4
const AComponent = () => {
5
const [isActive, setIsActive] = useState(false);
6
7
return (
8
<div>
9
<div draggable="true">Drag me</div>
10
<div
11
className={classNames(
12
"p-4 border-dashed border-2 border-gray-300",
13
isActive && "bg-red-300",
14
!isActive && "bg-transparent"
15
)}
16
onDragEnter={() => setIsActive(true)}
17
onDragLeave={() => setIsActive(false)}>
18
Drop here
19
</div>
20
</div>
21
);
22
}
Drag me
Drop here

Accept that drop

Finally, we need to do something if the user drops something on top of that target. For that, the onDrop event handler is what you’re looking for.

It does require some extra work though. Because by default, the browser will not allow you to drop anything on top of a droppable target. To allow this, we need to prevent the default behavior of the onDragOver event handler, like so:

1
import { useState } from "react";
2
import classNames from "classnames";
3
4
const AComponent = () => {
5
const [isActive, setIsActive] = useState(false);
6
7
return (
8
<div>
9
<div draggable="true">Drag me</div>
10
<div
11
className={classNames(
12
"p-4 border-dashed border-2 border-gray-300",
13
isActive && "bg-red-300",
14
!isActive && "bg-transparent"
15
)}
16
onDragEnter={() => setIsActive(true)}
17
onDragLeave={() => setIsActive(false)}
18
onDrop={() => {
19
// Handle that drop.
20
alert('Drop that beat!')
21
}}
22
// preventDefault can't be ommitted here.
23
onDragOver={(ev) => ev.preventDefault()}>
24
Drop here, and I'll tell you
25
</div>
26
</div>
27
);
28
}
Drag me
Drop here, and I'll tell you

That’s all there’s to it

With these few event handlers, you can create complicated drag and drop functionality, and build amazing experiences.

Now let’s add view transitions to the mix!

The view transitions API is a rather simple API, that allows you to animate between to states of you application. Or even two pages. The API is based around two pieces: The viewTransitionName property in CSS, and the JavaScript function document.startViewTransition.

The viewTransitionName property

The browser animates any elements on the page, that have the same viewTransitionName property between the two renders or pages. This means that you can animate elements that are not even on the same page, as long as they have the same viewTransitionName property.

The document.startViewTransition function

This function allows you to inform the browser that an update in the DOM, which you’d like to be animated, is about to happen.

The browser expects you to run this function, and accepts a callback function as an argument. This callback function is the function that will update the DOM. The browser watch the changes made by this function, and will then animate the changes that are made in this callback function.

1
document.startViewTransition(() => {
2
moveTheCards();
3
});

Watch the video

Watch the video for a more in-depth explanation on how to use the view transitions API, and how to combine it with the drag and drop API.