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)
-
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>;}tsx -
Add a
draggable
attribute to the node:<div draggable={true}>Drag and drop me into a design</div>tsxThe
draggable
attribute is a standard HTML feature that allows the node to be dragged. Additional steps are required to complete the integration with Canva. -
Add an
onDragStart
attribute to the node:<divdraggable={true}onDragStart={(event) => {console.log(event);}}>Drag and drop me into a design</div>tsxThis attribute accepts a callback that receives an
event
parameter. -
Import the
ui
namespace from the@canva/design
package:import { ui } from "@canva/design";tsThis namespace exposes a
ui.startDrag
method that makes Canva aware of a node as it's dragged. -
In the
onDragStart
callback, call theui.startDrag
method with theevent
object as the first argument:<divdraggable={true}onDragStart={(event) => {ui.startDrag(event);}}>Drag and drop me into a design</div>tsx -
As the second argument of the
ui.startDrag
method, pass in an object that defines the element to add to the design at the end of the drag event. The expected properties depend on the type of element:- Audio tracks
- Embeds
- 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() {return (<divdraggable={true}onDragStart={(event) => {ui.startDrag(event, {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,});}}>Drag and drop me into a design</div>);}tsx
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.