Supporting drag and drop
Throughout Canva, users can drag and drop content into their designs. You can use the Apps SDK to implement this behavior, allowing your app to offer a consistently delightful experience.
The user experience
When a user drags content into a design, the content moves through three states:
- Idle
- Dragging
- Dropped
The idle state is when the content is in the object panel, waiting for the user to interact with it.
The dragging state is when the content is being dragged into the user's design. In this state, a semi-transparent preview of the content is shown under the user's cursor. Typically, the content in the object panel is made invisible while it's being dragged. This creates the effect of the content being moved.
The dropped state is when the content is added to the user's design. If the content was made invisible in the object panel, it's made visible again.
For accessibility reasons and cross-platform support, all content that can be dragged and dropped into a design must also support clicking as a means of creating elements.
Supported content formats
When using the Apps SDK, only certain types of content can be created via drag and drop, including:
The following types of content are not supported:
How to support drag and drop (recommended)
In the starter kit, we've included React components for creating draggable content:
Using these components is the easiest way to support draggable content and, in most cases, we recommend using them instead of the underlying APIs.
How to support drag and drop (advanced)
Step 1: Create a draggable node
-
Create the node that will be made draggable, such as a
div
orimg
node:import React from "react";export function App() {return <div>Drag and drop me into a design</div>;} -
Add a
draggable
attribute to the node:<div draggable={true}>Drag and drop me into a design</div>The
draggable
attribute is a standard HTML feature that allows the node to be dragged, but additional steps are required to complete the integration with Canva.
Step 2: Get a reference to the node
Use the useRef
hook to grab a reference to the node:
import React from "react";export function App() {const ref = React.useRef<HTMLDivElement>(null);return (<div ref={ref} draggable={true}>Drag and drop me into a design</div>);}
This lets the app directly interact with the node, which is necessary for the next step.
Step 3: Set the drag data
Import the ui
namespace from the @canva/design
package:
import { ui } from "@canva/design";
This namespace exposes a makeDraggable
method that makes Canva aware of a node as it's being dragged and dropped. The method accepts a dragData
object that defines what will be added to the user's design at the end of the drag event.
The expected properties for the makeDraggable
method depend on what's being added to the design:
- Audio tracks
- Images
- Text
- Videos
The following snippet demonstrates how to add an audio track to the user's design:
import React from "react";import { ui } from "@canva/design";import { upload } from "@canva/asset";export function App() {const ref = React.useRef<HTMLDivElement>(null);React.useEffect(() => {if (!ref?.current) {return;}ui.makeDraggable({node: ref.current,dragData: {type: "AUDIO",resolveAudioRef: () => {return upload({type: "AUDIO",id: "uniqueidgoeshere",title: "Example audio",url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",mimeType: "audio/mp3",durationMs: 86047,});},title: "Example audio",durationMs: 86047,},onDragStart: () => {console.log("The drag event has started");},onDragEnd: () => {console.log("The drag event has ended");},});}, [ref]);return (<div ref={ref} draggable={true}>Drag and drop me into a design</div>);}
For a complete description of the available properties, see the API reference.
Step 4: Handle drag events
The makeDraggable
method accepts two callback functions:
onDragStart
onDragEnd
These callback functions run at the start and end of a drag event, respectively.
A use-case for these functions is to hide the draggable node at the start of a drag event and show it again at the end of a drag event. This creates the illusion of the node being moved from one location to another, rather than copied, which is consistent with the native Canva experience.
Known limitations
- Users can only drag and drop content on desktop devices. If an app supports mobile devices, it will need to ensure that content can also be added with a click or a tap.
- Only one piece of content can be dragged into a design at a time.