Creating tables

How to add tables to a user's design.

Apps can add tables to a user's design. These tables are a type of element, which means users can manipulate them as they would any other kind of element.

In addition to creating tables, apps can:

  • Set the text content of table cells.
  • Set the background color of table cells.
  • Merge table cells.

In the Developer Portal, enable the canva:design:content:write permission. In the future, the Apps SDK will throw an error if the required permissions are not enabled. To learn more, see Configuring permissions.

At their most basic, tables are plain JavaScript objects. These objects have rows, and the rows have cells. The cells can contain content and have attributes like background color.

The following code snippet contains an example of a table object that has a single row and cell:

import { TableElement } from "@canva/design";
const element: TableElement = {
type: "table",
rows: [
{
cells: [
{
type: "string",
value: "Hello world",
},
],
},
],
};
tsx

To create these objects, we recommend using the TableWrapper class in the starter kit. This class exposes methods for simplifying the creation of table element objects and provides additional layers of validation.

To use the TableWrapper class:

  1. Import the class:

    import { TableWrapper } from "utils/table_wrapper";
    tsx
  2. Call the create method, passing in the number of rows and columns the table should have:

    const table = TableWrapper.create(2, 2);
    tsx

    This statement creates a table with two rows and two columns, resulting in a table of four cells.

  3. Call the toElement method to convert the table into a table element:

    const element = table.toElement();
    console.log(element); // => { type: "table", rows: [ ... ]}
    tsx

In this case, the table has four empty cells. To learn how to customize the table further, such as by adding text content within cells or setting the background color of cells, see Customizing tables.

Apps can add table elements to a design by calling either of the following methods:

  • addElementAtPoint
  • addElementAtCursor

Both methods add an element to the user's design, but:

  • addElementAtPoint is only compatible with design types that support absolute positions, which is all design types except for documents.
  • addElementAtCursor doesn't accept a position and is only compatible with design types that contain streams of text, which is only the document design type.

Where possible, apps should determine the context in which the app is running and either call the compatible method or make it obvious when functionality isn't available:

import { Button, Rows } from "@canva/app-ui-kit";
import { addElementAtCursor, addElementAtPoint } from "@canva/design";
import { useFeatureSupport } from "utils/use_feature_support";
import { TableWrapper } from "utils/table_wrapper";
import * as styles from "styles/components.css";
export const App = () => {
const isSupported = useFeatureSupport();
function handleAddElementAtPoint() {
if (!isSupported(addElementAtPoint)) {
return;
}
const table = TableWrapper.create(2, 2);
const element = table.toElement();
addElementAtPoint(element);
}
function handleAddElementAtCursor() {
if (!isSupported(addElementAtCursor)) {
return;
}
const table = TableWrapper.create(2, 2);
const element = table.toElement();
addElementAtCursor(element);
}
return (
<div className={styles.scrollContainer}>
<Rows spacing="1u">
<Button
variant="primary"
onClick={handleAddElementAtPoint}
disabled={!isSupported(addElementAtPoint)}
>
Add table element at point
</Button>
<Button
variant="primary"
onClick={handleAddElementAtCursor}
disabled={!isSupported(addElementAtCursor)}
>
Add table element at cursor
</Button>
</Rows>
</div>
);
};
tsx

To learn more, see Feature support.

The TableWrapper class exposes methods for customizing the structure and appearance of tables. This section demonstrates how to accomplish some common requirements.

The addRow method adds a row to the table after the specified row:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Add a row *before* the first row
table.addRow(0);
// Add a row *after* the first row
table.addRow(1);
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

A value of 0 adds a row before the first row.

The addColumn method adds a column to the table after the specified column:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Add a column *before* the first column
table.addColumn(0);
// Add a column *after* the first column
table.addColumn(1);
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

A value of 0 adds a column before the first column.

You can use the setCellDetails method to set the text content of the specified cell:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Set the text content of the first cell
table.setCellDetails(1, 1, {
type: "string",
value: "Hello world",
});
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

The first two arguments are the row and column number of the cell. These numbers start from 1, not 0.

You can use the setCellDetails method to set the background color of the specified cell:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Set the background color of the first cell
table.setCellDetails(1, 1, {
attributes: {
backgroundColor: "#ff0099",
},
});
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

The first two arguments are the row and column number of the cell. These numbers start from 1, not 0.

You can use the setCellDetails method to set the row span of the cell, merging the specified number of rows:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Merge two rows
table.setCellDetails(1, 1, {
rowSpan: 2,
});
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

The first two arguments are the row and column number of the cell. These numbers start from 1, not 0.

You can use the setCellDetails method to set the column span of the cell, merging the specified number of columns:

import { addElementAtPoint } from "@canva/design";
import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Merge two columns
table.setCellDetails(1, 1, {
columnSpan: 2,
});
// Add the table to the design
const element = table.toElement();
addElementAtPoint(element);
tsx

The first two arguments are the row and column number of the cell. These numbers start from 1, not 0.

Use the getCellDetails method to get the details of the specified cell, such as its text content:

import { TableWrapper } from "utils/table_wrapper";
// Create a table
const table = TableWrapper.create(2, 2);
// Get the details of the first cell
const cell = table.getCellDetails(1, 1);
console.log(cell);
tsx

The first two arguments are the row and column number of the cell. These numbers start from 1, not 0.

  • Tables can't exist within app elements.
  • Tables can't exist within group elements.
  • Tables can't be dragged and dropped into a design.
  • Apps can't set the borders of tables.
  • A single table can't have more than 225 cells.