Rendering Snippets
Useful Links
Table Demo
Name | Age | Phone | |
---|---|---|---|
Kendra Weissnat-Ziemann | 41 | Lucious23@hotmail.com | (852) 838-0609 |
Eleanor Hirthe | 28 | Dion38@gmail.com | (279) 388-6308 |
Helen Nolan | 22 | Casimir.Stokes@gmail.com | (618) 580-1053 |
Richard Bartell-Conn | 36 | Adolf51@gmail.com | (359) 280-6211 |
Hubert Gorczany | 84 | Madaline27@hotmail.com | (444) 771-0168 |
Clint Jenkins | 89 | Linnie22@hotmail.com | (796) 471-3480 |
Mr. Melvin Leuschke-MacGyver | 66 | Ressie.Smith@yahoo.com | (383) 241-5706 |
Eddie Dickens IV | 32 | Tad18@yahoo.com | (698) 637-5272 |
Christian Conroy | 77 | Irwin.Lubowitz@gmail.com | (601) 550-2439 |
Earnest West | 83 | Garrett_Crist@hotmail.com | (761) 925-7502 |
Explanation
When you don't want to make an entire component for a small piece of reusable
code, snippets are a great way to encapsulate and reuse logic. In this example,
we'll create snippets for rendering text in a <strong>
tag and email addresses
as clickable mailto links.
You should already know how to make a basic table before proceeding.
Defining Snippets
Snippets can be defined in Svelte either directly in the markup or in the script tag. Here, we use two methods to define our snippets:
🗒️ NOTE: The implementation of snippets within this repo only works with snippets that take one argument.
Markup Snippet
Using Svelte's {#snippet ...}
block, you can define a reusable snippet
directly in your component's markup. For example, the snippet strongSnippet
is
defined to render its content in a <strong>
tag:
{#snippet strongSnippet(content: string)}
<strong>{content}</strong>
{/snippet}
Script (Raw) Snippet
Snippets can also be created programmatically in the script tag using the
createRawSnippet
function. This approach is useful when you do not need to use
a Svelte component in your snippet.
<script lang="ts">
import { createRawSnippet } from 'svelte';
const mailtoSnippet = createRawSnippet<[string]>((email) => {
const emailAddress = email();
return {
render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`,
// Optional - Setup function to run when the snippet is first rendered
setup: () => {
// Example of using a Svelte effect to implement reactivity
$effect(() => {
node.textContent = email();
});
}
};
});
</script>
This mailtoSnippet
generates a clickable email link, using the provided email
address.
Column Definitions
Next, we define a set of columns for our table. The column definition array
specifies how each cell should be rendered, and this is where renderSnippet
comes in. This function allows you to use the snippets defined earlier to
customize the cell content.
Here's an example of how we use renderSnippet
with our snippets in the column
definitions:
<script lang="ts">
import { createRawSnippet } from 'svelte';
import { createColumnHelper } from '$lib/table';
import { type UserProfile } from '$lib/services/user-profile';
const mailtoSnippet = createRawSnippet<[string]>((email) => {
const emailAddress = email();
return {
render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`
};
});
const colHelp = createColumnHelper<UserProfile>();
const columnDefs = [
// Column def using snippet from markup
colHelp.accessor('name', {
header: 'Name',
cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue())
}),
colHelp.accessor('age', { header: 'Age' }),
// Column def using snippet from above
colHelp.accessor('email', {
header: 'Email',
cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue())
}),
colHelp.accessor('phone', { header: 'Phone' })
];
</script>
{#snippet strongSnippet(content: string)}
<strong>{content}</strong>
{/snippet}
🗒️ NOTE: You can also use
renderSnippet
with theheader
field of each column.
Setting Up the Table
After defining the columns, the next step is to set up the table using the
createSvelteTable
function. This function initializes the table with the
specified data, columns, and core row model.
<script lang="ts">
import { createRawSnippet } from 'svelte';
import { createColumnHelper } from '$lib/table';
import { createColumnHelper, createSvelteTable, getCoreRowModel } from '$lib/table';
import { type UserProfile } from '$lib/services/user-profile';
import { type UserProfile, userProfiles } from '$lib/services/user-profile';
const mailtoSnippet = createRawSnippet<[string]>((email) => {
const emailAddress = email();
return {
render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`
};
});
const colHelp = createColumnHelper<UserProfile>();
const columnDefs = [
colHelp.accessor('name', {
header: 'Name',
cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue())
}),
colHelp.accessor('age', { header: 'Age' }),
colHelp.accessor('email', {
header: 'Email',
cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue())
}),
colHelp.accessor('phone', { header: 'Phone' })
];
const table = createSvelteTable({
data: userProfiles,
columns: columnDefs,
getCoreRowModel: getCoreRowModel()
});
</script>
{#snippet strongSnippet(content: string)}
<strong>{content}</strong>
{/snippet}
Rendering the Table
Finally, to render the table itself, we use the FlexRender
component.
FlexRender
is responsible for dynamically rendering the table's cells based on
the content and context provided.
<table>
<thead>
<tr>
{#each table.getHeaderGroups() as headerGroup}
{#each headerGroup.headers as header}
<th>
<FlexRender content={header.column.columnDef.header} context={header.getContext()} />
</th>
{/each}
{/each}
</tr>
</thead>
<tbody>
{#each table.getRowModel().rows as row}
<tr>
{#each row.getVisibleCells() as cell}
<td>
<FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
</td>
{/each}
</tr>
{/each}
</tbody>
</table>