Skip to main content

Adding custom content to cells

Grid allows adding custom components to table cells as well as header and footer cells.

Adding components​

Basically, what you need is four simple steps:

  • create a component (using HTML or ready-made components from the @svar-ui/svelte-core library)
  • in the component, access Grid properties via $props, if needed
  • import the configured component to the application page with Grid
  • add this component to the needed cell in Grid

Accessing Grid properties in components​

Components in cells have access to the following Grid data via $props:

  • api - Grid API, using which you can call actions or listen to them
  • row
    • row data for body cells (data item)
    • row index for header cells
  • column - column data (its id, dimensions, etc.)
  • cell - for header cells only, cell properties (its text, colspan, rowspan, etc.)
  • onaction - callback using which you can call built-in or custom actions

Let's look at some basic examples.

Creating static components​

Embedding HTML to table cells​

The example below demonstrates how to customize cells by adding images to them.

AvatarCell
<script>
let { row } = $props();// access Grid row data
</script>

<div class="container">
<div class="avatar">
<div class="user-avatar">
{#if row.avatar}
<img class="user-photo" alt="" src={row.avatar} />
{/if}
</div>
</div>
<div class="info">
<div class="name">{row.lastName}</div>
<div class="mail">{row.email || ""}</div>
</div>
</div>
<style>
.container {
display: flex;
align-items: center;
height: 56px;
padding: 0 12px;
}
.avatar {
width: 70px;
}
.name, .mail {
flex: 1;
}
.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #dfe2e6;
text-align: center;
}

.user-photo {
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #dfe2e6;
}
</style>

Now you can import your component and apply it to a cell by adding its name to the cell parameter of a column element in the columns array:

<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";
import AvatarCell from "../custom/AvatarCell.svelte"; //import the component

const { data } = getData();

const columns = [
{ id: "id", width: 50 },
{ id: "avatar", cell: AvatarCell, width: 350 }, //apply the component to a cell
];
</script>

<Grid sizes={{ rowHeight: 70 }} {data} {columns} />

Embedding HTML to header/footer​

The next example customizes a footer cell by rendering its text and the icon in it.

FooterTextCell
<script>
let { cell } = $props(); //access cell data
</script>

<div class="footer-content">
<span>{cell.text}</span>
<i class="wxi-check"></i>

<style>
.footer-content {
display: flex;
align-items: center;
gap: 6px;
}

.footer-content i {
display: inline-flex;
font-size: 20px;
}
</style>
</div>

Now we can import the component and apply it by adding its names as the value of the cell parameter of the footer element in the columns array.

<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";

import FooterTextCell from "../custom/FooterTextCell.svelte";

const { data } = getData();

const columns = [
{
id: "id",
width: 50,
footer: [
{
cell: FooterTextCell,
colspan: 3,
text: "Custom footer content",
},
],
}
];

</script>

<Grid {data} {columns} footer />

Embedding Core components​

The snippet below shows how to add a Button to a column cell. To connect button state with item data, use $props to access row and column objects. This is how the component looks like:

ButtonCell
<script>
import { Button } from "@svar-ui/svelte-core";
let { row, column } = $props();// access row and column data
</script>

<Button type="primary" disabled={!row[column.id]}>
Show on map
</Button>

Now you can render it in a column cell by adding its name to the cell parameter of a column element in the columns array:

<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";
import ButtonCell from "../custom/ButtonCell.svelte"; // import

const { data } = getData();

const columns = [
{
id: "city",
cell: ButtonCell,// add to a cell
width: 260,
},
//other columns
];

</script>

<Grid {data} {columns} />

Similarly, you can create a button within a header cell.

HeaderButtonCell
<script>
import { Button } from "@svar-ui/svelte-core";
</script>

<Button type={"secondary"} icon="wxi-plus">Add row</Button>

Now we can import the component and apply it to a header cell by adding its name as the value of the cell parameter of the header element in the columns array.

<script>
import { Grid } from "@svar-ui/svelte-grid";
import { getData } from "../data";
import HeaderButtonCell from "../custom/HeaderButtonCell.svelte";

const { data } = getData();

const columns = [
{
id: "id",
header: [{ cell: HeaderButtonCell }],
},
//other columns
];

</script>

<Grid {data} {columns} />

Enabling interactivity​

To enable communication between custom components and Grid, use either of the following ways:

Executing Grid actions​

Use $props to access Grid api and execute actions directly, e.g. add-row:

<script>
import { Button } from "@svar-ui/svelte-core";
let { api } = $props();

function onClick() {
api.exec("add-row", { row: { city: "New York"}});
}
</script>

<Button type={"secondary"} icon="wxi-plus" onclick={onClick}>Add row</Button>

Or, you can use the onaction property that allows sending a callback event to Grid. You can pass any existing Grid action with its parameters, and it will be executed by inner code:

<script>
import { Button } from "@svar-ui/svelte-core";
let { onaction } = $props();

function onClick() {
onaction &&
onaction({
action: "add-row", //Grid action name
data: { row: { city: "New York"}}, //action parameters
});
}
</script>

<Button type={"secondary"} icon="wxi-plus" onclick={onClick}>Add row</Button>

Calling custom events​

You can send a custom event in the onaction callback and handle it at your Grid level. For example:

<script>
import { Button } from "@svar-ui/svelte-core";
let { row, column, onaction } = $props();

function onClick() {
onaction &&
onaction({
action: "custom-button", // call custom event
data: {
column: column.id,
row: row.id,
},
});
}
</script>
<Button type="primary" disabled={!row[column.id]} onclick={onClick}>
Show on map
</Button>

Now handle this custom event in Grid. Beware that the on prefix should be added and a hyphen in the event name should be removed:

<script>
import { Grid } from "@svar-ui/svelte-grid";
import ButtonCell from "../custom/CheckboxCell.svelte"
import { getData } from "../data";

const { data } = getData();

const columns = [
{
header: "City",
cell: ButtonCell,
width: 260,
},
//other columns
];

function action(ev) {
const { row, column } = ev;
// e.g. open in Maps the city from row data
}

</script>

<Grid
{data}
{columns}
oncustombutton={ev => action(ev)} //handle the custom event
/>

Use cases​

Practical usage examples you can find here:

info

If you are interested to know how to apply custom styles to a cell, see the Styling section.


Related articles: